commit 5fa2fe0d57c7e55403f1a90e07e8366bc10c2256 Author: Igor I Date: Mon Nov 6 13:50:17 2023 +0600 Первый коммит diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..e070e43 --- /dev/null +++ b/.classpath @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.metadata/.lock b/.metadata/.lock new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.log b/.metadata/.log new file mode 100644 index 0000000..125c630 --- /dev/null +++ b/.metadata/.log @@ -0,0 +1,44 @@ +!SESSION 2023-11-03 14:21:07.017 ----------------------------------------------- +eclipse.buildId=4.29.0.20230907-1200 +java.version=17.0.8.1 +java.vendor=Eclipse Adoptium +BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=ru_RU +Framework arguments: -product org.eclipse.epp.package.jee.product +Command-line arguments: -os win32 -ws win32 -arch x86_64 -product org.eclipse.epp.package.jee.product + +!ENTRY org.eclipse.emf.ecore 2 0 2023-11-03 14:21:30.834 +!MESSAGE Both 'org.eclipse.jst.j2ee.core' and 'org.eclipse.jst.j2ee.core' register a package for 'application.xmi' + +!ENTRY ch.qos.logback.classic 1 0 2023-11-03 14:21:31.045 +!MESSAGE Activated before the state location was initialized. Retry after the state location is initialized. + +!ENTRY ch.qos.logback.classic 1 0 2023-11-03 14:22:08.054 +!MESSAGE Logback config file: O:\projects\Workspace_Java\CCALM_TOMCAT\.metadata\.plugins\org.eclipse.m2e.logback\logback.2.2.0.20230625-0847.xml + +!ENTRY org.eclipse.jface 2 0 2023-11-03 14:22:10.937 +!MESSAGE Keybinding conflicts occurred. They may interfere with normal accelerator operation. +!SUBENTRY 1 org.eclipse.jface 2 0 2023-11-03 14:22:10.937 +!MESSAGE A conflict occurred for CTRL+SHIFT+T: +Binding(CTRL+SHIFT+T, + ParameterizedCommand(Command(org.eclipse.jdt.ui.navigate.open.type,Open Type, + Open a type in a Java editor, + Category(org.eclipse.ui.category.navigate,Navigate,null,true), + WorkbenchHandlerServiceHandler("org.eclipse.jdt.ui.navigate.open.type"), + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.ui.contexts.window,,,system) +Binding(CTRL+SHIFT+T, + ParameterizedCommand(Command(org.eclipse.lsp4e.symbolinworkspace,Go to Symbol in Workspace, + , + Category(org.eclipse.lsp4e.category,Language Servers,null,true), + WorkbenchHandlerServiceHandler("org.eclipse.lsp4e.symbolinworkspace"), + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.ui.contexts.window,,,system) + +!ENTRY org.eclipse.egit.ui 2 0 2023-11-03 14:22:15.356 +!MESSAGE Warning: The environment variable HOME is not set. The following directory will be used to store the Git +user global configuration and to define the default location to store repositories: 'C:\Users\ivanov.i'. If this is +not correct please set the HOME environment variable and restart Eclipse. Otherwise Git for Windows and +EGit might behave differently since they see different configuration options. +This warning can be switched off on the Team > Git > Confirmations and Warnings preference page. diff --git a/.metadata/.mylyn/repositories.xml.zip b/.metadata/.mylyn/repositories.xml.zip new file mode 100644 index 0000000..17c91d2 Binary files /dev/null and b/.metadata/.mylyn/repositories.xml.zip differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.egit.core.cmp/.location b/.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.egit.core.cmp/.location new file mode 100644 index 0000000..cb7deac Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.egit.core.cmp/.location differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version new file mode 100644 index 0000000..25cb955 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index new file mode 100644 index 0000000..d237251 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version new file mode 100644 index 0000000..6b2aaa7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree b/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree new file mode 100644 index 0000000..1897f4c Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.root/1.tree differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources new file mode 100644 index 0000000..391198f Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources differ diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..30841eb --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +encoding=UTF-8 +version=1 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 0000000..3429fd0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,8 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.internal.ui.navigator.layout=2 +org.eclipse.jdt.internal.ui.navigator.librariesnode=true +org.eclipse.jdt.ui.formatterprofiles.version=23 +spelling_locale_initialized=true +typefilter_migrated_2=true +useAnnotationsPrefPage=true +useQuickDiffPrefPage=true diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jsch.core.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jsch.core.prefs new file mode 100644 index 0000000..d56c53f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jsch.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.jsch.core.hasChangedDefaultWin32SshHome=true diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jst.j2ee.webservice.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jst.j2ee.webservice.ui.prefs new file mode 100644 index 0000000..553bb96 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jst.j2ee.webservice.ui.prefs @@ -0,0 +1,2 @@ +areThereWebServices=false +eclipse.preferences.version=1 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs new file mode 100644 index 0000000..67b1d96 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.m2e.discovery.pref.projects= diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.context.core.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.context.core.prefs new file mode 100644 index 0000000..43e97e4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.context.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +mylyn.attention.migrated=true diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.monitor.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.monitor.ui.prefs new file mode 100644 index 0000000..8d462a6 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.monitor.ui.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.mylyn.monitor.activity.tracking.enabled.checked=true diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.tasks.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.tasks.ui.prefs new file mode 100644 index 0000000..5330e43 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.tasks.ui.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +migrated.task.repositories.secure.store=true +org.eclipse.mylyn.tasks.ui.filters.nonmatching=true +org.eclipse.mylyn.tasks.ui.filters.nonmatching.encouraged=true diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.browser.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.browser.prefs new file mode 100644 index 0000000..93ec8cd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.browser.prefs @@ -0,0 +1,2 @@ +browsers=\r\n\r\n\r\n\r\n\r\n\r\n +eclipse.preferences.version=1 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs new file mode 100644 index 0000000..2bed5e6 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +platformState=1698999668405 +quickStart=false +tipsAndTricks=true diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.navigator.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.navigator.prefs new file mode 100644 index 0000000..b1831cd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.navigator.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.ui.navigator.ProjectExplorer.filterActivation=\:org.eclipse.jdt.java.ui.filters.HidePackageDeclaration\:org.eclipse.jdt.java.ui.filters.HideOutputFolder\:org.eclipse.buildship.ui.navigator.filter.gradle.subProject\:org.eclipse.ui.navigator.resources.nested.HideTopLevelProjectIfNested\:org.eclipse.buildship.ui.navigator.filter.gradle.buildfolder\:org.eclipse.jdt.java.ui.filters.HideEmptyInnerPackages\:org.eclipse.jst.j2ee.navigator.ui.filters.jetemitters\:org.eclipse.jdt.java.ui.filters.HideInnerClassFiles\:org.eclipse.ui.navigator.resources.filters.startsWithDot\:org.eclipse.jdt.java.ui.filters.HideEmptyLibraryContainers\:org.eclipse.jdt.java.ui.filters.HideImportDeclaration\:org.eclipse.jdt.java.ui.filters.HideSyntheticMembers\:org.eclipse.mylyn.tasks.ui.navigator.filters.tasks\:org.eclipse.ui.navigator.resources.nested.HideFolderWhenProjectIsShownAsNested\: diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs new file mode 100644 index 0000000..08076f2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +showIntro=false diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs new file mode 100644 index 0000000..e2c27f7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs @@ -0,0 +1,14 @@ +//org.eclipse.ui.commands/state/org.eclipse.ui.navigator.resources.nested.changeProjectPresentation/org.eclipse.ui.commands.radioState=false +//org.eclipse.ui.commands/state/org.eclipse.wst.xml.views.XPathView.processor.xpathprocessor/org.eclipse.ui.commands.radioState=xpath10 +PLUGINS_NOT_ACTIVATED_ON_STARTUP=;org.eclipse.m2e.discovery; +SAVE_AUTOMATICALLY=true +eclipse.preferences.version=1 +org.eclipse.ui.workbench.ACTIVE_NOFOCUS_TAB_BG_END=41,41,41 +org.eclipse.ui.workbench.ACTIVE_NOFOCUS_TAB_BG_START=43,44,45 +org.eclipse.ui.workbench.ACTIVE_NOFOCUS_TAB_TEXT_COLOR=204,204,204 +org.eclipse.ui.workbench.ACTIVE_TAB_BG_END=41,41,41 +org.eclipse.ui.workbench.ACTIVE_TAB_BG_START=43,44,45 +org.eclipse.ui.workbench.ACTIVE_TAB_TEXT_COLOR=221,221,221 +org.eclipse.ui.workbench.INACTIVE_TAB_BG_END=49,53,56 +org.eclipse.ui.workbench.INACTIVE_TAB_BG_START=59,64,66 +org.eclipse.ui.workbench.INACTIVE_TAB_TEXT_COLOR=187,187,187 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.urischeme.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.urischeme.prefs new file mode 100644 index 0000000..855d634 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.urischeme.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +processedSchemes=,eclipse+command,eclipse+mpc diff --git a/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi new file mode 100644 index 0000000..9701248 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi @@ -0,0 +1,3121 @@ + + + + activeSchemeId:org.eclipse.ui.defaultAcceleratorConfiguration + + + + + + + + topLevel + + + + + persp.actionSet:org.eclipse.mylyn.doc.actionSet + persp.actionSet:org.eclipse.mylyn.tasks.ui.navigation + persp.actionSet:org.eclipse.ui.cheatsheets.actionSet + persp.actionSet:org.eclipse.search.searchActionSet + persp.actionSet:org.eclipse.text.quicksearch.actionSet + persp.actionSet:org.eclipse.ui.edit.text.actionSet.annotationNavigation + persp.actionSet:org.eclipse.ui.edit.text.actionSet.navigation + persp.actionSet:org.eclipse.ui.edit.text.actionSet.convertLineDelimitersTo + persp.actionSet:org.eclipse.ui.externaltools.ExternalToolsSet + persp.actionSet:org.eclipse.ui.actionSet.keyBindings + persp.actionSet:org.eclipse.ui.actionSet.openFiles + persp.actionSet:org.eclipse.jst.j2ee.J2eeMainActionSet + persp.actionSet:org.eclipse.jdt.ui.JavaActionSet + persp.actionSet:org.eclipse.debug.ui.launchActionSet + persp.actionSet:org.eclipse.ui.NavigateActionSet + persp.actionSet:org.eclipse.debug.ui.debugActionSet + persp.viewSC:org.eclipse.ui.navigator.ProjectExplorer + persp.viewSC:org.eclipse.wst.server.ui.ServersView + persp.viewSC:org.eclipse.datatools.connectivity.DataSourceExplorerNavigator + persp.viewSC:org.eclipse.ui.views.BookmarkView + persp.viewSC:org.eclipse.ui.views.ContentOutline + persp.viewSC:org.eclipse.ui.views.PropertySheet + persp.viewSC:org.eclipse.wst.common.snippets.internal.ui.SnippetsView + persp.viewSC:org.eclipse.ui.views.AllMarkersView + persp.viewSC:org.eclipse.ui.views.ProblemView + persp.viewSC:org.eclipse.mylyn.tasks.ui.views.tasks + persp.viewSC:org.eclipse.tm.terminal.view.ui.TerminalsView + persp.viewSC:org.eclipse.jdt.ui.PackagesView + persp.viewSC:org.eclipse.search.ui.views.SearchView + persp.viewSC:org.eclipse.ui.console.ConsoleView + persp.showIn:org.eclipse.ui.navigator.ProjectExplorer + persp.showIn:org.eclipse.jdt.ui.PackagesView + persp.actionSet:org.eclipse.wst.ws.explorer.explorer + persp.newWizSC:org.eclipse.m2e.core.wizards.Maven2ProjectWizard + persp.newWizSC:org.eclipse.wst.css.ui.internal.wizard.NewCSSWizard + persp.newWizSC:org.eclipse.wst.jsdt.ui.NewJSWizard + persp.editorOnboardingText:Open a file or drop files here to open them. + persp.editorOnboardingCommand:Find Actions$$$Ctrl+3 + persp.editorOnboardingCommand:Show Key Assist$$$Ctrl+Shift+L + persp.editorOnboardingCommand:New$$$Ctrl+N + persp.perspSC:org.eclipse.debug.ui.DebugPerspective + persp.perspSC:org.eclipse.jdt.ui.JavaPerspective + persp.perspSC:org.eclipse.ui.resourcePerspective + persp.perspSC:org.eclipse.wst.web.ui.webDevPerspective + persp.newWizSC:org.eclipse.jst.j2ee.ui.project.facet.EarProjectWizard + persp.newWizSC:org.eclipse.jst.servlet.ui.project.facet.WebProjectWizard + persp.newWizSC:org.eclipse.jst.ejb.ui.project.facet.EjbProjectWizard + persp.newWizSC:org.eclipse.jst.j2ee.jca.ui.internal.wizard.ConnectorProjectWizard + persp.newWizSC:org.eclipse.jst.j2ee.ui.project.facet.appclient.AppClientProjectWizard + persp.newWizSC:org.eclipse.wst.web.ui.internal.wizards.SimpleWebProjectWizard + persp.newWizSC:org.eclipse.jpt.ui.wizard.newJpaProject + persp.newWizSC:org.eclipse.jst.servlet.ui.internal.wizard.AddServletWizard + persp.newWizSC:org.eclipse.jst.ejb.ui.internal.wizard.AddSessionBeanWizard + persp.newWizSC:org.eclipse.jst.ejb.ui.internal.wizard.AddMessageDrivenBeanWizard + persp.newWizSC:org.eclipse.jpt.ui.wizard.newEntity + persp.newWizSC:org.eclipse.jst.ws.creation.ui.wizard.serverwizard + persp.newWizSC:org.eclipse.wst.html.ui.internal.wizard.NewHTMLWizard + persp.newWizSC:org.eclipse.wst.xml.ui.internal.wizards.NewXMLWizard + persp.newWizSC:org.eclipse.ui.wizards.new.folder + persp.newWizSC:org.eclipse.ui.wizards.new.file + persp.actionSet:org.eclipse.wst.server.ui.internal.webbrowser.actionSet + persp.actionSet:org.eclipse.debug.ui.breakpointActionSet + persp.actionSet:org.eclipse.eclemma.ui.CoverageActionSet + persp.showIn:org.eclipse.eclemma.ui.CoverageView + persp.showIn:org.eclipse.tm.terminal.view.ui.TerminalsView + persp.newWizSC:org.eclipse.jst.jsp.ui.internal.wizard.NewJSPWizard + persp.newWizSC:org.eclipse.jpt.jpa.ui.wizard.newJpaProject + persp.perspSC:org.eclipse.jpt.ui.jpaPerspective + + + active + + View + categoryTag:General + + + View + categoryTag:Java Browsing + + + View + categoryTag:General + + + View + categoryTag:Java + + + View + categoryTag:Debug + + + View + categoryTag:General + + + View + categoryTag:Git + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + + + + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + + + + View + categoryTag:General + + + View + categoryTag:Server + + + View + categoryTag:Terminal + + + View + categoryTag:Data Management + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:Java + + + View + categoryTag:Java Browsing + + + View + categoryTag:Java + + + + + + + + + View + categoryTag:Help + + + View + categoryTag:General + + + View + categoryTag:Help + + + + + + + View + categoryTag:Help + + + + + + View + categoryTag:General + + ViewMenu + menuContribution:menu + + + + + + + View + categoryTag:Help + + + + org.eclipse.e4.primaryDataStack + EditorStack + + + + + + + View + categoryTag:General + active + activeOnClose + + ViewMenu + menuContribution:menu + + + + + + + View + categoryTag:Java Browsing + + + + + View + categoryTag:Java + + + + + View + categoryTag:Debug + + + + + View + categoryTag:General + + + + + View + categoryTag:Git + + + + + + View + categoryTag:General + + ViewMenu + menuContribution:menu + + + + + + + View + categoryTag:Server + + + + + View + categoryTag:Terminal + + + + + View + categoryTag:Data Management + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:Java + + + + + View + categoryTag:Java Browsing + + + + + View + categoryTag:Java + + + + + + View + categoryTag:General + + ViewMenu + menuContribution:menu + + + + + + + View + categoryTag:General + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Debug + + + + toolbarSeparator + + + + Draggable + + + + toolbarSeparator + + + + Draggable + + + + + toolbarSeparator + + + + Draggable + + + Draggable + + + Draggable + + + Draggable + + + Draggable + + + toolbarSeparator + + + + Draggable + + + + toolbarSeparator + + + + toolbarSeparator + + + + Draggable + + + stretch + SHOW_RESTORE_MENU + + + Draggable + HIDEABLE + SHOW_RESTORE_MENU + + + + + stretch + + + Draggable + + + Draggable + + + + + TrimStack + Draggable + + + + + + + + + + + + + + + + + + + + + + platform:win32 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + platform:win32 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Editor + removeOnHide + + + + + View + categoryTag:Ant + + + + + View + categoryTag:Gradle + + + + + View + categoryTag:Gradle + + + + + View + categoryTag:Data Management + + + + + View + categoryTag:Data Management + + + + + View + categoryTag:Data Management + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + + + View + categoryTag:Java + + + + + View + categoryTag:Git + + + + + View + categoryTag:Git + + + + + View + categoryTag:Git + + + + + View + categoryTag:Git + NoRestore + + + + + View + categoryTag:Git + + + + + View + categoryTag:General + + + + + View + categoryTag:Help + + + + + View + categoryTag:Java + + + + + View + categoryTag:Java + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Java + + + + + View + categoryTag:Java + + + + + View + categoryTag:Java + + + + + View + categoryTag:Java Browsing + + + + + View + categoryTag:Java Browsing + + + + + View + categoryTag:Java Browsing + + + + + View + categoryTag:Java Browsing + + + + + View + categoryTag:Java + + + + + View + categoryTag:General + + + + + View + categoryTag:Java + + + + + View + categoryTag:Java + + + + + View + categoryTag:JPA + + + + + View + categoryTag:JPA + + + + + View + categoryTag:JavaServer Faces + + + + + View + categoryTag:JavaServer Faces + + + + + View + categoryTag:Web Services + + + + + View + categoryTag:Language Servers + + + + + View + categoryTag:Language Servers + + + + + View + categoryTag:Language Servers + + + + + View + categoryTag:Maven + + + + + View + categoryTag:Maven + + + + + View + categoryTag:Maven + + + + + View + categoryTag:Mylyn + + + + + View + categoryTag:Mylyn + + + + + View + categoryTag:Mylyn + + + + + View + categoryTag:Mylyn + + + + + View + categoryTag:Mylyn + + + + + View + categoryTag:Mylyn + + + + + View + categoryTag:Oomph + + + + + View + categoryTag:API Tools + + + + + View + categoryTag:Plug-in Development + + + + + View + categoryTag:Plug-in Development + + + + + View + categoryTag:Plug-in Development + + + + + View + categoryTag:Plug-in Development + + + + + View + categoryTag:Plug-in Development + + + + + View + categoryTag:Plug-in Development + + + + + View + categoryTag:General + + + + + View + categoryTag:Version Control (Team) + + + + + View + categoryTag:Version Control (Team) + + + View + categoryTag:Help + + + + + View + categoryTag:Terminal + + + + + View + categoryTag:Other + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:Help + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:General + + + + + View + categoryTag:Debug + + + + + View + categoryTag:Other + + + + + View + categoryTag:Other + + + + + View + categoryTag:Other + + + + + View + categoryTag:Server + + + + + View + categoryTag:XML + + + + + View + categoryTag:XML + + + + + View + categoryTag:XML + + + + + View + categoryTag:XML + + + + + View + categoryTag:XML + + + + glue + move_after:PerspectiveSpacer + SHOW_RESTORE_MENU + + + move_after:Spacer Glue + HIDEABLE + SHOW_RESTORE_MENU + + + glue + move_after:SearchField + SHOW_RESTORE_MENU + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.egit.core/.org.eclipse.egit.core.cmp/.project b/.metadata/.plugins/org.eclipse.egit.core/.org.eclipse.egit.core.cmp/.project new file mode 100644 index 0000000..3c10856 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.egit.core/.org.eclipse.egit.core.cmp/.project @@ -0,0 +1,11 @@ + + + .org.eclipse.egit.core.cmp + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.egit.core/.org.eclipse.egit.core.cmp/.settings/org.eclipse.core.resources.prefs b/.metadata/.plugins/org.eclipse.egit.core/.org.eclipse.egit.core.cmp/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.egit.core/.org.eclipse.egit.core.cmp/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/.metadata/.plugins/org.eclipse.jdt.core/assumedExternalFilesCache b/.metadata/.plugins/org.eclipse.jdt.core/assumedExternalFilesCache new file mode 100644 index 0000000..593f470 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/assumedExternalFilesCache differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache b/.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache new file mode 100644 index 0000000..593f470 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt b/.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt new file mode 100644 index 0000000..8586397 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt @@ -0,0 +1 @@ +java \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache b/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache new file mode 100644 index 0000000..593f470 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat b/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat new file mode 100644 index 0000000..3de398e Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat differ diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml new file mode 100644 index 0000000..a4ee3cb --- /dev/null +++ b/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml @@ -0,0 +1,2 @@ + + diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml new file mode 100644 index 0000000..9e390f5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml @@ -0,0 +1,2 @@ + + diff --git a/.metadata/.plugins/org.eclipse.m2e.core/workspaceState.ser b/.metadata/.plugins/org.eclipse.m2e.core/workspaceState.ser new file mode 100644 index 0000000..abbf8e5 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.m2e.core/workspaceState.ser differ diff --git a/.metadata/.plugins/org.eclipse.m2e.logback/0.log b/.metadata/.plugins/org.eclipse.m2e.logback/0.log new file mode 100644 index 0000000..1cc4067 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.m2e.logback/0.log @@ -0,0 +1 @@ +2023-11-03 14:22:15,281 [Worker-1: Loading available Gradle versions] INFO o.e.b.c.i.u.g.PublishedGradleVersions - Gradle version information cache is not available. Remote download required. diff --git a/.metadata/.plugins/org.eclipse.m2e.logback/logback.2.2.0.20230625-0847.xml b/.metadata/.plugins/org.eclipse.m2e.logback/logback.2.2.0.20230625-0847.xml new file mode 100644 index 0000000..9effde7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.m2e.logback/logback.2.2.0.20230625-0847.xml @@ -0,0 +1,41 @@ + + + + %date [%thread] %-5level %logger{35} - %msg%n + + + ${org.eclipse.m2e.log.console.threshold:-OFF} + + + + + ${org.eclipse.m2e.log.dir}/0.log + + ${org.eclipse.m2e.log.dir}/%i.log + 1 + 10 + + + 10MB + + + %date [%thread] %-5level %logger{35} - %msg%n + + + + + + WARN + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.mylyn.github.ui/avatars.ser b/.metadata/.plugins/org.eclipse.mylyn.github.ui/avatars.ser new file mode 100644 index 0000000..1e9a069 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.mylyn.github.ui/avatars.ser differ diff --git a/.metadata/.plugins/org.eclipse.oomph.setup/workspace.setup b/.metadata/.plugins/org.eclipse.oomph.setup/workspace.setup new file mode 100644 index 0000000..1f73e14 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.oomph.setup/workspace.setup @@ -0,0 +1,6 @@ + + diff --git a/.metadata/.plugins/org.eclipse.tips.ide/dialog_settings.xml b/.metadata/.plugins/org.eclipse.tips.ide/dialog_settings.xml new file mode 100644 index 0000000..5ca0b77 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.tips.ide/dialog_settings.xml @@ -0,0 +1,3 @@ + +
+
diff --git a/.metadata/.plugins/org.eclipse.ui.intro/introstate b/.metadata/.plugins/org.eclipse.ui.intro/introstate new file mode 100644 index 0000000..02f134f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ui.intro/introstate @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml b/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml new file mode 100644 index 0000000..3be1280 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.metadata/version.ini b/.metadata/version.ini new file mode 100644 index 0000000..c491dc7 --- /dev/null +++ b/.metadata/version.ini @@ -0,0 +1,3 @@ +#Fri Nov 03 14:22:07 ALMT 2023 +org.eclipse.core.runtime=2 +org.eclipse.platform=4.29.0.v20230903-1000 diff --git a/.project b/.project new file mode 100644 index 0000000..1d8a8ea --- /dev/null +++ b/.project @@ -0,0 +1,69 @@ + + + CCALM_TOMCAT + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.springframework.ide.eclipse.core.springbuilder + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.springframework.ide.eclipse.core.springnature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.wst.common.modulecore.ModuleCoreNature + org.eclipse.wst.jsdt.core.jsNature + + + + src/main/java/tctable/Point.java + 1 + O:/projects/Workspace_Android/ASDC/app/src/main/java/tctable/Point.java + + + src/main/java/tctable/TCField.java + 1 + O:/projects/Workspace_Android/ASDC/app/src/main/java/tctable/TCField.java + + + src/main/java/tctable/TCTable.java + 1 + O:/projects/Workspace_Android/ASDC/app/src/main/java/tctable/TCTable.java + + + src/main/java/tctable/Tools.java + 1 + O:/projects/Workspace_Android/ASDC/app/src/main/java/tctable/Tools.java + + + diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..f89addf --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,13 @@ +eclipse.preferences.version=1 +encoding//src/main/java/messages_az.properties_not_used=UTF-8 +encoding//src/main/java/messages_en.properties_not_used=UTF-8 +encoding//src/main/java/messages_hy.properties_not_used=UTF-8 +encoding//src/main/java/messages_ka.properties_not_used=UTF-8 +encoding//src/main/java/messages_kg.properties_not_used=UTF-8 +encoding//src/main/java/messages_ps.properties_not_used=UTF-8 +encoding//src/main/java/messages_ru.properties_not_used=UTF-8 +encoding//src/main/java/messages_tg.properties_not_used=UTF-8 +encoding//src/main/java/messages_tk.properties_not_used=UTF-8 +encoding//src/main/java/messages_uz.properties_not_used=UTF-8 +encoding//src/main/java/not_used=UTF-8 +encoding//src/main/webapp/WEB-INF/views/excel.jsp=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..3a0745f --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,16 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs b/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs new file mode 100644 index 0000000..7c8126d --- /dev/null +++ b/.settings/org.eclipse.jst.j2ee.ejb.annotations.xdoclet.prefs @@ -0,0 +1,5 @@ +XDOCLETBUILDERACTIVE=true +XDOCLETHOME= +XDOCLETUSEGLOBAL=true +XDOCLETVERSION=1.2.1 +eclipse.preferences.version=1 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/.settings/org.eclipse.wst.common.component b/.settings/org.eclipse.wst.common.component new file mode 100644 index 0000000..dbfa1b6 --- /dev/null +++ b/.settings/org.eclipse.wst.common.component @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 0000000..2ba37f6 --- /dev/null +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/.settings/org.eclipse.wst.jsdt.ui.prefs b/.settings/org.eclipse.wst.jsdt.ui.prefs new file mode 100644 index 0000000..6bf5ec1 --- /dev/null +++ b/.settings/org.eclipse.wst.jsdt.ui.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.wst.jsdt.ui.text.custom_code_templates= diff --git a/.settings/org.eclipse.wst.jsdt.ui.superType.container b/.settings/org.eclipse.wst.jsdt.ui.superType.container new file mode 100644 index 0000000..49c8cd4 --- /dev/null +++ b/.settings/org.eclipse.wst.jsdt.ui.superType.container @@ -0,0 +1 @@ +org.eclipse.wst.jsdt.launching.JRE_CONTAINER \ No newline at end of file diff --git a/.settings/org.eclipse.wst.jsdt.ui.superType.name b/.settings/org.eclipse.wst.jsdt.ui.superType.name new file mode 100644 index 0000000..11006e2 --- /dev/null +++ b/.settings/org.eclipse.wst.jsdt.ui.superType.name @@ -0,0 +1 @@ +Global \ No newline at end of file diff --git a/.settings/org.eclipse.wst.validation.prefs b/.settings/org.eclipse.wst.validation.prefs new file mode 100644 index 0000000..ca90b67 --- /dev/null +++ b/.settings/org.eclipse.wst.validation.prefs @@ -0,0 +1,6 @@ +DELEGATES_PREFERENCE=delegateValidatorListorg.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator\=org.eclipse.wst.wsdl.validation.internal.eclipse.Validator;org.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator\=org.eclipse.wst.xsd.core.internal.validation.eclipse.Validator; +USER_BUILD_PREFERENCE=enabledBuildValidatorListorg.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator;org.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator;org.eclipse.jst.jsf.validation.internal.JSPSemanticsValidator;org.eclipse.wst.dtd.core.internal.validation.eclipse.Validator;org.eclipse.wst.xml.core.internal.validation.eclipse.Validator;org.eclipse.wst.common.componentcore.internal.ModuleCoreValidator;org.eclipse.jst.jsf.validation.internal.appconfig.AppConfigValidator;org.eclipse.jst.jsp.core.internal.validation.JSPBatchValidator;org.eclipse.wst.html.internal.validation.HTMLValidator;org.eclipse.jst.jsp.core.internal.validation.JSPContentValidator;org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;org.eclipse.wst.wsi.ui.internal.WSIMessageValidator; +USER_MANUAL_PREFERENCE=enabledManualValidatorListorg.eclipse.wst.wsdl.validation.internal.eclipse.WSDLDelegatingValidator;org.eclipse.wst.xsd.core.internal.validation.eclipse.XSDDelegatingValidator;org.eclipse.jst.jsf.validation.internal.JSPSemanticsValidator;org.eclipse.wst.dtd.core.internal.validation.eclipse.Validator;org.eclipse.wst.xml.core.internal.validation.eclipse.Validator;org.eclipse.wst.common.componentcore.internal.ModuleCoreValidator;org.eclipse.jst.jsf.validation.internal.appconfig.AppConfigValidator;org.eclipse.jst.jsp.core.internal.validation.JSPBatchValidator;org.eclipse.wst.html.internal.validation.HTMLValidator;org.eclipse.jst.jsp.core.internal.validation.JSPContentValidator;org.eclipse.jst.j2ee.internal.classpathdep.ClasspathDependencyValidator;org.eclipse.wst.wsi.ui.internal.WSIMessageValidator; +USER_PREFERENCE=overrideGlobalPreferencesfalse +disabled=06target +eclipse.preferences.version=1 diff --git a/.settings/org.springframework.ide.eclipse.beans.core.prefs b/.settings/org.springframework.ide.eclipse.beans.core.prefs new file mode 100644 index 0000000..bb50bcf --- /dev/null +++ b/.settings/org.springframework.ide.eclipse.beans.core.prefs @@ -0,0 +1,78 @@ +#Mon Oct 18 12:37:52 EDT 2010 +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.osgi.org/xmlns/blueprint/v1.0.0= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/aop= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/batch= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/beans= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/context= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/faces= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/flex= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/integration= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/integration/file= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/integration/http= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/integration/httpinvoker= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/integration/ip= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/integration/jdbc= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/integration/jms= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/integration/jmx= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/integration/mail= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/integration/rmi= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/integration/security= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/integration/stream= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/integration/ws= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/integration/xml= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/jdbc= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/jee= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/jms= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/lang= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/mvc= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/osgi= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/osgi-compendium= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/oxm= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/p= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/security= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/task= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/tx= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/util= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/web-services= +//org.springframework.ide.eclipse.beans.core.default.version.http\://www.springframework.org/schema/webflow-config= +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.osgi.org/xmlns/blueprint/v1.0.0=bp +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/aop=aop +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/batch=batch +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/beans=beans +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/context=context +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/faces=faces +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/flex=flex +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/integration=int +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/integration/file=int-file +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/integration/http=int-http +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/integration/httpinvoker=int-httpinvoker +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/integration/ip=int-ip +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/integration/jdbc=int-jdbc +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/integration/jms=int-jms +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/integration/jmx=int-jmx +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/integration/mail=int-mail +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/integration/rmi=int-rmi +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/integration/security=int-security +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/integration/stream=int-stream +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/integration/ws=int-ws +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/integration/xml=int-xml +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/jdbc=jdbc +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/jee=jee +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/jms=jms +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/lang=lang +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/mvc=mvc +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/osgi=osgi +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/osgi-compendium=osgix +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/oxm=oxm +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/p=p +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/security=sec +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/task=task +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/tx=tx +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/util=util +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/web-services=ws +//org.springframework.ide.eclipse.beans.core.prefix.http\://www.springframework.org/schema/webflow-config=flow +eclipse.preferences.version=1 +org.springframework.ide.eclipse.beans.core.default.version.check.classpath=true +org.springframework.ide.eclipse.beans.core.enable.project.preferences=false +org.springframework.ide.eclipse.beans.core.ignoreMissingNamespaceHandler=false +org.springframework.ide.eclipse.beans.core.loadNamespaceHandlerFromClasspath=false diff --git a/.settings/org.springframework.ide.eclipse.core.prefs b/.settings/org.springframework.ide.eclipse.core.prefs new file mode 100644 index 0000000..0f65cd5 --- /dev/null +++ b/.settings/org.springframework.ide.eclipse.core.prefs @@ -0,0 +1,69 @@ +#Tue Apr 20 16:59:06 EDT 2010 +eclipse.preferences.version=1 +org.springframework.ide.eclipse.core.builders.enable.aopreferencemodelbuilder=true +org.springframework.ide.eclipse.core.builders.enable.beanmetadatabuilder=true +org.springframework.ide.eclipse.core.builders.enable.osgibundleupdater=false +org.springframework.ide.eclipse.core.enable.project.preferences=false +org.springframework.ide.eclipse.core.validator.enable.com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.enable.com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.core.springvalidator=false +org.springframework.ide.eclipse.core.validator.enable.org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.applicationSymbolicNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.applicationVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleActivationPolicyRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleActivatorRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleManifestVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleSymbolicNameRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.bundleVersionRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.exportPackageRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.importRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.parsingProblemsRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.server.ide.manifest.core.requireBundleRule-com.springsource.server.ide.manifest.core.manifestvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.AvoidDriverManagerDataSource-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.ImportElementsAtTopRulee-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.ParentBeanSpecifiesAbstractClassRule-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.RefElementRule-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.TooManyBeansInFileRule-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.UnnecessaryValueElementRule-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.com.springsource.sts.bestpractices.UseBeanInheritance-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.bestpractices.legacyxmlusage.jndiobjectfactory-com.springsource.sts.bestpractices.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importBundleVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importLibraryVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.importPackageVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.com.springsource.sts.server.quickfix.requireBundleVersionRule-com.springsource.sts.server.quickfix.manifestvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.autowire.autowire-org.springframework.ide.eclipse.beans.core.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanAlias-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanClass-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanConstructorArgument-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanDefinition-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanDefinitionHolder-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanFactory-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanInitDestroyMethod-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.beanReference-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.methodOverride-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.parsingProblems-org.springframework.ide.eclipse.beans.core.beansvalidator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.requiredProperty-org.springframework.ide.eclipse.beans.core.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.beans.core.toolAnnotation-org.springframework.ide.eclipse.beans.core.beansvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.core.springClasspath-org.springframework.ide.eclipse.core.springvalidator=false +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.action-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.actionstate-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.attributemapper-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.beanaction-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.evaluationaction-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.evaluationresult-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.exceptionhandler-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.import-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.inputattribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.mapping-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.outputattribute-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.set-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.state-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.subflowstate-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.transition-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.variable-org.springframework.ide.eclipse.webflow.core.validator=true +org.springframework.ide.eclipse.core.validator.rule.enable.org.springframework.ide.eclipse.webflow.core.validation.webflowstate-org.springframework.ide.eclipse.webflow.core.validator=true diff --git a/.springBeans b/.springBeans new file mode 100644 index 0000000..4d9eb32 --- /dev/null +++ b/.springBeans @@ -0,0 +1,13 @@ + + + 1 + + + + + + + + + + diff --git a/GettextDB/settings.ini b/GettextDB/settings.ini new file mode 100644 index 0000000..546e044 --- /dev/null +++ b/GettextDB/settings.ini @@ -0,0 +1,12 @@ +[main] +db_url = jdbc\:postgresql\://10.1.7.74\:5432/pilot +db_user = +db_password = + +[path0] +path = O\:\\projects\\Workspace_Java\\CCALM_TOMCAT +check = trt( +extensions = (.*\\.java$)||(.*\\.xml$)||(.*\\.js$) +pattern = [0-9|a-z|A-Z|_]+ +type = 1 + diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..635dbc7 --- /dev/null +++ b/pom.xml @@ -0,0 +1,257 @@ + + 4.0.0 + kz.locust + CCALM + Locust + war + 1.0.0-BUILD-SNAPSHOT + + 1.8 + 5.0.0.RELEASE + 1.8.12 + 1.7.25 + + + + + + + + + + org.gdal + gdal + 2.4.0 + system + O:\projects\_Libs\gdal-2.4.0.jar + + + + + + + org.json + json + 20200518 + + + + + org.postgresql + postgresql + 42.1.4 + + + + + + + edu.ucar + netcdfAll + 5.3.1 + system + O:\projects\_Libs\netcdfAll-5.3.1.jar + + + + + javax.mail + mail + 1.4 + + + + + org.apache.commons + commons-io + 1.3.2 + + + + + commons-fileupload + commons-fileupload + 1.3.1 + + + + + com.fasterxml.jackson.core + jackson-core + 2.13.0 + + + + + + com.fasterxml.jackson.core + jackson-databind + 2.9.1 + + + + + org.springframework + spring-context + ${org.springframework-version} + + + + commons-logging + commons-logging + + + + + org.springframework + spring-webmvc + ${org.springframework-version} + + + + + org.aspectj + aspectjrt + ${org.aspectj-version} + + + + + org.slf4j + slf4j-api + ${org.slf4j-version} + + + org.slf4j + jcl-over-slf4j + ${org.slf4j-version} + runtime + + + org.slf4j + slf4j-log4j12 + ${org.slf4j-version} + runtime + + + log4j + log4j + 1.2.15 + + + javax.mail + mail + + + javax.jms + jms + + + com.sun.jdmk + jmxtools + + + com.sun.jmx + jmxri + + + runtime + + + + + javax.inject + javax.inject + 1 + + + + + javax.servlet + servlet-api + 2.5 + provided + + + javax.servlet.jsp + jsp-api + 2.1 + provided + + + javax.servlet + jstl + 1.2 + + + + + junit + junit + 4.7 + test + + + + + + maven-war-plugin + 3.2.1 + + WebContent + + + + maven-eclipse-plugin + 2.9 + + + org.springframework.ide.eclipse.core.springnature + + + org.springframework.ide.eclipse.core.springbuilder + + true + true + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.5.1 + + 1.8 + 1.8 + -Xlint:all + true + true + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + org.test.int1.Main + + + + + diff --git a/src/main/java/kz/locust/CCALM/AcceptASDC.java b/src/main/java/kz/locust/CCALM/AcceptASDC.java new file mode 100644 index 0000000..3667137 --- /dev/null +++ b/src/main/java/kz/locust/CCALM/AcceptASDC.java @@ -0,0 +1,2288 @@ +package kz.locust.CCALM; + +import java.io.BufferedOutputStream; +import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; +import java.io.File; +//import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +//import java.io.OutputStream; +//import java.io.UnsupportedEncodingException; +import java.nio.file.Files; +//import java.nio.file.Paths; +import java.nio.file.attribute.BasicFileAttributes; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Types; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.TimeZone; +import java.util.concurrent.TimeUnit; +//import java.util.zip.CRC32; +//import java.util.zip.Checksum; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletResponse; +//import javax.servlet.http.Part; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.json.JSONObject; +//import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.FileSystemResource; +//import org.springframework.core.io.FileSystemResource; +import org.springframework.stereotype.Controller; +//import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.context.ServletContextAware; +import org.springframework.web.multipart.MultipartFile; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import tctable.TCField; +import tctable.TCTable; +import tctable.Tools; +import tools.STools; + +@Controller +public class AcceptASDC implements ServletContextAware { + + private static final Logger logger = LoggerFactory.getLogger(AcceptASDC.class); + private ServletContext context; + + public static final String md5(final String str) + { + try { + // Create MD5 Hash + MessageDigest digest = java.security.MessageDigest + .getInstance("MD5"); + digest.update(str.getBytes()); + byte messageDigest[] = digest.digest(); + + // Create Hex String + StringBuffer hexString = new StringBuffer(); + for (int i = 0; i < messageDigest.length; i++) { + String h = Integer.toHexString(0xFF & messageDigest[i]); + while (h.length() < 2) + h = "0" + h; + hexString.append(h); + } + return hexString.toString(); + + } catch (NoSuchAlgorithmException ex) { + ex.printStackTrace(); + } + return ""; + } + /*public String MD5(String md5) { + try { + java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5"); + byte[] array = md.digest(md5.getBytes()); + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < array.length; ++i) { + sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1,3)); + } + return sb.toString(); + } catch (java.security.NoSuchAlgorithmException e) { + } + return ""; + }*/ + + // To authorize a tablet using a QR code from "ScanActivity" form + @RequestMapping(value = "/asdc/qrcode",method = { RequestMethod.GET, RequestMethod.POST },produces = "application/json; charset=utf-8") + @ResponseBody + public Object uploadJSON(@RequestHeader(required=false,name="Content-Type") String contentType,HttpServletResponse response,@RequestBody(required=false) byte[] reqData) { + + JSONObject result = new JSONObject(); + result.put("errorCode", 0); + result.put("errorMessage", ""); + + String db_url=""; + String db_login=""; + String db_password=""; + //Load DB configuration + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain=doc.getDocumentElement(); + NodeList nl=nMain.getChildNodes(); + for (int i = 0; i Integer.parseInt(unixTime)) { + try{ conn.close(); }catch(Exception e){} + JSONObject obj = new JSONObject(); + obj.put("errorCode",1); + obj.put("errorMessage", "QR code is outdated!"); + return obj.toString(); + } + + //Clear the serial number if it is in the database + String sql="update main.terminals set serial=null where serial=?"; + PreparedStatement stmt=null; + try { + stmt = conn.prepareStatement(sql); + } catch (SQLException ex) { + try{ conn.close(); }catch(Exception e){} + JSONObject obj = new JSONObject(); + obj.put("errorCode",1); + obj.put("errorMessage", ex.getMessage()); + return obj.toString(); + } + try { + stmt.setString(1,android_id); + } catch (SQLException ex) { + try{ conn.close(); }catch(Exception e){} + JSONObject obj = new JSONObject(); + obj.put("errorCode",1); + obj.put("errorMessage", ex.getMessage()); + return obj.toString(); + } + try { + stmt.execute(); + } catch (SQLException ex) { + try{ conn.close(); }catch(Exception e){} + JSONObject obj = new JSONObject(); + obj.put("errorCode",1); + obj.put("errorMessage", ex.getMessage()); + return obj.toString(); + } + + sql="update main.terminals set serial=? where id=?"; + stmt=null; + try { + stmt = conn.prepareStatement(sql); + } catch (SQLException ex) { + try{ conn.close(); }catch(Exception e){} + JSONObject obj = new JSONObject(); + obj.put("errorCode",1); + obj.put("errorMessage", ex.getMessage()); + return obj.toString(); + } + + try { + stmt.setString(1,android_id); + stmt.setInt(2,Integer.parseInt(id)); + } catch (SQLException ex) { + try{ conn.close(); }catch(Exception e){} + JSONObject obj = new JSONObject(); + obj.put("errorCode",1); + obj.put("errorMessage", ex.getMessage()); + return obj.toString(); + } + + try { + stmt.execute(); + } catch (SQLException ex) { + try{ conn.close(); }catch(Exception e){} + JSONObject obj = new JSONObject(); + obj.put("errorCode",1); + obj.put("errorMessage", ex.getMessage()); + return obj.toString(); + } + + //Select data + sql = "select t.id,t.name,t.country_id,t.company_id,cp.name as company_name,cr.name as country_name from main.terminals t left join main.companies cp on cp.id=t.company_id left join main.countries cr on cr.id=t.country_id where t.del=false and t.id="+id; + try { + Statement st = conn.createStatement(); + ResultSet rs=null; + try { + rs = st.executeQuery(sql); + } catch( SQLException ex ) { + try{ conn.close(); }catch(Exception e){} //Necessarily! + JSONObject obj = new JSONObject(); + obj.put("errorCode",1); + obj.put("errorMessage", ex.getMessage()); + return obj.toString(); + } + if(rs!=null) + { + while (rs.next()) + { + result.put("id",rs.getInt("id")); + result.put("country_id",rs.getInt("country_id")); + result.put("company_id",rs.getInt("company_id")); + result.put("country_name",rs.getString("country_name")); + result.put("company_name",rs.getString("company_name")); + result.put("name",rs.getString("name")); + } + } + st.close(); + } catch (SQLException ex) { + try{ conn.close(); }catch(Exception e){} + JSONObject obj = new JSONObject(); + obj.put("errorCode",1); + obj.put("errorMessage", ex.getMessage()); + return obj.toString(); + } + }else { + try{ conn.close(); }catch(Exception e){} + JSONObject obj = new JSONObject(); + obj.put("errorCode",1); + obj.put("errorMessage", "Secret code is invalid!"); + return obj.toString(); + } + + + try{ if(conn!=null) conn.close(); }catch(Exception e){} + + return result.toString(); + } + + @RequestMapping(value = "/get",method = { RequestMethod.GET, RequestMethod.POST },produces = "application/xml; charset=utf-8") + @ResponseBody + public Object uploadXML(@RequestHeader(required=false,name="Content-Type") String contentType,HttpServletResponse response,@RequestBody(required=false) byte[] reqData) { + + if(contentType!=null) + logger.info("Content-Type = " + contentType); //INFO : kz.locust.CCALM.AcceptASDC - Content-Type = multipart/form-data; boundary=kTwyQRMc7R9JvmcYlXyvMEwX6B08jb + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + response.setContentType("application/xml"); + String result=""; + //boolean error=false; + + //String metadata_file = ""; + String db_url = ""; + String db_login = ""; + String db_password = ""; + //String mail_host = ""; + //String mail_port = ""; + //String mail_login = ""; + //String mail_password = ""; + String data_dir = ""; + //Load DB configuration from "config.xml" + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("db-url")) + db_url = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-login")) + db_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-password")) + db_password = nl.item(i).getTextContent(); + + if (nl.item(i).getNodeName().equals("data-dir")) + data_dir = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + + //Create temporary directory + String dataDir = data_dir; + String tmpDir = "temp"+File.separator; + try{ new File(dataDir+tmpDir).mkdirs(); }catch (Exception ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=""; + return result; + } + + //Connect to database + Connection conn = null; + try { + Class.forName("org.postgresql.Driver"); + conn = DriverManager.getConnection(db_url, db_login, db_password); + if (conn != null) { + logger.info("Connect is OK!"); + } else { + logRotate(data_dir+"errors.log","An error occurred while connecting to the database!"); + logger.info("An error occurred while connecting to the database!"); + } + } catch (Exception ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + } + /*Statement stt=null; + try { + stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + } catch (SQLException ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + }*/ + + //Set UTC time + Statement stm=null; + try { + stm = conn.createStatement(); + try { + stm.execute("SET timezone TO 'UTC';"); + } catch( SQLException ex ) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=""; + try{ conn.close(); }catch(Exception e){} + return result; + } + stm.close(); + } catch (SQLException ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=""; + try{ conn.close(); }catch(Exception e){} + return result; + } + + logRotate(data_dir+"errors.log","XML = "+(new String(reqData))); + + //Parse incoming XML string + String fn=""; + Document doc = null; + Element reqNode = null; + if(reqData!=null && reqData.length!=0) { + + //Request data + InputStream body = new ByteArrayInputStream(reqData); + + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + doc = dBuilder.parse(body); + } catch (Exception ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=""; + try{ conn.close(); }catch(Exception e){} + return result; + } + + if (doc != null) { + reqNode = doc.getDocumentElement(); + fn = reqNode.getAttribute("fn"); //Номер функции + } + } + if(fn==null) fn=""; + + if(fn.equals("4")) + { + boolean exists=false; //Is there a record. + String uid=getCdataValue(reqNode,"uid"); + logger.info("uid="+uid); + Statement st; + try { + st = conn.createStatement(); + ResultSet rs=null; + try { + rs = st.executeQuery("select 1 from main.frmlocust where uid='"+uid+"'"); + } catch( SQLException ex ) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=(""); + try{ conn.close(); }catch(Exception e){} + return result; + } + if(rs!=null) + { + if(rs.next()) + exists=true; + } + st.close(); + } catch (SQLException ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=(""); + try{ conn.close(); }catch(Exception e){} + return result; + } + + PreparedStatement stmt=null; + if(exists) + { + String sql="update main.frmlocust set\n" + +" uid = ?,\n" + +" changed = false,\n" + +" user_id=?,\n" + +" device_id=?,\n" + +" image_name1=?,\n" + +" image_name2=?,\n" + +" image_name3=?,\n" + +" country_id=?,\n" + +" region_id=?,\n" + +" area=?,\n" + +" district=?,\n" + +" village=?,\n" + +" terrain=?,\n" + +" observer=?,\n" + +" date=?,\n" + +" timezone=?::interval,\n" + +" lat1=?,\n" + +" lon1=?,\n" + +" lat2=?,\n" + +" lon2=?,\n" + +" lat3=?,\n" + +" lon3=?,\n" + +" lat4=?,\n" + +" lon4=?,\n" + +" lat5=?,\n" + +" lon5=?,\n" + +" lat6=?,\n" + +" lon6=?,\n" + +" bio_hectare=?,\n" + +" bio_biotope_id=?,\n" + +" bio_greenery_id=?,\n" + +" bio_greenery_cover_id=?,\n" + +" bio_temperature=?,\n" + +" bio_wind=?,\n" + +" locust_have=?,\n" + +" locust_type_id=?,\n" + +" locust_populated=?,\n" + +" eggs_capsules_area=?,\n" + +" eggs_capsules_density=?,\n" + +" eggs_capsules_density_to=?,\n" + +" eggs_capsules=?,\n" + +" eggs_live=?,\n" + +" eggs_enemies_id=?,\n" + +" larva_born_id=?,\n" + +" larva_age_id=?,\n" + +" larva_painting_id=?,\n" + +" larva_behavior_id=?,\n" + +" larva_density=?,\n" + +" larva_density_to=?,\n" + +" kuliguli_age_id=?,\n" + +" kuliguli_density=?,\n" + +" kuliguli_density_to=?,\n" + +" kuliguli_size=?,\n" + +" kuliguli_count=?,\n" + +" kuliguli_action_id=?,\n" + +" imago_wing_id=?,\n" + +" imago_maturity=?,\n" + +" imago_phase_id=?,\n" + +" imago_action_id=?,\n" + +" imago_density=?,\n" + +" imago_density_ga=?,\n" + +" imago_feeding=?,\n" + +" imago_copulation=?,\n" + +" imago_laying=?,\n" + +" imago_flying=?,\n" + +" swarm_maturity=?,\n" + +" swarm_density_id=?,\n" + +" swarm_size=?,\n" + +" swarm_count=?,\n" + +" swarm_copulation=?,\n" + +" swarm_laying=?,\n" + +" swarm_flying_direction_id=?,\n" + +" swarm_height_id=?,\n" + +" description=?,\n" + +" geom=ST_SetSRID(ST_GeomFromGeoJSON(?),4326),\n" + +" test=?\n" + +" where uid='"+uid+"'"; + try { + stmt = conn.prepareStatement(sql); + } catch (SQLException ex) { + logRotate(data_dir+"errors.log",ex.getMessage()+" "+sql); + logger.info(ex.getMessage()); + result=(""); + try{ conn.close(); }catch(Exception e){} + return result; + } + }else + { + String sql="insert into main.frmlocust(\n" + +" uid,\n" + +" changed,\n" + +" user_id,\n" + +" device_id,\n" + +" image_name1,\n" + +" image_name2,\n" + +" image_name3,\n" + +" country_id,\n" + +" region_id,\n" + +" area,\n" + +" district,\n" + +" village,\n" + +" terrain,\n" + +" observer,\n" + +" date,\n" + +" timezone,\n" + +" lat1,\n" + +" lon1,\n" + +" lat2,\n" + +" lon2,\n" + +" lat3,\n" + +" lon3,\n" + +" lat4,\n" + +" lon4,\n" + +" lat5,\n" + +" lon5,\n" + +" lat6,\n" + +" lon6,\n" + +" bio_hectare,\n" + +" bio_biotope_id,\n" + +" bio_greenery_id,\n" + +" bio_greenery_cover_id,\n" + +" bio_temperature,\n" + +" bio_wind,\n" + +" locust_have,\n" + +" locust_type_id,\n" + +" locust_populated,\n" + +" eggs_capsules_area,\n" + +" eggs_capsules_density,\n" + +" eggs_capsules_density_to,\n" + +" eggs_capsules,\n" + +" eggs_live,\n" + +" eggs_enemies_id,\n" + +" larva_born_id,\n" + +" larva_age_id,\n" + +" larva_painting_id,\n" + +" larva_behavior_id,\n" + +" larva_density,\n" + +" larva_density_to,\n" + +" kuliguli_age_id,\n" + +" kuliguli_density,\n" + +" kuliguli_density_to,\n" + +" kuliguli_size,\n" + +" kuliguli_count,\n" + +" kuliguli_action_id,\n" + +" imago_wing_id,\n" + +" imago_maturity,\n" + +" imago_phase_id,\n" + +" imago_action_id,\n" + +" imago_density,\n" + +" imago_density_ga,\n" + +" imago_feeding,\n" + +" imago_copulation,\n" + +" imago_laying,\n" + +" imago_flying,\n" + +" swarm_maturity,\n" + +" swarm_density_id,\n" + +" swarm_size,\n" + +" swarm_count,\n" + +" swarm_copulation,\n" + +" swarm_laying,\n" + +" swarm_flying_direction_id,\n" + +" swarm_height_id,\n" + +" description,\n" + +" geom,\n" + +" test\n" + +")values(\n" + +" ?,\n" //1 uid + +" false,\n" + +" ?,\n" //2 user_id + +" ?,\n" //3 device_id + +" ?,\n" //4 image_name1 + +" ?,\n" //5 image_name2 + +" ?,\n" //6 image_name3 + +" ?,\n" //7 country_id + +" ?,\n" //8 region_id + +" ?,\n" //9 area + +" ?,\n" //10 district + +" ?,\n" //11 village + +" ?,\n" //12 terrain + +" ?,\n" //13 observer + +" ?,\n" //14 date + +" ?::interval,\n" //15 timezone + +" ?,\n" //16 lat1 + +" ?,\n" //17 lon1 + +" ?,\n" //18 lat2 + +" ?,\n" //19 lon2 + +" ?,\n" //20 lat3 + +" ?,\n" //21 lon3 + +" ?,\n" //22 lat4 + +" ?,\n" //23 lon4 + +" ?,\n" //24 lat5 + +" ?,\n" //25 lon5 + +" ?,\n" //26 lat6 + +" ?,\n" //27 lon6 + +" ?,\n" //28 bio_hectare + +" ?,\n" //29 bio_biotope_id + +" ?,\n" //30 bio_greenery_id + +" ?,\n" //31 bio_greenery_cover_id + +" ?,\n" //32 bio_temperature + +" ?,\n" //33 bio_wind + +" ?,\n" //34 locust_have + +" ?,\n" //35 locust_type_id + +" ?,\n" //36 locust_populated + +" ?,\n" //37 eggs_capsules_area + +" ?,\n" //38 eggs_capsules_density + +" ?,\n" //39 eggs_capsules_density_to + +" ?,\n" //40 eggs_capsules + +" ?,\n" //41 eggs_live + +" ?,\n" //42 eggs_enemies_id + +" ?,\n" //43 larva_born_id + +" ?,\n" //44 larva_age_id + +" ?,\n" //45 larva_painting_id + +" ?,\n" //46 larva_behavior_id + +" ?,\n" //47 larva_density + +" ?,\n" //48 larva_density_to + +" ?,\n" //49 kuliguli_age_id + +" ?,\n" //50 kuliguli_density + +" ?,\n" //51 kuliguli_density_to + +" ?,\n" //52 kuliguli_size + +" ?,\n" //53 kuliguli_count + +" ?,\n" //54 kuliguli_action_id + +" ?,\n" //55 imago_wing_id + +" ?,\n" //56 imago_maturity + +" ?,\n" //57 imago_phase_id + +" ?,\n" //58 imago_action_id + +" ?,\n" //59 imago_density + +" ?,\n" //60 imago_density_ga + +" ?,\n" //61 imago_feeding + +" ?,\n" //62 imago_copulation + +" ?,\n" //63 imago_laying + +" ?,\n" //64 imago_flying + +" ?,\n" //65 swarm_maturity + +" ?,\n" //66 swarm_density_id + +" ?,\n" //67 swarm_size + +" ?,\n" //68 swarm_count + +" ?,\n" //69 swarm_copulation + +" ?,\n" //70 swarm_laying + +" ?,\n" //71 swarm_flying_direction_id + +" ?,\n" //72 swarm_height_id + +" ?,\n" //73 description + +" ST_SetSRID(ST_GeomFromGeoJSON(?),4326),\n" //74 geom + +" ?\n" //75 test + +")"; + try { + stmt = conn.prepareStatement(sql); + } catch (SQLException ex) { + logRotate(data_dir+"errors.log",ex.getMessage()+" "+sql); + logger.info(ex.getMessage()); + result=(""); + try{ conn.close(); }catch(Exception e){} + return result; + } + } + + //String id=getCdataValue(reqNode, "id"); + //String uid=getCdataValue(reqNode, "uid"); //���� ������ + //String del=getCdataValue(reqNode, "del"); + //String seq=getCdataValue(reqNode, "seq"); + //String fix_date=getCdataValue(reqNode, "fix_date"); + //String changed=getCdataValue(reqNode, "changed"); + String user_id=getCdataValue(reqNode, "user_id"); + String device_id=getCdataValue(reqNode, "device_id"); + String image_name1=getCdataValue(reqNode, "image_name1"); + String image_name2=getCdataValue(reqNode, "image_name2"); + String image_name3=getCdataValue(reqNode, "image_name3"); + String country_id=getCdataValue(reqNode, "country_id"); + String region_id=getCdataValue(reqNode, "region_id"); + String area=getCdataValue(reqNode, "area"); + String district=getCdataValue(reqNode, "district"); + String village=getCdataValue(reqNode, "village"); + String terrain=getCdataValue(reqNode, "terrain"); + String observer=getCdataValue(reqNode, "observer"); + String date=getCdataValue(reqNode, "date"); + String timezone=getCdataValue(reqNode, "timezone"); + timezone=Tools.numConvert(timezone); + String lat1=getCdataValue(reqNode, "lat1"); + if(lat1==null) { lat1=getCdataValue(reqNode, "lat"); } + String lon1=getCdataValue(reqNode, "lon1"); + if(lon1==null) { lon1=getCdataValue(reqNode, "lon"); } + String lat2=getCdataValue(reqNode, "lat2"); + String lon2=getCdataValue(reqNode, "lon2"); + String lat3=getCdataValue(reqNode, "lat3"); + String lon3=getCdataValue(reqNode, "lon3"); + String lat4=getCdataValue(reqNode, "lat4"); + String lon4=getCdataValue(reqNode, "lon4"); + String lat5=getCdataValue(reqNode, "lat5"); + String lon5=getCdataValue(reqNode, "lon5"); + String lat6=getCdataValue(reqNode, "lat6"); + String lon6=getCdataValue(reqNode, "lon6"); + String bio_hectare=getCdataValue(reqNode, "bio_hectare"); + String bio_biotope_id=getCdataValue(reqNode, "bio_biotope_id"); + String bio_greenery_id=getCdataValue(reqNode, "bio_greenery_id"); + String bio_greenery_cover_id=getCdataValue(reqNode, "bio_greenery_cover_id"); + String bio_temperature=getCdataValue(reqNode, "bio_temperature"); + String bio_wind=getCdataValue(reqNode, "bio_wind"); + String locust_have=getCdataValue(reqNode, "locust_have"); + String locust_type_id=getCdataValue(reqNode, "locust_type_id"); + String locust_populated=getCdataValue(reqNode, "locust_populated"); + String eggs_capsules_area=getCdataValue(reqNode, "eggs_capsules_area"); + String eggs_capsules_density=getCdataValue(reqNode, "eggs_capsules_density"); + String eggs_capsules_density_to=getCdataValue(reqNode, "eggs_capsules_density_to"); + String eggs_capsules=getCdataValue(reqNode, "eggs_capsules"); + String eggs_live=getCdataValue(reqNode, "eggs_live"); + String eggs_enemies_id=getCdataValue(reqNode, "eggs_enemies_id"); + String larva_born_id=getCdataValue(reqNode, "larva_born_id"); + String larva_age_id=getCdataValue(reqNode, "larva_age_id"); + String larva_painting_id=getCdataValue(reqNode, "larva_painting_id"); + String larva_behavior_id=getCdataValue(reqNode, "larva_behavior_id"); + String larva_density=getCdataValue(reqNode, "larva_density"); + String larva_density_to=getCdataValue(reqNode, "larva_density_to"); + String kuliguli_age_id=getCdataValue(reqNode, "kuliguli_age_id"); + String kuliguli_density=getCdataValue(reqNode, "kuliguli_density"); + String kuliguli_density_to=getCdataValue(reqNode, "kuliguli_density_to"); + String kuliguli_size=getCdataValue(reqNode, "kuliguli_size"); + String kuliguli_count=getCdataValue(reqNode, "kuliguli_count"); + String kuliguli_action_id=getCdataValue(reqNode, "kuliguli_action_id"); + String imago_wing_id=getCdataValue(reqNode, "imago_wing_id"); + String imago_maturity=getCdataValue(reqNode, "imago_maturity"); + String imago_phase_id=getCdataValue(reqNode, "imago_phase_id"); + String imago_action_id=getCdataValue(reqNode, "imago_action_id"); + String imago_density=getCdataValue(reqNode, "imago_density"); + String imago_density_ga=getCdataValue(reqNode, "imago_density_ga"); + String imago_feeding=getCdataValue(reqNode, "imago_feeding"); + String imago_copulation=getCdataValue(reqNode, "imago_copulation"); + String imago_laying=getCdataValue(reqNode, "imago_laying"); + String imago_flying=getCdataValue(reqNode, "imago_flying"); + String swarm_maturity=getCdataValue(reqNode, "swarm_maturity"); + String swarm_density_id=getCdataValue(reqNode, "swarm_density_id"); + String swarm_size=getCdataValue(reqNode, "swarm_size"); + String swarm_count=getCdataValue(reqNode, "swarm_count"); + String swarm_copulation=getCdataValue(reqNode, "swarm_copulation"); + String swarm_laying=getCdataValue(reqNode, "swarm_laying"); + String swarm_flying_direction_id=getCdataValue(reqNode, "swarm_flying_direction_id"); + String swarm_height_id=getCdataValue(reqNode, "swarm_height_id"); + String description=getCdataValue(reqNode, "description"); + String geom=getCdataValue(reqNode, "geom"); + String test=getCdataValue(reqNode, "test"); + if(test==null) test="0"; + + try { + //if(country_id==null) stmt.setNull(7, Types.INTEGER, null); else stmt.setInt(id); + stmt.setString(1,uid); + //stmt.setString(del); + //stmt.setString(seq); + //if(country_id==null) stmt.setNull(7, Types.INTEGER, null); else stmt.setInt(fix_date); + //if(country_id==null) stmt.setNull(7, Types.INTEGER, null); else stmt.setInt(changed); + if(user_id==null) stmt.setNull(2, Types.INTEGER, null); else stmt.setInt(2,Integer.parseInt(user_id)); + stmt.setString(3,device_id); + + stmt.setString(4,image_name1); + stmt.setString(5,image_name2); + stmt.setString(6,image_name3); + + if(country_id==null) stmt.setNull(7, Types.INTEGER, null); else stmt.setInt(7,Integer.parseInt(country_id)); + if(region_id==null) stmt.setNull(8, Types.INTEGER, null); else stmt.setInt(8,Integer.parseInt(region_id)); + stmt.setString(9,area); + stmt.setString(10,district); //�������� ����� �/��� ��������� + + stmt.setString(11,village); + stmt.setString(12,terrain); + + stmt.setString(13,observer); //��� ����������� + if(date==null) + { + stmt.setNull(14, Types.DATE, null); + }else + { + if(date.indexOf("-")==-1) //If old date format in UNIX time + { + int uDate=Integer.parseInt(date)+1; + java.sql.Timestamp tm=new java.sql.Timestamp((long)uDate*1000); + stmt.setTimestamp(14, tm); + }else + { + java.sql.Timestamp tm=null; + DateFormat dfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //2016-05-29 18:00:01 in "GMT" + try{ + tm = new java.sql.Timestamp(dfm.parse(date).getTime()); + } catch (Exception e) { + logger.info(e.getMessage()); + } + stmt.setTimestamp(14, tm); + } + } + + stmt.setString(15,timezone); + + if(lat1==null) stmt.setNull(16, Types.DOUBLE, null); else stmt.setDouble(16,Double.parseDouble(lat1)); + if(lon1==null) stmt.setNull(17, Types.DOUBLE, null); else stmt.setDouble(17,Double.parseDouble(lon1)); + if(lat2==null) stmt.setNull(18, Types.DOUBLE, null); else stmt.setDouble(18,Double.parseDouble(lat2)); + if(lon2==null) stmt.setNull(19, Types.DOUBLE, null); else stmt.setDouble(19,Double.parseDouble(lon2)); + if(lat3==null) stmt.setNull(20, Types.DOUBLE, null); else stmt.setDouble(20,Double.parseDouble(lat3)); + if(lon3==null) stmt.setNull(21, Types.DOUBLE, null); else stmt.setDouble(21,Double.parseDouble(lon3)); + if(lat4==null) stmt.setNull(22, Types.DOUBLE, null); else stmt.setDouble(22,Double.parseDouble(lat4)); + if(lon4==null) stmt.setNull(23, Types.DOUBLE, null); else stmt.setDouble(23,Double.parseDouble(lon4)); + if(lat5==null) stmt.setNull(24, Types.DOUBLE, null); else stmt.setDouble(24,Double.parseDouble(lat5)); + if(lon5==null) stmt.setNull(25, Types.DOUBLE, null); else stmt.setDouble(25,Double.parseDouble(lon5)); + if(lat6==null) stmt.setNull(26, Types.DOUBLE, null); else stmt.setDouble(26,Double.parseDouble(lat6)); + if(lon6==null) stmt.setNull(27, Types.DOUBLE, null); else stmt.setDouble(27,Double.parseDouble(lon6)); + + if(bio_hectare==null) stmt.setNull(28, Types.DOUBLE, null); else stmt.setDouble(28,Double.parseDouble(bio_hectare)); //������������� �������(��) + if(bio_biotope_id==null) stmt.setNull(29, Types.INTEGER, null); else stmt.setInt(29,Integer.parseInt(bio_biotope_id)); + if(bio_greenery_id==null) stmt.setNull(30, Types.INTEGER, null); else stmt.setInt(30,Integer.parseInt(bio_greenery_id)); + if(bio_greenery_cover_id==null) stmt.setNull(31, Types.INTEGER, null); else stmt.setInt(31,Integer.parseInt(bio_greenery_cover_id)); + if(bio_temperature==null) stmt.setNull(32, Types.DOUBLE, null); else stmt.setDouble(32,Double.parseDouble(bio_temperature)); + if(bio_wind==null) stmt.setNull(33, Types.DOUBLE, null); else stmt.setDouble(33,Double.parseDouble(bio_wind)); + if(locust_have==null) stmt.setNull(34, Types.INTEGER, null); else stmt.setInt(34,Integer.parseInt(locust_have)); + if(locust_type_id==null) stmt.setNull(35, Types.INTEGER, null); else stmt.setInt(35,Integer.parseInt(locust_type_id)); //��� ������� + if(locust_populated==null) stmt.setNull(36, Types.DOUBLE, null); else stmt.setDouble(36,Double.parseDouble(locust_populated)); //��������� �������(��) + + if(eggs_capsules_area==null) stmt.setNull(37, Types.DOUBLE, null); else stmt.setDouble(37,Double.parseDouble(eggs_capsules_area)); + if(eggs_capsules_density==null) stmt.setNull(38, Types.DOUBLE, null); else stmt.setDouble(38,Double.parseDouble(eggs_capsules_density)); + if(eggs_capsules_density_to==null) stmt.setNull(39, Types.DOUBLE, null); else stmt.setDouble(39,Double.parseDouble(eggs_capsules_density_to)); + if(eggs_capsules==null) stmt.setNull(40, Types.DOUBLE, null); else stmt.setDouble(40,Double.parseDouble(eggs_capsules)); + if(eggs_live==null) stmt.setNull(41, Types.DOUBLE, null); else stmt.setDouble(41,Double.parseDouble(eggs_live)); + if(eggs_enemies_id==null) stmt.setNull(42, Types.INTEGER, null); else stmt.setInt(42,Integer.parseInt(eggs_enemies_id)); //������� ������������ ������(�����?) + + if(larva_born_id==null) stmt.setNull(43, Types.INTEGER, null); else stmt.setInt(43,Integer.parseInt(larva_born_id)); + if(larva_age_id==null) stmt.setNull(44, Types.INTEGER, null); else stmt.setInt(44,Integer.parseInt(larva_age_id)); + if(larva_painting_id==null) stmt.setNull(45, Types.INTEGER, null); else stmt.setInt(45,Integer.parseInt(larva_painting_id)); + if(larva_behavior_id==null) stmt.setNull(46, Types.INTEGER, null); else stmt.setInt(46,Integer.parseInt(larva_behavior_id)); + + if(larva_density==null) stmt.setNull(47, Types.DOUBLE, null); else stmt.setDouble(47,Double.parseDouble(larva_density)); + if(larva_density_to==null) stmt.setNull(48, Types.DOUBLE, null); else stmt.setDouble(48,Double.parseDouble(larva_density_to)); + if(kuliguli_age_id==null) stmt.setNull(49, Types.INTEGER, null); else stmt.setInt(49,Integer.parseInt(kuliguli_age_id)); //c�. �������(������� ������� �������) + + if(kuliguli_density==null) stmt.setNull(50, Types.DOUBLE, null); else stmt.setDouble(50,Double.parseDouble(kuliguli_density)); + if(kuliguli_density_to==null) stmt.setNull(51, Types.DOUBLE, null); else stmt.setDouble(51,Double.parseDouble(kuliguli_density_to)); + if(kuliguli_size==null) stmt.setNull(52, Types.DOUBLE, null); else stmt.setDouble(52,Double.parseDouble(kuliguli_size)); + if(kuliguli_count==null) stmt.setNull(53, Types.DOUBLE, null); else stmt.setDouble(53,Double.parseDouble(kuliguli_count)); + if(kuliguli_action_id==null) stmt.setNull(54, Types.INTEGER, null); else stmt.setInt(54,Integer.parseInt(kuliguli_action_id)); + if(imago_wing_id==null) stmt.setNull(55, Types.INTEGER, null); else stmt.setInt(55,Integer.parseInt(imago_wing_id)); + if(imago_maturity==null) stmt.setNull(56, Types.BOOLEAN, null); + else { + if(imago_maturity.equals("1")) stmt.setBoolean(56,true); + else stmt.setBoolean(56,false); + } + if(imago_phase_id==null) stmt.setNull(57, Types.INTEGER, null); else stmt.setInt(57,Integer.parseInt(imago_phase_id)); //����(���������S, �����o���� �, �������G) + if(imago_action_id==null) stmt.setNull(58, Types.INTEGER, null); else stmt.setInt(58,Integer.parseInt(imago_action_id)); + + if(imago_density==null) stmt.setNull(59, Types.DOUBLE, null); else stmt.setDouble(59,Double.parseDouble(imago_density)); + if(imago_density_ga==null) stmt.setNull(60, Types.DOUBLE, null); else stmt.setDouble(60,Double.parseDouble(imago_density_ga)); + if(imago_feeding==null) stmt.setNull(61, Types.BOOLEAN, null); + else { + if(imago_feeding.equals("1")) stmt.setBoolean(61,true); + else stmt.setBoolean(61,false); + } + if(imago_copulation==null) stmt.setNull(62, Types.BOOLEAN, null); + else { + if(imago_copulation.equals("1")) stmt.setBoolean(62,true); + else stmt.setBoolean(62,false); + } + if(imago_laying==null) stmt.setNull(63, Types.BOOLEAN, null); + else { + if(imago_laying.equals("1")) stmt.setBoolean(63,true); + else stmt.setBoolean(63,false); + } + if(imago_flying==null) stmt.setNull(64, Types.BOOLEAN, null); + else { + if(imago_flying.equals("1")) stmt.setBoolean(64,true); + else stmt.setBoolean(64,false); + } + if(swarm_maturity==null) stmt.setNull(65, Types.BOOLEAN, null); + else { + if(swarm_maturity.equals("1")) stmt.setBoolean(65,true); + else stmt.setBoolean(65,false); + } + if(swarm_density_id==null) stmt.setNull(66, Types.INTEGER, null); else stmt.setInt(66,Integer.parseInt(swarm_density_id)); + if(swarm_size==null) stmt.setNull(67, Types.DOUBLE, null); else stmt.setDouble(67,Double.parseDouble(swarm_size)); + if(swarm_count==null) stmt.setNull(68, Types.DOUBLE, null); else stmt.setDouble(68,Double.parseDouble(swarm_count)); + if(swarm_copulation==null) stmt.setNull(69, Types.BOOLEAN, null); + else { + if(swarm_copulation.equals("1")) stmt.setBoolean(69,true); + else stmt.setBoolean(69,false); + } + if(swarm_laying==null) stmt.setNull(70, Types.BOOLEAN, null); + else { + if(swarm_laying.equals("1")) stmt.setBoolean(70,true); + else stmt.setBoolean(70,false); + } + if(swarm_flying_direction_id==null) stmt.setNull(71, Types.INTEGER, null); else stmt.setInt(71,Integer.parseInt(swarm_flying_direction_id)); + if(swarm_height_id==null) stmt.setNull(72, Types.INTEGER, null); else stmt.setInt(72,Integer.parseInt(swarm_height_id)); //������(������- �������- �������) + + stmt.setString(73,description); + stmt.setString(74,geom); + if(test==null) stmt.setNull(75, Types.BOOLEAN, null); + else { + if(test.equals("1")) stmt.setBoolean(75,true); + else stmt.setBoolean(75,false); + } + + } catch (SQLException ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=(""); + try{ conn.close(); }catch(Exception e){} + return result; + } + + //Execute SQL + try { + stmt.execute(); + } catch (SQLException ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=(""); + try{ conn.close(); }catch(Exception e){} + return result; + } + + //If there are drawings, then copy them. + String imgDir="./data/frmlocust/"; + try{ new File(dataDir+imgDir).mkdirs(); }catch (Exception exception) {} + + if(image_name1!=null && !image_name1.equals("")) + { + String filename1=dataDir+tmpDir+image_name1; + File f = new File(filename1); + if(f.exists() && !f.isDirectory()) { + f.renameTo(new File(dataDir+imgDir+image_name1)); + } + } + if(image_name2!=null && !image_name2.equals("")) + { + String filename2=dataDir+tmpDir+image_name2; + File f = new File(filename2); + if(f.exists() && !f.isDirectory()) { + f.renameTo(new File(dataDir+imgDir+image_name2)); + } + } + if(image_name3!=null && !image_name3.equals("")) + { + String filename3=dataDir+tmpDir+image_name3; + File f = new File(filename3); + if(f.exists() && !f.isDirectory()) { + f.renameTo(new File(dataDir+imgDir+image_name3)); + } + } + + result=""; + logRotate(data_dir+"errors.log","XML="+result); + try{ conn.close(); }catch(Exception e){} + return result; + + }else if(fn.equals("5")) + { + boolean exists=false; + String uid=getCdataValue(reqNode,"uid"); + logger.info("uid="+uid); + Statement st; + try { + st = conn.createStatement(); + ResultSet rs=null; + try { + rs = st.executeQuery("select 1 from main.frmlocustdel where uid='"+uid+"'"); + } catch( SQLException ex ) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=(""); + try{ conn.close(); }catch(Exception e){} + return result; + } + if(rs!=null) + { + if(rs.next()) + exists=true; + } + st.close(); + } catch (SQLException ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=(""); + try{ conn.close(); }catch(Exception e){} + return result; + } + + PreparedStatement stmt=null; + if(exists) + { + String sql="update main.frmlocustdel set \n" + +" uid=?,\n" + +" changed=false,\n" + +" user_id=?,\n" + +" device_id=?,\n" + +" image_name1=?,\n" + +" image_name2=?,\n" + +" image_name3=?,\n" + +" country_id=?,\n" + +" region_id=?,\n" + +" area=?,\n" + +" district=?,\n" + +" village=?,\n" + +" terrain=?,\n" + +" observer=?,\n" + +" date=?,\n" + +" timezone=?::interval,\n" + +" lat_center=?,\n" + +" lon_center=?,\n" + +" lat1=?,\n" + +" lon1=?,\n" + +" lat2=?,\n" + +" lon2=?,\n" + +" lat3=?,\n" + +" lon3=?,\n" + +" lat4=?,\n" + +" lon4=?,\n" + +" lat5=?,\n" + +" lon5=?,\n" + +" lat6=?,\n" + +" lon6=?,\n" + +" infested_area=?,\n" + +" treated_area=?,\n" + +" vegetation_type_id=?,\n" + +" vegetation_height=?,\n" + +" vegetation_crop=?,\n" + +" vegetation_cover_id=?,\n" + +" vegetation_damage=?,\n" + +" vegetation_damage_area=?,\n" + +" insecticide_name=?,\n" + +" insecticide_active_substance=?,\n" + +" insecticide_concentration=?,\n" + +" insecticide_formulation_id=?,\n" + +" insecticide_dose=?,\n" + +" insecticide_rate=?,\n" + +" insecticide_used_volume=?,\n" + +" insecticide_number_spores=?,\n" + +" insecticide_expiry_date=?,\n" + +" insecticide_mixed=?,\n" + +" insecticide_mixed_name=?,\n" + +" insecticide_mixed_ratio=?,\n" + +" weather_time_start=?,\n" + +" weather_time_end=?,\n" + +" weather_temperature_start=?,\n" + +" weather_temperature_end=?,\n" + +" weather_humidity_start=?,\n" + +" weather_humidity_end=?,\n" + +" weather_wind_speed_start=?,\n" + +" weather_wind_speed_end=?,\n" + +" weather_direction_start=?,\n" + +" weather_direction_end=?,\n" + +" weather_spray_direction_start=?,\n" + +" weather_spray_direction_end=?,\n" + +" locust_type_id=?,\n" + +" locust_hoppers_id=?,\n" + +" locust_imago=?,\n" + +" locust_density=?,\n" + +" locust_kuliguli=?,\n" + +" locust_swarm=?,\n" + +" locust_sparse=?,\n" + +" locust_phase_id=?,\n" + +" spray_platform=?,\n" + +" spray_platform_a=?,\n" + +" spray_platform_g=?,\n" + +" spray_platform_h=?,\n" + +" spray_capacity_id=?,\n" + +" spray_operatortype_id=?,\n" + +" spray_manufacturer_name=?,\n" + +" spray_model_name=?,\n" + +" spray_height=?,\n" + +" spray_width=?,\n" + +" spray_barrier=?,\n" + +" spray_barrier_width=?,\n" + +" spray_barrier_space=?,\n" + +" spray_speed=?,\n" + +" spray_gps=?,\n" + +" spray_marking_id=?,\n" + +" efficacy_mortality=?,\n" + +" efficacy_passed_time=?,\n" + +" efficacy_mortality_method=?,\n" + +" safety_clothing=?,\n" + +" safety_clothing_clean=?,\n" + +" safety_operator_health=?,\n" + +" description=?,\n" + +" safety_inform=?,\n" + +" safety_container=?,\n" + +" safety_non_target=?,\n" + +" safety_non_target_effect=?,\n" + +" safety_incident=?,\n" + +" safety_incident_effect=?,\n" + +" comments=?,\n" + +" geom=ST_SetSRID(ST_GeomFromGeoJSON(?),4326),\n" + +" test=?\n" + +" where uid='"+uid+"'"; + try { + stmt = conn.prepareStatement(sql); + } catch (SQLException ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=(""); + try{ conn.close(); }catch(Exception e){} + return result; + } + }else + { + String sql="insert into main.frmlocustdel(\n" + +" uid,\n" + +" changed,\n" + +" user_id,\n" + +" device_id,\n" + +" image_name1,\n" + +" image_name2,\n" + +" image_name3,\n" + +" country_id,\n" + +" region_id,\n" + +" area,\n" + +" district,\n" + +" village,\n" + +" terrain,\n" + +" observer,\n" + +" date,\n" + +" timezone,\n" + +" lat_center,\n" + +" lon_center,\n" + +" lat1,\n" + +" lon1,\n" + +" lat2,\n" + +" lon2,\n" + +" lat3,\n" + +" lon3,\n" + +" lat4,\n" + +" lon4,\n" + +" lat5,\n" + +" lon5,\n" + +" lat6,\n" + +" lon6,\n" + +" infested_area,\n" + +" treated_area,\n" + +" vegetation_type_id,\n" + +" vegetation_height,\n" + +" vegetation_crop,\n" + +" vegetation_cover_id,\n" + +" vegetation_damage,\n" + +" vegetation_damage_area,\n" + +" insecticide_name,\n" + +" insecticide_active_substance,\n" + +" insecticide_concentration,\n" + +" insecticide_formulation_id,\n" + +" insecticide_dose,\n" + +" insecticide_rate,\n" + +" insecticide_used_volume,\n" + +" insecticide_number_spores,\n" + +" insecticide_expiry_date,\n" + +" insecticide_mixed,\n" + +" insecticide_mixed_name,\n" + +" insecticide_mixed_ratio,\n" + +" weather_time_start,\n" + +" weather_time_end,\n" + +" weather_temperature_start,\n" + +" weather_temperature_end,\n" + +" weather_humidity_start,\n" + +" weather_humidity_end,\n" + +" weather_wind_speed_start,\n" + +" weather_wind_speed_end,\n" + +" weather_direction_start,\n" + +" weather_direction_end,\n" + +" weather_spray_direction_start,\n" + +" weather_spray_direction_end,\n" + +" locust_type_id,\n" + +" locust_hoppers_id,\n" + +" locust_imago,\n" + +" locust_density,\n" + +" locust_kuliguli,\n" + +" locust_swarm,\n" + +" locust_sparse,\n" + +" locust_phase_id,\n" + +" spray_platform,\n" + +" spray_platform_a,\n" + +" spray_platform_g,\n" + +" spray_platform_h,\n" + +" spray_capacity_id,\n" + +" spray_operatortype_id,\n" + +" spray_manufacturer_name,\n" + +" spray_model_name,\n" + +" spray_height,\n" + +" spray_width,\n" + +" spray_barrier,\n" + +" spray_barrier_width,\n" + +" spray_barrier_space,\n" + +" spray_speed,\n" + +" spray_gps,\n" + +" spray_marking_id,\n" + +" efficacy_mortality,\n" + +" efficacy_passed_time,\n" + +" efficacy_mortality_method,\n" + +" safety_clothing,\n" + +" safety_clothing_clean,\n" + +" safety_operator_health,\n" + +" description,\n" + +" safety_inform,\n" + +" safety_container,\n" + +" safety_non_target,\n" + +" safety_non_target_effect,\n" + +" safety_incident,\n" + +" safety_incident_effect,\n" + +" comments,\n" + +" geom,\n" + +" test\n" + +")values(\n" + +" ?,\n" //1 uid + +" false,\n" + +" ?,\n" //2 user_id + +" ?,\n" //3 device_id + +" ?,\n" //4 image_name1 + +" ?,\n" //5 image_name2 + +" ?,\n" //6 image_name3 + +" ?,\n" //7 country_id + +" ?,\n" //8 region_id + +" ?,\n" //9 area + +" ?,\n" //10 district + +" ?,\n" //11 village + +" ?,\n" //12 terrain + +" ?,\n" //13 observer + +" ?,\n" //14 date + +" ?::interval,\n" //15 timezone + +" ?,\n" //16 lat_center + +" ?,\n" //17 lon_center + +" ?,\n" //18 lat1 + +" ?,\n" //19 lon1 + +" ?,\n" //20 lat2 + +" ?,\n" //21 lon2 + +" ?,\n" //22 lat3 + +" ?,\n" //23 lon3 + +" ?,\n" //24 lat4 + +" ?,\n" //25 lon4 + +" ?,\n" //26 lat5 + +" ?,\n" //27 lon5 + +" ?,\n" //28 lat6 + +" ?,\n" //29 lon6 + +" ?,\n" //30 infested_area + +" ?,\n" //31 treated_area + +" ?,\n" //32 vegetation_type_id + +" ?,\n" //33 vegetation_height + +" ?,\n" //34 vegetation_crop + +" ?,\n" //35 vegetation_cover_id + +" ?,\n" //36 vegetation_damage + +" ?,\n" //37 vegetation_damage_area + +" ?,\n" //38 insecticide_name + +" ?,\n" //39 insecticide_active_substance + +" ?,\n" //40 insecticide_concentration + +" ?,\n" //41 insecticide_formulation_id + +" ?,\n" //42 insecticide_dose + +" ?,\n" //43 insecticide_rate + +" ?,\n" //44 insecticide_used_volume + +" ?,\n" //45 insecticide_number_spores + +" ?,\n" //46 insecticide_expiry_date + +" ?,\n" //47 insecticide_mixed + +" ?,\n" //48 insecticide_mixed_name + +" ?,\n" //49 insecticide_mixed_ratio + +" ?,\n" //50 weather_time_start + +" ?,\n" //51 weather_time_end + +" ?,\n" //52 weather_temperature_start + +" ?,\n" //53 weather_temperature_end + +" ?,\n" //54 weather_humidity_start + +" ?,\n" //55 weather_humidity_end + +" ?,\n" //56 weather_wind_speed_start + +" ?,\n" //57 weather_wind_speed_end + +" ?,\n" //58 weather_direction_start + +" ?,\n" //59 weather_direction_end + +" ?,\n" //60 weather_spray_direction_start + +" ?,\n" //61 weather_spray_direction_end + +" ?,\n" //62 locust_type_id + +" ?,\n" //63 locust_hoppers_id + +" ?,\n" //64 locust_imago + +" ?,\n" //65 locust_density + +" ?,\n" //66 locust_kuliguli + +" ?,\n" //67 locust_swarm + +" ?,\n" //68 locust_sparse + +" ?,\n" //69 locust_phase_id + +" ?,\n" //70 spray_platform + +" ?,\n" //71 spray_platform_a + +" ?,\n" //72 spray_platform_g + +" ?,\n" //73 spray_platform_h + +" ?,\n" //74 spray_capacity_id + +" ?,\n" //75 spray_operatortype_id + +" ?,\n" //76 spray_manufacturer_name + +" ?,\n" //77 spray_model_name + +" ?,\n" //78 spray_height + +" ?,\n" //79 spray_width + +" ?,\n" //80 spray_barrier + +" ?,\n" //81 spray_barrier_width + +" ?,\n" //82 spray_barrier_space + +" ?,\n" //83 spray_speed + +" ?,\n" //84 spray_gps + +" ?,\n" //85 spray_marking_id + +" ?,\n" //86 efficacy_mortality + +" ?,\n" //87 efficacy_passed_time + +" ?,\n" //88 efficacy_mortality_method + +" ?,\n" //89 safety_clothing + +" ?,\n" //90 safety_clothing_clean + +" ?,\n" //91 safety_operator_health + +" ?,\n" //92 description + +" ?,\n" //93 safety_inform + +" ?,\n" //94 safety_container_id + +" ?,\n" //95 safety_non_target + +" ?,\n" //96 safety_non_target_effect + +" ?,\n" //97 safety_incident + +" ?,\n" //98 safety_incident_effect + +" ?,\n" //99 comments + +" ST_SetSRID(ST_GeomFromGeoJSON(?),4326),\n" //100 geom + +" ?\n" //101 test + +")"; + try { + stmt = conn.prepareStatement(sql); + } catch (SQLException ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=(""); + try{ conn.close(); }catch(Exception e){} + return result; + } + } + + //String id=getCdataValue(reqNode, "id"); + //String uid=getCdataValue(reqNode, "uid"); //���� ������ + //String del=getCdataValue(reqNode, "del"); + //String seq=getCdataValue(reqNode, "seq"); + String user_id=getCdataValue(reqNode, "user_id"); + String device_id=getCdataValue(reqNode, "device_id"); + String image_name1=getCdataValue(reqNode, "image_name1"); + String image_name2=getCdataValue(reqNode, "image_name2"); + String image_name3=getCdataValue(reqNode, "image_name3"); + + String country_id=getCdataValue(reqNode, "country_id"); + String region_id=getCdataValue(reqNode, "region_id"); + String area=getCdataValue(reqNode, "area"); + String district=getCdataValue(reqNode, "district"); + String village=getCdataValue(reqNode, "village"); + String terrain=getCdataValue(reqNode, "terrain"); + String observer=getCdataValue(reqNode, "observer"); + String date=getCdataValue(reqNode, "date"); + String timezone=getCdataValue(reqNode, "timezone"); + timezone=Tools.numConvert(timezone); + String lat_center=getCdataValue(reqNode, "lat_center"); + String lon_center=getCdataValue(reqNode, "lon_center"); + String lat1=getCdataValue(reqNode, "lat1"); + String lon1=getCdataValue(reqNode, "lon1"); + String lat2=getCdataValue(reqNode, "lat2"); + String lon2=getCdataValue(reqNode, "lon2"); + String lat3=getCdataValue(reqNode, "lat3"); + String lon3=getCdataValue(reqNode, "lon3"); + String lat4=getCdataValue(reqNode, "lat4"); + String lon4=getCdataValue(reqNode, "lon4"); + String lat5=getCdataValue(reqNode, "lat5"); + String lon5=getCdataValue(reqNode, "lon5"); + String lat6=getCdataValue(reqNode, "lat6"); + String lon6=getCdataValue(reqNode, "lon6"); + String infested_area=getCdataValue(reqNode, "infested_area"); + String treated_area=getCdataValue(reqNode, "treated_area"); + String vegetation_type_id=getCdataValue(reqNode, "vegetation_type_id"); + String vegetation_height=getCdataValue(reqNode, "vegetation_height"); + String vegetation_crop=getCdataValue(reqNode, "vegetation_crop"); + String vegetation_cover_id=getCdataValue(reqNode, "vegetation_cover_id"); + String vegetation_damage=getCdataValue(reqNode, "vegetation_damage"); + String vegetation_damage_area=getCdataValue(reqNode, "vegetation_damage_area"); + String insecticide_name=getCdataValue(reqNode, "insecticide_name"); + String insecticide_active_substance=getCdataValue(reqNode, "insecticide_active_substance"); + String insecticide_concentration=getCdataValue(reqNode, "insecticide_concentration"); + String insecticide_formulation_id=getCdataValue(reqNode, "insecticide_formulation_id"); + String insecticide_dose=getCdataValue(reqNode, "insecticide_dose"); + String insecticide_rate=getCdataValue(reqNode, "insecticide_rate"); + String insecticide_used_volume=getCdataValue(reqNode, "insecticide_used_volume"); + String insecticide_number_spores=getCdataValue(reqNode, "insecticide_number_spores"); + String insecticide_expiry_date=getCdataValue(reqNode, "insecticide_expiry_date"); + String insecticide_mixed=getCdataValue(reqNode, "insecticide_mixed"); + String insecticide_mixed_name=getCdataValue(reqNode, "insecticide_mixed_name"); + String insecticide_mixed_ratio=getCdataValue(reqNode, "insecticide_mixed_ratio"); + String weather_time_start=getCdataValue(reqNode, "weather_time_start"); + String weather_time_end=getCdataValue(reqNode, "weather_time_end"); + String weather_temperature_start=getCdataValue(reqNode, "weather_temperature_start"); + String weather_temperature_end=getCdataValue(reqNode, "weather_temperature_end"); + String weather_humidity_start=getCdataValue(reqNode, "weather_humidity_start"); + String weather_humidity_end=getCdataValue(reqNode, "weather_humidity_end"); + String weather_wind_speed_start=getCdataValue(reqNode, "weather_wind_speed_start"); + String weather_wind_speed_end=getCdataValue(reqNode, "weather_wind_speed_end"); + String weather_direction_start=getCdataValue(reqNode, "weather_direction_start"); + String weather_direction_end=getCdataValue(reqNode, "weather_direction_end"); + String weather_spray_direction_start=getCdataValue(reqNode, "weather_spray_direction_start"); + String weather_spray_direction_end=getCdataValue(reqNode, "weather_spray_direction_end"); + String locust_type_id=getCdataValue(reqNode, "locust_type_id"); + String locust_hoppers_id=getCdataValue(reqNode, "locust_hoppers_id"); + String locust_imago=getCdataValue(reqNode, "locust_imago"); + String locust_density=getCdataValue(reqNode, "locust_density"); + String locust_kuliguli=getCdataValue(reqNode, "locust_kuliguli"); + String locust_swarm=getCdataValue(reqNode, "locust_swarm"); + String locust_sparse=getCdataValue(reqNode, "locust_sparse"); + String locust_phase_id=getCdataValue(reqNode, "locust_phase_id"); + String spray_platform=getCdataValue(reqNode, "spray_platform"); + String spray_platform_a=getCdataValue(reqNode, "spray_platform_a"); + String spray_platform_g=getCdataValue(reqNode, "spray_platform_g"); + String spray_platform_h=getCdataValue(reqNode, "spray_platform_h"); + String spray_capacity_id=getCdataValue(reqNode, "spray_capacity_id"); + String spray_operatortype_id=getCdataValue(reqNode, "spray_operatortype_id"); + String spray_manufacturer_name=getCdataValue(reqNode, "spray_manufacturer_name"); + String spray_model_name=getCdataValue(reqNode, "spray_model_name"); + String spray_height=getCdataValue(reqNode, "spray_height"); + String spray_width=getCdataValue(reqNode, "spray_width"); + String spray_barrier=getCdataValue(reqNode, "spray_barrier"); + String spray_barrier_width=getCdataValue(reqNode, "spray_barrier_width"); + String spray_barrier_space=getCdataValue(reqNode, "spray_barrier_space"); + String spray_speed=getCdataValue(reqNode, "spray_speed"); + String spray_gps=getCdataValue(reqNode, "spray_gps"); + String spray_marking_id=getCdataValue(reqNode, "spray_marking_id"); + String efficacy_mortality=getCdataValue(reqNode, "efficacy_mortality"); + String efficacy_passed_time=getCdataValue(reqNode, "efficacy_passed_time"); + String efficacy_mortality_method=getCdataValue(reqNode, "efficacy_mortality_method"); + String safety_clothing=getCdataValue(reqNode, "safety_clothing"); + String safety_clothing_clean=getCdataValue(reqNode, "safety_clothing_clean"); + String safety_operator_health=getCdataValue(reqNode, "safety_operator_health"); + String description=getCdataValue(reqNode, "description"); + String safety_inform=getCdataValue(reqNode, "safety_inform"); + + String safety_container_id=getCdataValue(reqNode, "safety_container_id"); + String safety_container=getCdataValue(reqNode, "safety_container"); + if(safety_container==null) safety_container=safety_container_id; + + String safety_non_target=getCdataValue(reqNode, "safety_non_target"); + String safety_non_target_effect=getCdataValue(reqNode, "safety_non_target_effect"); + + String safety_incident=getCdataValue(reqNode, "safety_incident"); + String safety_incident_effect=getCdataValue(reqNode, "safety_incident_effect"); + String comments=getCdataValue(reqNode, "comments"); + String geom=getCdataValue(reqNode, "geom"); + String test=getCdataValue(reqNode, "test"); + if(test==null) test="0"; + + //stmt.setString(':id', $id, PDO::PARAM_INT); + try { + stmt.setString(1,uid); + + //stmt.setInt(':del', del); + //stmt.setInt(':seq', seq); + //stmt.setInt(':changed', changed); + + if(user_id==null) + stmt.setNull(2, Types.INTEGER, null); + else + stmt.setInt(2,Integer.parseInt(user_id)); + + stmt.setString(3,device_id); + stmt.setString(4,image_name1); + stmt.setString(5,image_name2); + stmt.setString(6,image_name3); + if(country_id==null) stmt.setNull(7, Types.INTEGER, null); else stmt.setInt(7,Integer.parseInt(country_id)); + if(region_id==null) stmt.setNull(8, Types.INTEGER, null); else stmt.setInt(8,Integer.parseInt(region_id)); + stmt.setString(9,area); + stmt.setString(10,district); + stmt.setString(11,village); + stmt.setString(12,terrain); + stmt.setString(13,observer); + + if(date==null) + { + stmt.setNull(14, Types.DATE, null); + }else + { + if(date.indexOf("-")==-1) //If old date format in UNIX time + { + int uDate=Integer.parseInt(date)+1; + java.sql.Timestamp tm=new java.sql.Timestamp((long)uDate*1000); + stmt.setTimestamp(14, tm); + }else + { + java.sql.Timestamp tm=null; + DateFormat dfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //2016-05-29 18:00:01 in "GMT" + try{ + tm = new java.sql.Timestamp(dfm.parse(date).getTime()); + } catch (Exception e) { + logger.info(e.getMessage()); + } + stmt.setTimestamp(14, tm); + } + } + stmt.setString(15,timezone); + + if(lat_center==null) stmt.setNull(16, Types.DOUBLE, null); else stmt.setDouble(16,Double.parseDouble(lat_center)); + if(lon_center==null) stmt.setNull(17, Types.DOUBLE, null); else stmt.setDouble(17,Double.parseDouble(lon_center)); + if(lat1==null) stmt.setNull(18, Types.DOUBLE, null); else stmt.setDouble(18,Double.parseDouble(lat1)); + if(lon1==null) stmt.setNull(19, Types.DOUBLE, null); else stmt.setDouble(19,Double.parseDouble(lon1)); + if(lat2==null) stmt.setNull(20, Types.DOUBLE, null); else stmt.setDouble(20,Double.parseDouble(lat2)); + if(lon2==null) stmt.setNull(21, Types.DOUBLE, null); else stmt.setDouble(21,Double.parseDouble(lon2)); + if(lat3==null) stmt.setNull(22, Types.DOUBLE, null); else stmt.setDouble(22,Double.parseDouble(lat3)); + if(lon3==null) stmt.setNull(23, Types.DOUBLE, null); else stmt.setDouble(23,Double.parseDouble(lon3)); + if(lat4==null) stmt.setNull(24, Types.DOUBLE, null); else stmt.setDouble(24,Double.parseDouble(lat4)); + if(lon4==null) stmt.setNull(25, Types.DOUBLE, null); else stmt.setDouble(25,Double.parseDouble(lon4)); + if(lat5==null) stmt.setNull(26, Types.DOUBLE, null); else stmt.setDouble(26,Double.parseDouble(lat5)); + if(lon5==null) stmt.setNull(27, Types.DOUBLE, null); else stmt.setDouble(27,Double.parseDouble(lon5)); + if(lat6==null) stmt.setNull(28, Types.DOUBLE, null); else stmt.setDouble(28,Double.parseDouble(lat6)); + if(lon6==null) stmt.setNull(29, Types.DOUBLE, null); else stmt.setDouble(29,Double.parseDouble(lon6)); + + if(infested_area==null) stmt.setNull(30, Types.DOUBLE, null); else stmt.setDouble(30,Double.parseDouble(infested_area)); + if(treated_area==null) stmt.setNull(31, Types.DOUBLE, null); else stmt.setDouble(31,Double.parseDouble(treated_area)); + + if(vegetation_type_id==null) stmt.setNull(32, Types.INTEGER, null); else stmt.setInt(32,Integer.parseInt(vegetation_type_id)); + + if(vegetation_height==null) stmt.setNull(33, Types.DOUBLE, null); else stmt.setDouble(33,Double.parseDouble(vegetation_height)); + stmt.setString(34,vegetation_crop); + if(vegetation_cover_id==null) stmt.setNull(35, Types.INTEGER, null); else stmt.setInt(35,Integer.parseInt(vegetation_cover_id)); + if(vegetation_damage==null) stmt.setNull(36, Types.INTEGER, null); else stmt.setInt(36,Integer.parseInt(vegetation_damage)); + if(vegetation_damage_area==null) stmt.setNull(37, Types.DOUBLE, null); else stmt.setDouble(37,Double.parseDouble(vegetation_damage_area)); + + stmt.setString(38,insecticide_name); + stmt.setString(39,insecticide_active_substance); + stmt.setString(40,insecticide_concentration); //if(insecticide_concentration==null) stmt.setNull(39, Types.INTEGER, null); else stmt.setInt(39,Integer.parseInt(insecticide_concentration)); + if(insecticide_formulation_id==null) stmt.setNull(41, Types.INTEGER, null); else stmt.setInt(41,Integer.parseInt(insecticide_formulation_id)); + + if(insecticide_dose==null) stmt.setNull(42, Types.DOUBLE, null); else stmt.setDouble(42,Double.parseDouble(insecticide_dose)); + if(insecticide_rate==null) stmt.setNull(43, Types.DOUBLE, null); else stmt.setDouble(43,Double.parseDouble(insecticide_rate)); + if(insecticide_used_volume==null) stmt.setNull(44, Types.DOUBLE, null); else stmt.setDouble(44,Double.parseDouble(insecticide_used_volume)); + if(insecticide_number_spores==null) stmt.setNull(45, Types.DOUBLE, null); else stmt.setDouble(45,Double.parseDouble(insecticide_number_spores)); + if(insecticide_expiry_date==null) stmt.setNull(46, Types.INTEGER, null); else stmt.setInt(46,Integer.parseInt(insecticide_expiry_date)); + stmt.setString(47,insecticide_mixed); + stmt.setString(48,insecticide_mixed_name); + if(insecticide_mixed_ratio==null) stmt.setNull(49, Types.INTEGER, null); else stmt.setInt(49,Integer.parseInt(insecticide_mixed_ratio)); + + if(weather_time_start==null) stmt.setNull(50, Types.DOUBLE, null); else stmt.setDouble(50,Double.parseDouble(weather_time_start)); + if(weather_time_end==null) stmt.setNull(51, Types.DOUBLE, null); else stmt.setDouble(51,Double.parseDouble(weather_time_end)); + if(weather_temperature_start==null) stmt.setNull(52, Types.DOUBLE, null); else stmt.setDouble(52,Double.parseDouble(weather_temperature_start)); + if(weather_temperature_end==null) stmt.setNull(53, Types.DOUBLE, null); else stmt.setDouble(53,Double.parseDouble(weather_temperature_end)); + if(weather_humidity_start==null) stmt.setNull(54, Types.DOUBLE, null); else stmt.setDouble(54,Double.parseDouble(weather_humidity_start)); + if(weather_humidity_end==null) stmt.setNull(55, Types.DOUBLE, null); else stmt.setDouble(55,Double.parseDouble(weather_humidity_end)); + if(weather_wind_speed_start==null) stmt.setNull(56, Types.DOUBLE, null); else stmt.setDouble(56,Double.parseDouble(weather_wind_speed_start)); + if(weather_wind_speed_end==null) stmt.setNull(57, Types.DOUBLE, null); else stmt.setDouble(57,Double.parseDouble(weather_wind_speed_end)); + + if(weather_direction_start==null) stmt.setNull(58, Types.INTEGER, null); else stmt.setInt(58,Integer.parseInt(weather_direction_start)); + if(weather_direction_end==null) stmt.setNull(59, Types.INTEGER, null); else stmt.setInt(59,Integer.parseInt(weather_direction_end)); + if(weather_spray_direction_start==null) stmt.setNull(60, Types.INTEGER, null); else stmt.setInt(60,Integer.parseInt(weather_spray_direction_start)); + if(weather_spray_direction_end==null) stmt.setNull(61, Types.INTEGER, null); else stmt.setInt(61,Integer.parseInt(weather_spray_direction_end)); + + if(locust_type_id==null) stmt.setNull(62, Types.INTEGER, null); else stmt.setInt(62,Integer.parseInt(locust_type_id)); + if(locust_hoppers_id==null) stmt.setNull(63, Types.INTEGER, null); else stmt.setInt(63,Integer.parseInt(locust_hoppers_id)); + if(locust_imago==null) stmt.setNull(64, Types.BOOLEAN, null); + else { if(locust_imago.equals("1")) stmt.setBoolean(64,true); else stmt.setBoolean(64,false); } + + if(locust_density==null) stmt.setNull(65, Types.DOUBLE, null); else stmt.setDouble(65,Double.parseDouble(locust_density)); + if(locust_kuliguli==null) stmt.setNull(66, Types.BOOLEAN, null); + else { + if(locust_kuliguli.equals("1")) stmt.setBoolean(66,true); + else stmt.setBoolean(66,false); + } + if(locust_swarm==null) stmt.setNull(67, Types.BOOLEAN, null); + else { + if(locust_swarm.equals("1")) stmt.setBoolean(67,true); + else stmt.setBoolean(67,false); + } + if(locust_sparse==null) stmt.setNull(68, Types.BOOLEAN, null); + else { + if(locust_sparse.equals("1")) stmt.setBoolean(68,true); + else stmt.setBoolean(68,false); + } + + if(locust_phase_id==null) stmt.setNull(69, Types.INTEGER, null); else stmt.setInt(69,Integer.parseInt(locust_phase_id)); + + + if(spray_platform==null) stmt.setNull(70, Types.INTEGER, null); else stmt.setInt(70,Integer.parseInt(spray_platform)); + if(spray_platform_a==null) stmt.setNull(71, Types.INTEGER, null); else stmt.setInt(71,Integer.parseInt(spray_platform_a)); + if(spray_platform_g==null) stmt.setNull(72, Types.INTEGER, null); else stmt.setInt(72,Integer.parseInt(spray_platform_g)); + if(spray_platform_h==null) stmt.setNull(73, Types.INTEGER, null); else stmt.setInt(73,Integer.parseInt(spray_platform_h)); + if(spray_capacity_id==null) stmt.setNull(74, Types.INTEGER, null); else stmt.setInt(74,Integer.parseInt(spray_capacity_id)); + if(spray_operatortype_id==null) stmt.setNull(75, Types.INTEGER, null); else stmt.setInt(75,Integer.parseInt(spray_operatortype_id)); + stmt.setString(76,spray_manufacturer_name); + stmt.setString(77,spray_model_name); + if(spray_height==null) stmt.setNull(78, Types.DOUBLE, null); else stmt.setDouble(78,Double.parseDouble(spray_height)); + if(spray_width==null) stmt.setNull(79, Types.DOUBLE, null); else stmt.setDouble(79,Double.parseDouble(spray_width)); + if(spray_barrier==null) stmt.setNull(80, Types.BOOLEAN, null); + else { + if(spray_barrier.equals("1")) stmt.setBoolean(80,true); + else stmt.setBoolean(80,false); + } + if(spray_barrier_width==null) stmt.setNull(81, Types.DOUBLE, null); else stmt.setDouble(81,Double.parseDouble(spray_barrier_width)); + if(spray_barrier_space==null) stmt.setNull(82, Types.DOUBLE, null); else stmt.setDouble(82,Double.parseDouble(spray_barrier_space)); + if(spray_speed==null) stmt.setNull(83, Types.DOUBLE, null); else stmt.setDouble(83,Double.parseDouble(spray_speed)); + if(spray_gps==null) stmt.setNull(84, Types.BOOLEAN, null); + else { + if(spray_gps.equals("1")) stmt.setBoolean(84,true); + else stmt.setBoolean(84,false); + } + if(spray_marking_id==null) stmt.setNull(85, Types.INTEGER, null); else stmt.setInt(85,Integer.parseInt(spray_marking_id)); + + if(efficacy_mortality==null) stmt.setNull(86, Types.DOUBLE, null); else stmt.setDouble(86,Double.parseDouble(efficacy_mortality)); + if(efficacy_passed_time==null) stmt.setNull(87, Types.DOUBLE, null); else stmt.setDouble(87,Double.parseDouble(efficacy_passed_time)); + if(efficacy_mortality_method==null) stmt.setNull(88, Types.INTEGER, null); else stmt.setInt(88,Integer.parseInt(efficacy_mortality_method)); + stmt.setString(89,safety_clothing); + if(safety_clothing_clean==null) stmt.setNull(90, Types.BOOLEAN, null); + else { + if(safety_clothing_clean.equals("1")) stmt.setBoolean(90,true); + else stmt.setBoolean(90,false); + } + if(safety_operator_health==null) stmt.setNull(91, Types.BOOLEAN, null); + else { + if(safety_operator_health.equals("1")) stmt.setBoolean(91,true); + else stmt.setBoolean(91,false); + } + stmt.setString(92,description); + stmt.setString(93,safety_inform); + stmt.setString(94,safety_container); //Теперь набор id в виде строки, раньше было так: "if(safety_container_id==null) stmt.setNull(93, Types.INTEGER, null); else stmt.setInt(93,Integer.parseInt(safety_container_id));" + if(safety_non_target==null) stmt.setNull(95, Types.BOOLEAN, null); + else { + if(safety_non_target.equals("1")) stmt.setBoolean(95,true); + else stmt.setBoolean(95,false); + } + stmt.setString(96,safety_non_target_effect); + if(safety_incident==null) stmt.setNull(97, Types.BOOLEAN, null); + else { + if(safety_incident.equals("1")) stmt.setBoolean(97,true); + else stmt.setBoolean(97,false); + } + stmt.setString(98,safety_incident_effect); + stmt.setString(99,comments); + stmt.setString(100,geom); + if(test==null) stmt.setNull(101, Types.BOOLEAN, null); + else { + if(test.equals("1")) stmt.setBoolean(101,true); + else stmt.setBoolean(101,false); + } + + } catch (SQLException ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=""; + try{ conn.close(); }catch(Exception e){} + return result; + } + + //Execute SQL + try { + stmt.execute(); + } catch (SQLException ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=""; + try{ conn.close(); }catch(Exception e){} + return result; + } + + //If there are drawings, then copy them. + String imgDir="./data/frmlocustdel/"; + try{ new File(dataDir+imgDir).mkdirs(); }catch (Exception exception) {} + if(image_name1!=null && !image_name1.equals("")) + { + String filename1=dataDir+tmpDir+image_name1; + File f = new File(filename1); + if(f.exists() && !f.isDirectory()) { + f.renameTo(new File(dataDir+imgDir+image_name1)); + } + } + if(image_name2!=null && !image_name2.equals("")) + { + String filename2=dataDir+tmpDir+image_name2; + File f = new File(filename2); + if(f.exists() && !f.isDirectory()) { + f.renameTo(new File(dataDir+imgDir+image_name2)); + } + } + if(image_name3!=null && !image_name3.equals("")) + { + String filename3=dataDir+tmpDir+image_name3; + File f = new File(filename3); + if(f.exists() && !f.isDirectory()) { + f.renameTo(new File(dataDir+imgDir+image_name3)); + } + } + + result=""; + logRotate(data_dir+"errors.log","XML="+result); + try{ conn.close(); }catch(Exception e){} + return result; + + }else + { + result=""; + try{ conn.close(); }catch(Exception e){} + return result; + } + } + + @RequestMapping(value = "/get",params = {"fn"},method = { RequestMethod.GET, RequestMethod.POST }) + @ResponseBody + public Object uploadFILE(@RequestHeader(required=false,name="Content-Type") String contentType,HttpServletResponse response,@RequestBody(required=false) String reqData,@RequestParam(required=false,name="file") MultipartFile file,@RequestParam(required=false,name="fn") String fn,@RequestParam(required=false,name="r") String reqR,@RequestParam(required=false,name="n") String reqN,@RequestParam(required=false,name="s") String reqS,@RequestParam(required=false,name="l") String reqL) { + + if(contentType!=null) + logger.info("Content-Type = " + contentType); //INFO : kz.locust.CCALM.AcceptASDC - Content-Type = multipart/form-data; boundary=kTwyQRMc7R9JvmcYlXyvMEwX6B08jb + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + + String result=""; + if(fn==null || (!fn.equals("1") && !fn.equals("6"))) + { + response.setContentType("application/xml"); + return result; + } + + //String metadata_file = ""; + String db_url = ""; + String db_login = ""; + String db_password = ""; + //String mail_host = ""; + //String mail_port = ""; + //String mail_login = ""; + //String mail_password = ""; + String data_dir = ""; + //Load DB configuration from "config.xml" + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("db-url")) + db_url = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-login")) + db_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-password")) + db_password = nl.item(i).getTextContent(); + + if (nl.item(i).getNodeName().equals("data-dir")) + data_dir = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=""; + response.setContentType("application/xml"); + return result; + } + + + //Send tables handbook(list) to client. + if(fn.equals("1")) + { + //Connect to database + Connection conn = null; + try { + Class.forName("org.postgresql.Driver"); + conn = DriverManager.getConnection(db_url, db_login, db_password); + if (conn != null) { + logger.info("Connect is OK!"); + } else { + logger.info("An error occurred while connecting to the database!"); + } + } catch (Exception ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + } + /*Statement stt=null; + try { + stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + }*/ + + //Set UTC time + Statement stm=null; + try { + stm = conn.createStatement(); + try { + stm.execute("SET timezone TO 'UTC';"); + } catch( SQLException ex ) { + try{ conn.close(); }catch(Exception e){} + logger.info(ex.getMessage()); + result=""; + response.setContentType("application/xml"); + return result; + } + stm.close(); + } catch (SQLException ex) { + try{ conn.close(); }catch(Exception e){} + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=""; + response.setContentType("application/xml"); + return result; + } + + + //int pR=0; + String pN=""; + int pS=0; + //int pL=0; + + String val; + val = reqR; + //if(val!=null) pR=Integer.parseInt(val); + pN = reqN; + val = reqS; + if(val!=null) pS=Integer.parseInt(val); + val = reqL; + //if(val!=null) pL=100; + + //return new FileSystemResource(file); + response.setContentType("application/octet-stream"); + response.setHeader("Content-Disposition","attachment; filename="+pN+".tbl"); + + + String sql; + if(pN.equals("_translations")) + { + sql = "select * from main."+pN+" where seq>"+pS+" and translation_type_id=2 order by seq"; + }else + { + sql = "select * from main."+pN+" where seq>"+pS+" order by seq"; + } + + try { + Statement st = conn.createStatement(); + ResultSet rs=null; + try { + rs = st.executeQuery(sql); + } catch( SQLException ex ) { + try{ conn.close(); }catch(Exception e){} + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=""; + response.setContentType("application/xml"); + return result; + } + + try { + if(rs!=null) + { + TCTable tbl=new TCTable(pN,123456); + logger.info("*** "+pN+" ***"); + + ResultSetMetaData rsmd = rs.getMetaData(); + for(int i=1;i<=rsmd.getColumnCount();i++) + { + logger.info(i+") name="+rsmd.getColumnName(i)+" type="+rsmd.getColumnTypeName(i)); + + TCField field=new TCField(rsmd.getColumnName(i), rsmd.getColumnTypeName(i)); + tbl.addField(field); + } + + tbl.getHeader(response.getOutputStream()); + while (rs.next()) + { + for(int i=1;i<=rsmd.getColumnCount();i++) + { + if(!rsmd.getColumnTypeName(i).equals("geometry")) + tbl.fields.get(i-1).setValue(rs.getString(i)); + else + tbl.fields.get(i-1).setValue(null); + } + //Save binary data to stream + tbl.getCol(response.getOutputStream()); + } + } + st.close(); + + //response.getOutputStream(); + response.flushBuffer(); + } catch (IOException e) { + } + + + } catch (SQLException ex) { + try{ conn.close(); }catch(Exception e){} + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=""; + response.setContentType("application/xml"); + return result; + } + + try{ conn.close(); }catch(Exception e){} + return null; + + }else + if(fn.equals("6")) { + + //Create temporary directory + String dataDir = data_dir; + String tmpDir = "temp"+File.separator; + try{ new File(dataDir+tmpDir).mkdirs(); }catch (Exception ex) { + logger.info(ex.getMessage()); + result=""; + response.setContentType("application/xml"); + return result; + } + + deleteOldFiles(dataDir+tmpDir,24*60*60*10); //If the files are older than 10 days then delete them. + + String fileName = ""; + + if (file!=null && !file.isEmpty()) { + try { + + byte[] bytes = file.getBytes(); + fileName = file.getOriginalFilename(); + + File dir = new File(dataDir+tmpDir); + if (!dir.exists()) dir.mkdirs(); + + BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(dataDir+tmpDir+fileName))); + stream.write(bytes); + stream.flush(); + stream.close(); + logger.info("Uploaded Filename: " + dataDir+tmpDir+fileName); + + } catch (Exception ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + } + result=""; + }else + { + result=""; + } + } + response.setContentType("application/xml"); + return result; + } + + //table=frmlocust&file=3a28b88f_locust_1508816625.jpg + @RequestMapping(value = "/photo",method = RequestMethod.GET, produces = "image/jpeg") + @ResponseBody + public FileSystemResource sendPhoto(HttpServletResponse response,@RequestParam(required=true,name="table") String tableName,@RequestParam(required=true,name="file") String fileName) { + + String data_dir = ""; + //Load DB configuration from "config.xml" + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("data-dir")) + data_dir = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + + + File file = new File(data_dir + "data/" + tableName + "/" + fileName); + if(file.exists()) + { + logger.info("Send photo: " + fileName); + + response.setContentType("image/jpeg"); + response.setHeader("Content-Disposition","filename="+fileName); + response.setContentLength((int) file.length()); + return new FileSystemResource(file); + }else + { + logger.info("File not found: " + fileName); + + //Redirect to external storage. + response.setHeader("Location", "http://data.ccalm.org/photo/?table="+tableName+"&file=" + fileName); + response.setStatus(302); + + return null; + } + } + + //@RequestMapping(value = "/get",params = {"fn"},method = { RequestMethod.GET, RequestMethod.POST }) + //Для проверки какие фото есть на сервере а каких нет чтобы удалить из имена фотографий которых нет в базе + @RequestMapping(value = "/photolist",method = RequestMethod.GET, produces = "text/html") + @ResponseBody + public Object getPhotoList(HttpServletResponse response) { + + String result="Результат
"; + + String db_url = ""; + String db_login = ""; + String db_password = ""; + String data_dir = ""; + //Load DB configuration from "config.xml" + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("db-url")) + db_url = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-login")) + db_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-password")) + db_password = nl.item(i).getTextContent(); + + if (nl.item(i).getNodeName().equals("data-dir")) + data_dir = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + + //Connect to database + Connection conn = null; + try { + Class.forName("org.postgresql.Driver"); + conn = DriverManager.getConnection(db_url, db_login, db_password); + if (conn != null) { + logger.info("Connect is OK!"); + } else { + logRotate(data_dir+"errors.log","An error occurred while connecting to the database!"); + logger.info("An error occurred while connecting to the database!"); + } + } catch (Exception ex) { + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + } + + int cnt=0; + String sql; + + sql = "select id,image_name1,image_name2,image_name3 from main.frmlocust where del=false order by id desc"; + try { + Statement st = conn.createStatement(); + ResultSet rs=null; + try { + rs = st.executeQuery(sql); + } catch( SQLException ex ) { + try{ conn.close(); }catch(Exception e){} + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=ex.getMessage(); + return result; + } + + //try { + if(rs!=null) + { + while (rs.next()) + { + if(rs.getString(2)!=null) + { + File file = new File(data_dir + "data/frmlocust/" + rs.getString(2)); + if(!file.exists()) + { + cnt++; + result+=cnt+") update main.frmlocust set image_name1=null where id="+rs.getString(1)+" and image_name1='"+rs.getString(2)+"';
"; + } + } + if(rs.getString(3)!=null) + { + File file = new File(data_dir + "data/frmlocust/" + rs.getString(3)); + if(!file.exists()) + { + cnt++; + result+=cnt+") update main.frmlocust set image_name2=null where id="+rs.getString(1)+" and image_name2='"+rs.getString(3)+"';
"; + } + } + if(rs.getString(4)!=null) + { + File file = new File(data_dir + "data/frmlocust/" + rs.getString(4)); + if(!file.exists()) + { + cnt++; + result+=cnt+") update main.frmlocust set image_name3=null where id="+rs.getString(1)+" and image_name3='"+rs.getString(4)+"';
"; + } + } + } + } + //st.close(); + //response.getOutputStream(); + //response.flushBuffer(); + //} catch (IOException e) { + //} + + + } catch (SQLException ex) { + try{ conn.close(); }catch(Exception e){} + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=ex.getMessage(); + return result; + } + + result+="
"; + + sql = "select id,image_name1,image_name2,image_name3 from main.frmlocustdel where del=false order by id desc"; + try { + Statement st = conn.createStatement(); + ResultSet rs=null; + try { + rs = st.executeQuery(sql); + } catch( SQLException ex ) { + try{ conn.close(); }catch(Exception e){} + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=ex.getMessage(); + return result; + } + + //try { + if(rs!=null) + { + while (rs.next()) + { + if(rs.getString(2)!=null) + { + File file = new File(data_dir + "data/frmlocustdel/" + rs.getString(2)); + if(!file.exists()) + { + cnt++; + result+=cnt+") update main.frmlocustdel set image_name1=null where id="+rs.getString(1)+" and image_name1='"+rs.getString(2)+"';
"; + } + } + if(rs.getString(3)!=null) + { + File file = new File(data_dir + "data/frmlocustdel/" + rs.getString(3)); + if(!file.exists()) + { + cnt++; + result+=cnt+") update main.frmlocustdel set image_name2=null where id="+rs.getString(1)+" and image_name2='"+rs.getString(3)+"';
"; + } + } + if(rs.getString(4)!=null) + { + File file = new File(data_dir + "data/frmlocustdel/" + rs.getString(4)); + if(!file.exists()) + { + cnt++; + result+=cnt+") update main.frmlocustdel set image_name3=null where id="+rs.getString(1)+" and image_name3='"+rs.getString(4)+"';
"; + } + } + } + } + //st.close(); + //response.getOutputStream(); + //response.flushBuffer(); + //} catch (IOException e) { + //} + + + } catch (SQLException ex) { + try{ conn.close(); }catch(Exception e){} + logRotate(data_dir+"errors.log",ex.getMessage()); + logger.info(ex.getMessage()); + result=ex.getMessage(); + return result; + } + + result+=""; + return result; + } + + + + @Override + public void setServletContext(ServletContext context) { + this.context=context; + } + + public String getCdataValue(Element node,String name) + { + String result=""; + Node nextnode=node.getFirstChild(); + while(nextnode!=null) + { + if(nextnode.getNodeName().equals(name)) + { + Node cdata=nextnode.getFirstChild(); + if(cdata!=null) result=cdata.getNodeValue(); + break; + } + nextnode = nextnode.getNextSibling(); + } + if(result.equals("") || result.equals("null")) + return null; + else + return result; + } + + boolean deleteOldFiles(String dir,int sec) + { + boolean result=true; + try{ + File folder = new File(dir); + File[] listOfFiles = folder.listFiles(); + if(listOfFiles!=null) + { + for (int i = 0; i < listOfFiles.length; i++) + { if (listOfFiles[i].isFile()) + { + BasicFileAttributes attr = Files.readAttributes(listOfFiles[i].toPath(), BasicFileAttributes.class); + long time = (System.currentTimeMillis() - attr.creationTime().to(TimeUnit.MILLISECONDS)) / 1000L; + if(time>sec) + listOfFiles[i].delete(); + } else if (listOfFiles[i].isDirectory()) + { //System.out.println("Directory " + listOfFiles[i].getName()); + } + } + } + }catch(Exception ex) + { + System.out.println(ex.getMessage()); + result=false; + } + return result; + } + + //Сохраняю лог в текстовый файл (для логирования ошибок) + void logRotate(String aFileName, String line) + { + try { + long fileSize = 0; + File file = new File(aFileName); + if (file.exists() || file.isFile()) + { + fileSize = file.length(); + } + if(fileSize>1024*1024*10) //Переименовываем файл если он привысил размер + { + + } + BufferedWriter writer = new BufferedWriter(new FileWriter(aFileName,true)); + writer.write(line); + writer.newLine(); + writer.close(); + } catch (IOException e) { + } + } + + +} diff --git a/src/main/java/kz/locust/CCALM/AcceptEXCEL.java b/src/main/java/kz/locust/CCALM/AcceptEXCEL.java new file mode 100644 index 0000000..beae5fd --- /dev/null +++ b/src/main/java/kz/locust/CCALM/AcceptEXCEL.java @@ -0,0 +1,408 @@ +package kz.locust.CCALM; + + + +import java.io.BufferedReader; +import java.io.File; +//import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +//import java.io.OutputStream; +//import java.io.UnsupportedEncodingException; +//import java.nio.file.Paths; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +//import java.util.zip.CRC32; +//import java.util.zip.Checksum; + +import javax.servlet.ServletContext; +//import javax.servlet.http.Part; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.springframework.core.io.ClassPathResource; +//import org.apache.commons.io.FileUtils; +//import org.springframework.core.io.FileSystemResource; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ModelAttribute; +//import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.context.ServletContextAware; +import org.springframework.web.multipart.MultipartFile; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import tools.User; + + +@Controller +public class AcceptEXCEL implements ServletContextAware { + + private ServletContext context; + + @Override + public void setServletContext(ServletContext context) { + this.context=context; + } + + @RequestMapping(value = "/AcceptCSV", method = { RequestMethod.GET, RequestMethod.POST }) + public String acceptCSV(@ModelAttribute User user, Model model,@RequestParam(required=false,name="file") MultipartFile file,@RequestParam(required=false,name="skip",defaultValue = "0") Boolean skip) { + + String db_url=""; + String db_login=""; + String db_password=""; + //Load DB configuration from "config.xml" + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain=doc.getDocumentElement(); + NodeList nl=nMain.getChildNodes(); + for (int i = 0; i "; + table+="№Latitude (Широта)Longitude (Долгота)Oblast (область)District (Район)Сельский округХозяйство или местностьВид саранчиФазаЭПВЗаселено ГаДата"; + + //row+=""+i+""+locust.lat+""+locust.lon+""+locust.region+" = "+locust.region_id+""+locust.district+" = "+locust.district_id+""+locust.terrain+""+locust.village+""; + + if (file!=null && !file.isEmpty()) { + + BufferedReader reader; + try { + int i=1; //for testing + + reader = new BufferedReader(new InputStreamReader(file.getInputStream(), "UTF-8")); + //reader = new BufferedReader(new FileReader(file)); + + String line = reader.readLine(); + if(skip) line = reader.readLine(); + while (line != null) { + + StringBuffer data=new StringBuffer(line); + Boolean error=false; + + Locust locust = new Locust(); + try { + String lat=CutBeforeFirst(data,";"); + if(lat.equals("46.3104.6")) lat="46.31046"; + if(lat.equals("43.21303.")) lat="43.21303"; + if(lat.equals("43.26067.")) lat="43.26067"; + if(lat.equals("43.20181.")) lat="43.20181"; + if(lat.equals("43.20181.")) lat="43.20181"; + if(lat.equals("43.74691.")) lat="43.74691"; + if(lat.equals("43.41954.")) lat="43.41954"; + if(lat.equals("43.78288.")) lat="43.78288"; + if(lat.equals("43.26260.")) lat="43.26260"; + if(lat.equals("43.79702.")) lat="43.79702"; + if(lat.equals("43.64891.")) lat="43.64891"; + if(lat.equals("43.64891.")) lat="43.64891"; + if(lat.equals("43.42271.")) lat="43.42271"; + if(lat.equals("43.64891.")) lat="43.64891"; + if(lat.equals("43.89990.")) lat="43.89990"; + if(lat.equals("43.96273.")) lat="43.96273"; + if(lat.equals("43.26907.")) lat="43.26907"; + if(lat.equals("43.26630.")) lat="43.26630"; + if(lat.equals("43.50605.")) lat="43.50605"; + if(lat.equals("43.74965.")) lat="43.74965"; + if(lat.equals("43.20813.")) lat="43.20813"; + if(lat.equals("43.23298.")) lat="43.23298"; + if(lat.equals("43.74774.")) lat="43.74774"; + if(lat.equals("43.77144.")) lat="43.77144"; + if(lat.equals("43.58847.")) lat="43.58847"; + if(lat.equals("43.58944.")) lat="43.58944"; + if(lat.equals("4342755.")) lat="43.42755"; + if(lat.equals("43.80416.")) lat="43.80416"; + if(lat.equals("43.79536.")) lat="43.79536"; + if(lat.equals("50.75 767")) lat="50.75767"; + if(lat.equals("50.77 542")) lat="50.77542"; + if(lat.equals("50.85 140")) lat="50.85140"; + if(lat.equals("50.79 773")) lat="50.79773"; + if(lat.equals("50.63 469")) lat="50.63469"; + if(lat.equals("51.23 130")) lat="51.23130"; + if(lat.equals("51.03 220")) lat="51.03220"; + if(lat.equals("51.38 922")) lat="51.38922"; + if(lat.equals("51.06.940")) lat="51.06940"; + if(lat.equals("51.08 273")) lat="51.08273"; + if(lat.equals("50.96 705")) lat="50.96705"; + if(lat.equals("51.03 021")) lat="51.03021"; + if(lat.equals("51.01 764")) lat="51.01764"; + if(lat.equals("50.99 388")) lat="50.99388"; + if(lat.equals("50.50 509")) lat="50.50509"; + if(lat.equals("43.109.94")) lat="43.10994"; + if(lat.equals("50.11.926")) lat="50.11926"; + if(lat.equals("50.04.966")) lat="50.04966"; + if(lat.equals("49.26.385")) lat="49.26385"; + if(lat.equals("49.26.251")) lat="49.26251"; + if(lat.equals("49.25.307")) lat="49.25307"; + if(lat.equals("44.4930.")) lat="49.25307"; + + locust.lat=Double.parseDouble(lat); + + String lon=CutBeforeFirst(data,";"); + if(lon.equals("51.25 560")) lon="51.25560"; + if(lon.equals("51.25 099")) lon="51.25099"; + if(lon.equals("51.26 378")) lon="51.26378"; + if(lon.equals("51.25 235")) lon="51.25235"; + if(lon.equals("51.83 107")) lon="51.83107"; + if(lon.equals("51.71 702")) lon="51.71702"; + if(lon.equals("52.21 390")) lon="52.21390"; + if(lon.equals("52.10 873")) lon="52.10873"; + if(lon.equals("51.85 606")) lon="51.85606"; + if(lon.equals("52.41 085")) lon="52.41085"; + if(lon.equals("52.36 125")) lon="52.36125"; + if(lon.equals("51. 56 025")) lon="51.56025"; + if(lon.equals("51.56 786")) lon="51.56786"; + if(lon.equals("51.57 946")) lon="51.57946"; + if(lon.equals("51.16 758")) lon="51.16758"; + if(lon.equals("85.09.142")) lon="85.09142"; + + + locust.lon=Double.parseDouble(lon); + + }catch(Exception ex) + { + error=true; + } + + locust.region=CutBeforeFirst(data,";"); + + //Выбираю ID области + Statement stt = null; + ResultSet rs = null; + try { + + if(locust.region.equals("Алматинский")) locust.region="Алматинская"; + if(locust.region.equals("Туркестанский")) locust.region="Туркестанская"; + + stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + String sql_query = "select id from main.countriesregions where name like '%"+locust.region+"%';"; + rs = stt.executeQuery(sql_query); + if (rs != null) { + try { + if (rs.next()) { + locust.region_id=rs.getString(1); + } + rs.close(); + } catch (SQLException ex) { + } + } + } catch (SQLException ex) { + + }finally { + if(rs!=null) try{rs.close();}catch(SQLException ex){} + if(stt!=null) try{stt.close();}catch(SQLException ex){} + } + + //Выбираю id региона (main.countriesdistricts) + locust.district_id=""; + locust.district=CutBeforeFirst(data,";"); + stt = null; + rs = null; + try { + + if(locust.district.equals("Сарканский ")) locust.district="Саркандский"; + if(locust.district.equals("Уйгуский")) locust.district="Уйгурский"; + if(locust.district.equals("г.Капшагай")) locust.district="Капчагайский городской округ"; + if(locust.district.equals("Каратальскиий")) locust.district="Каратальский"; + if(locust.district.equals("г. Талдыкорган")) locust.district="Талдыкорганский"; + if(locust.district.equals("г Атырау ")) locust.district="Атырауский городской округ"; + if(locust.district.equals("г. Атырау")) locust.district="Атырауский городской округ"; + if(locust.district.equals("Кызылкуга")) locust.district="Кзылкогинский район"; + if(locust.district.equals("Курчумский ")) locust.district="Куршимский район"; + if(locust.district.equals("г.Семей")) locust.district="Семипалатинский городской округ"; + if(locust.region_id.equals("4") && locust.district.equals("Жамбылский")) locust.district="Джамбулский район"; + if(locust.district.equals("Т.Рыскуловский")) locust.district="Рыскуловский район"; + if(locust.district.equals("Шуйский")) locust.district="Чуйский район"; + if(locust.district.equals("Сарысуский")) locust.district="Сары-Суйский район"; + if(locust.district.equals("Федоровский")) locust.district="Фёдоровский район"; + if(locust.district.equals("Жангельдинский")) locust.district="Джангельдинский район"; + if(locust.district.equals("Сырдария")) locust.district="Сырдарьинский район"; + if(locust.district.equals("Кызылорда")) locust.district="Кызылординский городской округ"; + if(locust.district.equals("к.Кызылорда")) locust.district="Кызылординский городской округ"; + if(locust.district.equals("Аралский")) locust.district="Аральский район"; + if(locust.district.equals("Шиелі")) locust.district="Шиелийский район"; + if(locust.region_id.equals("11") && locust.district.equals("Аксуский")) locust.district="Аксуйский городской округ"; + if(locust.region_id.equals("11") && locust.district.equals("Аксуский")) locust.district="Аксуйский городской округ"; + if(locust.region_id.equals("11") && locust.district.equals("Ақсуский")) locust.district="Аксуйский городской округ"; + if(locust.district.equals("Аққулы")) locust.district="Аккулинский район"; + if(locust.district.equals("Аккулы")) locust.district="Аккулинский район"; + if(locust.district.equals("Тереңкөл")) locust.district="Теренкольский"; + if(locust.district.equals("г. Павлодар")) locust.district="Павлодарский городской округ"; + if(locust.district.equals("Екибастузский")) locust.district="Экибастузский городской округ"; + if(locust.district.equals("Шербактнский")) locust.district="Щербактинский район"; + if(locust.district.equals("Толебиский ")) locust.district="Толебийский район"; + if(locust.district.equals("г.Шымкент Абайский ")) locust.district="Шымкентский городской округ"; + if(locust.district.equals("г.Шымкент Каратауский ")) locust.district="Шымкентский городской округ"; + if(locust.district.equals("Баянауыл")) locust.district="Баянаул"; + if(locust.district.equals("Екібастұз")) locust.district="Экибастуз"; + + + + + stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + String sql_query = "select id from main.countriesdistricts where region_id="+locust.region_id+" and name like '%"+locust.district+"%';"; + rs = stt.executeQuery(sql_query); + if (rs != null) { + try { + if (rs.next()) { + locust.district_id=rs.getString(1); + } + rs.close(); + } catch (SQLException ex) { + } + } + } catch (SQLException ex) { + + }finally { + if(rs!=null) try{rs.close();}catch(SQLException ex){} + if(stt!=null) try{stt.close();}catch(SQLException ex){} + } + + //Сельский округ + locust.terrain=CutBeforeFirst(data,";"); + //Хозяйство или местность + locust.village=CutBeforeFirst(data,";"); + //Вид саранчи + locust.locust=CutBeforeFirst(data,";"); + locust.locust_id=""; + if(locust.locust.equals(" итальянский прус")) locust.locust_id="1"; + if(locust.locust.equals("итальянский прус")) locust.locust_id="1"; + if(locust.locust.equals("Итальянский прус")) locust.locust_id="1"; + if(locust.locust.equals("итальянский прус ")) locust.locust_id="1"; + if(locust.locust.equals("Азиатская саранча")) locust.locust_id="3"; + if(locust.locust.equals("азиатская саранча")) locust.locust_id="3"; + if(locust.locust.equals("нестадные")) locust.locust_id="4"; + if(locust.locust.equals("нестадные саранчовые")) locust.locust_id="4"; + if(locust.locust.equals("Нестадные саранчевые")) locust.locust_id="4"; + if(locust.locust.equals("Нестадная саранча ")) locust.locust_id="4"; + if(locust.locust.equals("Нестадная саранча")) locust.locust_id="4"; + if(locust.locust.equals("нестадная саранча")) locust.locust_id="4"; + if(locust.locust.equals("Мароккская саранча")) locust.locust_id="2"; + + //фаза саранчи + locust.phase=CutBeforeFirst(data,";"); + locust.locust_have="3"; + if(locust.phase.equals("кубышки")) locust.locust_have="2"; + if(locust.phase.equals("личинки")) locust.locust_have="3"; + if(locust.phase.equals("имаго")) locust.locust_have="5"; + + locust.evp=CutBeforeFirst(data,";"); //ЭФП + locust.size=CutBeforeFirst(data,";"); //Заселённая площадь + locust.size=locust.size.replace(",","."); + locust.date=CutBeforeFirst(data,";"); //Дата + + String row=""; + if(error==true || locust.lat==0 || locust.lon==0 || locust.region_id.equals("") || locust.district_id.equals("") || locust.terrain.equals("") || locust.locust_id.equals("")) { + row=""; + } + row+=""+i+""+locust.lat+""+locust.lon+""+locust.region+" = "+locust.region_id+""+locust.district+" = "+locust.district_id+""+locust.terrain+""+locust.village+""+locust.locust+" = "+locust.locust_id+""+locust.phase+" = "+locust.locust_have+""+locust.evp+""+locust.size+""+locust.date+""; + row+="\n"; + + + + table += row; + i++; + + json+=" \n{\"type\":\"Feature\",\"geometry\":{\"type\":\"Point\",\"coordinates\":["+locust.lon+","+locust.lat+"]},\"properties\":{\"oblast\":\""+locust.region.replace("\"", "'")+"\",\"district\":\""+locust.district.replace("\"", "'")+"\",\"region\":\""+locust.terrain.replace("\"", "'")+"\",\"village\":\""+locust.village.replace("\"", "'")+"\",\"phase\":\""+locust.phase+"\",\"locust\":\""+locust.locust+"\",\"evp\": \""+locust.evp+"\",\"ga\": \""+locust.size+"\",\"date\": \""+locust.date+"\"}},"; + + sqlData+="insert into main.frmlocust(country_id,region_id,district,terrain,village,lon1,lat1,locust_type_id,locust_have,locust_populated,date)values(5,"+locust.region_id+",'"+locust.district.trim()+"','"+locust.terrain.trim()+"','"+locust.village.trim()+"',"+locust.lon+","+locust.lat+","+locust.locust_id+","+locust.locust_have+","+locust.size+",TO_DATE('"+locust.date+"','DD.MM.YYYY'));\n"; + + if(i>5000) break; + line=reader.readLine(); + } + reader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + + + }else { + table="CSV file is empty! "+skip; + } + table += ""; + + json=json.substring(0,json.length()-1); //Удаляю последнюю запятую + json+="\n]}"; + + model.addAttribute("PreviewTable",table); + model.addAttribute("PreviewGEOJSON",json); + model.addAttribute("PreviewSQL",sqlData); + + return "excel"; + + } + //--------------------------------------------------------------------------- + public static String CutBeforeFirst(StringBuffer str,String ch) + { + int pos=str.indexOf(ch); + String result=""; + if(pos==-1) + { + result.concat(str.toString()); + str.delete(0,str.length()); + }else + { + result=str.substring(0,pos); + str.delete(0,pos+1); + } + return result; + } + //--------------------------------------------------------------------------- + class Locust{ + double lon; + double lat; + String region; //Область + String region_id; + + String district; //Район + String district_id; + + String terrain; //Название месности + + String village; //Хозяйство или местность + + String locust; //Вид саранчи + String locust_id; //Вид саранчи + + String phase; //Фаза саранчи + String locust_have; //id Фазы саранчи + String evp; //ЭФП + String size; //Заселённая площадь + String date; //Дата + + } +} diff --git a/src/main/java/kz/locust/CCALM/AcceptJSON.java b/src/main/java/kz/locust/CCALM/AcceptJSON.java new file mode 100644 index 0000000..eccaaac --- /dev/null +++ b/src/main/java/kz/locust/CCALM/AcceptJSON.java @@ -0,0 +1,1740 @@ +//Согласно документу полученному от росийской стороны + +package kz.locust.CCALM; + +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.image.BufferedImage; +import java.awt.image.RenderedImage; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Types; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.Year; +import java.time.format.DateTimeFormatter; +import java.util.Base64; + +import javax.imageio.ImageIO; +import javax.servlet.ServletContext; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.json.JSONObject; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.json.JSONArray; +import org.json.JSONException; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.context.ServletContextAware; +import org.springframework.web.multipart.MultipartFile; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +//import com.google.common.io.CharStreams; + +//import jdk.nashorn.internal.parser.JSONParser; +//import kz.locust.CCALM.AcceptEXCEL.Locust; +//import sun.nio.cs.StandardCharsets; +//import kz.locust.CCALM.AcceptEXCEL.Locust; +//import kz.locust.CCALM.AcceptEXCEL.Locust; +import tctable.Tools; +import tools.User; + +@Controller +public class AcceptJSON implements ServletContextAware { + + private ServletContext context; + private static final int BUFFER_SIZE = 4096; + + @Override + public void setServletContext(ServletContext servletContext) { + this.context=servletContext; + } + + @RequestMapping(value = "/AcceptJSON", method = { RequestMethod.GET, RequestMethod.POST }) + public String acceptCSV(@ModelAttribute User user, Model model,@RequestParam(required=false,name="file") MultipartFile file,@RequestParam(required=false,name="skip",defaultValue = "0") Boolean skip) { + + String db_url=""; + String db_login=""; + String db_password=""; + //Load DB configuration + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain=doc.getDocumentElement(); + NodeList nl=nMain.getChildNodes(); + for (int i = 0; i "; + table+="№Ext idLatitude (Широта)Longitude (Долгота)Oblast (область)District (Район)Сельский округХозяйство или местностьВид саранчиФазаЭПВЗаселено ГаДата"; + + //By number of day downloading data and write result of downloading to database, try or false, after repair need repeat download + for(int day=277;day<367;day++) { + //Year y = Year.now(); + Year y = Year.of(2023); + LocalDate ld = y.atDay( day ) ; + if(ld.isAfter(LocalDate.now())) + break; + + //System.out.println( "dayOfYear: " + day + " at year: " + y + " = " + ld ) ; + String dateBegin=ld.format(DateTimeFormatter.ofPattern("dd.MM.yyyy")); + String dateEnd=dateBegin; + + System.out.println( "dayOfYear: " + day + " at year: " + y + " = " + dateEnd ); + + //Download JSON data from server + StringBuilder sb = new StringBuilder(); + try + { + //String strURL="http://rscase.ngnm.ru/pmon/rest/getPhytomons?token=QVOUE97HBSI6LBSGJGQZMP3KPSS1QK&dateBegin="+dateBegin+"&dateEnd="+dateEnd; + String strURL="https://rscagex.ru/pmon/rest/getPhytomons?token=QVOUE97HBSI6LBSGJGQZMP3KPSS1QK&dateBegin="+dateBegin+"&dateEnd="+dateEnd; + URL url = new URL(strURL); + HttpURLConnection hConn = (HttpURLConnection) url.openConnection(); + hConn.setRequestMethod("GET"); + hConn.connect(); + int responseCode = hConn.getResponseCode(); + if (responseCode / 100 == 2) //Code 206 is "Partial Content" + { + //InputStream inputStream = hConn.getInputStream(); + InputStreamReader inputStream = new InputStreamReader(hConn.getInputStream(), "UTF-8"); + int bytesRead; + char[] buffer = new char[BUFFER_SIZE]; + while ((bytesRead = inputStream.read(buffer)) != -1) { + sb.append(new String(buffer,0,bytesRead)); + } + inputStream.close(); + } + hConn.disconnect(); + } + catch (IOException e) + { + e.printStackTrace(); + } + String content=sb.toString(); + if(content==null || content.equals("")) + continue; + //byte[] data = sb.toByteArray(in); + //String content=new String(data, Charsets.UTF_8); + + //Iterate over the elements of the array. + int i=1; + JSONArray jsonArray= new JSONArray(content); + for (Object o : jsonArray) { + JSONObject jsonObj = (JSONObject) o; + Locust locust = new Locust(); + + locust.date=jsonObj.getString("date"); + + if(!jsonObj.isNull("regionName")) + locust.region=jsonObj.getString("regionName"); + else + locust.region=""; + + if(!jsonObj.isNull("townName")) + locust.district=jsonObj.getString("townName"); + + if(!jsonObj.isNull("point")) { + locust.lon=jsonObj.getJSONObject("point").getJSONArray("coordinates").getDouble(0); + locust.lat=jsonObj.getJSONObject("point").getJSONArray("coordinates").getDouble(1); + } + + //Контур зоны распространения ВО Polygon (geoJSON) + locust.drawPolygon=null; + if(!jsonObj.isNull("drawPolygon")) { + locust.drawPolygon=jsonObj.getJSONObject("drawPolygon").toString(); + } + + //Площадь контура зоны распространения, в случае если специалист указал его + locust.size="null"; + if(!jsonObj.isNull("polygonArea")) + locust.size=String.valueOf(jsonObj.getDouble("polygonArea")); + + //jsonObj.drawPolygon Краснодар + + if(locust.region.length()>0) { + //Выбираю ID области + locust.region_id=""; + Statement stt = null; + ResultSet rs = null; + try { + + stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + String sql_query = "select id from main.countriesregions where name like '%"+locust.region+"%';"; + rs = stt.executeQuery(sql_query); + if (rs != null) { + try { + if (rs.next()) { + locust.region_id=rs.getString(1); + } + rs.close(); + } catch (SQLException ex) { + ex.printStackTrace(); + } + } + } catch (SQLException ex) { + ex.printStackTrace(); + }finally { + if(rs!=null) try{rs.close();}catch(SQLException ex){ ex.printStackTrace(); } + if(stt!=null) try{stt.close();}catch(SQLException ex){ ex.printStackTrace(); } + } + + + /*if(locust.region_id.equals("")){ + if(locust.region.indexOf("Воронежс��ая область")>=0) locust.region_id="110"; + if(locust.region.indexOf("Кра��нодарский край")>=0) locust.region_id="164"; + if(locust.region.indexOf("Астраха��ская область")>=0) locust.region_id="68"; //dayOfYear: 97 at year: 2022 = 07.04.2022 + if(locust.region.indexOf("Астраханская област��")>=0) locust.region_id="68"; // dayOfYear: 101 at year: 2022 = 11.04.2022 + }*/ + + if(locust.region_id.length()>0) { + //Выбираю id региона (main.countriesdistricts) + locust.district_id=""; + stt = null; + rs = null; + try { + + if(locust.district.equals("Алапаевский район")) locust.district="городской округ Алапаевское"; + if(locust.district.equals("Сухоложский район")) locust.district="городской округ Сухой Лог"; + if(locust.district.equals("Талицкий район")) locust.district="Талицкий городской округ"; + if(locust.district.equals("Артинский район")) locust.district="Талицкий городской округ"; + if(locust.district.equals("Богдановичский район")) locust.district="городской округ Богданович"; + if(locust.district.equals("Красноуфимский район")) locust.district="Красноуфимский округ"; + if(locust.district.equals("Белоярский район")) locust.region_id="210"; + if(locust.district.equals("Пышминский район")) locust.district="Пышминский городской округ"; + if(locust.district.equals("Ирбитский район")) locust.district="городской округ Ирбитское"; + if(locust.district.equals("Фрязино г.о.")) locust.district="городской округ Фрязино"; + if(locust.district.equals("Коломенский г.о.")) locust.district="Коломенский район"; + if(locust.district.equals("Протвино г.о.")) locust.district="городской округ Протвино"; + if(locust.district.equals("Зарайск г.о.")) locust.district="Зарайский район"; + if(locust.district.equals("Анапский район")) locust.district="городской округ Анапа"; + if(locust.district.equals("Луховицы г.о.")) locust.district="Луховицкий район"; + if(locust.district.equals("Дергачевский район")) locust.district="Дергачёвский район"; + if(locust.district.equals("Чистоозерный район")) locust.district="Чистоозёрный район"; + if(locust.district.equals("Сунжа город")) locust.district="Сунженский район"; + if(locust.district.equals("Буденновский район")) locust.district="Будённовский район"; + if(locust.district.equals("Новоселовский район")) { locust.district="Новоселицкий район"; locust.region_id="168"; } + if(locust.district.equals("Тимашевский район")) locust.district="Тимашёвский район"; + if(locust.district.equals("Славгородский район")) locust.district="городской округ Славгород"; + if(locust.district.equals("Режевский район")) locust.district="Режевской городской округ"; + if(locust.district.equals("Веселовский район")) locust.district="Весёловский район"; + if(locust.district.equals("Карабулак город")) locust.district="городской округ Карабулак"; + if(locust.district.equals("Пугачевский район")) locust.district="Пугачёвский район"; + if(locust.district.equals("Кущевский район")) locust.district="Кущёвский район"; + if(locust.district.equals("Репьевский район")) locust.district="Репьёвский район"; + if(locust.district.equals("Калачевский район")) locust.district="Калачёвский район"; + if(locust.district.equals("Гайский район")) locust.district="Гайский городской округ"; + if(locust.district.equals("Новохоперский район")) locust.district="Новохопёрский район"; + if(locust.district.equals("Федоровский район")) locust.district="Фёдоровский район"; + if(locust.district.equals("Серебряные Пруды г.о.")) locust.district="городской округ Серебряные Пруды"; + if(locust.district.equals("Минераловодский район")) locust.district="Минераловодский городской округ"; + if(locust.district.equals("Рузский г.о.")) locust.district="Рузский район"; + if(locust.district.equals("Воробьевский район")) locust.district="Воробьёвский район"; + if(locust.district.equals("Ачитский район")) locust.district="Ачитский городской округ"; + if(locust.district.equals("Грачевский район")) locust.district="Грачёвский район"; + if(locust.district.equals("Уссурийский район")) locust.district="Уссурийский городской округ"; + if(locust.district.equals("Сорочинский район")) locust.district="Сорочинский городской округ"; + if(locust.district.equals("Ясненский район")) locust.district="Ясненский городской округ"; + + stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + String sql_query = "select id from main.countriesdistricts where region_id="+locust.region_id+" and name like '%"+locust.district+"%';"; + rs = stt.executeQuery(sql_query); + if (rs != null) { + try { + if (rs.next()) { + locust.district_id=rs.getString(1); + } + rs.close(); + } catch (SQLException ex) { + ex.printStackTrace(); + } + } + } catch (SQLException ex) { + ex.printStackTrace(); + }finally { + if(rs!=null) try{rs.close();}catch(SQLException ex){ ex.printStackTrace(); } + if(stt!=null) try{stt.close();}catch(SQLException ex){ ex.printStackTrace(); } + } + } + } + + String row=""; + + if(!jsonObj.isNull("subjectList")) { + JSONArray jsonArraySub = jsonObj.getJSONArray("subjectList"); + + for (Object o2 : jsonArraySub) { + JSONObject jsonObjSub = (JSONObject) o2; + + locust.eid=jsonObjSub.getInt("id"); + locust.phytoType=jsonObjSub.getString("phytoType"); //"Вредители" или "Обработка" + if(locust.phytoType.equals("Обработка")) + { + locust.insecticide_name = jsonObjSub.getString("nameSubject"); //Наименование действующего вещества + if(!jsonObjSub.isNull("nameLatSubject")) + locust.insecticide_active_substance = jsonObjSub.getString("nameLatSubject"); //Латинское наименование действующего вещества + if(!jsonObjSub.isNull("protectionDoze")) + locust.insecticide_dose = String.valueOf(jsonObjSub.getFloat("protectionDoze")); //Доза внесения препарата (л/га) + + if(!jsonObjSub.isNull("agroTreatmentType")) { + String agroTreatmentType = jsonObjSub.getString("agroTreatmentType"); //Тип обработки (Агротехнический, Авиационный, Наземный) + if(agroTreatmentType!=null && !agroTreatmentType.equals("")) { + if(agroTreatmentType.equals("GROUND")) { + locust.spray_platform = "3"; + }else if(agroTreatmentType.equals("AGROTECHNICAL")) { + locust.spray_platform = "5"; + } else if(agroTreatmentType.equals("AVIATION")) { + locust.spray_platform = "1"; + } + } + if(locust.spray_platform==null || locust.spray_platform.equals("")) { + model.addAttribute("PreviewTable","Error spray_platform"); + return "json"; + } + } + + //То что не знаю куда записывать записываю в description + locust.description=""; + if(!jsonObjSub.isNull("agroTreatmentPercentage")) + locust.description+="Процент обработанной площади: "+String.valueOf(jsonObjSub.getFloat("agroTreatmentPercentage"))+"\n"; + if(!jsonObjSub.isNull("agroTreatmentPow")) + locust.description+="Степень обработки: "+jsonObjSub.getString("agroTreatmentPow")+"\n"; + + //Если записи не существует то вставляем если существует то обновляем + boolean exists=false; //Is there a record. + Statement st; + try { + st = conn.createStatement(); + ResultSet rs=null; + try { + String sql="select 1 from main.frmlocustdel where eid="+String.valueOf(locust.eid); + rs = st.executeQuery(sql); + } catch( SQLException ex ) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error select"); + return "json"; + } + if(rs!=null) + { + if(rs.next()) + exists=true; + } + st.close(); + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error select 2"); + return "json"; + } + + PreparedStatement stmt=null; + String sql=""; + if(exists) + { + System.out.println( "update main.frmlocustdel"); + sql="update main.frmlocustdel set\n" + +" eid=?,\n" + +" lat_center=?,\n" + +" lon_center=?,\n" + +" country_id=?,\n" + +" region_id=?,\n" + +" area=?,\n" + +" district=?,\n" + +" date=TO_TIMESTAMP(?, 'DD.MM.YYYY HH24:MI'),\n" + +" description=?,\n" + +" geom=ST_SetSRID(ST_GeomFromGeoJSON(?),4326),\n" + + +" insecticide_name=?,\n" + +" insecticide_active_substance=?,\n" + +" insecticide_dose=?,\n" + +" spray_platform=?\n" + +" where eid='"+locust.eid+"'"; + try { + stmt = conn.prepareStatement(sql); + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error prepare 1"); + return "json"; + } + }else + { + System.out.println( "insert into main.frmlocustdel"); + sql="insert into main.frmlocustdel(\n" + +" eid,\n" //1 + +" lat_center,\n" //2 + +" lon_center,\n" //3 + +" country_id,\n" //4 + +" region_id,\n" //5 + +" area,\n" //6 + +" district,\n" //7 + +" date,\n" //8 + +" description,\n" //9 + +" geom,\n" //10 + + +" insecticide_name,\n" //11 + +" insecticide_active_substance,\n" //12 + +" insecticide_dose,\n" //13 + +" spray_platform\n" //14 + + +")values(\n" + +" ?,\n" //1 eid + +" ?,\n" //2 lat1 + +" ?,\n" //3 lon1 + +" ?,\n" //4 country_id + +" ?,\n" //5 region_id + +" ?,\n" //6 district (area) + +" ?,\n" //7 district (area) + +" TO_TIMESTAMP(?, 'DD.MM.YYYY HH24:MI'),\n" //8 date + +" ?,\n" //9 description + +" ST_SetSRID(ST_GeomFromGeoJSON(?),4326),\n" //10 geom + + +" ?,\n" //11 insecticide_name + +" ?,\n" //12 insecticide_active_substance + +" ?,\n" //13 insecticide_dose + +" ?\n" //14 spray_platform + +")"; + try { + stmt = conn.prepareStatement(sql); + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error prepare 2"); + return "json"; + } + } + + try { + stmt.setInt(1,locust.eid); + stmt.setDouble(2,locust.lat); + stmt.setDouble(3,locust.lon); + stmt.setInt(4,7); //country_id + stmt.setInt(5,Integer.parseInt(locust.region_id)); //region_id + stmt.setString(6,locust.district); //Пишу в поле "area" + stmt.setString(7,null); + stmt.setString(8,locust.date); //27.04.2020 09:17 + stmt.setString(9,locust.description); + stmt.setString(10,locust.drawPolygon); + + stmt.setString(11,locust.insecticide_name); + stmt.setString(12,locust.insecticide_active_substance); + if(locust.insecticide_dose==null || locust.insecticide_dose.equals("")) + stmt.setNull(13,Types.DOUBLE); + else + stmt.setDouble(13,Double.parseDouble(locust.insecticide_dose)); + + if(locust.spray_platform==null || locust.spray_platform.equals("")) + stmt.setNull(14,Types.INTEGER); + else + stmt.setInt(14,Integer.parseInt(locust.spray_platform)); + + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error set data"); + return "json"; + } + + //Выпоняю запрос на свтавку либо обновление + try { + stmt.execute(); + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error execute frmlocustdel"); + return "json"; + } + + + }else if(locust.phytoType.equals("Вредители")) + { + if(!jsonObjSub.isNull("nameSubject")) + locust.locust =jsonObjSub.getString("nameSubject"); + + //Вид саранчи + locust.locust_id=""; + if(locust.locust.equals("Короткокрылый зеленчук")) locust.locust_id="4"; + if(locust.locust.equals("Среднерусская перелётная саранча")) locust.locust_id="4"; + if(locust.locust.equals("Сибирская кобылка")) locust.locust_id="4"; + if(locust.locust.equals("Кобылка изменчивая")) locust.locust_id="4"; + if(locust.locust.equals("Кобылка пёстрая")) locust.locust_id="4"; + if(locust.locust.equals("Кобылка крестовая")) locust.locust_id="4"; + if(locust.locust.equals("Кобылка сибирская")) locust.locust_id="4"; + if(locust.locust.equals("Кобылка голубокрылая")) locust.locust_id="4"; + if(locust.locust.equals("Кобылка бескрылая")) locust.locust_id="4"; + if(locust.locust.equals("Кобылка чернополосая")) locust.locust_id="4"; + if(locust.locust.equals("Кобылка трескучая")) locust.locust_id="4"; + if(locust.locust.equals("Кобылка египетская")) locust.locust_id="4"; + if(locust.locust.equals("Трещотка ширококрылая")) locust.locust_id="4"; + if(locust.locust.equals("Бахчевая кобылка")) locust.locust_id="4"; + if(locust.locust.equals("Малая крестовичка")) locust.locust_id="4"; + if(locust.locust.equals("Конёк белополосый (белополосая кобылка)")) locust.locust_id="4"; + if(locust.locust.equals("Конек обыкновенный")) locust.locust_id="4"; + if(locust.locust.equals("Конек обыкновенный")) locust.locust_id="4"; + if(locust.locust.equals("Кобылка темнокрылая")) locust.locust_id="4"; + if(locust.locust.equals("Краснокрылая кобылка")) locust.locust_id="4"; + if(locust.locust.equals("Краснокрылая кобылка")) locust.locust_id="4"; + if(locust.locust.equals("Степная кобылка")) locust.locust_id="4"; + if(locust.locust.equals("Гребневка")) locust.locust_id="4"; + if(locust.locust.equals("Азиатская перелётная саранча")) locust.locust_id="3"; + if(locust.locust.equals("Итальянский прус")) locust.locust_id="1"; + if(locust.locust.equals("Мароккская саранча, мароккская кобылка, марокканка")) locust.locust_id="2"; + + //фаза саранчи + if(!jsonObjSub.isNull("phaseEvolutionName")) + locust.phase =jsonObjSub.getString("phaseEvolutionName"); + + locust.locust_have="3"; + if(locust.phase!=null) { + if(locust.phase.equals("Кубышка")) locust.locust_have="2"; //Кубышка = Яйца + if(locust.phase.equals("Гусеница")) locust.locust_have="3"; + if(locust.phase.equals("Личинка 2-го возраста")) locust.locust_have="3"; + if(locust.phase.equals("Личинка 3-го возраста")) locust.locust_have="3"; + if(locust.phase.equals("Личинка 4-го возраста")) locust.locust_have="3"; + if(locust.phase.equals("Личинка 5-го возраста")) locust.locust_have="3"; + if(locust.phase.equals("Имаго")) locust.locust_have="5"; + } + //Если эта анкета "Имаго" то записываем плотность имаго на m2 + if(locust.locust_have.equals("5")) { + if(!jsonObjSub.isNull("subPestCount")) + locust.imago_density=String.valueOf(jsonObjSub.getFloat("subPestCount")); + } + //Если эта анкета "Кубышка"="Яйца" то записываем плотность кулиг на m2 + if(locust.locust_have.equals("2")) { + if(!jsonObjSub.isNull("subPestCount")) + locust.eggs_capsules_density=String.valueOf(jsonObjSub.getFloat("subPestCount")); + } + //Если эта анкета "Кулиги" то записываем плотность кулиг на m2 + if(locust.locust_have.equals("4")) { + if(!jsonObjSub.isNull("subPestCount")) + locust.kuliguli_density=String.valueOf(jsonObjSub.getFloat("subPestCount")); + } + //Если эта анкета "Личинок" то записываем плотность личинок на m2 + if(locust.locust_have.equals("3")) { + if(!jsonObjSub.isNull("subPestCount")) + locust.larva_density=String.valueOf(jsonObjSub.getFloat("subPestCount")); + } + + //Если те виды что нам нужны + if(locust.region==null || locust.region.equals("") || locust.lat==0 || locust.lon==0 || locust.locust.equals("Совка ипсилон") || locust.locust.equals("Восточный майский хрущ") || locust.locust.equals("Кукурузный стеблевой мотылек") || locust.locust.equals("Картофельная, или болотная совка, лиловатая яровая совка") || locust.locust.equals("Луговой мотылёк") || locust.locust.equals("Хлопковая совка") || locust.locust.equals("Стеблевой кукурузный мотылек") || locust.locust.equals("Восточная луговая совка") || locust.locust.equals("Коричневая щитовка") || locust.locust.equals("Продолговатая (чайная) подушечница") || locust.locust.equals("Яблоневая запятовидная щитовка") || locust.locust.equals("Виноградная филлоксера") || locust.locust.equals("Бахчевая коровка")) + { + + }else { + + if(locust.locust_id.equals("")) { + System.out.println(locust.locust); + model.addAttribute("PreviewTable","locust.locust_id == 0 locust name = "+locust.locust); + return "json"; + } + if(locust.region_id.equals("")) { + System.out.println(locust.region); + model.addAttribute("PreviewTable","locust.region_id == 0 region name = "+locust.region); + return "json"; + } + + //Тех полей что нет в анкете вствляю в комментарии + try { + locust.description=""; + + if(jsonObjSub.getBoolean("notFound")) + locust.description+="Вредитель не обнаружен: "+jsonObjSub.getString("nameSubject")+"\n"; + else + locust.description+="Вредитель обнаружен: "+jsonObjSub.getString("nameSubject")+"\n"; + + if(!jsonObjSub.isNull("phaseEvolutionName")) + locust.description+="Фаза: "+jsonObjSub.getString("phaseEvolutionName")+"\n"; //Так как фаза у росиян более подробная + if(!jsonObjSub.isNull("subPestCount")) { + locust.description+="Вредителей: "+jsonObjSub.getFloat("subPestCount"); + if(!jsonObjSub.isNull("unitName")) + locust.description+=" "+jsonObjSub.getString("unitName"); + locust.description+="\n"; + } + + if(!jsonObj.isNull("cropCurrentType")) + locust.description+="Тип сева: "+jsonObj.getString("cropCurrentType")+"\n"; + if(!jsonObj.isNull("cropCurrentCulture")) + locust.description+="Наименование культуры: "+jsonObj.getString("cropCurrentCulture")+"\n"; + if(!jsonObj.isNull("cropCurrentCultureSort")) + locust.description+="Наименование сорта культуры: "+jsonObj.getString("cropCurrentCultureSort")+"\n"; + if(!jsonObj.isNull("cropCurrentGrowthPhase")) + locust.description+="Фаза роста культуры: "+jsonObj.getString("cropCurrentGrowthPhase")+"\n"; + if(!jsonObj.isNull("cropFieldArea")) { + locust.description+="Площадь поля: "+jsonObj.getFloat("cropFieldArea")+"\n"; + locust.bio_hectare=String.valueOf(jsonObj.getFloat("cropFieldArea")); + } + + + } catch (Exception ex) { + ex.printStackTrace(); + } + + locust.terrain="null"; //У росиян нет сельского округа + + row=""; + if(locust.region_id==null || locust.region_id.equals("") || locust.district_id==null || locust.district_id.equals("") || locust.locust_id==null || locust.locust_id.equals("")) { + row=""; + } + row+=""+i+""+locust.eid+""+locust.lat+""+locust.lon+""+locust.region+" = "+locust.region_id+""+locust.district+" = "+locust.district_id+""+locust.terrain+""+locust.village+""+locust.locust+" = "+locust.locust_id+""+locust.phase+" = "+locust.locust_have+""+locust.evp+""+locust.size+" = "+locust.drawPolygon+""+locust.date+""; + row+="\n"; + + //Если записи не существует то вставляем если существует то обновляем + boolean exists=false; //Is there a record. + Statement st; + try { + st = conn.createStatement(); + ResultSet rs=null; + try { + String sql="select 1 from main.frmlocust where eid="+String.valueOf(locust.eid); + rs = st.executeQuery(sql); + } catch( SQLException ex ) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error select"); + return "json"; + } + if(rs!=null) + { + if(rs.next()) + exists=true; + } + st.close(); + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error select 2"); + return "json"; + } + + PreparedStatement stmt=null; + String sql=""; + if(exists) + { + System.out.println( "update main.frmlocust"); + sql="update main.frmlocust set\n" + +" eid=?,\n" + +" lat1=?,\n" + +" lon1=?,\n" + +" country_id=?,\n" + +" region_id=?,\n" + +" area=?,\n" + +" district=?,\n" + +" date=TO_TIMESTAMP(?, 'DD.MM.YYYY HH24:MI'),\n" + +" description=?,\n" + +" geom=ST_SetSRID(ST_GeomFromGeoJSON(?),4326),\n" + +" locust_type_id=?,\n" + +" imago_density=?,\n" + +" kuliguli_density=?,\n" + +" larva_density=?,\n" + +" bio_hectare=?\n," + +" eggs_capsules_density=?\n" + +" where eid='"+locust.eid+"'"; + try { + stmt = conn.prepareStatement(sql); + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error prepare 1"); + return "json"; + } + }else + { + System.out.println( "insert into main.frmlocust"); + sql="insert into main.frmlocust(\n" + +" eid,\n" //1 + +" lat1,\n" //2 + +" lon1,\n" //3 + +" country_id,\n" //4 + +" region_id,\n" //5 + +" area,\n" //6 + +" district,\n" //7 + +" date,\n" //8 + +" description,\n" //9 + +" geom,\n" //10 + +" locust_type_id,\n" //11 + +" imago_density,\n" //12 + +" kuliguli_density,\n" //13 + +" larva_density,\n" //14 + +" bio_hectare,\n" //15 + +" eggs_capsules_density\n" //16 + +")values(\n" + +" ?,\n" //1 eid + +" ?,\n" //2 lat1 + +" ?,\n" //3 lon1 + +" ?,\n" //4 country_id + +" ?,\n" //5 region_id + +" ?,\n" //6 district (area) + +" ?,\n" //7 district (area) + +" TO_TIMESTAMP(?, 'DD.MM.YYYY HH24:MI'),\n" //8 date + +" ?,\n" //9 description + +" ST_SetSRID(ST_GeomFromGeoJSON(?),4326),\n" //10 geom + +" ?,\n" //11 locust_type_id + +" ?,\n" //12 imago_density + +" ?,\n" //13 kuliguli_density + +" ?,\n" //14 larva_density + +" ?,\n" //15 + +" ?\n" //16 + +")"; + try { + stmt = conn.prepareStatement(sql); + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error prepare 2"); + return "json"; + } + } + + try { + stmt.setInt(1,locust.eid); + stmt.setDouble(2,locust.lat); + stmt.setDouble(3,locust.lon); + stmt.setInt(4,7); + stmt.setInt(5,Integer.parseInt(locust.region_id)); + stmt.setString(6,locust.district); //Пишу в поле "area" + stmt.setString(7,null); + stmt.setString(8,locust.date); //27.04.2020 09:17 + stmt.setString(9,locust.description); + stmt.setString(10,locust.drawPolygon); + stmt.setInt(11,Integer.parseInt(locust.locust_id)); + if(locust.imago_density!=null) + stmt.setFloat(12,Float.parseFloat(locust.imago_density)); + else + stmt.setNull(12, Types.FLOAT); + if(locust.kuliguli_density!=null) + stmt.setFloat(13,Float.parseFloat(locust.kuliguli_density)); + else + stmt.setNull(13, Types.FLOAT); + if(locust.larva_density!=null) + stmt.setFloat(14,Float.parseFloat(locust.larva_density)); + else + stmt.setNull(14, Types.FLOAT); + if(locust.bio_hectare!=null) + stmt.setFloat(15,Float.parseFloat(locust.bio_hectare)); + else + stmt.setNull(15, Types.FLOAT); + if(locust.eggs_capsules_density!=null) + stmt.setFloat(16,Float.parseFloat(locust.eggs_capsules_density)); + else + stmt.setNull(16, Types.FLOAT); + + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error set data"); + return "json"; + } + //Выпоняю запрос на свтавку либо обновление + try { + stmt.execute(); + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error execute 0"); + return "json"; + } + + //Скачиваю фотографию для анкеты + sb = new StringBuilder(); + try + { + //String strURL="http://rscase.ngnm.ru/pmon/rest/getPhotosByParentId?token=QVOUE97HBSI6LBSGJGQZMP3KPSS1QK&parentId="+locust.eid; + String strURL="https://rscagex.ru/pmon/rest/getPhotosByParentId?token=QVOUE97HBSI6LBSGJGQZMP3KPSS1QK&parentId="+locust.eid; + URL url = new URL(strURL); + HttpURLConnection hConn = (HttpURLConnection) url.openConnection(); + hConn.setRequestMethod("GET"); + //hConn.setRequestProperty("Range","bytes=" + posStart + "-" + posEnd); + hConn.connect(); + int responseCode = hConn.getResponseCode(); + if (responseCode / 100 == 2) //Code 206 is "Partial Content" + { + InputStream inputStream = hConn.getInputStream(); + //FileOutputStream outputStream = new FileOutputStream(strFile); + int bytesRead; + byte[] buffer = new byte[BUFFER_SIZE]; + while ((bytesRead = inputStream.read(buffer)) != -1) { + //outputStream.write(buffer, 0, bytesRead); + sb.append(new String(buffer,0,bytesRead)); + } + //outputStream.close(); + inputStream.close(); + } + hConn.disconnect(); + } + catch (IOException e) + { + e.printStackTrace(); + } + + String base64=sb.toString(); + if(base64.length()>10) { + //Так как мне присылаю неправильный jSOM то пытаюсь его поправить,. + base64 = base64.replace("[", "[\""); + base64 = base64.replace("]", "\"]"); + base64 = base64.replace(", ", "\",\""); + + String strFile="O:\\temp\\CCALM\\ru_"+locust.eid; + int pos=0; + + JSONArray jsonArrayIMGS= new JSONArray(base64); + for (Object oStr : jsonArrayIMGS) { + String jsonObjIMG = (String) oStr; + pos++; + if(pos>3) break; + + //try { + // BufferedWriter writer = new BufferedWriter(new FileWriter(strFile)); + // writer.write(jsonObjIMG); + // writer.close(); + //} catch (IOException e1) { + // e1.printStackTrace(); + //} + + byte[] decodedString=null; + try { + decodedString = Base64.getDecoder().decode(jsonObjIMG); + } catch (Exception e) { + e.printStackTrace(); + model.addAttribute("PreviewTable","Error decode"); + return "json"; + } + + if(decodedString!=null) { + try { + FileUtils.writeByteArrayToFile(new File(strFile+"_"+pos+".jpg"), decodedString); + } catch (IOException e) { + e.printStackTrace(); + } + } + decodedString=null; + + BufferedImage imageOnDisk=null; + try { + imageOnDisk = ImageIO.read(new File(strFile+"_"+pos+".jpg")); + } catch (IOException e) { + e.printStackTrace(); + } + if(imageOnDisk!=null) + { + Image img; + BufferedImage buffered; + if(imageOnDisk.getWidth()>imageOnDisk.getHeight()){ + img = imageOnDisk.getScaledInstance(1024, 768, Image.SCALE_DEFAULT); + buffered = new BufferedImage(1024, 768, BufferedImage.TYPE_INT_RGB); + buffered.getGraphics().drawImage(img, 0, 0 , null); + }else { + img = imageOnDisk.getScaledInstance(768, 1024, Image.SCALE_DEFAULT); + buffered = new BufferedImage(768, 1024, BufferedImage.TYPE_INT_RGB); + buffered.getGraphics().drawImage(img, 0, 0 , null); + } + try { + //BufferedImage bIMG = toBufferedImage(img); + ImageIO.write(buffered, "jpg", new File(strFile+"_"+pos+".jpg")); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + + if(pos>3) + { + break; + }else + { + sql=""; + if(pos==1) { + sql="update main.frmlocust set image_name1='ru_"+locust.eid+"_"+pos+".jpg"+"' where eid="+locust.eid; + } + if(pos==2) { + sql="update main.frmlocust set image_name2='ru_"+locust.eid+"_"+pos+".jpg"+"' where eid="+locust.eid; + } + if(pos==3) { + sql="update main.frmlocust set image_name3='ru_"+locust.eid+"_"+pos+".jpg"+"' where eid="+locust.eid; + } + if(sql.length()>0) { + try { + st = conn.createStatement(); + st.execute(sql); + st.close(); + } catch( SQLException ex ) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error update img"); + return "json"; + } + } + } + } + } + } + + } //equals("Вредители") + + } + + } + + table += row; + i++; + } + + + table += ""; + + //json=json.substring(0,json.length()-1); //Удаляю последнюю запятую + //json+="\n]}"; + + + } + model.addAttribute("PreviewTable",table); + //model.addAttribute("PreviewGEOJSON",json); + model.addAttribute("PreviewSQL",sqlData); + +/* + String sqlData=""; + //String json="{\"type\": \"FeatureCollection\",\"features\":["; + + String table=""; + table+=""; + + //row+=""; + if(locust.region_id==null || locust.region_id.equals("") || locust.district_id==null || locust.district_id.equals("") || locust.locust_id==null || locust.locust_id.equals("")) { + row=""; + } + row+=""; + row+="\n"; + + //Если записи не существует то вставляем если существует то обновляем + boolean exists=false; //Is there a record. + Statement st; + try { + st = conn.createStatement(); + ResultSet rs=null; + try { + String sql="select 1 from main.frmlocust where eid="+String.valueOf(locust.eid); + rs = st.executeQuery(sql); + } catch( SQLException ex ) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error select"); + return "json"; + } + if(rs!=null) + { + if(rs.next()) + exists=true; + } + st.close(); + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error select 2"); + return "json"; + } + + PreparedStatement stmt=null; + String sql=""; + if(exists) + { + sql="update main.frmlocust set\n" + +" eid=?,\n" + +" lat1=?,\n" + +" lon1=?,\n" + +" country_id=?,\n" + +" region_id=?,\n" + +" area=?,\n" + +" district=?,\n" + +" date=TO_TIMESTAMP(?, 'DD.MM.YYYY HH24:MI'),\n" + +" description=?,\n" + +" geom=ST_SetSRID(ST_GeomFromGeoJSON(?),4326),\n" + +" locust_type_id=?,\n" + +" imago_density=?,\n" + +" kuliguli_density=?,\n" + +" larva_density=?,\n" + +" bio_hectare=?\n" + +" where eid='"+locust.eid+"'"; + try { + stmt = conn.prepareStatement(sql); + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error prepare 1"); + return "json"; + } + }else + { + sql="insert into main.frmlocust(\n" + +" eid,\n" //1 + +" lat1,\n" //2 + +" lon1,\n" //3 + +" country_id,\n" //4 + +" region_id,\n" //5 + +" area,\n" //6 + +" district,\n" //7 + +" date,\n" //8 + +" description,\n" //9 + +" geom,\n" //10 + +" locust_type_id,\n" //11 + +" imago_density,\n" //12 + +" kuliguli_density,\n" //13 + +" larva_density,\n" //14 + +" bio_hectare\n" //15 + +")values(\n" + +" ?,\n" //1 eid + +" ?,\n" //2 lat1 + +" ?,\n" //3 lon1 + +" ?,\n" //4 country_id + +" ?,\n" //5 region_id + +" ?,\n" //6 district (area) + +" ?,\n" //7 district (area) + +" TO_TIMESTAMP(?, 'DD.MM.YYYY HH24:MI'),\n" //8 date + +" ?,\n" //9 description + +" ST_SetSRID(ST_GeomFromGeoJSON(?),4326),\n" //10 geom + +" ?,\n" //11 locust_type_id + +" ?,\n" //12 imago_density + +" ?,\n" //13 kuliguli_density + +" ?,\n" //14 larva_density + +" ?\n" //15 + +")"; + try { + stmt = conn.prepareStatement(sql); + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error prepare 2"); + return "json"; + } + } + + try { + stmt.setInt(1,locust.eid); + stmt.setDouble(2,locust.lat); + stmt.setDouble(3,locust.lon); + stmt.setInt(4,7); + stmt.setInt(5,Integer.parseInt(locust.region_id)); + stmt.setString(6,locust.district); //Пишу в поле "area" + stmt.setString(7,null); + stmt.setString(8,locust.date); //27.04.2020 09:17 + stmt.setString(9,locust.description); + stmt.setString(10,locust.drawPolygon); + stmt.setInt(11,Integer.parseInt(locust.locust_id)); + if(locust.imago_density!=null) + stmt.setFloat(12,Float.parseFloat(locust.imago_density)); + else + stmt.setNull(12, Types.FLOAT); + if(locust.kuliguli_density!=null) + stmt.setFloat(13,Float.parseFloat(locust.kuliguli_density)); + else + stmt.setNull(13, Types.FLOAT); + if(locust.larva_density!=null) + stmt.setFloat(14,Float.parseFloat(locust.larva_density)); + else + stmt.setNull(14, Types.FLOAT); + if(locust.bio_hectare!=null) + stmt.setFloat(15,Float.parseFloat(locust.bio_hectare)); + else + stmt.setNull(15, Types.FLOAT); + + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error set data"); + return "json"; + } + //Выпоняю запрос на свтавку либо обновление + try { + stmt.execute(); + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error execute 0"); + return "json"; + } + + //Скачиваю фотографию для анкеты + StringBuilder sb = new StringBuilder(); + try + { + //String strURL="http://rscase.ngnm.ru/pmon/rest/getPhotosByParentId?token=MLQEXBCYQROFKFHWTYYLPCTCDRJMMF&parentId="+locust.eid; + String strURL="https://rscagex.ru/pmon/rest/getPhotosByParentId?token=MLQEXBCYQROFKFHWTYYLPCTCDRJMMF&parentId="+locust.eid; + + URL url = new URL(strURL); + HttpURLConnection hConn = (HttpURLConnection) url.openConnection(); + hConn.setRequestMethod("GET"); + //hConn.setRequestProperty("Range","bytes=" + posStart + "-" + posEnd); + hConn.connect(); + int responseCode = hConn.getResponseCode(); + if (responseCode / 100 == 2) //Code 206 is "Partial Content" + { + InputStream inputStream = hConn.getInputStream(); + //FileOutputStream outputStream = new FileOutputStream(strFile); + int bytesRead; + byte[] buffer = new byte[BUFFER_SIZE]; + while ((bytesRead = inputStream.read(buffer)) != -1) { + //outputStream.write(buffer, 0, bytesRead); + sb.append(new String(buffer,0,bytesRead)); + } + //outputStream.close(); + inputStream.close(); + } + hConn.disconnect(); + } + catch (IOException e) + { + e.printStackTrace(); + } + + String base64=sb.toString(); + if(base64.length()>10) { + //Так как мне присылаю неправильный jSOM то пытаюсь его поправить,. + base64 = base64.replace("[", "[\""); + base64 = base64.replace("]", "\"]"); + base64 = base64.replace(", ", "\",\""); + + String strFile="O:\\temp\\CCALM\\ru_"+locust.eid; + int pos=0; + + JSONArray jsonArrayIMGS= new JSONArray(base64); + for (Object oStr : jsonArrayIMGS) { + String jsonObjIMG = (String) oStr; + pos++; + if(pos>3) break; + + //try { + // BufferedWriter writer = new BufferedWriter(new FileWriter(strFile)); + // writer.write(jsonObjIMG); + // writer.close(); + //} catch (IOException e1) { + // e1.printStackTrace(); + //} + + byte[] decodedString=null; + try { + decodedString = Base64.getDecoder().decode(jsonObjIMG); + } catch (Exception e) { + e.printStackTrace(); + model.addAttribute("PreviewTable","Error decode"); + return "json"; + } + + if(decodedString!=null) { + try { + FileUtils.writeByteArrayToFile(new File(strFile+"_"+pos+".jpg"), decodedString); + } catch (IOException e) { + e.printStackTrace(); + } + } + decodedString=null; + + BufferedImage imageOnDisk=null; + try { + imageOnDisk = ImageIO.read(new File(strFile+"_"+pos+".jpg")); + } catch (IOException e) { + e.printStackTrace(); + } + if(imageOnDisk!=null) + { + Image img; + BufferedImage buffered; + if(imageOnDisk.getWidth()>imageOnDisk.getHeight()){ + img = imageOnDisk.getScaledInstance(1024, 768, Image.SCALE_DEFAULT); + buffered = new BufferedImage(1024, 768, BufferedImage.TYPE_INT_RGB); + buffered.getGraphics().drawImage(img, 0, 0 , null); + }else { + img = imageOnDisk.getScaledInstance(768, 1024, Image.SCALE_DEFAULT); + buffered = new BufferedImage(768, 1024, BufferedImage.TYPE_INT_RGB); + buffered.getGraphics().drawImage(img, 0, 0 , null); + } + try { + //BufferedImage bIMG = toBufferedImage(img); + ImageIO.write(buffered, "jpg", new File(strFile+"_"+pos+".jpg")); + } catch (IOException ex) { + ex.printStackTrace(); + } + } + + + if(pos>3) + { + break; + }else + { + sql=""; + if(pos==1) { + sql="update main.frmlocust set image_name1='ru_"+locust.eid+"_"+pos+".jpg"+"' where eid="+locust.eid; + } + if(pos==2) { + sql="update main.frmlocust set image_name2='ru_"+locust.eid+"_"+pos+".jpg"+"' where eid="+locust.eid; + } + if(pos==3) { + sql="update main.frmlocust set image_name3='ru_"+locust.eid+"_"+pos+".jpg"+"' where eid="+locust.eid; + } + if(sql.length()>0) { + try { + st = conn.createStatement(); + st.execute(sql); + st.close(); + } catch( SQLException ex ) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error update img"); + return "json"; + } + } + } + } + } + } + + } //equals("Вредители") + + } + + } + + table += row; + i++; + } + + }else { + table="CSV file is empty! "+skip; + } + table += "
Ext idLatitude (Широта)Longitude (Долгота)Oblast (область)District (Район)Сельский округХозяйство или местностьВид саранчиФазаЭПВЗаселено ГаДата
"+i+""+locust.lat+""+locust.lon+""+locust.region+" = "+locust.region_id+""+locust.district+" = "+locust.district_id+""+locust.terrain+""+locust.village+""; + + if (file!=null && !file.isEmpty()) { + int i=1; + + String content=""; + try { + content = Tools.readStringFromInputStream(file.getInputStream()); + } catch (IOException e) { + e.printStackTrace(); + } + JSONArray jsonArray= new JSONArray(content); + for (Object o : jsonArray) { + JSONObject jsonObj = (JSONObject) o; + Locust locust = new Locust(); + + locust.date=jsonObj.getString("date"); + + if(!jsonObj.isNull("regionName")) + locust.region=jsonObj.getString("regionName"); + else + locust.region=""; + + if(!jsonObj.isNull("townName")) + locust.district=jsonObj.getString("townName"); + + if(!jsonObj.isNull("point")) { + locust.lon=jsonObj.getJSONObject("point").getJSONArray("coordinates").getDouble(0); + locust.lat=jsonObj.getJSONObject("point").getJSONArray("coordinates").getDouble(1); + } + + //Контур зоны распространения ВО Polygon (geoJSON) + locust.drawPolygon=null; + if(!jsonObj.isNull("drawPolygon")) { + locust.drawPolygon=jsonObj.getJSONObject("drawPolygon").toString(); + } + + //Площадь контура зоны распространения, в случае если специалист указал его + locust.size="null"; + if(!jsonObj.isNull("polygonArea")) + locust.size=String.valueOf(jsonObj.getDouble("polygonArea")); + + //jsonObj.drawPolygon + + + if(locust.region.length()>0) { + //Выбираю ID области + locust.region_id=""; + Statement stt = null; + ResultSet rs = null; + try { + + stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + String sql_query = "select id from main.countriesregions where name like '%"+locust.region+"%';"; + rs = stt.executeQuery(sql_query); + if (rs != null) { + try { + if (rs.next()) { + locust.region_id=rs.getString(1); + } + rs.close(); + } catch (SQLException ex) { + ex.printStackTrace(); + } + } + } catch (SQLException ex) { + ex.printStackTrace(); + }finally { + if(rs!=null) try{rs.close();}catch(SQLException ex){ ex.printStackTrace(); } + if(stt!=null) try{stt.close();}catch(SQLException ex){ ex.printStackTrace(); } + } + + if(locust.region_id.length()>0) { + //Выбираю id региона (main.countriesdistricts) + locust.district_id=""; + stt = null; + rs = null; + try { + + if(locust.district.equals("Алапаевский район")) locust.district="городской округ Алапаевское"; + if(locust.district.equals("Сухоложский район")) locust.district="городской округ Сухой Лог"; + if(locust.district.equals("Талицкий район")) locust.district="Талицкий городской округ"; + if(locust.district.equals("Артинский район")) locust.district="Талицкий городской округ"; + if(locust.district.equals("Богдановичский район")) locust.district="городской округ Богданович"; + if(locust.district.equals("Красноуфимский район")) locust.district="Красноуфимский округ"; + if(locust.district.equals("Белоярский район")) locust.region_id="210"; + if(locust.district.equals("Пышминский район")) locust.district="Пышминский городской округ"; + if(locust.district.equals("Ирбитский район")) locust.district="городской округ Ирбитское"; + if(locust.district.equals("Фрязино г.о.")) locust.district="городской округ Фрязино"; + if(locust.district.equals("Коломенский г.о.")) locust.district="Коломенский район"; + if(locust.district.equals("Протвино г.о.")) locust.district="городской округ Протвино"; + if(locust.district.equals("Зарайск г.о.")) locust.district="Зарайский район"; + if(locust.district.equals("Анапский район")) locust.district="городской округ Анапа"; + if(locust.district.equals("Луховицы г.о.")) locust.district="Луховицкий район"; + if(locust.district.equals("Дергачевский район")) locust.district="Дергачёвский район"; + if(locust.district.equals("Чистоозерный район")) locust.district="Чистоозёрный район"; + if(locust.district.equals("Сунжа город")) locust.district="Сунженский район"; + if(locust.district.equals("Буденновский район")) locust.district="Будённовский район"; + if(locust.district.equals("Новоселовский район")) { locust.district="Новоселицкий район"; locust.region_id="168"; } + if(locust.district.equals("Тимашевский район")) locust.district="Тимашёвский район"; + if(locust.district.equals("Славгородский район")) locust.district="городской округ Славгород"; + if(locust.district.equals("Режевский район")) locust.district="Режевской городской округ"; + if(locust.district.equals("Веселовский район")) locust.district="Весёловский район"; + if(locust.district.equals("Карабулак город")) locust.district="городской округ Карабулак"; + if(locust.district.equals("Пугачевский район")) locust.district="Пугачёвский район"; + if(locust.district.equals("Кущевский район")) locust.district="Кущёвский район"; + if(locust.district.equals("Репьевский район")) locust.district="Репьёвский район"; + if(locust.district.equals("Калачевский район")) locust.district="Калачёвский район"; + if(locust.district.equals("Гайский район")) locust.district="Гайский городской округ"; + if(locust.district.equals("Новохоперский район")) locust.district="Новохопёрский район"; + if(locust.district.equals("Федоровский район")) locust.district="Фёдоровский район"; + if(locust.district.equals("Серебряные Пруды г.о.")) locust.district="городской округ Серебряные Пруды"; + if(locust.district.equals("Минераловодский район")) locust.district="Минераловодский городской округ"; + if(locust.district.equals("Рузский г.о.")) locust.district="Рузский район"; + if(locust.district.equals("Воробьевский район")) locust.district="Воробьёвский район"; + if(locust.district.equals("Ачитский район")) locust.district="Ачитский городской округ"; + if(locust.district.equals("Грачевский район")) locust.district="Грачёвский район"; + if(locust.district.equals("Уссурийский район")) locust.district="Уссурийский городской округ"; + if(locust.district.equals("Сорочинский район")) locust.district="Сорочинский городской округ"; + if(locust.district.equals("Ясненский район")) locust.district="Ясненский городской округ"; + + stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + String sql_query = "select id from main.countriesdistricts where region_id="+locust.region_id+" and name like '%"+locust.district+"%';"; + rs = stt.executeQuery(sql_query); + if (rs != null) { + try { + if (rs.next()) { + locust.district_id=rs.getString(1); + } + rs.close(); + } catch (SQLException ex) { + ex.printStackTrace(); + } + } + } catch (SQLException ex) { + ex.printStackTrace(); + }finally { + if(rs!=null) try{rs.close();}catch(SQLException ex){ ex.printStackTrace(); } + if(stt!=null) try{stt.close();}catch(SQLException ex){ ex.printStackTrace(); } + } + } + } + + String row=""; + + if(!jsonObj.isNull("subjectList")) { + JSONArray jsonArraySub = jsonObj.getJSONArray("subjectList"); + + for (Object o2 : jsonArraySub) { + JSONObject jsonObjSub = (JSONObject) o2; + + locust.eid=jsonObjSub.getInt("id"); + locust.phytoType=jsonObjSub.getString("phytoType"); //"Вредители" или "Обработка" + if(locust.phytoType.equals("Обработка")) + { + locust.insecticide_name = jsonObjSub.getString("nameSubject"); //Наименование действующего вещества + if(!jsonObjSub.isNull("nameLatSubject")) + locust.insecticide_active_substance = jsonObjSub.getString("nameLatSubject"); //Латинское наименование действующего вещества + if(!jsonObjSub.isNull("protectionDoze")) + locust.insecticide_dose = String.valueOf(jsonObjSub.getFloat("protectionDoze")); //Доза внесения препарата (л/га) + + if(!jsonObjSub.isNull("agroTreatmentType")) { + String agroTreatmentType = jsonObjSub.getString("agroTreatmentType"); //Тип обработки (Агротехнический, Авиационный, Наземный) + if(agroTreatmentType!=null && !agroTreatmentType.equals("")) { + if(agroTreatmentType.equals("GROUND")) { + locust.spray_platform = "3"; + }else if(agroTreatmentType.equals("AGROTECHNICAL")) { + locust.spray_platform = "5"; + } else if(agroTreatmentType.equals("AVIATION")) { + locust.spray_platform = "1"; + } + } + if(locust.spray_platform==null || locust.spray_platform.equals("")) { + model.addAttribute("PreviewTable","Error spray_platform"); + return "json"; + } + } + + //То что не знаю куда записывать записываю в description + locust.description=""; + if(!jsonObjSub.isNull("agroTreatmentPercentage")) + locust.description+="Процент обработанной площади: "+String.valueOf(jsonObjSub.getFloat("agroTreatmentPercentage"))+"\n"; + if(!jsonObjSub.isNull("agroTreatmentPow")) + locust.description+="Степень обработки: "+jsonObjSub.getString("agroTreatmentPow")+"\n"; + + //Если записи не существует то вставляем если существует то обновляем + boolean exists=false; //Is there a record. + Statement st; + try { + st = conn.createStatement(); + ResultSet rs=null; + try { + String sql="select 1 from main.frmlocustdel where eid="+String.valueOf(locust.eid); + rs = st.executeQuery(sql); + } catch( SQLException ex ) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error select"); + return "json"; + } + if(rs!=null) + { + if(rs.next()) + exists=true; + } + st.close(); + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error select 2"); + return "json"; + } + + PreparedStatement stmt=null; + String sql=""; + if(exists) + { + sql="update main.frmlocustdel set\n" + +" eid=?,\n" + +" lat_center=?,\n" + +" lon_center=?,\n" + +" country_id=?,\n" + +" region_id=?,\n" + +" area=?,\n" + +" district=?,\n" + +" date=TO_TIMESTAMP(?, 'DD.MM.YYYY HH24:MI'),\n" + +" description=?,\n" + +" geom=ST_SetSRID(ST_GeomFromGeoJSON(?),4326),\n" + + +" insecticide_name=?,\n" + +" insecticide_active_substance=?,\n" + +" insecticide_dose=?,\n" + +" spray_platform=?\n" + +" where eid='"+locust.eid+"'"; + try { + stmt = conn.prepareStatement(sql); + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error prepare 1"); + return "json"; + } + }else + { + sql="insert into main.frmlocustdel(\n" + +" eid,\n" //1 + +" lat_center,\n" //2 + +" lon_center,\n" //3 + +" country_id,\n" //4 + +" region_id,\n" //5 + +" area,\n" //6 + +" district,\n" //7 + +" date,\n" //8 + +" description,\n" //9 + +" geom,\n" //10 + + +" insecticide_name,\n" //11 + +" insecticide_active_substance,\n" //12 + +" insecticide_dose,\n" //13 + +" spray_platform\n" //14 + + +")values(\n" + +" ?,\n" //1 eid + +" ?,\n" //2 lat1 + +" ?,\n" //3 lon1 + +" ?,\n" //4 country_id + +" ?,\n" //5 region_id + +" ?,\n" //6 district (area) + +" ?,\n" //7 district (area) + +" TO_TIMESTAMP(?, 'DD.MM.YYYY HH24:MI'),\n" //8 date + +" ?,\n" //9 description + +" ST_SetSRID(ST_GeomFromGeoJSON(?),4326),\n" //10 geom + + +" ?,\n" //11 insecticide_name + +" ?,\n" //12 insecticide_active_substance + +" ?,\n" //13 insecticide_dose + +" ?\n" //14 spray_platform + +")"; + try { + stmt = conn.prepareStatement(sql); + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error prepare 2"); + return "json"; + } + } + + try { + stmt.setInt(1,locust.eid); + stmt.setDouble(2,locust.lat); + stmt.setDouble(3,locust.lon); + stmt.setInt(4,7); //country_id + stmt.setInt(5,Integer.parseInt(locust.region_id)); //region_id + stmt.setString(6,locust.district); //Пишу в поле "area" + stmt.setString(7,null); + stmt.setString(8,locust.date); //27.04.2020 09:17 + stmt.setString(9,locust.description); + stmt.setString(10,locust.drawPolygon); + + stmt.setString(11,locust.insecticide_name); + stmt.setString(12,locust.insecticide_active_substance); + if(locust.insecticide_dose==null || locust.insecticide_dose.equals("")) + stmt.setNull(13,Types.DOUBLE); + else + stmt.setDouble(13,Double.parseDouble(locust.insecticide_dose)); + + if(locust.spray_platform==null || locust.spray_platform.equals("")) + stmt.setNull(14,Types.INTEGER); + else + stmt.setInt(14,Integer.parseInt(locust.spray_platform)); + + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error set data"); + return "json"; + } + + //Выпоняю запрос на свтавку либо обновление + try { + stmt.execute(); + } catch (SQLException ex) { + ex.printStackTrace(); + model.addAttribute("PreviewTable","Error execute frmlocustdel"); + return "json"; + } + + + }else if(locust.phytoType.equals("Вредители")) + { + if(!jsonObjSub.isNull("nameSubject")) + locust.locust =jsonObjSub.getString("nameSubject"); + + //Вид саранчи + locust.locust_id=""; + if(locust.locust.equals("Среднерусская перелётная саранча")) locust.locust_id="4"; + if(locust.locust.equals("Сибирская кобылка")) locust.locust_id="4"; + if(locust.locust.equals("Азиатская перелётная саранча")) locust.locust_id="3"; + if(locust.locust.equals("Итальянский прус")) locust.locust_id="1"; + if(locust.locust.equals("Мароккская саранча, мароккская кобылка, марокканка")) locust.locust_id="2"; + + + + //фаза саранчи + if(!jsonObjSub.isNull("phaseEvolutionName")) + locust.phase =jsonObjSub.getString("phaseEvolutionName"); + + locust.locust_have="3"; + if(locust.phase!=null) { + if(locust.phase.equals("Кубышка")) locust.locust_have="2"; + if(locust.phase.equals("Гусеница")) locust.locust_have="3"; + if(locust.phase.equals("Личинка 2-го возраста")) locust.locust_have="3"; + if(locust.phase.equals("Личинка 3-го возраста")) locust.locust_have="3"; + if(locust.phase.equals("Личинка 4-го возраста")) locust.locust_have="3"; + if(locust.phase.equals("Личинка 5-го возраста")) locust.locust_have="3"; + if(locust.phase.equals("Имаго")) locust.locust_have="5"; + } + //Если эта анкета "Имаго" то записываем плотность имаго на m2 + if(locust.locust_have.equals("5")) { + if(!jsonObjSub.isNull("subPestCount")) + locust.imago_density=String.valueOf(jsonObjSub.getFloat("subPestCount")); + } + //Если эта анкета "Кулиги" то записываем плотность кулиг на m2 + if(locust.locust_have.equals("2")) { + if(!jsonObjSub.isNull("subPestCount")) + locust.kuliguli_density=String.valueOf(jsonObjSub.getFloat("subPestCount")); + } + //Если эта анкета "Личинок" то записываем плотность личинок на m2 + if(locust.locust_have.equals("3")) { + if(!jsonObjSub.isNull("subPestCount")) + locust.larva_density=String.valueOf(jsonObjSub.getFloat("subPestCount")); + } + + //Если те виды что нам нужны + if(locust.region==null || locust.region.equals("") || locust.lat==0 || locust.lon==0 || locust.locust.equals("Совка ипсилон") || locust.locust.equals("Восточный майский хрущ") || locust.locust.equals("Кукурузный стеблевой мотылек") || locust.locust.equals("Картофельная, или болотная совка, лиловатая яровая совка") || locust.locust.equals("Луговой мотылёк") || locust.locust.equals("Хлопковая совка") || locust.locust.equals("Стеблевой кукурузный мотылек") || locust.locust.equals("Восточная луговая совка") || locust.locust.equals("Коричневая щитовка") || locust.locust.equals("Продолговатая (чайная) подушечница") || locust.locust.equals("Яблоневая запятовидная щитовка") || locust.locust.equals("Виноградная филлоксера") || locust.locust.equals("Бахчевая коровка")) + { + + }else { + + if(locust.locust_id.equals("")) { + System.out.println(locust.locust); + model.addAttribute("PreviewTable","locust.locust_id == 0 locust name = "+locust.locust); + return "json"; + } + if(locust.region_id.equals("")) { + System.out.println(locust.region); + model.addAttribute("PreviewTable","locust.region_id == 0 region name = "+locust.region); + return "json"; + } + + //Тех полей что нет в анкете вствляю в комментарии + try { + locust.description=""; + + if(jsonObjSub.getBoolean("notFound")) + locust.description+="Вредитель не обнаружен: "+jsonObjSub.getString("nameSubject")+"\n"; + else + locust.description+="Вредитель обнаружен: "+jsonObjSub.getString("nameSubject")+"\n"; + if(!jsonObjSub.isNull("phaseEvolutionName")) + locust.description+="Фаза: "+jsonObjSub.getString("phaseEvolutionName")+"\n"; //Так как фаза у росиян более подробная + if(!jsonObjSub.isNull("subPestCount")) { + locust.description+="Вредителей: "+jsonObjSub.getFloat("subPestCount"); + if(!jsonObjSub.isNull("unitName")) + locust.description+=" "+jsonObjSub.getString("unitName"); + locust.description+="\n"; + } + + if(!jsonObj.isNull("cropCurrentType")) + locust.description+="Тип сева: "+jsonObj.getString("cropCurrentType")+"\n"; + if(!jsonObj.isNull("cropCurrentCulture")) + locust.description+="Наименование культуры: "+jsonObj.getString("cropCurrentCulture")+"\n"; + if(!jsonObj.isNull("cropCurrentCultureSort")) + locust.description+="Наименование сорта культуры: "+jsonObj.getString("cropCurrentCultureSort")+"\n"; + if(!jsonObj.isNull("cropCurrentGrowthPhase")) + locust.description+="Фаза роста культуры: "+jsonObj.getString("cropCurrentGrowthPhase")+"\n"; + if(!jsonObj.isNull("cropFieldArea")) { + locust.description+="Площадь поля: "+jsonObj.getFloat("cropFieldArea")+"\n"; + locust.bio_hectare=String.valueOf(jsonObj.getFloat("cropFieldArea")); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + + locust.terrain="null"; //У росиян нет сельского округа + + row="
"+i+""+locust.eid+""+locust.lat+""+locust.lon+""+locust.region+" = "+locust.region_id+""+locust.district+" = "+locust.district_id+""+locust.terrain+""+locust.village+""+locust.locust+" = "+locust.locust_id+""+locust.phase+" = "+locust.locust_have+""+locust.evp+""+locust.size+" = "+locust.drawPolygon+""+locust.date+"
"; + + //json=json.substring(0,json.length()-1); //Удаляю последнюю запятую + //json+="\n]}"; + + model.addAttribute("PreviewTable",table); + //model.addAttribute("PreviewGEOJSON",json); + model.addAttribute("PreviewSQL",sqlData); +*/ + return "json"; + } + //--------------------------------------------------------------------------- + public static BufferedImage toBufferedImage(Image img) + { + if (img instanceof BufferedImage) + { + return (BufferedImage) img; + } + + // Create a buffered image with transparency + BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB); + + // Draw the image on to the buffered image + Graphics2D bGr = bimage.createGraphics(); + bGr.drawImage(img, 0, 0, null); + bGr.dispose(); + + // Return the buffered image + return bimage; + } + //--------------------------------------------------------------------------- + public static String CutBeforeFirst(StringBuffer str,String ch) + { + int pos=str.indexOf(ch); + String result=""; + if(pos==-1) + { + result.concat(str.toString()); + str.delete(0,str.length()); + }else + { + result=str.substring(0,pos); + str.delete(0,pos+1); + } + return result; + } + //--------------------------------------------------------------------------- + class Locust{ + int eid; //Внешний идентификатор + String phytoType; //Вредители либо обработка + + double lon; + double lat; + String region; //Область + String region_id; + + String district; //Район + String district_id; + + String terrain=""; //Название месности + + String village; //Хозяйство или местность + + String locust; //Вид саранчи + String locust_id; //Вид саранчи + + String phase=null; //Фаза саранчи + String locust_have; //id Фазы саранчи + String evp; //ЭФП + String drawPolygon="null"; //Область обследования GeoGSON + String size; //Заселённая площадь (polygonArea Площадь контура зоны распространения, в случае если специалист указал его) + String date; //Дата + + String description=""; + + + String eggs_capsules_density=null; //Плотность яиц + String kuliguli_density=null; //Плотность кулиг на м² + String imago_density=null; //Плотность имаго (/м²)* + String larva_density=null; //Плотность личинок + + String bio_hectare=null; //Обследованная площадь + + //Ниже то что относиться только к обработке + String insecticide_name=null; + String insecticide_active_substance=null; + String insecticide_dose=null; + String spray_platform=null; + + } + +} diff --git a/src/main/java/kz/locust/CCALM/DBMSRecords.java b/src/main/java/kz/locust/CCALM/DBMSRecords.java new file mode 100644 index 0000000..6d994b1 --- /dev/null +++ b/src/main/java/kz/locust/CCALM/DBMSRecords.java @@ -0,0 +1,2382 @@ +package kz.locust.CCALM; //Главная + +import java.io.BufferedOutputStream; +import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.StringReader; +import java.io.Reader; +import java.io.StringWriter; +import java.io.Writer; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +//import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.Random; +import java.util.zip.CRC32; +import java.util.zip.Checksum; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +//import org.apache.commons.fileupload.FileItem; +//import org.apache.commons.fileupload.disk.DiskFileItemFactory; +//import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.io.FileUtils; +import org.json.JSONArray; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.FileSystemResource; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.SessionAttributes; +import org.springframework.web.context.ServletContextAware; +import org.springframework.web.multipart.MultipartFile; +import org.w3c.dom.CharacterData; +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.ls.DOMImplementationLS; +import org.w3c.dom.ls.LSSerializer; +import org.xml.sax.InputSource; + +import tctable.Tools; +import tools.EmailUtility; +import tools.User; + + +@Controller +@SessionAttributes( { "user" }) //Сесионный объект +public class DBMSRecords implements ServletContextAware { + + //private static final Logger logger = LoggerFactory.getLogger(Translation.class); + private static final Logger logger = LoggerFactory.getLogger(DBMSRecords.class); + private ServletContext context; + private Properties m_props=null; + private String m_props_loc=""; + + //If not created object "user", create him. + @ModelAttribute("user") + public User populatePerson() { + return new User("none"); + } + + public String sendError(int code, String message) { + JSONObject json = new JSONObject(); + json.put("errorCode",code); + json.put("errorMessage",message); + return json.toString(); + } + + //Документация по @RequestBody http://javastudy.ru/spring-mvc/json-xml/ + @RequestMapping(value = "/records",method = RequestMethod.POST,produces = "application/xml; charset=utf-8") + @ResponseBody + public Object ajaxTamer(@ModelAttribute User user,@RequestBody byte[] reqData,@RequestParam(required=false,name="lng") String language_id) { + + if(language_id!=null && !language_id.equals("")) + user.language_id=language_id; + logger.info("user.id="+user.id+" user.name="+user.name+" user.language_id="+user.language_id+" user.country_id="+user.country_id); + + boolean error=false; + String result=sendError(1,"Request not processed!"); + //response.setCharacterEncoding("UTF-8"); + + //response.getWriter().append("Served at: ").append(request.getContextPath()); + //Thread.sleep(5000); // sleep 5 seconds + //String metadata_file = ""; + String db_url = ""; + String db_login = ""; + String db_password = ""; + String mail_host = ""; + String mail_port = ""; + String mail_login = ""; + String mail_password = ""; + String data_dir = ""; + //Load DB configuration from "config.xml" + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("db-url")) + db_url = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-login")) + db_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-password")) + db_password = nl.item(i).getTextContent(); + + if (nl.item(i).getNodeName().equals("mail-host")) + mail_host = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("mail-port")) + mail_port = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("mail-login")) + mail_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("mail-password")) + mail_password = nl.item(i).getTextContent(); + + //if (nl.item(i).getNodeName().equals("metadata")) + // metadata_file = nl.item(i).getTextContent(); + + if (nl.item(i).getNodeName().equals("data-dir")) + data_dir = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + + String jspPath = context.getRealPath("/"); + + String fn = "";//request.getParameter("fn"); + String name = "";//request.getParameter("n"); //type name + + InputStream body = new ByteArrayInputStream(reqData); + + //logger.info("Send \"Records\" for user = ."+user.name); + //logger.info("req = "+req); + + Document doc = null; + Element reqNode = null; + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + doc = dBuilder.parse(body); + } catch (Exception ex) { + logger.info(ex.getMessage()); + //return ""; + return sendError(1,"Parsing request error!"); + } + + if (doc != null) { + reqNode = doc.getDocumentElement(); + fn = reqNode.getAttribute("fn"); //Номер функции + } + + //logger.info(""); + //logger.info("XML = "); + //logger.info(toString(doc)); + + Connection conn = null; + try { + Class.forName("org.postgresql.Driver"); + conn = DriverManager.getConnection(db_url, db_login, db_password); + if (conn != null) { + logger.info("Connect is OK!"); + } else { + error=true; + //result=""; + result=sendError(1,"An error occurred while connecting to the database!"); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + error=true; + //result=""; + result=sendError(1,"An error occurred while connecting to the database!"); + } + + try { + Statement stt0 = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + //st.executeUpdate("SET TIME ZONE 'UTC';"); зачем коментил? + stt0.executeUpdate("SET TIME ZONE 'Asia/Almaty';"); + stt0.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + error=true; + //result=""; + result=sendError(1,"An set TYPE_SCROLL_SENSITIVE!"); + } + + //response.getWriter().append("fn="+fn); + //out.print("
"+ request.getRequestURI() ); + + //XPathFactory xPathfactory = XPathFactory.newInstance(); //If error set path in tomcat to xalan.jar + javax.xml.xpath.XPathFactory xPathfactory = javax.xml.xpath.XPathFactory.newInstance(); + XPath xpath = xPathfactory.newXPath(); + XPathExpression expr=null; + + //Description + // (Fn == 0) - Send the metadata to the client at the requested site + // (Fn == 1) - Insert one record in the database + // (Fn == 2) - Update the record + // (Fn == 3) - Delete the record + // (Fn == 4) - Send data to the client according to the filter value + // (Fn == 5) - Take the data for editing 1st record by id + // (Fn == 6) - Return the data to the client to fill SELECT object into a separate function to save bandwidth filters can also be used here + // (Fn == 7) - Login (or sent restore email) + // (Fn == 8) - Reports almost the same as the function 4 + // (Fn == 9) - Save the binary data into the database + + if (fn != null && fn.equals("0")) //Send metadata to client + { + if (doc != null) { + xPathfactory = XPathFactory.newInstance(); + xpath = xPathfactory.newXPath(); + try { + expr = xpath.compile("//metadata/type/@n"); + name = "" + expr.evaluate(doc, XPathConstants.STRING); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + error=true; + } + } + + String xml = ""; + + //Get XML node from database and parse to DOM + doc = parseString(getTypeStrNode(conn,name)); + + if (doc != null) { + doc.getDocumentElement().normalize(); //Del or concat text node + + xml += ""; + + //Delete all child "sql-query" nodes. + XPathExpression exp=null; + NodeList nl=null; + try { + exp = xpath.compile("//sql-query"); + nl = (NodeList) exp.evaluate(doc, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + + for (int j = 0; j < nl.getLength(); j++) { + nl.item(j).getParentNode().removeChild(nl.item(j)); + } + // XML Node Serialisation + DOMImplementationLS domImplementation = (DOMImplementationLS) doc.getImplementation(); + LSSerializer lsSerializer = domImplementation.createLSSerializer(); + lsSerializer.getDomConfig().setParameter("xml-declaration", false); + + //Set attributes to define access level (insert,update,selete,select). + String sql_query = ""; + String allow; + Statement stt=null; + ResultSet rs=null; + + allow = "1"; + try { + stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + sql_query = "select main.p_getAccess(" + user.id + ", 'Select_" + name + "') as acc;"; + rs = stt.executeQuery(sql_query); + if (rs != null) { + try { + if (rs.next()) + if (rs.getBoolean(1)) + allow = "1"; + else + allow = "0"; + rs.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + } + } catch (SQLException ex) { + logger.info(ex.getMessage() + " SQL=" + sql_query); + //result=""; + result=sendError(1,"Error: " + ex.getMessage()); + error=true; + }finally { + if(rs!=null) try{rs.close();}catch(SQLException ex){} + if(stt!=null) try{stt.close();}catch(SQLException ex){} + } + doc.getDocumentElement().setAttribute("sel", allow); + + stt=null; rs=null; + allow = "1"; + try { + stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + rs = stt.executeQuery("select main.p_getAccess(" + user.id + ", 'Insert_" + name + "') as acc;"); + if (rs != null) { + try { + if (rs.next()) + if (rs.getBoolean(1)) + allow = "1"; + else + allow = "0"; + rs.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + } + } catch (SQLException ex) { + logger.info(ex.getMessage()); + //result=""; + result=sendError(1,"Error: " + ex.getMessage()); + error=true; + }finally { + if(rs!=null) try{rs.close();}catch(SQLException ex){} + if(stt!=null) try{stt.close();}catch(SQLException ex){} + } + doc.getDocumentElement().setAttribute("ins", allow); + + stt=null; rs=null; + allow = "1"; + try { + stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + rs = stt.executeQuery("select main.p_getAccess(" + user.id + ", 'Update_" + name + "') as acc;"); + if (rs != null) { + try { + if (rs.next()) + if (rs.getBoolean(1)) + allow = "1"; + else + allow = "0"; + rs.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + } + } catch (SQLException ex) { + logger.info(ex.getMessage()); + //result=""; + result=sendError(1,"Error: " + ex.getMessage()); + error=true; + }finally { + if(rs!=null) try{rs.close();}catch(SQLException ex){} + if(stt!=null) try{stt.close();}catch(SQLException ex){} + } + doc.getDocumentElement().setAttribute("upd", allow); + + stt=null; rs=null; + allow = "1"; + try { + stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + rs = stt.executeQuery("select main.p_getAccess(" + user.id + ", 'Delete_" + name + "') as acc;"); + if (rs != null) { + try { + if (rs.next()) + if (rs.getBoolean(1)) + allow = "1"; + else + allow = "0"; + rs.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + } + } catch (SQLException ex) { + logger.info(ex.getMessage()); + //result=""; + result=sendError(1,"Error: " + ex.getMessage()); + error=true; + }finally { + if(rs!=null) try{rs.close();}catch(SQLException ex){} + if(stt!=null) try{stt.close();}catch(SQLException ex){} + } + doc.getDocumentElement().setAttribute("del", allow); + + xml += lsSerializer.writeToString(doc.getDocumentElement()); + xml += ""; + } else { + xml += ""; + } + + result=getText(conn,xml,user); + + } else if (fn != null && fn.equals("1")) { + String typename = ""; + String obj_id = ""; + NodeList node_properties = null; + + Node nTypeR = null; + if (doc != null) { + Object exprResult=null; + try { + expr = xpath.compile("//metadata/type"); + exprResult = expr.evaluate(reqNode, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + NodeList nodeList = (NodeList) exprResult; + if (nodeList.getLength() > 0) { + nTypeR = nodeList.item(0); + + typename = "" + nTypeR.getAttributes().getNamedItem("n").getNodeValue(); + //obj_id = "" + nTypeR.getAttributes().getNamedItem("id").getNodeValue(); //The current page number + try { + expr = xpath.compile("properties/prop"); + node_properties = (NodeList) expr.evaluate(nTypeR, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + } + } + + //Get XML node "type" from database and parse to DOM + doc = parseString(getTypeStrNode(conn,typename)); + + if (doc != null) { + //doc.getDocumentElement().normalize(); //Del or concat text node + Node nTypeS = doc.getDocumentElement(); + + String sql_query=""; + try { + expr = xpath.compile("properties/sql-query[@t='i']/text()"); + sql_query = (String) expr.evaluate(nTypeS, XPathConstants.STRING); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + + logger.info("sql_query11 = " + sql_query); + + for (int i = 0; i < node_properties.getLength(); i++) { + String vn = node_properties.item(i).getAttributes().getNamedItem("n").getNodeValue(); + String val = node_properties.item(i).getTextContent(); + + //Since the node type does not appear in the query, we select it separately + String vt = ""; + NodeList nodeList=null; + try { + expr = xpath.compile("properties/prop[@n='" + vn + "']"); + nodeList = (NodeList) expr.evaluate(nTypeS, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + if (nodeList!=null && nodeList.getLength() > 0) { + vt = nodeList.item(0).getAttributes().getNamedItem("vt").getNodeValue(); + //If this "file" is then copy it from the temporary folder to the specified path + if(vt.equals("file")) + { + String srcPath = data_dir;//context.getInitParameter("file-upload"); + String destPath = nodeList.item(0).getAttributes().getNamedItem("path").getNodeValue(); + File srcFile = new File(srcPath+val); //Upload folder + if(srcFile.isFile()) + { + File destFile = new File(destPath+val); //Foldef from metadata.xml + try { + FileUtils.copyFile(srcFile, destFile); + FileUtils.forceDelete(srcFile); + } catch (IOException ex) { + logger.info(ex.getMessage()); + } + } + } + } + + sql_query = Tools.replaceAll(sql_query,"${" + vn + "}", getSQLValue(vt, val)); + + } + sql_query = Tools.replaceAll(sql_query,"${_user_id}", (String) user.id); //Set current user id in sql query. + + logger.info("sql_query22 = " + sql_query); + + try { + Statement stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + ResultSet rs = stt.executeQuery(sql_query); + if (rs != null) { + try { + if (rs.next()) + obj_id = rs.getString(1); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + String xmlstring = ""; + + result=xmlstring; + logger.info("xmlstring = " + xmlstring); + } + stt.close(); + rs.close(); + stt=null; + rs=null; + } catch (SQLException ex) { + logger.info(ex.getMessage()); + //result=""; + result=sendError(1,"Error: " + ex.getMessage()+"\n\nSQL query: " + sql_query); + error=true; + } + } + + } else if (fn != null && fn.equals("2")) //Update record by ID from XML data + { + String typename = ""; + String obj_id = ""; + NodeList node_properties = null; + + Node nTypeR = null; + if (doc != null) { + Object exprResult=null; + try { + expr = xpath.compile("//metadata/type"); + exprResult = expr.evaluate(reqNode, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + NodeList nodeList = (NodeList) exprResult; + if (nodeList.getLength() > 0) { + nTypeR = nodeList.item(0); + + typename = "" + nTypeR.getAttributes().getNamedItem("n").getNodeValue(); + obj_id = "" + nTypeR.getAttributes().getNamedItem("id").getNodeValue(); //The current page number + try { + expr = xpath.compile("properties/prop"); + node_properties = (NodeList) expr.evaluate(nTypeR, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + } + } + + //Get XML node "type" from database and parse to DOM + doc = parseString(getTypeStrNode(conn,typename)); + + if (doc != null) { + //doc.getDocumentElement().normalize(); //Del or concat text node + Node nTypeS = doc.getDocumentElement(); + + String sql_query=""; + try { + expr = xpath.compile("properties/sql-query[@t='u']/text()"); + sql_query = (String) expr.evaluate(nTypeS, XPathConstants.STRING); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + + logger.info("sql_query = " + sql_query); + for (int i = 0; i < node_properties.getLength(); i++) { + String vn = node_properties.item(i).getAttributes().getNamedItem("n").getNodeValue(); + String val = node_properties.item(i).getTextContent(); + + //Так как тип узла не передётся в запросе выбираем его отдельно + String vt = ""; + NodeList nodeList = null; + try { + expr = xpath.compile("properties/prop[@n='" + vn + "']"); + nodeList = (NodeList) expr.evaluate(nTypeS, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + if (nodeList!=null && nodeList.getLength() > 0) { + vt = nodeList.item(0).getAttributes().getNamedItem("vt").getNodeValue(); + //If this "file" is then copy it from the temporary folder to the specified path + if(vt.equals("file")) + { + String srcPath = data_dir;//context.getInitParameter("file-upload"); + String destPath = nodeList.item(0).getAttributes().getNamedItem("path").getNodeValue(); + File srcFile = new File(srcPath+val); //Upload folder + if(srcFile.isFile()) + { + File destFile = new File(destPath+val); //Foldef from metadata.xml + try { + FileUtils.copyFile(srcFile, destFile); + FileUtils.forceDelete(srcFile); + } catch (IOException ex) { + logger.info(ex.getMessage()); + } + + } + } + } + sql_query=Tools.replaceAll(sql_query,"${" + vn + "}", getSQLValue(vt, val)); + } + sql_query = Tools.replaceAll(sql_query,"${_user_id}", (String) user.id); //Set current user id in sql query. + + logger.info("sql_query = " + sql_query); + + try { + Statement stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + ResultSet rs = stt.executeQuery(sql_query); + if (rs != null) { + try { + if (rs.next()) + obj_id = rs.getString(1); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + + String xmlstring = ""; + + result=xmlstring; + logger.info("xmlstring = " + xmlstring); + } + rs.close(); + stt.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + //result=""; + result=sendError(1,"Error: " + ex.getMessage()+"\n\nSQL query: " + sql_query); + error=true; + } + } + + } else if (fn != null && fn.equals("3")) { + String typename = ""; + String obj_id = ""; + //NodeList node_properties=null; + + Node nTypeR = null; + if (doc != null) { + Object exprResult=null; + try { + expr = xpath.compile("//metadata/type"); + exprResult = expr.evaluate(reqNode, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + NodeList nodeList = (NodeList) exprResult; + if (nodeList.getLength() > 0) { + nTypeR = nodeList.item(0); + + typename = "" + nTypeR.getAttributes().getNamedItem("n").getNodeValue(); + obj_id = "" + nTypeR.getAttributes().getNamedItem("id").getNodeValue(); //The current page number + + //expr = xpath.compile("properties/prop"); + //node_properties = (NodeList)expr.evaluate(nTypeR, XPathConstants.NODESET); + } + } + + //Get XML node "type" from database and parse to DOM + doc = parseString(getTypeStrNode(conn,typename)); + + if (doc != null) { + //doc.getDocumentElement().normalize(); //Del or concat text node + Node nTypeS = doc.getDocumentElement(); + + String sql_query=""; + try { + expr = xpath.compile("properties/sql-query[@t='d']/text()"); + sql_query = (String) expr.evaluate(nTypeS, XPathConstants.STRING); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + + logger.info("sql_query = " + sql_query); + /*for(int i=0;i0) + { + vt=nodeList.item(0).getAttributes().getNamedItem("vt").getNodeValue(); + } + + sql_query=Tools.replaceAll(sql_query,"${"+vn+"}",getSQLValue(vt,val)); + } */ + + sql_query = Tools.replaceAll(sql_query,"${id}", getSQLValue("string", obj_id)); //string а не i4 так как некоторые таблицы с uuid + sql_query = Tools.replaceAll(sql_query,"${_user_id}", (String) user.id); //Set current user id in sql query. + + //logger.info("sql_query = " + sql_query); + + try { + Statement stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + ResultSet rs = stt.executeQuery(sql_query); + if (rs != null) { + try { + if (rs.next()) + obj_id = rs.getString(1); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + String xmlstring = ""; + + result=xmlstring; + //logger.info("xmlstring = " + xmlstring); + } + rs.close(); + stt.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + //result=""; + result=sendError(1,"Error: " + ex.getMessage()+"\n\nSQL query: " + sql_query); + error=true; + } + + } + + } else if (fn != null && (fn.equals("4") || fn.equals("11"))) { + int rowspagecount = 100; //Records per page + String typename = ""; + String pagepos = ""; + + Node nTypeR = null; + if (doc != null) { + Object exprResult=null; + try { + expr = xpath.compile("//metadata/type"); + exprResult = expr.evaluate(reqNode, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + NodeList nodeList = (NodeList) exprResult; + if (nodeList.getLength() > 0) { + nTypeR = nodeList.item(0); + typename = "" + nTypeR.getAttributes().getNamedItem("n").getNodeValue(); + pagepos = "" + nTypeR.getAttributes().getNamedItem("pp").getNodeValue(); //The current page number + } + } + + //Get XML node "type" from database and parse to DOM + doc = parseString(getTypeStrNode(conn,typename)); + + //Find XML node "type" by name + if (doc != null) { + //doc.getDocumentElement().normalize(); //Del or concat text node + Node nTypeS = doc.getDocumentElement(); + + if (nTypeS != null) { + Node f1 = null, f2 = null; + //В переданном запросе может быть не полный фильтр заполняем серверный значениями из переданного + NodeList nodeList = null; + try { + nodeList = (NodeList) xpath.compile("objects-list/filter").evaluate(nTypeS, XPathConstants.NODESET); + if (nodeList.getLength() > 0) + f1 = nodeList.item(0); + nodeList = (NodeList) xpath.compile("objects-list/filter").evaluate(nTypeR, XPathConstants.NODESET); + if (nodeList.getLength() > 0) + f2 = nodeList.item(0); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + + //logger.info("f1=\n" + nodeToString(f1)); + //logger.info("f1=\n" + nodeToString(f2)); + + setFilter(f1, f2);//заменить все значения первого фильтра значениями из второго + + //logger.info("f1=\n" + nodeToString(f1)); + //logger.info("f1=\n" + nodeToString(f2)); + + String sql_query=""; + try { + sql_query = (String) xpath.compile("objects-list/sql-query/text()").evaluate(nTypeS, XPathConstants.STRING); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + + //logger.info("sql_query = " + sql_query); + + Node nextnode = f1.getFirstChild(); + while (nextnode != null) { + if (nextnode.getNodeName().equals("column")) { + try { + String vn = nextnode.getAttributes().getNamedItem("n").getNodeValue(); + /*String size; + Node n = nextnode.getAttributes().getNamedItem("size"); + if (n != null) { + size = n.getNodeValue(); + }*/ + String vt = nextnode.getAttributes().getNamedItem("vt").getNodeValue(); + String val = getCharacterDataFromElement((Element) nextnode); + + val = getSQLValue(vt, val); + + sql_query = Tools.replaceAll(sql_query,"${" + vn + "}", val); + } catch (Exception ex) { + logger.info(ex.getMessage()); + logger.info("exception = " + ex.getMessage()); + } + } + nextnode = nextnode.getNextSibling(); + } + sql_query = Tools.replaceAll(sql_query,"${_user_id}", (String) user.id); //Set current user id in sql query. + + //logger.info("sql_query = " + sql_query); + + try { + Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + ResultSet rs = stmt.executeQuery(sql_query); + int pagecount = 0; + try { + if (rs.last()) { + pagecount = rs.getRow(); + rs.beforeFirst(); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + //result=""; + result=sendError(1,"Error: " + ex.getMessage()+"\n\nSQL query: " + sql_query); + error=true; + } + pagecount = (int) Math.ceil((double) pagecount / (double) rowspagecount); + + //В месте с фильтром может прити и название полей которые нужно выбрать если есть хоть 1 поле то выберать только его + List columns = new ArrayList(); + + try { + nodeList = (NodeList) xpath.compile("objects-list/column").evaluate(nTypeR, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + if(nodeList!=null) + { + for (int i = 0; i < nodeList.getLength(); i++) { + columns.add(nodeList.item(i).getAttributes().getNamedItem("n").getNodeValue()); + } + } + + if (columns.size() == 0) //Если нет ни одного столбца заполняем массив из серверного XML + { + try { + nodeList = (NodeList) xpath.compile("objects-list/column").evaluate(nTypeS, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + for (int i = 0; i < nodeList.getLength(); i++) { + columns.add(nodeList.item(i).getAttributes().getNamedItem("n").getNodeValue()); + } + } + + //перебираем RS и строим XML только из тех столбцов которые записанны в секци objects-list поля column в не зависимости от их видимости + /*String xmlstring = ""; + xmlstring += "\n"; + + int pos = -1; + + // iterate through the java resultset + try { + while (rs.next()) { + pos++; + if ((Integer.parseInt(pagepos) != -1) && ((pos < (Integer.parseInt(pagepos) * rowspagecount)) || (pos >= Integer.parseInt(pagepos) * rowspagecount + rowspagecount))) + continue; + + String access = ""; //u = enable update field, d = enable delete field + try { + if (rs.getBoolean("_u") == true) + access += "u"; + } catch (java.sql.SQLException e) { + access += "u"; + } + try { + if (rs.getBoolean("_d") == true) + access += "d"; + } catch (java.sql.SQLException e) { + access += "d"; + } + + String id = ""; + try { + id = rs.getString(nTypeS.getAttributes().getNamedItem("ObjectID").getNodeValue()); + } catch (SQLException e) { + } + + xmlstring += " "; + for (int i = 0; i < columns.size(); i++) { + try { + String val = rs.getString(columns.get(i)); + if (val == null) + val = ""; + xmlstring += ""; + } catch (SQLException e) { + } + } + xmlstring += "\n"; + } + } catch (NumberFormatException | DOMException | SQLException ex) { + logger.info(ex.getMessage()); + } + + xmlstring += "\n"; + result=xmlstring;*/ + JSONObject json = new JSONObject(); + json.put("errorCode",0); + json.put("errorMessage",""); + json.put("fn",fn); + json.put("n",typename); + json.put("pc",pagecount); + json.put("pp",pagepos); + JSONArray datas = new JSONArray(); + json.put("data",datas); + + int pos = -1; + + // iterate through the java resultset + try { + while (rs.next()) { + pos++; + if ((Integer.parseInt(pagepos) != -1) && ((pos < (Integer.parseInt(pagepos) * rowspagecount)) || (pos >= Integer.parseInt(pagepos) * rowspagecount + rowspagecount))) + continue; + + JSONObject data = new JSONObject(); + datas.put(data); + + + String access = ""; //u = enable update field, d = enable delete field + try { + if (rs.getBoolean("_u") == true) + access += "u"; + } catch (java.sql.SQLException e) { + access += "u"; + } + try { + if (rs.getBoolean("_d") == true) + access += "d"; + } catch (java.sql.SQLException e) { + access += "d"; + } + + String id = ""; + try { + id = rs.getString(nTypeS.getAttributes().getNamedItem("ObjectID").getNodeValue()); + } catch (SQLException e) { + } + + data.put("id", id); + data.put("a", access); + + JSONArray row = new JSONArray(); + data.put("row",row); + for (int i = 0; i < columns.size(); i++) { + try { + String val = rs.getString(columns.get(i)); + row.put(val); + } catch (SQLException e) { + } + } + } + } catch (NumberFormatException | DOMException | SQLException ex) { + logger.info(ex.getMessage()); + } + + result=json.toString(); + //logger.info("json = " + json); + + rs.close(); + stmt.close(); + rs=null; + stmt=null; + + } catch (SQLException ex) { + logger.info(ex.getMessage()); + ex.printStackTrace(); + //result=""; + result=sendError(1,"Error: " + ex.getMessage()+"\n\nSQL query: " + sql_query); + error=true; + } + } + } + } else if (fn != null && fn.equals("5")) { + String sql_query = ""; + String typename = ""; + String idname = ""; + + Node nTypeR = null; + if (doc != null) { + Object exprResult=null; + try { + expr = xpath.compile("//metadata/type"); + exprResult = expr.evaluate(reqNode, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + NodeList nodeList = (NodeList) exprResult; + if (nodeList.getLength() > 0) { + nTypeR = nodeList.item(0); + typename = "" + nTypeR.getAttributes().getNamedItem("n").getNodeValue(); + idname = "" + nTypeR.getAttributes().getNamedItem("id").getNodeValue(); + } + } + + //Get XML node "type" from database and parse to DOM + doc = parseString(getTypeStrNode(conn,typename)); + + if (doc != null) { + //doc.getDocumentElement().normalize(); //Del or concat text node + Node nTypeS = doc.getDocumentElement(); + + if (nTypeS != null) { + //Select SQL query to editing record + sql_query=""; + try { + sql_query = (String) xpath.compile("properties/sql-query[@t='s']/text()").evaluate(nTypeS, XPathConstants.STRING); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + + sql_query = Tools.replaceAll(sql_query,"${id}", getSQLValue("string", idname)); //Set current record id into sql query. + sql_query = Tools.replaceAll(sql_query,"${_user_id}", (String) user.id); //Set current user id into sql query. + + //logger.info("sql_query = " + sql_query); + + //st = conn.createStatement(); + + + try { + Statement stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + ResultSet rs = stt.executeQuery(sql_query); + if (rs != null) { + //Выбираем данные и строим XML для отправки клиенту + String xmlstring = ""; + xmlstring += "\n"; + NodeList nodeList=null; + try { + nodeList = (NodeList) xpath.compile("properties/prop").evaluate(nTypeS, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + // iterate through the java resultset + if(nodeList!=null) + { + try { + while (rs.next()) { + for (int i = 0; i < nodeList.getLength(); i++) { + String fName = nodeList.item(i).getAttributes().getNamedItem("n").getNodeValue(); + String val = rs.getString(fName); + if (val == null) + val = ""; + xmlstring += ""; + } + } + } catch (DOMException | SQLException ex) { + logger.info(ex.getMessage()); + } + } + xmlstring += "\n"; + + result=xmlstring; + //logger.info("xmlstring = " + xmlstring); + } + rs.close(); + stt.close(); + rs=null; + stt=null; + } catch (SQLException ex) { + logger.info(ex.getMessage()); + //result=""; + result=sendError(1,"Error: " + ex.getMessage()+"\n\nSQL query: " + sql_query); + error=true; + } + } + } + } else if (fn != null && fn.equals("6")) //TODO concat width 4 and 11 function + { + //String sql_query=""; + String typename = ""; + String[] columns = null; + String propName = ""; + + Node nTypeR = null; + if (doc != null) { + Object exprResult=null; + try { + expr = xpath.compile("//metadata/type"); + exprResult = expr.evaluate(reqNode, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + NodeList nodeList = (NodeList) exprResult; + if (nodeList.getLength() > 0) { + nTypeR = nodeList.item(0); + typename = "" + nTypeR.getAttributes().getNamedItem("n").getNodeValue(); + String columnname; + columnname = "" + nTypeR.getAttributes().getNamedItem("c").getNodeValue(); + + //logger.info("columnname = " + columnname); + columns = columnname.split(","); + + propName = "" + nTypeR.getAttributes().getNamedItem("pn").getNodeValue(); //Название поля нигде не используется передаётся обратно в результат + } + } + + //Get XML node "type" from database and parse to DOM + doc = parseString(getTypeStrNode(conn,typename)); + + //Находим серверный XML узел по имени + if (doc != null) { + //doc.getDocumentElement().normalize(); //Del or concat text node + Node nTypeS = doc.getDocumentElement(); + + if (nTypeS != null) { + Node f1 = null, f2 = null; + //В переданном запросе может быть не полный фильтр заполняем серверный значениями из переданного + //NodeList nodeList; + try { + NodeList nodeList = (NodeList) xpath.compile("objects-list/filter").evaluate(nTypeS, XPathConstants.NODESET); + if (nodeList.getLength() > 0) + f1 = nodeList.item(0); + nodeList = (NodeList) xpath.compile("objects-list/filter").evaluate(nTypeR, XPathConstants.NODESET); + if (nodeList.getLength() > 0) + f2 = nodeList.item(0); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + + //logger.info("Server f1=\n" + nodeToString(f1)); + //logger.info("Request f2=\n" + nodeToString(f2)); + + setFilter(f1, f2);//заменить все значения первого фильтра значениями из второго + + //logger.info("Server f1=\n" + nodeToString(f1)); + //logger.info("Request f2=\n" + nodeToString(f2)); + + String sql_query=""; + try { + sql_query = (String) xpath.compile("objects-list/sql-query/text()").evaluate(nTypeS, XPathConstants.STRING); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + + //logger.info("sql_query = " + sql_query); + + Node nextnode = f1.getFirstChild(); + while (nextnode != null) { + if (nextnode.getNodeName().equals("column")) { + try { + String vn = nextnode.getAttributes().getNamedItem("n").getNodeValue(); + /*String size; + Node n = nextnode.getAttributes().getNamedItem("size"); + if (n != null) { + size = n.getNodeValue(); + }*/ + String vt = nextnode.getAttributes().getNamedItem("vt").getNodeValue(); + String val = getCharacterDataFromElement((Element) nextnode); + + val = getSQLValue(vt, val); + + sql_query = Tools.replaceAll(sql_query,"${" + vn + "}", val); + } catch (Exception ex) { + logger.info(ex.getMessage()); + //error=true; //throw new Exception(ex); + } + } + nextnode = nextnode.getNextSibling(); + } + + sql_query = Tools.replaceAll(sql_query,"${_user_id}", (String) user.id); //Set current user id in sql query. + + //logger.info("sql_query = " + sql_query); + + try { + Statement stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + ResultSet rs = stt.executeQuery(sql_query); + if (rs != null) { + //перебираем RS и строим XML только из тех столбцов которые записанны в секци objects-list поля column в не зависимости от их видимости + String xmlstring = ""; + xmlstring += "\n"; + + // iterate through the java resultset + try { + while (rs.next()) { + xmlstring += " "; + for (int i = 0; i < columns.length; i++) { + xmlstring += ""; + } + xmlstring += "\n"; + } + } catch (DOMException | SQLException ex) { + logger.info(ex.getMessage()); + } + xmlstring += "\n"; + + result=xmlstring; + //logger.info("xmlstring = " + xmlstring); + } + rs.close(); + stt.close(); + rs=null; + stt=null; + } catch (SQLException ex) { + logger.info(ex.getMessage()); + //result=""; + result=sendError(1,"Error: " + ex.getMessage()+"\n\nSQL query: " + sql_query); + error=true; + } + + + + } else { + //result=""; + result=sendError(1,"Could not find the requested node!"); + error=true; + } + } + + } else if (fn != null && fn.equals("7")) //Login function + { + String user_id = ""; + String cmd=""; + String login = ""; + String password = ""; + String hash = ""; + //String captcha = ""; + //For registration new user + String country_id = ""; + String lastname = ""; + String firstname = ""; + String company = ""; + String position = ""; + String phone = ""; + String email = ""; + + try { + cmd = (String) xpath.compile("//metadata/cmd/text()").evaluate(reqNode, XPathConstants.STRING); + login = (String) xpath.compile("//metadata/login/text()").evaluate(reqNode, XPathConstants.STRING); + password = (String) xpath.compile("//metadata/password/text()").evaluate(reqNode, XPathConstants.STRING); + hash = (String) xpath.compile("//metadata/hash/text()").evaluate(reqNode, XPathConstants.STRING); //Сессия для авто логина если не пустая то сначала пытаемся авторизоваться по ней + //captcha = (String) xpath.compile("//metadata/captcha/text()").evaluate(reqNode, XPathConstants.STRING); + //For registration new user + country_id = (String) xpath.compile("//metadata/country_id/text()").evaluate(reqNode, XPathConstants.STRING); + lastname = (String) xpath.compile("//metadata/lastname/text()").evaluate(reqNode, XPathConstants.STRING); + firstname = (String) xpath.compile("//metadata/firstname/text()").evaluate(reqNode, XPathConstants.STRING); + company = (String) xpath.compile("//metadata/company/text()").evaluate(reqNode, XPathConstants.STRING); + position = (String) xpath.compile("//metadata/position/text()").evaluate(reqNode, XPathConstants.STRING); + phone = (String) xpath.compile("//metadata/phone/text()").evaluate(reqNode, XPathConstants.STRING); + email = (String) xpath.compile("//metadata/email/text()").evaluate(reqNode, XPathConstants.STRING); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + + String xmlstring = ""; + if (cmd.equals("0")) //Restore password by email + { + boolean find = false; + + try { + Statement stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + String sql = "select id from main._users where del=false and lower(email)=lower('" + login + "');"; + ResultSet rs = stt.executeQuery(sql); + if (rs != null) { + try { + if (rs.next()) + find = true; + rs.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + } + rs.close(); + stt.close(); + rs=null; + stt=null; + } catch (SQLException ex) { + logger.info(ex.getMessage()); + //xmlstring = ""; + xmlstring=sendError(1,"Error: " + ex.getMessage()); + error=true; + } + + + if (find) { + String newPass = getRandomString(6); + + boolean mEerror = false; + + String recipient = login; + String subject = "New password for CCALM from http://www.ccalm.org"; + String content = "Login is: "+ email.toLowerCase()+"\n
New password: " + newPass+""; + content += "

Sincerely, the administration of ccalm.org."; + + String answer = ""; + try { + EmailUtility.sendEmail(mail_host, mail_port, mail_login, mail_password, recipient, subject, content); + answer = "New password was sent successfully on \"" + recipient + "\".\nIf there is no email then check the spam folder."; + } catch (Exception ex) { + logger.info(ex.getMessage()); + answer = "There were an error: " + ex.getMessage(); + //error=true; + } finally { + //request.setAttribute("Message", resultMessage); + //context.getRequestDispatcher("/Result.jsp").forward(request, response); + } + + if (!mEerror) { + try { + Statement stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + stt.execute("update main._users set password=md5('" + newPass + "') where email=lower('" + login + "');"); + stt.close(); + stt=null; + } catch (SQLException ex) { + logger.info(ex.getMessage()); + //xmlstring = ""; + xmlstring=sendError(1,"Error: " + ex.getMessage()); + } + } + + xmlstring = ""; + } else { + //xmlstring = ""; + xmlstring=sendError(1,"This email address was not registered!"); + } + + } else if (cmd.equals("1")) //Logout + { + String sql_query="select main.p__logout("+user.id+");"; + + //Отмечаем в базе что пользователь вышел (для электронной очереди если пользователь обрабатывается) + try { + Statement stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + ResultSet rs = stt.executeQuery(sql_query); + rs.close(); + stt.close(); + rs=null; + stt=null; + } catch (SQLException ex) { + logger.info(ex.getMessage()); + //xmlstring = ""; + xmlstring=sendError(1,"Error: " + ex.getMessage() + "\n\nSQL query: " + sql_query); + error=true; + } + + if(!error) + { + user.Logout(); //Обнуляем значения + xmlstring = ""; + } + + } else if (cmd.equals("2")) //Check if user not logged. + { + if (user.id != null && !user.id.equals("null")) { + xmlstring = ""; + } else { + xmlstring = ""; + } + + } else if (cmd.equals("3")) //Login user (Login function from metadata.xml) + { + if (login.equals("") && password.equals("")) { + user_id = (String) user.id; + if (user_id == null) + user_id = "null"; + } + + String typename = "_Login"; + //Get XML node "type" from database and parse to DOM + doc = parseString(getTypeStrNode(conn,typename)); + + //Находим серверный XML узел по имени + if (doc != null) { + //doc.getDocumentElement().normalize(); //Del or concat text node + Node nTypeS = doc.getDocumentElement(); + + if (nTypeS != null) { + String sql_query=""; + try { + sql_query = (String) xpath.compile("objects-list/sql-query/text()").evaluate(nTypeS, XPathConstants.STRING); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + + String val; + val = getSQLValue("i4", user_id); + sql_query = Tools.replaceAll(sql_query,"${user_id}", val); + val = getSQLValue("string", login); + sql_query = Tools.replaceAll(sql_query,"${login}", val); + val = getSQLValue("string", password); + sql_query = Tools.replaceAll(sql_query,"${password}", val); + val = getSQLValue("string", hash); + sql_query = Tools.replaceAll(sql_query,"${hash}", val); + val = getSQLValue("string", ""/*request.getSession().getId()*/); + sql_query = Tools.replaceAll(sql_query,"${sessionid}", val); + val = getSQLValue("string", ""/*request.getRemoteAddr()*/); + sql_query = Tools.replaceAll(sql_query,"${ip}", val); + + //logger.info("sql_query = " + sql_query); + + try { + Statement stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + ResultSet rs = stt.executeQuery(sql_query); + + if (rs != null) { + if (rs.next()) { + user_id = rs.getString("id"); + if(user_id==null) user_id="null"; + user.id=user_id; + String uName = rs.getString("name"); + user.name=uName; + String role = rs.getString("role"); + user.role=role; + user.language_id=rs.getString("language_id"); + String date = rs.getString("date"); //Дата с sql сервера + String expiration = rs.getString("expiration"); //Дата до которой действует пароль + String renewal = rs.getString("renewal"); //На сколько дней продлевать действие пароля + + xmlstring = ""; + }else + { + //xmlstring = ""; + xmlstring=sendError(1,trt(conn,"Error_in_login_or_password",user)); + } + } + rs.close(); + stt.close(); + rs=null; + stt=null; + } catch (SQLException ex) { + logger.info(ex.getMessage()); + //xmlstring = ""; + xmlstring=sendError(1,"Error: " + ex.getMessage() + "\n\nSQL query: " + sql_query); + error=true; + } + + } + } + } else if (cmd.equals("4")) //Create new user + { + xmlstring = ""; //if error + String sql_query = ""; + String val; + + //Check exists user by email email + sql_query = "select id from main._users where email=LOWER(TRIM(${email}))"; + val = getSQLValue("string", email); + sql_query = Tools.replaceAll(sql_query,"${email}", val); + try { + Statement stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + ResultSet rs = stt.executeQuery(sql_query); + if (rs != null) { + try { + if (rs.next()) { + //xmlstring = ""; + xmlstring=sendError(1,trt(conn,"E_mail_already_exists_in_the_database",user)); + error=true; + } + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + } + rs.close(); + stt.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + //xmlstring = ""; + xmlstring=sendError(1,"Error: " + ex.getMessage()); + error=true; + } + + if(!error) { + String newPass = getRandomString(8); + sql_query = "select * from main.p__Users_1(4,${country_id},${surname},${name},${company},${position},${phone},${email},${password});"; + + val = getSQLValue("i4", country_id); + sql_query = Tools.replaceAll(sql_query,"${country_id}", val); + val = getSQLValue("string", lastname); + sql_query = Tools.replaceAll(sql_query,"${surname}", val); + val = getSQLValue("string", firstname); + sql_query = Tools.replaceAll(sql_query,"${name}", val); + val = getSQLValue("string", company); + sql_query = Tools.replaceAll(sql_query,"${company}", val); + val = getSQLValue("string", position); + sql_query = Tools.replaceAll(sql_query,"${position}", val); + val = getSQLValue("string", phone); + sql_query = Tools.replaceAll(sql_query,"${phone}", val); + val = getSQLValue("string", email); + sql_query = Tools.replaceAll(sql_query,"${email}", val); + val = getSQLValue("string", newPass); + sql_query = Tools.replaceAll(sql_query,"${password}", val); + + //logger.info("sql_query = " + sql_query); + + + try { + Statement stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + ResultSet rs = stt.executeQuery(sql_query); + if (rs != null) { + try { + if (rs.next()) { + xmlstring = ""; + + //Отправляем пароль на Email + String recipient = email; + String subject = "Password for new user on http://www.ccalm.org"; + String content = "Login is: "+ email.toLowerCase()+"\n
Password: " + newPass+""; + content += "

Sincerely, the administration of ccalm.org."; + + //String answer = ""; + try { + EmailUtility.sendEmail(mail_host, mail_port, mail_login, mail_password, recipient, subject, content); + //answer = "New password was sent successfully on \"" + recipient + "\".\nIf there is no email then check the spam folder."; + } catch (Exception ex) { + logger.info(ex.getMessage()); + //answer = "There were an error: " + ex.getMessage(); + } finally { + //request.setAttribute("Message", resultMessage); + //context.getRequestDispatcher("/Result.jsp").forward(request, response); + } + + } + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + } + rs.close(); + stt.close(); + rs=null; + stt=null; + } catch (SQLException ex) { + logger.info(ex.getMessage()); + //xmlstring = ""; + xmlstring=sendError(1,"Error: " + ex.getMessage()); + error=true; + } + } + } + + result=xmlstring; + //logger.info("xmlstring = " + xmlstring); + + } else if (fn != null && fn.equals("8")) { + //Select information about the current user + String uName = "
"; + + try { + Statement stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + ResultSet rs = stt.executeQuery("select Coalesce(surname,'') || ' ' || Coalesce(name,'') || ' ' || Coalesce(patronymic,'') as name from main._users where id=" + user.id + ""); + if (rs != null) { + try { + while (rs.next()) { + uName = "" + rs.getString("name") + "
"; + } + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + } + rs.close(); + stt.close(); + rs=null; + stt=null; + } catch (SQLException ex) { + logger.info(ex.getMessage()); + //result=""; + result=sendError(1,"Error: " + ex.getMessage()); + error=true; + } + + String typename = ""; + //String pagepos=""; + + Node nTypeR = null; + if (doc != null) { + Object exprResult=null; + try { + expr = xpath.compile("//metadata/type"); + exprResult = expr.evaluate(reqNode, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + NodeList nodeList = (NodeList) exprResult; + if (nodeList.getLength() > 0) { + nTypeR = nodeList.item(0); + typename = "" + nTypeR.getAttributes().getNamedItem("n").getNodeValue(); + //pagepos = "" + nTypeR.getAttributes().getNamedItem("pp").getNodeValue(); //The current page number + } + } + + //Get XML node "type" from database and parse to DOM + doc = parseString(getTypeStrNode(conn,typename)); + + //Находим серверный XML узел по имени + if (doc != null) { + Node nTypeS = doc.getDocumentElement(); + + if (nTypeS != null) { + Node f1 = null, f2 = null; + //В переданном запросе может быть не полный фильтр заполняем серверный значениями из переданного + NodeList nodeList=null; + try { + nodeList = (NodeList) xpath.compile("objects-list/filter").evaluate(nTypeS, XPathConstants.NODESET); + if (nodeList.getLength() > 0) + f1 = nodeList.item(0); + nodeList = (NodeList) xpath.compile("objects-list/filter").evaluate(nTypeR, XPathConstants.NODESET); + if (nodeList.getLength() > 0) + f2 = nodeList.item(0); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + + + //logger.info("f1=\n" + nodeToString(f1)); + //logger.info("f1=\n" + nodeToString(f2)); + + setFilter(f1, f2);//заменить все значения первого фильтра значениями из второго + + //logger.info("f1=\n" + nodeToString(f1)); + //logger.info("f1=\n" + nodeToString(f2)); + + //Filter options for display in the header Excel(XLS) document. + /* + String filter=""+trt("Filter_options",user)+":
"; + expr = xpath.compile("objects-list/filter/column"); + exprResult = expr.evaluate(nTypeR, XPathConstants.NODESET); + nodeList = (NodeList) exprResult; + for(int i=0;i"; + filter+=getCharacterDataFromElement((Element)nodeList.item(i)); + filter+="
"; + } + } + */ + + String sql_query=""; + try { + sql_query = (String) xpath.compile("objects-list/sql-query/text()").evaluate(nTypeS, XPathConstants.STRING); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + + //sql_query=Tools.replaceAll(sql_query,"${id}","null"); + //logger.info("sql_query1 = " + sql_query); + + Node nextnode = f1.getFirstChild(); + while (nextnode != null) { + if (nextnode.getNodeName().equals("column")) { + try { + String vn = nextnode.getAttributes().getNamedItem("n").getNodeValue(); + /*String size; + Node n = nextnode.getAttributes().getNamedItem("size"); + if (n != null) { + size = n.getNodeValue(); + }*/ + String vt = nextnode.getAttributes().getNamedItem("vt").getNodeValue(); + String val = getCharacterDataFromElement((Element) nextnode); + + val = getSQLValue(vt, val); + + sql_query = Tools.replaceAll(sql_query,"${" + vn + "}", val); + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + } + nextnode = nextnode.getNextSibling(); + } + sql_query = Tools.replaceAll(sql_query,"${_user_id}", (String) user.id); //Set current user id in sql query. + + //logger.info("sql_query2 = " + sql_query); + + + try { + Statement stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + ResultSet rs = stt.executeQuery(sql_query); + if (rs != null) { + //Create Excel file and write result set + Writer writer = null; + Random rand = new Random(); + String tmpName = "file_" + rand.nextInt(1000) + ".xls"; //TODO Not safety, the file names can match. + + try { + String tmpPath = data_dir + "temp" + File.separator; + File file = new File(tmpPath); + if (!file.exists()) { + file.mkdirs(); + } + + writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tmpPath + tmpName), "utf-8")); + + writer.write("\n"); + writer.write(" \n"); + writer.write(" " + nTypeS.getAttributes().getNamedItem("d").getNodeValue() + "\n"); + writer.write(" \n"); + writer.write(""); + writer.write(" \n"); + writer.write(" \n"); + + writer.write("" + trt(conn,"Time_and_date_of_generation",user) + ": " + (new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date())) + "
"); + writer.write("" + trt(conn,"Creator",user) + ": " + uName); + + //writer.write(filter); + + xPathfactory = XPathFactory.newInstance(); + xpath = xPathfactory.newXPath(); + try { + expr = xpath.compile("objects-list/@d"); + + writer.write(" \n"); + writer.write(" \n"); + writer.write(" \n"); + writer.write(" "); + + expr = xpath.compile("objects-list/column"); + Object exprResult = expr.evaluate(nTypeS, XPathConstants.NODESET); + nodeList = (NodeList) exprResult; + for (int i = 0; i < nodeList.getLength(); i++) { + writer.write(""); + } + writer.write(" \n"); + writer.write(" \n"); + writer.write(" \n"); + + while (rs.next()) { + writer.write(" "); + for (int i = 0; i < nodeList.getLength(); i++) { + String val = rs.getString(nodeList.item(i).getAttributes().getNamedItem("n").getNodeValue()); + if (val == null) + val = ""; + writer.write(""); + } + writer.write("\n"); + } + writer.write(" \n"); + writer.write("
" + getText(conn,"" + expr.evaluate(nTypeS, XPathConstants.STRING),user) + "
" + getText(conn,nodeList.item(i).getAttributes().getNamedItem("d").getNodeValue(),user) + + "
" + val + "
\n"); + writer.write(" \n"); + writer.write("\n"); + } catch (XPathExpressionException | DOMException | SQLException ex) { + logger.info(ex.getMessage()); + } + } catch (IOException ex) { + logger.info(ex.getMessage()); + //result=""; + result=sendError(1,"Error: " + ex.getMessage()); + error=true; + } finally { + try { + writer.close(); + } catch (Exception ex) { + } + } + //Отправляем название файла на сервер + result=""; + } + rs.close(); + stt.close(); + rs=null; + stt=null; + } catch (SQLException ex) { + logger.info(ex.getMessage()); + //result=""; + result=sendError(1,"Error: " + ex.getMessage() + "\n\nSQL query: " + sql_query); + error=true; + } + } + } + + } else if (fn != null && fn.equals("9")) { + // https://www.tutorialspoint.com/jsp/jsp_file_uploading.htm +/* + File file; + int maxFileSize = 5000 * 1024; + int maxMemSize = 5000 * 1024; + String filePath = context.getInitParameter("file-upload"); + + // Verify the content type + String contentType = request.getContentType(); + + if (contentType != null && contentType.indexOf("multipart/form-data") >= 0) { + DiskFileItemFactory factory = new DiskFileItemFactory(); + //factory.setSizeThreshold(maxMemSize); // maximum size that will be stored in memory + //factory.setRepository(new File("O:\\temp\\upload")); // Location to save data that is larger than maxMemSize. + + // Create a new file upload handler + ServletFileUpload upload = new ServletFileUpload(factory); + + // maximum file size to be uploaded. + upload.setSizeMax(maxFileSize); + + try { + // Parse the request to get file items. + List fileItems = upload.parseRequest(request); + + // Process the uploaded file items + Iterator i = fileItems.iterator(); + + while (i.hasNext()) { + FileItem fi = (FileItem) i.next(); + if (!fi.isFormField()) { + // Get the uploaded file parameters + String fieldName = fi.getFieldName(); + String fileName = fi.getName(); + boolean isInMemory = fi.isInMemory(); + long sizeInBytes = fi.getSize(); + + // Write the file + file = new File(filePath + fileName); + fi.write(file); + + //Calc CRC32 + long crc32=0; + FileInputStream fin = new FileInputStream(filePath + fileName); + Checksum sum_control = new CRC32(); + for (int b = fin.read(); b != -1; b = fin.read()) { + sum_control.update(b); + } + crc32 = sum_control.getValue(); + fin.close(); + + //To be rename file, add CRC32 in begin. + File srcFile = new File(filePath + fileName); + File destFile = new File(filePath + Long.toHexString(crc32) +"_"+ fileName); + FileUtils.copyFile(srcFile, destFile); + FileUtils.forceDelete(srcFile); + + logger.info("Uploaded Filename: " + Long.toHexString(crc32) +"_"+ fileName); + response.getWriter().append("ok=" + Long.toHexString(crc32) +"_"+ fileName + "\n"); + } + } + + } catch (Exception ex) { + logger.info(ex); + } + } + + //This code put into iframe + response.setContentType("text/html"); + + response.getWriter().append(""); + response.getWriter().append(""); + response.getWriter().append(" "); + response.getWriter().append(" "); + response.getWriter().append(" "); + response.getWriter().append(" "); + response.getWriter().append("
"); + response.getWriter().append(" "); + response.getWriter().append("
"); + response.getWriter().append(" "); + response.getWriter().append(" "); + response.getWriter().append("
"); + response.getWriter().append(" "); + response.getWriter().append(""); + + //Отчищяем временные файлы которые больше суток на сервере + //deleteTempFiles($dir); +*/ + + } else { + result=sendError(1,"Unknown function \"" + fn + "\" !"); + error=true; + } + + try { + conn.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + //return body content + return result; + } + + @Override + public void setServletContext(ServletContext context) { + this.context=context; + } + + /** + * Example request: http://localhost:8080/CCALM/download?t=FrmLocust&f=image_name1&i=1298 + */ + @RequestMapping(value = "/download", method = RequestMethod.GET,produces = "application/octet-stream") + @ResponseBody + public FileSystemResource home(HttpServletResponse response,@ModelAttribute User user,@RequestParam(required=false,name="t") String typename,@RequestParam(required=false,name="f") String field,@RequestParam(required=false,name="i") String id) { + + String metadata_file = ""; + String db_url = ""; + String db_login = ""; + String db_password = ""; + //String data_dir = ""; + //Load DB configuration from "config.xml" + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("db-url")) + db_url = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-login")) + db_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-password")) + db_password = nl.item(i).getTextContent(); + + if (nl.item(i).getNodeName().equals("metadata")) + metadata_file = nl.item(i).getTextContent(); + + //if (nl.item(i).getNodeName().equals("data-dir")) + // data_dir = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + + + Connection conn = null; + try { + Class.forName("org.postgresql.Driver"); + conn = DriverManager.getConnection(db_url, db_login, db_password); + if (conn != null) { + logger.info("Connect is OK!"); + } else { + logger.info("An error occurred while connecting to the database!"); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + Statement stt=null; + try { + stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + + //Send the binary data to the client as a file (no resume). + //String typename = request.getParameter("t"); //Type from metadata.xml + //String field = request.getParameter("f"); //field name + //String id = request.getParameter("i"); //field id + String path=""; + String filename=""; + File file=null; + + //Parse main XML + Document doc = null; + try { + File inputFile = new File(context.getRealPath("/")+"resources"+File.separator+metadata_file); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + doc = dBuilder.parse(inputFile); + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + + if (doc != null) { + doc.getDocumentElement().normalize(); //Del or concat text node + //response.getWriter().append("Root element: " + doc.getDocumentElement().getNodeName()+" !
"); + + javax.xml.xpath.XPathFactory xPathfactory = XPathFactory.newInstance(); + XPath xpath = xPathfactory.newXPath(); + XPathExpression expr=null; + + Object exprResult=null; + try { + expr = xpath.compile("//metadata/type[@n='" + typename + "']"); + exprResult = expr.evaluate(doc, XPathConstants.NODESET); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + NodeList nodeList = (NodeList) exprResult; + + Node nTypeS = null; + if (nodeList.getLength() > 0) + nTypeS = nodeList.item(0); + + try { + expr = xpath.compile("properties/prop[@n='"+field+"']/@path"); + path = (String) expr.evaluate(nTypeS, XPathConstants.STRING); + } catch (XPathExpressionException ex) { + logger.info(ex.getMessage()); + } + } + + if(path!=null && !path.equals("")) + { + ResultSet rs = null; + try { + String sql="SELECT "+field+" as name FROM main."+typename+" WHERE id="+String.valueOf(id); + rs = stt.executeQuery(sql); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + if (rs != null) { + try { + if (rs.next()) + filename = rs.getString(1); + rs.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + } + if(!filename.equals("")) + { + file = new File(path+File.separator+filename); + } + } + + if(conn!=null){try{conn.close();}catch(SQLException ex){}} + + if(file!=null) { + response.setContentType("application/octet-stream"); + response.setHeader("Content-Disposition", "attachment; filename="+afterFirst(filename,"_")); + response.setHeader("Cache-Control", "no-cache"); + return new FileSystemResource(file); + }else { + response.setContentType("text/html"); + return null; + } + } + + + @RequestMapping(value = "/upload", method = { RequestMethod.GET, RequestMethod.POST }) + @ResponseBody + public String uploadFile(HttpServletResponse response,@RequestParam(required=false,name="file") MultipartFile file) { + + String result=""; + String data_dir=""; + + + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("data-dir")) + data_dir = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + + + String fileName = ""; + + if (file!=null && !file.isEmpty()) { + try { + + byte[] bytes = file.getBytes(); + fileName = file.getOriginalFilename(); + + File dir = new File(data_dir); + if (!dir.exists()) dir.mkdirs(); + + BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(data_dir + fileName))); + stream.write(bytes); + stream.flush(); + stream.close(); + + //Calc CRC32 + long crc32=0; + FileInputStream fin = new FileInputStream(data_dir + fileName); + Checksum sum_control = new CRC32(); + for (int b = fin.read(); b != -1; b = fin.read()) { + sum_control.update(b); + } + crc32 = sum_control.getValue(); + fin.close(); + + //To be rename file, add CRC32 in begin. + File srcFile = new File(data_dir + fileName); + File destFile = new File(data_dir + Long.toHexString(crc32) +"_"+ fileName); + FileUtils.copyFile(srcFile, destFile); + FileUtils.forceDelete(srcFile); + + //logger.info("Uploaded Filename: " + Long.toHexString(crc32) +"_"+ fileName); + result+="ok=" + Long.toHexString(crc32) +"_"+ fileName + "\n"; + + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + } + + //This code put into iframe + response.setContentType("text/html"); + + result+=""; + result+=""; + result+=" "; + result+=" "; + result+=" "; + result+=" "; + result+="
"; + result+=" "; + result+="
"; + result+=" "; + result+=" "; + result+="
"; + result+=" "; + result+=""; + + //deleteTempFiles($dir); + + return result; + } + + //Send generated report to the client for downloading + @RequestMapping(value = "/reports",method = RequestMethod.GET, produces = "application/octet-stream") + @ResponseBody + public FileSystemResource sendReport(HttpServletResponse response,@RequestParam(required=true,name="file") String fileName) { + String data_dir = ""; + //Load DB configuration from "config.xml" + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("data-dir")) + data_dir = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + + + File file = new File(data_dir + "temp" + File.separator + fileName); + if(file.exists()) + { + //logger.info("Send report: " + fileName); + + //response.setContentType("application/octet-stream"); //Commented because it is specified in the function declaration. + response.setHeader("Content-Disposition","attachment; filename="+fileName); + response.setContentLength((int) file.length()); + return new FileSystemResource(file); + }else + { + logger.info("File not found: " + fileName); + return null; + } + } + + String getSQLValue(String t, String v) { + //if($t=='object' && (strtoupper($v)!='NULL' && gettype($v)=='string')) $t='string'; //Если id шники uuid + + if (t.equals("object") || t.equals("uid")) { + if (v.equals("")) + v = "NULL"; + } else if (t.equals("i4") || t.equals("integer")) { + if (v.equals("")) + v = "NULL"; + } else if (t.equals("f8")) { + if (v.equals("")) + v = "NULL"; + v = Tools.replaceAll(v,",", "."); //The decimal part: point. + } else if (t.equals("f4")) { + if (v.equals("")) + v = "NULL"; + v = Tools.replaceAll(v,",", "."); //The decimal part: point. + } else if (t.equals("b")) { + if (v.equals("")) + v = "NULL"; + else if (v.equals("1")) + v = "true"; + else if (v.equals("0")) + v = "false"; + } else if (t.equals("string") || t.equals("text") || t.equals("dateTime") || t.equals("date")) { + if (v.equals("")) { + v = "NULL"; + } else { + v = Tools.replaceAll(v,"'", "''"); + v = "'" + v + "'"; + } + } else { + v = "'" + v + "'"; + } + return v; + } + + private String nodeToString(Node node) { + StringWriter sw = new StringWriter(); + try { + Transformer t = TransformerFactory.newInstance().newTransformer(); + t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); + t.transform(new DOMSource(node), new StreamResult(sw)); + } catch (TransformerException ex) { + System.out.println(ex.getMessage()); + System.out.println("nodeToString Transformer Exception"); + } + return sw.toString(); + } + + //Replace all the values of the first filter values from the second + public void setFilter(Node n1, Node n2) { + if (n1 == null || n2 == null) + return; + + XPathFactory xPathfactory = XPathFactory.newInstance(); + XPath xpath = xPathfactory.newXPath(); + + Node nc1 = n1.getFirstChild(); + while (nc1 != null) { + if (nc1.getNodeName().equals("column")) { + try { + String path = "column[@n='" + nc1.getAttributes().getNamedItem("n").getNodeValue() + "']"; + XPathExpression expr = xpath.compile(path); + NodeList nodeList = (NodeList) expr.evaluate(n2, XPathConstants.NODESET); + if (nodeList.getLength() > 0) { + Node nc2 = nodeList.item(0); + + setCharacterDataToElement((Element) nc1, getCharacterDataFromElement((Element) nc2)); + + //getCdata($nc1)->nodeValue=getCdata($nc2)->nodeValue; + } + + } catch (Exception ex) { + System.out.println(ex.getMessage()); + //String message = "XML parsing error!"; + //return; + } + } + nc1 = nc1.getNextSibling(); + } + } + + public static String getCharacterDataFromElement(Element e) { + Node child = e.getFirstChild(); + if (child instanceof CharacterData) { + CharacterData cd = (CharacterData) child; + return cd.getData().trim(); + } + return ""; + } + + public void setCharacterDataToElement(Element e, String data) { + Node child = e.getFirstChild(); + if (child instanceof CharacterData) { + CharacterData cd = (CharacterData) child; + cd.setData(data); + } else //Create new CDATA node + { + Document doc = e.getOwnerDocument(); + e.appendChild(doc.createCDATASection(data)); + } + } + + public static String getRandomString(int length) { + final String characters = "abcdefghijklmnopqrstuvwxyz1234567890"; + StringBuilder result = new StringBuilder(); + while (length > 0) { + Random rand = new Random(); + result.append(characters.charAt(rand.nextInt(characters.length()))); + length--; + } + return result.toString(); + } + + //Translate word by id from database + public String trt(Connection conn,String key,User user) + { + String result=""; + ResultSet rs=null; + Statement st = null; + try { + st = conn.createStatement(); + String sql = "select case when '"+user.language_id+"'='666' then translation||'''\"' else translation end as translation from main._translations t where t.identifier='"+key+"' and (t.language_id='"+user.language_id+"' or ('"+user.language_id+"'='666' and t.language_id=1));"; + rs = st.executeQuery(sql); + if(rs != null) { + if (rs.next()) { + result = rs.getString(1); + } + } + } catch( SQLException ex ) + { + logger.info(ex.getMessage()); + }finally{ + if(st!=null) try{st.close();}catch(SQLException ex) {} + if(rs!=null) try{rs.close();}catch(SQLException ex) {} + } + if(result.equals("")) + { + result = Tools.replaceAll(key,"_", " "); + } + return result; + } + + //Translate text by patterns + public String getText(Connection conn,String text,User user) { + int pos1 = 0; + while (true) { + pos1 = text.indexOf("trt('", pos1); + if (pos1 == -1) + break; + int pos2 = text.indexOf("')", pos1); + if (pos2 == -1) + break; + + text = text.substring(0, pos1) + trt(conn,text.substring(pos1 + 5, pos2),user) + text.substring(pos2 + 2); + } + return text; + } + + public static String afterFirst(String str, String ch) + { + int i=str.indexOf(ch); + if(i!=-1) + { + return str.substring(i+ch.length()); + } + return ""; + } + + //Получить узел метаданных из базы данных + public String getTypeStrNode(Connection conn,String typeName) + { + String result=""; + String sql="select xml from main._metadata where name='"+typeName+"';"; + try { + Statement st = conn.createStatement(); + ResultSet rs=null; + try { + rs = st.executeQuery(sql); + } catch( SQLException ex ) { + ex.printStackTrace(); + } + try { + if(rs!=null) + { + if(rs.next()) + { + result=rs.getString(1); + } + rs.close(); + } + st.close(); + } catch (SQLException ex) { + ex.printStackTrace(); + } + } catch (SQLException ex) { + ex.printStackTrace(); + } + return result; + } + + //Пропарсить сткоку в DOM + public Document parseString(String xml) + { + Document doc=null; + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + doc = dBuilder.parse(new InputSource(new StringReader(xml))); + } catch (Exception ex) { + ex.printStackTrace(); + } + return doc; + } + +} \ No newline at end of file diff --git a/src/main/java/kz/locust/CCALM/DataJSON.java b/src/main/java/kz/locust/CCALM/DataJSON.java new file mode 100644 index 0000000..c3bdb62 --- /dev/null +++ b/src/main/java/kz/locust/CCALM/DataJSON.java @@ -0,0 +1,226 @@ +package kz.locust.CCALM; + +import java.io.BufferedOutputStream; +import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.StringReader; +import java.io.Reader; +import java.io.StringWriter; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +//import java.util.Iterator; +import java.util.List; +import java.util.Properties; +import java.util.Random; +import java.util.zip.CRC32; +import java.util.zip.Checksum; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; +import javax.xml.xpath.XPathFactory; + +//import org.apache.commons.fileupload.FileItem; +//import org.apache.commons.fileupload.disk.DiskFileItemFactory; +//import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.io.FileUtils; +import org.json.JSONArray; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.FileSystemResource; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.SessionAttributes; +import org.springframework.web.context.ServletContextAware; +import org.springframework.web.multipart.MultipartFile; +import org.w3c.dom.CharacterData; +import org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.ls.DOMImplementationLS; +import org.w3c.dom.ls.LSSerializer; +import org.xml.sax.InputSource; + +import tctable.Tools; +import tools.EmailUtility; +import tools.PreparedStatementNamed; +import tools.User; + +@Controller +@SessionAttributes( { "user" }) +public class DataJSON implements ServletContextAware { + + private static final Logger logger = LoggerFactory.getLogger(DataJSON.class); + private ServletContext context; + + //If not created object "user", create him. + @ModelAttribute("user") + public User populatePerson() { + return new User("none"); + } + + @RequestMapping(value = "/get_companies",method = {RequestMethod.POST,RequestMethod.GET}, produces = "application/json;charset=UTF-8") + @ResponseBody + public String getCompanies(@ModelAttribute User user,@RequestParam(required=false,name="country_id") String country_id,@RequestParam(required=false,name="lng") String language_id) { + + int errorCode=0; + String errorMessage=""; + + //Load configuration from "config.xml" + String db_url = ""; + String db_login = ""; + String db_password = ""; + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("db-url")) + db_url = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-login")) + db_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-password")) + db_password = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + errorCode=1; + errorMessage+="Internal server error, settings."; + logger.info(ex.getMessage()); + } + + Connection conn = null; + try { + Class.forName("org.postgresql.Driver"); + conn = DriverManager.getConnection(db_url, db_login, db_password); + if (conn != null) { + logger.info("Connect is OK!"); + } else { + errorCode=1; + errorMessage+="An error occurred while connecting to the database!"; + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + errorCode=1; + errorMessage+="An error occurred while connecting to the database!"; + } + + try { + Statement stt0 = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + stt0.executeUpdate("SET TIME ZONE 'UTC';"); + //stt0.executeUpdate("SET TIME ZONE 'Asia/Almaty';"); + stt0.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + errorCode=1; + errorMessage+="Failed to execute SQL query!"; + } + + JSONObject doc=null; + JSONArray array=new JSONArray(); //Результирующий набор данных + + String sql_query = ""; + Statement stt=null; + ResultSet rs=null; + try { + stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + sql_query = "select id,name from main.companies where del=false and name is not null and name!='' and (${country_id} is null or country_id=${country_id})"; + + PreparedStatementNamed stmtn = new PreparedStatementNamed(conn, sql_query); + if(country_id==null || country_id.equals("")) + stmtn.setNULLInt("country_id"); + else + stmtn.setInt("country_id",Integer.parseInt(country_id)); + PreparedStatement stmt=stmtn.getPreparedStatement(); + + rs = stmt.executeQuery(); + if (rs != null) { + try { + while(rs.next()) { + + JSONObject obj = new JSONObject(); + obj.put("id", rs.getLong("id")); + + if(rs.getObject("name")!=null) + obj.put("name", rs.getString("name")); + + array.put(obj); + } + rs.close(); + } catch (SQLException ex) { + errorCode=4; + errorMessage+="Internal server error, sampling."; + ex.printStackTrace(); + logger.info(ex.getMessage()); + } + } + } catch (SQLException ex) { + errorCode=5; + errorMessage+="Internal server error, query. "; + ex.printStackTrace(); + logger.info(ex.getMessage()); + }finally { + if(rs!=null) try{rs.close();}catch(SQLException ex){} + if(stt!=null) try{stt.close();}catch(SQLException ex){} + } + + if(errorCode!=0) { + JSONObject obj = new JSONObject(); + obj.put("errorCode",errorCode); + obj.put("errorMessage", errorMessage); + return obj.toString(); + }else { + JSONObject obj = new JSONObject(); + obj.put("errorCode",0); + obj.put("errorMessage", ""); + if(doc!=null) + obj.put("indicator",doc.getString("indicator")); + obj.put("data",array); + return obj.toString(); + } + } + + @Override + public void setServletContext(ServletContext servletContext) { + this.context=servletContext; + } + +} \ No newline at end of file diff --git a/src/main/java/kz/locust/CCALM/DownloadNDVI.java b/src/main/java/kz/locust/CCALM/DownloadNDVI.java new file mode 100644 index 0000000..6dc3418 --- /dev/null +++ b/src/main/java/kz/locust/CCALM/DownloadNDVI.java @@ -0,0 +1,365 @@ +package kz.locust.CCALM; + + +import org.gdal.gdal.Band; +import org.gdal.gdal.Dataset; +import org.gdal.gdal.gdal; +import org.gdal.gdalconst.gdalconstConstants; + + +import javax.servlet.ServletContext; + +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.context.ServletContextAware; +import org.w3c.dom.Document; + +/*import ucar.ma2.Array; +import ucar.nc2.Dimension; +import ucar.nc2.Variable; +import ucar.nc2.dataset.NetcdfDataset;*/ + +@Controller +public class DownloadNDVI implements ServletContextAware { + + private static final org.slf4j.Logger logger = LoggerFactory.getLogger(DownloadNDVI.class); + + private ServletContext context; + + @RequestMapping(value = "/DownloadNDVI",method = RequestMethod.GET,produces = "text/html;charset=UTF-8") + @ResponseBody + public Object ajaxTamer(@RequestParam(required=false,name="forecast") String forecast) { + + + //String forecast = request.getParameter("forecast"); //Date like as "000". + //response.setContentType("text/html"); + //PrintWriter out = response.getWriter(); + String result=""; + result+="Start!
"; + + + //http://gis-lab.info/forum/viewtopic.php?style=1&t=15764 + gdal.AllRegister(); + Dataset dataset=gdal.Open("O:\\Desctop\\NDVI_from_HDF\\1\\MOD13Q1.A2019049.h27v12.006.2019073153055.hdf" , gdalconstConstants.GA_ReadOnly); + Band o=(Band)dataset.GetRasterBand(1); + long flen=o.getXSize()*o.getYSize(); + + result+=flen; + +/* + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + + //Load DB configuration from "config.xml" + String db_url = ""; + String db_login = ""; + String db_password = ""; + String data_dir = ""; + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("db-url")) + db_url = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-login")) + db_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-password")) + db_password = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("data-dir")) + data_dir = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + data_dir+="temp"+File.separator; + + File dir = new File(data_dir); + if (!dir.exists()) dir.mkdirs(); + + //response.getWriter().append("Served at: ").append(request.getContextPath()); + Connection conn = null; + try{ + Class.forName("org.postgresql.Driver"); + conn = DriverManager.getConnection(db_url,db_login,db_password); + if(conn!=null) + { + logger.info("Connect is OK!"); + result+="Connect is OK!
"; + }else + { + logger.info("
Connect is ERROR
"); + result+="Connect is ERROR!
"; + } + }catch(Exception e) + { + logger.info("
Connect Exception:"+e.getMessage()+"
"); + result+="Connect Exception:"+e.getMessage()+"
"; + } + + //Example request: http://localhost:8080/CCALM/DownloadWeather?forecast=000 + DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); + String date=dateFormat.format(new Date()); //Date like as "20170327". + + String time = "00"; //00 hours,06 hours,12 hours and 18 hours + //String forecast = request.getParameter("forecast"); //Date like as "000". + String measurement = "TSOIL:0-0.1 m below ground"; + //String measurement = "TSOIL:0.1-0.4 m below ground"; + + //Build URL to download + String URL = "https://www.ftp.ncep.noaa.gov/data/nccf/com/gfs/prod/gfs."+date+time+"/gfs.t"+time+"z.pgrb2.0p25.f"+forecast; + + //URL = "http://www.ftp.ncep.noaa.gov/data/nccf/com/gfs/prod/gfs.2017091200/gfs.t00z.pgrb2.0p25.f000"; + + WeatherDownload wd = new WeatherDownload(); + if(wd.download(URL+".idx", data_dir+"text.idx", "0", "")) + { + result+="Download "+URL+".idx"+" to "+data_dir+"text.idx"+"
"; + + String strPos1=""; + String strPos2=""; + //Read file and find required line. + try { + BufferedReader br = new BufferedReader(new FileReader(data_dir+"text.idx")); + String line; + while ((line = br.readLine()) != null) + { + //if (line.contains("TSOIL:0-0.1 m below ground")) + if (line.contains(measurement)) + { + strPos1=line; + strPos2=br.readLine(); + break; + } + } + br.close(); + } catch (IOException ex) { + logger.info(ex.getMessage()); + result+=ex.getMessage()+"
"; + } + if(!strPos1.equals("")) + { + //String strPos1 = "250:146339365:d=2017022818:TSOIL:0-0.1 m below ground:anl:" + StringBuffer answer1=new StringBuffer(strPos1); + CutBeforeFirst(answer1,":"); + String posStart = CutBeforeFirst(answer1,":"); + + StringBuffer answer2=new StringBuffer(strPos2); + CutBeforeFirst(answer2,":"); + String posEnd = CutBeforeFirst(answer2,":"); + if(posEnd==null || posEnd.equals("")) posEnd=""; else + { + posEnd=String.valueOf(Long.parseLong(posEnd)-1); + } + + wd.download(URL, data_dir+"text.f000", String.valueOf(posStart), String.valueOf(posEnd)); + } + }else + { + result+="Not download "+URL+".idx"+" to "+data_dir+"text.idx"+"
"; + } + + Array dataArrayLat=null; + Array dataArrayLon=null; + Array dataArrayTmp=null; + + try { + // open netcdf/grib/grib2 file from argument + NetcdfDataset gid = NetcdfDataset.openDataset(data_dir+"text.f000"); + + //logger.info("Desc: " + gid.getDescription()); + logger.info(gid.getDetailInfo()); + //logger.info("Feature type: " + gid.getFeatureType().toString()); + + // get all grid tables in the file + List variables = gid.getReferencedFile().getVariables(); + for (int i = 0; i < variables.size(); i++) + { + System.out.print(variables.get(i).getName()+" "); + //LatLon_Projection, lat, lon, reftime, time, depth_below_surface_layer, depth_below_surface_layer_bounds, Soil_temperature_depth_below_surface_layer + + if(variables.get(i).getName().equals("reftime")) + { + logger.info(""); + logger.info("Description = "+variables.get(i).getDescription()); + logger.info("DimensionsString = "+variables.get(i).getDimensionsString()); + logger.info("DataType = "+variables.get(i).getDataType()); + logger.info("UnitsString = "+variables.get(i).getUnitsString()); //Hour since 2017-02-28T18:00:00Z + } + + if(variables.get(i).getName().equals("lon")) + { + dataArrayLon = variables.get(i).read(); + } + if(variables.get(i).getName().equals("lat")) + { + dataArrayLat = variables.get(i).read(); + } + if(variables.get(i).getName().equals("Soil_temperature_depth_below_surface_layer")) + { + //Section sec=new Section(); + dataArrayTmp = variables.get(i).read(); + + //for(int j=0;j dims = gid.getDimensions(); + logger.info("dims.size() = " + dims.size()); + + Iterator dimIt = dims.iterator(); + while( dimIt.hasNext()) { + Dimension dim = dimIt.next(); + logger.info("Dim = " + dim); + logger.info("Dim name = "+dim.getName()); + } + dimIt = null; + + Statement st=null; + try { + st = conn.createStatement(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + + try { + st.executeUpdate("BEGIN TRANSACTION;"); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + logger.info(ex.getMessage()); + } + + result+="Size="+dataArrayLat.getSize()+"
"; + + int pos=0; + for(int nLat=0;nLat180) lon=lon-360; + double lat = dataArrayLat.getFloat(nLat); + + if(lat>29 && lat<67 && lon>17 && lon<180) //Central Asia + { + if(!Float.isNaN(dataArrayTmp.getFloat(pos))) //On the water none temperatyre. + { + String country_id=""; + ResultSet rs=null; + try { + rs = st.executeQuery("select c.id from main.countries c where ST_Contains(c.geom,ST_SetSRID(st_makepoint("+lon+","+lat+"),4326)) limit 1"); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + if (rs != null) { + try { + if (rs.next()) + country_id=rs.getString(1); + rs.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + } + if(country_id!=null && !country_id.equals("") && !country_id.equals("null")) + { + //logger.info(lon + "," + lat +","+dataArrayTmp.getFloat(pos)); + try { + //String sql="insert into weather(weather_type_id,date,hours,val,geom)values(1,cast(to_timestamp('"+date+" "+time+"', 'YYYYMMDD HH24') as timestamp without time zone),"+forecast+","+dataArrayTmp.getFloat(pos)+",ST_SetSRID(st_makepoint("+lon+","+lat+"),4326));"; + //String sql="insert into main.weather(weather_type_id,date,hours,val,geom,country_id)values(1,cast(to_timestamp('"+date+" "+time+"', 'YYYYMMDD HH24') as timestamp without time zone),"+forecast+","+dataArrayTmp.getFloat(pos)+",ST_SetSRID(st_makepoint("+lon+","+lat+"),4326),(select c.id from main.countries c where ST_Contains(c.geom,ST_SetSRID(st_makepoint("+lon+","+lat+"),4326)) limit 1));"; + String sql="insert into main.weather(weather_type_id,date,hours,val,geom,country_id)values(1,cast(to_timestamp('"+date+" "+time+"', 'YYYYMMDD HH24') as timestamp without time zone),"+forecast+","+dataArrayTmp.getFloat(pos)+",ST_SetSRID(st_makepoint("+lon+","+lat+"),4326),"+country_id+");"; + st.executeUpdate(sql); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + } + + } + } + pos++; + } + } + + //Cut data pise for Russia + try { + //String sql="update weather w set country_id=null where country_id=7 and not ST_Contains((select geom from main.countriesregions where id=97),w.geom);"; + String sql="update main.weather w set country_id=null where country_id=7 and not ST_Contains(ST_SetSRID(ST_GeomFromText('POLYGON((10.00 66.00,10.00 40.00,179.00 40.00,179.00 66.00,10.00 66.00))'),4326),w.geom);"; + st.executeUpdate(sql); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + + //Delete values where country_id is null + try { + String sql="delete from main.weather where country_id is null;"; + st.executeUpdate(sql); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + + //Delete all old values + try { + String sql="delete from main.weather where date!=(select max(date) from main.weather limit 1);"; + st.executeUpdate(sql); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + logger.info(ex.getMessage()); + } + + try { + st.executeUpdate("END TRANSACTION;"); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + logger.info(ex.getMessage()); + } + + gid.close(); + } catch (IOException ex) { + //Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + System.out.print("ERROR!"); + } + + try {conn.close();} catch (SQLException ex) {logger.info(ex.getMessage());} + + result+="End!
"; +*/ + return result; + } + //--------------------------------------------------------------------------- + @Override + public void setServletContext(ServletContext context) { + this.context=context; + } + //--------------------------------------------------------------------------- + public static String CutBeforeFirst(StringBuffer str,String ch) + { + int pos=str.indexOf(ch); + String result=""; + if(pos==-1) + { + result.concat(str.toString()); + str.delete(0,str.length()); + }else + { + result=str.substring(0,pos); + str.delete(0,pos+1); + } + return result; + } + +} diff --git a/src/main/java/kz/locust/CCALM/DownloadWeather.java b/src/main/java/kz/locust/CCALM/DownloadWeather.java new file mode 100644 index 0000000..b084e9a --- /dev/null +++ b/src/main/java/kz/locust/CCALM/DownloadWeather.java @@ -0,0 +1,470 @@ +package kz.locust.CCALM; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.TimeZone; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.servlet.ServletContext; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.context.ServletContextAware; +import org.w3c.dom.Document; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +//import main.DownloadFromHTTP; +import kz.locust.CCALM.WeatherDownload; +import ucar.ma2.Array; +import ucar.nc2.Dimension; +import ucar.nc2.Variable; +import ucar.nc2.dataset.NetcdfDataset; + +@Controller +public class DownloadWeather implements ServletContextAware { + + private static final org.slf4j.Logger logger = LoggerFactory.getLogger(DownloadWeather.class); + + private ServletContext context; + + @RequestMapping(value = "/DownloadWeather",method = RequestMethod.GET,produces = "text/html;charset=UTF-8") + @ResponseBody + public Object ajaxTamer(@RequestParam(required=false,name="forecast") String forecast,@RequestParam(required=false,name="date") String date) { + //String forecast = request.getParameter("forecast"); //Date like as "000". + //response.setContentType("text/html"); + //PrintWriter out = response.getWriter(); + String result=""; + result+="Start!
"; + + TimeZone.setDefault(TimeZone.getTimeZone("UTC")); + + //Load DB configuration from "config.xml" + String db_url = ""; + String db_login = ""; + String db_password = ""; + String data_dir = ""; + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("db-url")) + db_url = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-login")) + db_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-password")) + db_password = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("data-dir")) + data_dir = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + data_dir+="temp"+File.separator; + + File dir = new File(data_dir); + if (!dir.exists()) dir.mkdirs(); + + //response.getWriter().append("Served at: ").append(request.getContextPath()); + Connection conn = null; + try{ + Class.forName("org.postgresql.Driver"); + conn = DriverManager.getConnection(db_url,db_login,db_password); + if(conn!=null) + { + logger.info("Connect is OK!"); + result+="Connect is OK!
"; + }else + { + logger.info("
Connect is ERROR
"); + result+="Connect is ERROR!
"; + } + }catch(Exception e) + { + logger.info("
Connect Exception:"+e.getMessage()+"
"); + result+="Connect Exception:"+e.getMessage()+"
"; + } + + //Example request: http://ccalm.org/DownloadWeather?forecast=000&date=20210531 + //Example request: http://localhost:8080/CCALM/DownloadWeather?forecast=000 + //Example request: http://127.0.0.1:8080/CCALM/DownloadWeather?forecast=000 + if(date==null || date.equals("")) + { + DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd"); + date=dateFormat.format(new Date()); //Date like as "20170327". + } + + String time = "00"; //00 hours,06 hours,12 hours and 18 hours + //String forecast = request.getParameter("forecast"); //Date like as "000". + String measurement = "TSOIL:0-0.1 m below ground"; + //String measurement = "TSOIL:0.1-0.4 m below ground"; + + //Build URL to download + String URL = "https://www.ftp.ncep.noaa.gov/data/nccf/com/gfs/prod/gfs."+date+"/"+time+"/atmos/gfs.t"+time+"z.pgrb2.0p25.f"+forecast; + + File f = new File(data_dir+"text.idx"); + if(f.exists()) { + if (!f.delete()) { + System.out.println("Failed to delete the file."); + } + } + + WeatherDownload wd = new WeatherDownload(); + if(wd.download(URL+".idx", data_dir+"text.idx", "0", "")) + { + result+="Download "+URL+".idx"+" to "+data_dir+"text.idx"+"
"; + + String strPos1=""; + String strPos2=""; + //Read file and find required line. + try { + BufferedReader br = new BufferedReader(new FileReader(data_dir+"text.idx")); + String line; + while ((line = br.readLine()) != null) + { + //if (line.contains("TSOIL:0-0.1 m below ground")) + if (line.contains(measurement)) + { + strPos1=line; + strPos2=br.readLine(); + break; + } + } + br.close(); + } catch (IOException ex) { + logger.info(ex.getMessage()); + result+=ex.getMessage()+"
"; + } + if(!strPos1.equals("")) + { + //String strPos1 = "250:146339365:d=2017022818:TSOIL:0-0.1 m below ground:anl:" + StringBuffer answer1=new StringBuffer(strPos1); + CutBeforeFirst(answer1,":"); + String posStart = CutBeforeFirst(answer1,":"); + + StringBuffer answer2=new StringBuffer(strPos2); + CutBeforeFirst(answer2,":"); + String posEnd = CutBeforeFirst(answer2,":"); + if(posEnd==null || posEnd.equals("")) posEnd=""; else + { + posEnd=String.valueOf(Long.parseLong(posEnd)-1); + } + + wd.download(URL, data_dir+"text.f000", String.valueOf(posStart), String.valueOf(posEnd)); + } + }else + { + result+="Not download "+URL+".idx"+" to "+data_dir+"text.idx"+"
"; + } + + Array dataArrayLat=null; + Array dataArrayLon=null; + Array dataArrayTmp=null; + + try { + // open netcdf/grib/grib2 file from argument + NetcdfDataset gid = NetcdfDataset.openDataset(data_dir+"text.f000"); + + //logger.info("Desc: " + gid.getDescription()); + logger.info(gid.getDetailInfo()); + //logger.info("Feature type: " + gid.getFeatureType().toString()); + + // get all grid tables in the file + List variables = gid.getReferencedFile().getVariables(); + for (int i = 0; i < variables.size(); i++) + { + System.out.print(variables.get(i).getName()+" "); + //LatLon_Projection, lat, lon, reftime, time, depth_below_surface_layer, depth_below_surface_layer_bounds, Soil_temperature_depth_below_surface_layer + + if(variables.get(i).getName().equals("reftime")) + { + logger.info(""); + logger.info("Description = "+variables.get(i).getDescription()); + logger.info("DimensionsString = "+variables.get(i).getDimensionsString()); + logger.info("DataType = "+variables.get(i).getDataType()); + logger.info("UnitsString = "+variables.get(i).getUnitsString()); //Hour since 2017-02-28T18:00:00Z + } + + if(variables.get(i).getName().equals("lon")) + { + dataArrayLon = variables.get(i).read(); + } + if(variables.get(i).getName().equals("lat")) + { + dataArrayLat = variables.get(i).read(); + } + if(variables.get(i).getName().equals("Soil_temperature_depth_below_surface_layer")) + { + //Section sec=new Section(); + dataArrayTmp = variables.get(i).read(); + + /*for(int j=0;j dims = gid.getDimensions(); + logger.info("dims.size() = " + dims.size()); + + Iterator dimIt = dims.iterator(); + while( dimIt.hasNext()) { + Dimension dim = dimIt.next(); + logger.info("Dim = " + dim); + logger.info("Dim name = "+dim.getName()); + } + dimIt = null; + + Statement st=null; + try { + st = conn.createStatement(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + + try { + st.executeUpdate("BEGIN TRANSACTION;"); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + logger.info(ex.getMessage()); + } + + result+="Size="+dataArrayLat.getSize()+"
"; + + int pos=0; + for(int nLat=0;nLat180) lon=lon-360; + double lat = dataArrayLat.getFloat(nLat); + + if(lat>29 && lat<67 && lon>17 && lon<180) //Central Asia + { + if(!Float.isNaN(dataArrayTmp.getFloat(pos))) //On the water none temperatyre. + { + String country_id=""; + ResultSet rs=null; + try { + rs = st.executeQuery("select c.id from main.countries c where ST_Contains(c.geom,ST_SetSRID(st_makepoint("+lon+","+lat+"),4326)) limit 1"); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + if (rs != null) { + try { + if (rs.next()) + country_id=rs.getString(1); + rs.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + } + if(country_id!=null && !country_id.equals("") && !country_id.equals("null")) + { + //logger.info(lon + "," + lat +","+dataArrayTmp.getFloat(pos)); + try { + //String sql="insert into main.weather(weather_type_id,date,hours,val,geom)values(1,cast(to_timestamp('"+date+" "+time+"', 'YYYYMMDD HH24') as timestamp without time zone),"+forecast+","+dataArrayTmp.getFloat(pos)+",ST_SetSRID(st_makepoint("+lon+","+lat+"),4326));"; + //String sql="insert into main.weather(weather_type_id,date,hours,val,geom,country_id)values(1,cast(to_timestamp('"+date+" "+time+"', 'YYYYMMDD HH24') as timestamp without time zone),"+forecast+","+dataArrayTmp.getFloat(pos)+",ST_SetSRID(st_makepoint("+lon+","+lat+"),4326),(select c.id from main.countries c where ST_Contains(c.geom,ST_SetSRID(st_makepoint("+lon+","+lat+"),4326)) limit 1));"; + String sql="insert into main.weather(weather_type_id,date,hours,val,geom,country_id)values(1,cast(to_timestamp('"+date+" "+time+"', 'YYYYMMDD HH24') as timestamp without time zone),"+forecast+","+dataArrayTmp.getFloat(pos)+",ST_SetSRID(st_makepoint("+lon+","+lat+"),4326),"+country_id+");"; + st.executeUpdate(sql); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + } + + } + } + pos++; + } + } + + //Cut data piece from big country of Russia + try { + //String sql="update weather w set country_id=null where country_id=7 and not ST_Contains((select geom from main.countriesregions where id=97),w.geom);"; + String sql="update main.weather w set country_id=null where country_id=7 and not ST_Contains(ST_SetSRID(ST_GeomFromText('POLYGON((10.00 66.00,10.00 40.00,179.00 40.00,179.00 66.00,10.00 66.00))'),4326),w.geom);"; + st.executeUpdate(sql); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + + //Delete values where country_id is null + try { + String sql="delete from main.weather where country_id is null;"; + st.executeUpdate(sql); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + + //Delete all old values аnd not a multiple of 10. + try { + String sql="delete from main.weather where date!=(select max(date) from main.weather limit 1) and ((DATE_PART('doy',date)::INTEGER-1)%10!=0 or ((DATE_PART('doy',date)::INTEGER-1)%10=0 and hours=48));"; + st.executeUpdate(sql); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + logger.info(ex.getMessage()); + } + + try { + st.executeUpdate("END TRANSACTION;"); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + logger.info(ex.getMessage()); + } + + gid.close(); + } catch (IOException ex) { + //Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); + System.out.print("ERROR!"); + } + + try {conn.close();} catch (SQLException ex) {logger.info(ex.getMessage());} + + result+="End!
"; + return result; + } + //--------------------------------------------------------------------------- + @Override + public void setServletContext(ServletContext context) { + this.context=context; + } + //--------------------------------------------------------------------------- + public static String CutBeforeFirst(StringBuffer str,String ch) + { + int pos=str.indexOf(ch); + String result=""; + if(pos==-1) + { + result.concat(str.toString()); + str.delete(0,str.length()); + }else + { + result=str.substring(0,pos); + str.delete(0,pos+1); + } + return result; + } + //--------------------------------------------------------------------------- + //List of "Soil temperature" dates from database in JSON + @RequestMapping(value = "/WeatherSoilDates",method = RequestMethod.GET,produces = "text/html;charset=UTF-8") + @ResponseBody + public Object ajaxSoilDates() { + boolean error=false; + String result=""; + + //Load DB configuration from "config.xml" + String db_url = ""; + String db_login = ""; + String db_password = ""; + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("db-url")) + db_url = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-login")) + db_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-password")) + db_password = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + + Connection conn = null; + try { + Class.forName("org.postgresql.Driver"); + conn = DriverManager.getConnection(db_url, db_login, db_password); + if (conn != null) { + logger.info("Connect is OK!"); + } else { + error=true; + result="An error occurred while connecting to the database!"; + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + error=true; + result="
SQLException: "+ex.getMessage()+"
"; + } + + if(!error) + { + Statement st; + try { + st = conn.createStatement(); + String sql = "SELECT to_char(date, 'YYYY-MM-DD') as date,hours as hour,DATE_PART('doy',date)-1 as day FROM main.weather group by date,hours order by date,hours"; + ResultSet rs = st.executeQuery(sql); + if(rs!=null) + { + boolean exists=false; + result="["; + while (rs.next()) + { + exists=true; + try { + result+= "{\"num\":\""+rs.getString("day")+"\", \"hour\":\""+rs.getString("hour")+"\", \"date\":\""+rs.getString("date")+"\"},"; + } catch( Exception ex ) + { + + } + } + if(exists) { + result=result.substring(0, result.length()-1); + result+="]"; + }else { + result="[]"; + } + + } + st.close(); + conn.close(); + } catch (SQLException ex) { + result="
SQLException:"+ex.getMessage()+"
"; + } + } + return result; + } + //--------------------------------------------------------------------------- + +} diff --git a/src/main/java/kz/locust/CCALM/GeoGSON.java b/src/main/java/kz/locust/CCALM/GeoGSON.java new file mode 100644 index 0000000..3cefb1f --- /dev/null +++ b/src/main/java/kz/locust/CCALM/GeoGSON.java @@ -0,0 +1,278 @@ +package kz.locust.CCALM; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.context.ServletContextAware; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import tctable.TCField; +import tctable.TCTable; + +@Controller +public class GeoGSON implements ServletContextAware { + + private static final Logger logger = LoggerFactory.getLogger(GeoGSON.class); + private ServletContext context; + + @RequestMapping(value = "/geojson", method = RequestMethod.GET) + @ResponseBody + public Object home(HttpServletResponse response,@RequestParam(required=false,name="table") String table,@RequestParam(required=false,name="id") String id) + { + boolean error=false; + String result=""; + + String db_url = ""; + String db_login = ""; + String db_password = ""; + //Load DB configuration from "config.xml" + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("db-url")) + db_url = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-login")) + db_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-password")) + db_password = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + error=true; + result="
SQLException: "+ex.getMessage()+"
"; + } + + Connection conn = null; + try { + Class.forName("org.postgresql.Driver"); + conn = DriverManager.getConnection(db_url, db_login, db_password); + if (conn != null) { + logger.info("Connect is OK!"); + } else { + error=true; + result="An error occurred while connecting to the database!"; + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + error=true; + result="
SQLException: "+ex.getMessage()+"
"; + } + + if(!error) + { + Statement st; + try { + st = conn.createStatement(); + String sql="select id,name,ST_AsGeoJSON(geom,3,0) as geom from main."+table+" where id="+id+";"; + ResultSet rs = st.executeQuery(sql); + if(rs!=null) + { + while (rs.next()) + { + String geom=null; + try { + geom=rs.getString("geom"); + } catch( Exception ex ) + { + result=""; + } + if(geom==null) geom=""; + result=geom; + } + } + st.close(); + conn.close(); + } catch (SQLException ex) { + result="
SQLException:"+ex.getMessage()+"
"; + } + } + + return result; + } + + @Override + public void setServletContext(ServletContext context) { + this.context=context; + } + + + //For compilatin android project + //http://127.0.0.1:8080/CCALM/countriesregionspoints + @RequestMapping(value = "/countriesregionspoints", method = RequestMethod.GET) + @ResponseBody + public Object countriesregions(HttpServletResponse response) + { + boolean error=false; + String result="OK
"; + + String db_url = ""; + String db_login = ""; + String db_password = ""; + String data_dir = ""; + //Load DB configuration from "config.xml" + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("db-url")) + db_url = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-login")) + db_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-password")) + db_password = nl.item(i).getTextContent(); + + if (nl.item(i).getNodeName().equals("data-dir")) + data_dir = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + error=true; + result+="
SQLException: "+ex.getMessage()+"
"; + } + + Connection conn = null; + try { + Class.forName("org.postgresql.Driver"); + conn = DriverManager.getConnection(db_url, db_login, db_password); + if (conn != null) { + logger.info("Connect is OK!"); + } else { + error=true; + result+="An error occurred while connecting to the database!"; + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + error=true; + result+="
SQLException: "+ex.getMessage()+"
"; + } + + if(!error) + { + Statement st,stC; + //Каждую геозонку области записываю в отдельный файл + String sql="select id from main.countriesregions where del=false"; + try { + stC = conn.createStatement(); + ResultSet rsC = stC.executeQuery(sql); + if(rsC!=null) + { + while (rsC.next()) + { + sql=""; + //sql+=" select t1.id as country_region_id,(ST_DumpPoints(geom)).path[1] as pos,cast(ST_X((ST_DumpPoints(geom)).geom) as real) lon,cast(ST_Y((ST_DumpPoints(geom)).geom) as real) lat from"; + sql+=" select cast(ST_X((ST_DumpPoints(geom)).geom) as real) lon,cast(ST_Y((ST_DumpPoints(geom)).geom) as real) lat from"; + sql+=" ("; + sql+=" select id,name,ST_Area(t.gone) area,ST_ExteriorRing(gone) as geom from"; + sql+=" (select id,name,ST_NumGeometries(geom),(ST_Dump(geom)).geom gone from main.countriesregions where del=false and id="+rsC.getString("id")+") t"; + sql+=" )t1"; + sql+=" ,"; + sql+=" (select id,max(ST_Area(t.gone)) area from"; + sql+=" (select id,name,ST_NumGeometries(geom),(ST_Dump(geom)).geom gone from main.countriesregions where del=false and id="+rsC.getString("id")+") t"; + sql+=" group by id) t2"; + sql+=" where"; + sql+=" t1.id=t2.id"; + sql+=" and t1.area=t2.area"; + + st = conn.createStatement(); + ResultSet rs = st.executeQuery(sql); + + try { + if(rs!=null) + { + File targetFile = new File(data_dir+"region_"+rsC.getString("id")+".tbl"); //Андроид не разрешает ресурсы с циферки + OutputStream outStream = new FileOutputStream(targetFile); + + + TCTable tbl=new TCTable("crcountriesregionspoints",123456); + logger.info("countriesregionspoints"); + + ResultSetMetaData rsmd = rs.getMetaData(); + for(int i=1;i<=rsmd.getColumnCount();i++) + { + logger.info(i+") name="+rsmd.getColumnName(i)+" type="+rsmd.getColumnTypeName(i)); + + TCField field=new TCField(rsmd.getColumnName(i), rsmd.getColumnTypeName(i)); + tbl.addField(field); + } + + tbl.getHeader(outStream); + while (rs.next()) + { + for(int i=1;i<=rsmd.getColumnCount();i++) + { + if(!rsmd.getColumnTypeName(i).equals("geometry")) + tbl.fields.get(i-1).setValue(rs.getString(i)); + else + tbl.fields.get(i-1).setValue(null); + } + //Save binary data to stream + tbl.getCol(outStream); + } + + outStream.flush(); + outStream.close(); + } + rs.close(); + st.close(); + + //response.getOutputStream(); + //response.flushBuffer(); + + } catch (IOException ex) { + result+="
SQLException:"+ex.getMessage()+"
"; + } + } + } + rsC.close(); + stC.close(); + conn.close(); + + } catch (SQLException ex) { + // TODO Auto-generated catch block + result+="
SQLException:"+ex.getMessage()+"
"; + } + + + + } + + return result; + } + +} diff --git a/src/main/java/kz/locust/CCALM/Integration.java b/src/main/java/kz/locust/CCALM/Integration.java new file mode 100644 index 0000000..287e915 --- /dev/null +++ b/src/main/java/kz/locust/CCALM/Integration.java @@ -0,0 +1,774 @@ +package kz.locust.CCALM; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.json.JSONArray; +import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.context.ServletContextAware; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import java.util.Base64; +import java.nio.file.Files; +import tctable.Tools; + +@Controller +public class Integration implements ServletContextAware { + + private static final int BUFFER_SIZE = 4096; + + private static final Logger logger = LoggerFactory.getLogger(Integration.class); + private ServletContext context; + + @RequestMapping(value = "/integration/getByTime", method = RequestMethod.GET,produces = "application/json; charset=utf-8") + @ResponseBody + public Object getByTime(HttpServletResponse response,@RequestParam(required=true,name="token") String token,@RequestParam(required=true,name="timeBegin") String timeBegin,@RequestParam(required=false,name="timeEnd") String timeEnd,@RequestParam(required=false,name="type") String type) + { + if(type!=null && type.equals("del")) + return getDataDel(token,timeBegin,timeEnd,null,null); + else + return getData(token,timeBegin,timeEnd,null,null); + } + + @RequestMapping(value = "/integration/getByDate", method = RequestMethod.GET,produces = "application/json; charset=utf-8") + @ResponseBody + public Object getByDate(HttpServletResponse response,@RequestParam(required=true,name="token") String token,@RequestParam(required=true,name="dateBegin") String dateBegin,@RequestParam(required=false,name="dateEnd") String dateEnd,@RequestParam(required=false,name="type") String type) + { + if(type!=null && type.equals("del")) + return getDataDel(token,null,null,dateBegin,dateEnd); + else + return getData(token,null,null,dateBegin,dateEnd); + } + + //Prepare data for sending to integration servers. + String getData(String token, String timeBegin,String timeEnd,String dateBegin,String dateEnd) { + + int errorCode=0; + String errorCodeDescription=""; + if(!( + token.equals("DA46DCA8E49D52A12614D4FE4CF4") + || token.equals("R5375VJERFJKFTGKT8235QFSJHDE") + || token.equals("QIWGHIEEEEEE732RUEWHDHREU92Z") + || token.equals("BA46DCA8E49D52A12614D4FE4CF5") //Kazahstan + )) { //Access only for Russians + JSONObject obj = new JSONObject(); + obj.put("errorCode",1); + obj.put("errorCodeDescription", "Token is not correct!"); + return obj.toString(); + } + + String db_url=""; + String db_login=""; + String db_password=""; + //Load DB configuration from "config.xml" + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain=doc.getDocumentElement(); + NodeList nl=nMain.getChildNodes(); + for (int i = 0; i \n" + + "\n" + + " \n" + + " https://ccalm.org\n" + + " \n" + + "\n"); + } catch (IOException e) { + logger.info(e.getMessage()); + } + } + + /** + * Testing new main index page + */ + @RequestMapping(value = "/", method = RequestMethod.GET) + public String home2(@ModelAttribute User user, Model model,@RequestParam(required=false,name="lng") String language_id) { + //logger.info("Welcome home! The client locale is {}.", locale); + + if(language_id!=null && !language_id.equals("")) user.language_id=language_id; + logger.info("user.id="+user.id+" user.name="+user.name+" user.language_id="+user.language_id); + + String db_url=""; + String db_login=""; + String db_password=""; + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain=doc.getDocumentElement(); + NodeList nl=nMain.getChildNodes(); + for (int i = 0; i Connect is ERROR
"); + } + }catch(Exception e) + { + System.out.println("
Connect Exception:"+e.getMessage()+"
"); + } + + try { + Statement st = conn.createStatement(); + ResultSet rs=null; + if(user.id!=null){ + + if(language_id!=null && !language_id.equals("")) + { + //Set the language for the current user if it is transferred. + user.language_id=language_id; + try { + st.execute("update main._users set language_id='"+user.language_id+"' where id="+user.id); + } catch( SQLException ex ) + { + System.out.println("
SQLException:"+ex.getMessage()+"
"); + } + } + + //Select language for current user + try { + String sql="select language_id,country_id from main._users u where u.id="+String.valueOf(user.id)+";"; + rs = st.executeQuery(sql); + } catch( SQLException ex ) + { + System.out.println("
SQLException:"+ex.getMessage()+"
"); + } + + if(rs!=null) + { + while (rs.next()) + { + user.language_id = rs.getString("language_id"); + user.country_id = rs.getString("country_id"); + } + } + } + st.close(); + } catch( SQLException ex ) + { + System.out.println("
SQLException:"+ex.getMessage()+"
"); + } + + //Send user name and role + model.addAttribute("uName",user.name+" ("+user.role+")"); + model.addAttribute("m_locale",user.language_id); + model.addAttribute("country_id",user.country_id); + + //Для перевода выбираю всё что под номером 1 в переводе + try { + m_props = new Properties(); + Statement stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + String sql_query = "select identifier,case when '"+user.language_id+"'='666' then translation||'''\"' else translation end as translation from main._translations t where t.del=false and (t.language_id='"+user.language_id+"' or ('"+user.language_id+"'='666' and t.language_id=1)) and translation_type_id=1;"; + ResultSet rs = stt.executeQuery(sql_query); + if (rs != null) { + while (rs.next()) + { + String identifier = rs.getString("identifier"); + String translation = rs.getString("translation"); + m_props.setProperty(identifier, translation); + } + rs.close(); + } + stt.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + Set keys = m_props.keySet(); + for(Object k:keys){ + String key = (String)k; + String val=""; + if(val.equals("")) + { + val = m_props.getProperty(key,""); + if(val.equals("")) + { + val = val.replaceAll("_", " "); + } + } + model.addAttribute(key,val); + } + + + try{ conn.close(); }catch(Exception e){} + + return "index"; + //return "test"; + } + + //Returns data for building a map on the first index page + @RequestMapping(value = "/dataindex",method = {RequestMethod.POST,RequestMethod.GET},produces = "application/json; charset=utf-8") + @ResponseBody + public Object ajaxIndexData(HttpServletResponse response,@ModelAttribute User user,@RequestParam(required=false,name="date_start",defaultValue = "null") String date_start,@RequestParam(required=false,name="date_end",defaultValue = "null") String date_end, @RequestParam(required=false,name="lng") String language_id) { + String headerValue = CacheControl.maxAge(60, TimeUnit.SECONDS).getHeaderValue(); + response.addHeader("Cache-Control", headerValue); + + JSONObject result = new JSONObject(); + JSONArray array=new JSONArray(); + + String db_url=""; + String db_login=""; + String db_password=""; + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain=doc.getDocumentElement(); + NodeList nl=nMain.getChildNodes(); + for (int i = 0; i Connect is ERROR
"); + } + }catch(Exception e) + { + System.out.println("
Connect Exception:"+e.getMessage()+"
"); + } + + String sql; + sql = "select * from main.p_dataindex(to_timestamp("+date_start+")::timestamp without time zone,to_timestamp("+date_end+")::timestamp without time zone);"; + ResultSet rs = null; + try { + Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + rs = stmt.executeQuery(sql); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + ex.printStackTrace(); + } + + try { + while (rs.next()) { + JSONObject rsRez = new JSONObject(); + rsRez.put("id",rs.getInt("id")); + rsRez.put("lon",rs.getDouble("lon")); + rsRez.put("lat",rs.getDouble("lat")); + rsRez.put("type",rs.getInt("type")); + rsRez.put("terrain",rs.getString("terrain")); + array.put(rsRez); + } + } catch (SQLException ex) { + logger.info(ex.getMessage()); + ex.printStackTrace(); + } + result.put("ErrorCode", "0"); + result.put("ErrorMessage", ""); + + result.put("data", array); + + if(conn!=null) + { + try { + conn.close(); + } catch (SQLException e) { + } + } + + return result.toString(); + } + + +} diff --git a/src/main/java/kz/locust/CCALM/Products.java b/src/main/java/kz/locust/CCALM/Products.java new file mode 100644 index 0000000..216093a --- /dev/null +++ b/src/main/java/kz/locust/CCALM/Products.java @@ -0,0 +1,697 @@ +package kz.locust.CCALM; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.FileSystemResource; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.SessionAttributes; +import org.springframework.web.context.ServletContextAware; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import org.json.JSONObject; +import org.json.JSONArray; +import org.json.JSONException; + +import tools.PreparedStatementNamed; +import tools.User; + +@Controller +@SessionAttributes( { "user" }) //Сесионный объект +public class Products implements ServletContextAware { + + private static final Logger logger = LoggerFactory.getLogger(Products.class); + private ServletContext context; + + //If not created object "user", create him. + @ModelAttribute("user") + public User populatePerson() { + return new User("none"); + } + + @RequestMapping(value = "/get_survey",method = RequestMethod.POST, produces = "application/json;charset=UTF-8") + @ResponseBody + public String getLocustSurvey(@ModelAttribute User user,@RequestBody(required=false) byte[] reqData,@RequestParam(required=false,name="lng") String language_id) { + + int errorCode=0; + String errorMessage=""; + + //Load configuration from "config.xml" + String db_url = ""; + String db_login = ""; + String db_password = ""; + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("db-url")) + db_url = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-login")) + db_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-password")) + db_password = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + errorCode=1; + errorMessage+="Internal server error, settings."; + logger.info(ex.getMessage()); + } + + Connection conn = null; + try { + Class.forName("org.postgresql.Driver"); + conn = DriverManager.getConnection(db_url, db_login, db_password); + if (conn != null) { + logger.info("Connect is OK!"); + } else { + errorCode=1; + errorMessage+="An error occurred while connecting to the database!"; + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + errorCode=1; + errorMessage+="An error occurred while connecting to the database!"; + } + + try { + Statement stt0 = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + //st.executeUpdate("SET TIME ZONE 'UTC';"); зачем коментил? + stt0.executeUpdate("SET TIME ZONE 'Asia/Almaty';"); //Зачем раскоментил? может в начале поставить ещё TimeZone.setDefault(TimeZone.getTimeZone("UTC")); ? + stt0.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + errorCode=1; + errorMessage+="Failed to execute SQL query!"; + } + + JSONObject doc=null; + InputStream body; + if(reqData!=null) { + + + body = new ByteArrayInputStream(reqData); + + String text=""; + try { + text = new String(body.readAllBytes(), StandardCharsets.UTF_8); + } catch (IOException e) { + e.printStackTrace(); + } + logger.info(text); + + //JSONParser jsonParser = new JSONParser(); + //doc = (JSONObject)jsonParser.parse(text); + //doc = new JSONObject(body); + doc = new JSONObject(text); + } + + JSONArray array=new JSONArray(); //Результирующий набор данных + + String sql_query = ""; + Statement stt=null; + ResultSet rs=null; + try { + stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + sql_query = "select id," + + " lat1," + + " lon1," + + " lat2," + + " lon2," + + " lat3," + + " lon3," + + " lat4," + + " lon4," + + " lat5," + + " lon5," + + " lat6," + + " lon6," + + " terrain," + + " locust_populated," + + " eggs_capsules_density," + + " eggs_capsules_density_to," + + " imago_density," + + " larva_density," + + " larva_density_to," + + " kuliguli_size," + + " CASE swarm_maturity WHEN true THEN 1 WHEN false THEN 0 ELSE null END as swarm_maturity," + + " swarm_density_id," + + " ST_AsGeoJSON(geom) as geom" + + " from main.frmlocust fl where" + + " fl.del=false" + + " and (${country_id} is null or (${country_id}=-1 and fl.country_id in (7,3,4,2)) or (${country_id}=-2 and fl.country_id in (7,1,5,6,8,9,10)) or ${country_id}=fl.country_id)" + + " and (${region_id} is null or ${region_id}=fl.region_id)" + + " and (${locust_type_id} is null or ${locust_type_id}=fl.locust_type_id)" + + " and (${date_start} is null or to_timestamp(${date_start})<=fl.date)" + + " and (${date_end} is null or to_timestamp(${date_end})>=fl.date)" + + " and (${device_id} is null or (${device_id} and fl.device_id is not null) or (not ${device_id} and fl.device_id is null))" + + " and (${registered} is null or (${registered} and (fl.device_id is null or fl.device_id in (select serial from main.terminals where del=false))) or (not ${registered} and (fl.device_id not in (select serial from main.terminals where del=false))))" + + " and ((${test} is null and (test!=true or test is null)) or ${test}=fl.test)" + + " order by fl.id desc;"; + + PreparedStatementNamed stmtn = new PreparedStatementNamed(conn, sql_query); + if(doc!=null) { + stmtn.setInt("_user_id", Integer.parseInt(user.id)); + + if(doc.isNull("country_id")) stmtn.setNULLInt("country_id"); + else stmtn.setInt("country_id",doc.getInt("country_id")); + + if(doc.isNull("region_id")) stmtn.setNULLInt("region_id"); + else stmtn.setInt("region_id",doc.getInt("region_id")); + + if(doc.isNull("locust_type_id")) stmtn.setNULLInt("locust_type_id"); + else stmtn.setInt("locust_type_id",doc.getInt("locust_type_id")); + + if(doc.isNull("date_start")) stmtn.setNULLInt("date_start"); + else stmtn.setInt("date_start",doc.getInt("date_start")); + + if(doc.isNull("date_end")) stmtn.setNULLInt("date_end"); + else stmtn.setInt("date_end",doc.getInt("date_end")); + + if(doc.isNull("device_id")) stmtn.setNULLBoolean("device_id"); + else stmtn.setBoolean("device_id",doc.getInt("device_id")); + + if(doc.isNull("registered")) stmtn.setNULLBoolean("registered"); + else stmtn.setBoolean("registered",doc.getInt("registered")); + + if(doc.isNull("test")) stmtn.setNULLBoolean("test"); + else stmtn.setBoolean("test",doc.getInt("test")); + } + PreparedStatement stmt=stmtn.getPreparedStatement(); + + rs = stmt.executeQuery(); + if (rs != null) { + try { + while(rs.next()) { + + JSONObject obj = new JSONObject(); + obj.put("id", rs.getLong("id")); + if(rs.getObject("terrain")!=null) + obj.put("terrain", rs.getString("terrain")); + if(rs.getObject("locust_populated")!=null) + obj.put("locust_populated", rs.getFloat("locust_populated")); + if(rs.getObject("eggs_capsules_density")!=null) + obj.put("eggs_capsules_density", rs.getFloat("eggs_capsules_density")); + if(rs.getObject("eggs_capsules_density_to")!=null) + obj.put("eggs_capsules_density_to", rs.getFloat("eggs_capsules_density_to")); + if(rs.getObject("imago_density")!=null) + obj.put("imago_density", rs.getFloat("imago_density")); + if(rs.getObject("larva_density")!=null) + obj.put("larva_density", rs.getFloat("larva_density")); + if(rs.getObject("larva_density_to")!=null) + obj.put("larva_density_to", rs.getFloat("larva_density_to")); + if(rs.getObject("kuliguli_size")!=null) + obj.put("kuliguli_size", rs.getFloat("kuliguli_size")); + if(rs.getObject("swarm_maturity")!=null) + obj.put("swarm_maturity", rs.getString("swarm_maturity")); + if(rs.getObject("swarm_density_id")!=null) + obj.put("swarm_density_id", rs.getInt("swarm_density_id")); + + //obj.put("town_name", rs.getString("town_name")); //Район + //obj.put("date", rs.getString("date")); //Дата анкетирования + //obj.put("surveyed_area", rs.getDouble("surveyed_area")); //Обследованная площадь га + + + double lat=0; + double lon=0; + int cnt1=0; + if(rs.getString("lat1")!=null && rs.getString("lon1")!=null && rs.getFloat("lat1")!=0 && rs.getFloat("lon1")!=0) { + lat+=rs.getDouble("lat1"); + lon+=rs.getDouble("lon1"); + cnt1++; + } + if(rs.getString("lat2")!=null && rs.getString("lon2")!=null && rs.getFloat("lat2")!=0 && rs.getFloat("lon2")!=0) { + lat+=rs.getDouble("lat2"); + lon+=rs.getDouble("lon2"); + cnt1++; + } + if(rs.getString("lat3")!=null && rs.getString("lon3")!=null && rs.getFloat("lat3")!=0 && rs.getFloat("lon3")!=0) { + lat+=rs.getDouble("lat3"); + lon+=rs.getDouble("lon3"); + cnt1++; + } + if(rs.getString("lat4")!=null && rs.getString("lon4")!=null && rs.getFloat("lat4")!=0 && rs.getFloat("lon4")!=0) { + lat+=rs.getDouble("lat4"); + lon+=rs.getDouble("lon4"); + cnt1++; + } + if(rs.getString("lat5")!=null && rs.getString("lon5")!=null && rs.getFloat("lat5")!=0 && rs.getFloat("lon5")!=0) { + lat+=rs.getDouble("lat5"); + lon+=rs.getDouble("lon5"); + cnt1++; + } + if(rs.getString("lat6")!=null && rs.getString("lon6")!=null && rs.getFloat("lat6")!=0 && rs.getFloat("lon6")!=0) { + lat+=rs.getDouble("lat6"); + lon+=rs.getDouble("lon6"); + cnt1++; + } + if(cnt1>0) { + lat=lat/cnt1; + lon=lon/cnt1; + } + obj.put("lat", lat); + obj.put("lon", lon); + boolean point=cnt1<=2; + + JSONObject geom = null; + if(rs.getString("geom")!=null) + { + try { + geom = new JSONObject(rs.getString("geom")); + }catch (JSONException err){ + + } + }else { + if(point) { + /*geom = new JSONObject(); + geom.put("type","Point"); + JSONArray crdSub=new JSONArray(); + crdSub.put(rs.getDouble("lon1")); + crdSub.put(rs.getDouble("lat1")); + geom.put("coordinates", crdSub);*/ + }else { + geom = new JSONObject(); + geom.put("type","Polygon"); + JSONArray crdMain=new JSONArray(); + JSONArray crdSub=new JSONArray(); + crdMain.put(crdSub); + + if(rs.getString("lat1")!=null && rs.getString("lon1")!=null && rs.getFloat("lat1")!=0 && rs.getFloat("lon1")!=0) { + JSONArray crd=new JSONArray(); + crd.put(rs.getDouble("lon1")); + crd.put(rs.getDouble("lat1")); + crdSub.put(crd); + } + if(rs.getString("lat2")!=null && rs.getString("lon2")!=null && rs.getFloat("lat2")!=0 && rs.getFloat("lon2")!=0) { + JSONArray crd=new JSONArray(); + crd.put(rs.getDouble("lon2")); + crd.put(rs.getDouble("lat2")); + crdSub.put(crd); + } + if(rs.getString("lat3")!=null && rs.getString("lon3")!=null && rs.getFloat("lat3")!=0 && rs.getFloat("lon3")!=0) { + JSONArray crd=new JSONArray(); + crd.put(rs.getDouble("lon3")); + crd.put(rs.getDouble("lat3")); + crdSub.put(crd); + } + if(rs.getString("lat4")!=null && rs.getString("lon4")!=null && rs.getFloat("lat4")!=0 && rs.getFloat("lon4")!=0) { + JSONArray crd=new JSONArray(); + crd.put(rs.getDouble("lon4")); + crd.put(rs.getDouble("lat4")); + crdSub.put(crd); + } + if(rs.getString("lat5")!=null && rs.getString("lon5")!=null && rs.getFloat("lat5")!=0 && rs.getFloat("lon5")!=0) { + JSONArray crd=new JSONArray(); + crd.put(rs.getDouble("lon5")); + crd.put(rs.getDouble("lat5")); + crdSub.put(crd); + } + if(rs.getString("lat6")!=null && rs.getString("lon6")!=null && rs.getFloat("lat6")!=0 && rs.getFloat("lon6")!=0) { + JSONArray crd=new JSONArray(); + crd.put(rs.getDouble("lon6")); + crd.put(rs.getDouble("lat6")); + crdSub.put(crd); + } + geom.put("coordinates", crdMain); + } + } + + if(geom!=null) + obj.put("geom", geom); + + array.put(obj); + } + rs.close(); + } catch (SQLException ex) { + errorCode=4; + errorMessage+="Internal server error, sampling."; + ex.printStackTrace(); + logger.info(ex.getMessage()); + } + } + } catch (SQLException ex) { + errorCode=5; + errorMessage+="Внутренняя ошибка сервера, запрос. "; + ex.printStackTrace(); + logger.info(ex.getMessage()); + }finally { + if(rs!=null) try{rs.close();}catch(SQLException ex){} + if(stt!=null) try{stt.close();}catch(SQLException ex){} + } + + + if(errorCode!=0) { + JSONObject obj = new JSONObject(); + obj.put("errorCode",errorCode); + obj.put("errorMessage", errorMessage); + return obj.toString(); + }else { + JSONObject obj = new JSONObject(); + obj.put("errorCode",0); + obj.put("errorMessage", ""); + if(doc!=null) + obj.put("indicator",doc.getString("indicator")); + obj.put("data",array); + return obj.toString(); + } + + } + + @RequestMapping(value = "/get_spray",method = RequestMethod.POST, produces = "application/json;charset=UTF-8") + @ResponseBody + public String getSprayMonitoring(@ModelAttribute User user,@RequestBody byte[] reqData,@RequestParam(required=false,name="lng") String language_id) { + + int errorCode=0; + String errorMessage=""; + + //Load configuration from "config.xml" + String db_url = ""; + String db_login = ""; + String db_password = ""; + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("db-url")) + db_url = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-login")) + db_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-password")) + db_password = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + errorCode=1; + errorMessage+="Internal server error, settings."; + logger.info(ex.getMessage()); + } + + Connection conn = null; + try { + Class.forName("org.postgresql.Driver"); + conn = DriverManager.getConnection(db_url, db_login, db_password); + if (conn != null) { + logger.info("Connect is OK!"); + } else { + errorCode=1; + errorMessage+="An error occurred while connecting to the database!"; + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + errorCode=1; + errorMessage+="An error occurred while connecting to the database!"; + } + + try { + Statement stt0 = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + //st.executeUpdate("SET TIME ZONE 'UTC';"); зачем коментил? + stt0.executeUpdate("SET TIME ZONE 'Asia/Almaty';"); + stt0.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + errorCode=1; + errorMessage+="Failed to execute SQL query!"; + } + + JSONObject doc=null; + InputStream body; + if(reqData!=null) { + + + body = new ByteArrayInputStream(reqData); + + String text=""; + try { + text = new String(body.readAllBytes(), StandardCharsets.UTF_8); + } catch (IOException e) { + e.printStackTrace(); + } + logger.info(text); + + //JSONParser jsonParser = new JSONParser(); + //doc = (JSONObject)jsonParser.parse(text); + //doc = new JSONObject(body); + doc = new JSONObject(text); + } + + JSONArray array=new JSONArray(); //Результирующий набор данных + + String sql_query = ""; + Statement stt=null; + ResultSet rs=null; + try { + stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + sql_query = "select id," + + " lat_center," + + " lon_center," + + " lat1," + + " lon1," + + " lat2," + + " lon2," + + " lat3," + + " lon3," + + " lat4," + + " lon4," + + " lat5," + + " lon5," + + " lat6," + + " lon6," + + " terrain," + + " treated_area," + + " infested_area," + + " ST_AsGeoJSON(geom) as geom" + + " from main.frmlocustdel fld where" + + " fld.del=false" + + " and (${country_id} is null or (${country_id}=-1 and fld.country_id in (7,3,4,2)) or (${country_id}=-2 and fld.country_id in (7,1,5,6,8,9,10)) or ${country_id}=fld.country_id)" + + " and (${region_id} is null or ${region_id}=fld.region_id)" + + " and (${date_start} is null or to_timestamp(${date_start})<=fld.date)" + + " and (${date_end} is null or to_timestamp(${date_end})>=fld.date)" + + " and (${device_id} is null or (${device_id} and fld.device_id is not null) or (not ${device_id} and fld.device_id is null))" + + " and (${registered} is null or (${registered} and (fld.device_id is null or fld.device_id in (select serial from main.terminals where del=false))) or (not ${registered} and (fld.device_id not in (select serial from main.terminals where del=false))))" + + " and ((${test} is null and (test!=true or test is null)) or ${test}=fld.test)" + + " order by fld.id desc;"; + + PreparedStatementNamed stmtn = new PreparedStatementNamed(conn, sql_query); + if(doc!=null) { + stmtn.setInt("_user_id", Integer.parseInt(user.id)); + + if(doc.isNull("country_id")) stmtn.setNULLInt("country_id"); + else stmtn.setInt("country_id",doc.getInt("country_id")); + + if(doc.isNull("region_id")) stmtn.setNULLInt("region_id"); + else stmtn.setInt("region_id",doc.getInt("region_id")); + + if(doc.isNull("locust_type_id")) stmtn.setNULLInt("locust_type_id"); + else stmtn.setInt("locust_type_id",doc.getInt("locust_type_id")); + + if(doc.isNull("date_start")) stmtn.setNULLInt("date_start"); + else stmtn.setInt("date_start",doc.getInt("date_start")); + + if(doc.isNull("date_end")) stmtn.setNULLInt("date_end"); + else stmtn.setInt("date_end",doc.getInt("date_end")); + + if(doc.isNull("device_id")) stmtn.setNULLBoolean("device_id"); + else stmtn.setBoolean("device_id",doc.getInt("device_id")); + + if(doc.isNull("registered")) stmtn.setNULLBoolean("registered"); + else stmtn.setBoolean("registered",doc.getInt("registered")); + + if(doc.isNull("test")) stmtn.setNULLBoolean("test"); + else stmtn.setBoolean("test",doc.getInt("test")); + } + PreparedStatement stmt=stmtn.getPreparedStatement(); + + rs = stmt.executeQuery(); + if (rs != null) { + try { + while(rs.next()) { + + JSONObject obj = new JSONObject(); + obj.put("id", rs.getLong("id")); + if(rs.getObject("terrain")!=null) + obj.put("terrain", rs.getString("terrain")); + if(rs.getObject("treated_area")!=null) + obj.put("treated_area", rs.getFloat("treated_area")); + if(rs.getObject("infested_area")!=null) + obj.put("infested_area", rs.getFloat("infested_area")); + + double lat=0; + double lon=0; + int cnt1=0; + if(rs.getString("lat1")!=null && rs.getString("lon1")!=null && rs.getFloat("lat1")!=0 && rs.getFloat("lon1")!=0) { + lat+=rs.getDouble("lat1"); + lon+=rs.getDouble("lon1"); + cnt1++; + } + if(rs.getString("lat2")!=null && rs.getString("lon2")!=null && rs.getFloat("lat2")!=0 && rs.getFloat("lon2")!=0) { + lat+=rs.getDouble("lat2"); + lon+=rs.getDouble("lon2"); + cnt1++; + } + if(rs.getString("lat3")!=null && rs.getString("lon3")!=null && rs.getFloat("lat3")!=0 && rs.getFloat("lon3")!=0) { + lat+=rs.getDouble("lat3"); + lon+=rs.getDouble("lon3"); + cnt1++; + } + if(rs.getString("lat4")!=null && rs.getString("lon4")!=null && rs.getFloat("lat4")!=0 && rs.getFloat("lon4")!=0) { + lat+=rs.getDouble("lat4"); + lon+=rs.getDouble("lon4"); + cnt1++; + } + if(rs.getString("lat5")!=null && rs.getString("lon5")!=null && rs.getFloat("lat5")!=0 && rs.getFloat("lon5")!=0) { + lat+=rs.getDouble("lat5"); + lon+=rs.getDouble("lon5"); + cnt1++; + } + if(rs.getString("lat6")!=null && rs.getString("lon6")!=null && rs.getFloat("lat6")!=0 && rs.getFloat("lon6")!=0) { + lat+=rs.getDouble("lat6"); + lon+=rs.getDouble("lon6"); + cnt1++; + } + //lat=lat/cnt1; + //lon=lon/cnt1; + lat=rs.getDouble("lat_center"); + lon=rs.getDouble("lon_center"); + obj.put("lat", lat); + obj.put("lon", lon); + boolean point=cnt1<=2; + + JSONObject geom = null; + + if(rs.getString("geom")!=null) + { + try { + geom = new JSONObject(rs.getString("geom")); + }catch (JSONException err){ + + } + }else { + if(point) { + /*geom = new JSONObject(); + geom.put("type","Point"); + JSONArray crdSub=new JSONArray(); + crdSub.put(rs.getDouble("lon1")); + crdSub.put(rs.getDouble("lat1")); + geom.put("coordinates", crdSub);*/ + }else { + geom = new JSONObject(); + geom.put("type","Polygon"); + JSONArray crdMain=new JSONArray(); + JSONArray crdSub=new JSONArray(); + crdMain.put(crdSub); + + if(rs.getString("lat1")!=null && rs.getString("lon1")!=null && rs.getFloat("lat1")!=0 && rs.getFloat("lon1")!=0) { + JSONArray crd=new JSONArray(); + crd.put(rs.getDouble("lon1")); + crd.put(rs.getDouble("lat1")); + crdSub.put(crd); + } + if(rs.getString("lat2")!=null && rs.getString("lon2")!=null && rs.getFloat("lat2")!=0 && rs.getFloat("lon2")!=0) { + JSONArray crd=new JSONArray(); + crd.put(rs.getDouble("lon2")); + crd.put(rs.getDouble("lat2")); + crdSub.put(crd); + } + if(rs.getString("lat3")!=null && rs.getString("lon3")!=null && rs.getFloat("lat3")!=0 && rs.getFloat("lon3")!=0) { + JSONArray crd=new JSONArray(); + crd.put(rs.getDouble("lon3")); + crd.put(rs.getDouble("lat3")); + crdSub.put(crd); + } + if(rs.getString("lat4")!=null && rs.getString("lon4")!=null && rs.getFloat("lat4")!=0 && rs.getFloat("lon4")!=0) { + JSONArray crd=new JSONArray(); + crd.put(rs.getDouble("lon4")); + crd.put(rs.getDouble("lat4")); + crdSub.put(crd); + } + if(rs.getString("lat5")!=null && rs.getString("lon5")!=null && rs.getFloat("lat5")!=0 && rs.getFloat("lon5")!=0) { + JSONArray crd=new JSONArray(); + crd.put(rs.getDouble("lon5")); + crd.put(rs.getDouble("lat5")); + crdSub.put(crd); + } + if(rs.getString("lat6")!=null && rs.getString("lon6")!=null && rs.getFloat("lat6")!=0 && rs.getFloat("lon6")!=0) { + JSONArray crd=new JSONArray(); + crd.put(rs.getDouble("lon6")); + crd.put(rs.getDouble("lat6")); + crdSub.put(crd); + } + geom.put("coordinates", crdMain); + } + } + if(geom!=null) + obj.put("geom", geom); + + array.put(obj); + } + rs.close(); + } catch (SQLException ex) { + errorCode=4; + errorMessage+="Internal server error, sampling."; + ex.printStackTrace(); + logger.info(ex.getMessage()); + } + } + } catch (SQLException ex) { + errorCode=5; + errorMessage+="Внутренняя ошибка сервера, запрос. "; + ex.printStackTrace(); + logger.info(ex.getMessage()); + }finally { + if(rs!=null) try{rs.close();}catch(SQLException ex){} + if(stt!=null) try{stt.close();}catch(SQLException ex){} + } + + + if(errorCode!=0) { + JSONObject obj = new JSONObject(); + obj.put("errorCode",errorCode); + obj.put("errorMessage", errorMessage); + return obj.toString(); + }else { + JSONObject obj = new JSONObject(); + obj.put("errorCode",0); + obj.put("errorMessage", ""); + obj.put("data",array); + return obj.toString(); + } + } + + @Override + public void setServletContext(ServletContext servletContext) { + this.context=servletContext; + } + + +} diff --git a/src/main/java/kz/locust/CCALM/QGIS.java b/src/main/java/kz/locust/CCALM/QGIS.java new file mode 100644 index 0000000..9ec14e9 --- /dev/null +++ b/src/main/java/kz/locust/CCALM/QGIS.java @@ -0,0 +1,498 @@ +package kz.locust.CCALM; + + + + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.MediaType; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.SessionAttributes; +import org.springframework.web.context.ServletContextAware; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import tctable.Tools; +import tools.User; + +@Controller +@SessionAttributes( { "user" }) +public class QGIS implements ServletContextAware { + + private static final Logger logger = LoggerFactory.getLogger(QGIS.class); + private ServletContext context; + private Properties m_props=null; + private String m_props_loc=""; + public String m_locale="ru"; + + //If not created object "user", create him. + @ModelAttribute("user") + public User populatePerson() { + return new User("none"); + } + + @RequestMapping(value = "/QGIS",method = RequestMethod.GET,produces = "application/octet-stream") + @ResponseBody + public HttpEntity ajaxTamer(@ModelAttribute User user,@RequestParam(required=false,name="day") String day,@RequestParam(required=false,name="name") String name,@RequestParam(required=false,name="time") String time,@RequestParam(required=false,name="time_start") String time_start,@RequestParam(required=false,name="time_end") String time_end,@RequestParam(required=false,name="country_id") String country_id,@RequestParam(required=false,name="locust_type_id") String locust_type_id,@RequestParam(required=false,name="date_start") String date_start,@RequestParam(required=false,name="date_end") String date_end,@RequestParam(required=false,name="registered") String registered,@RequestParam(required=false,name="year") String year,@RequestParam(required=false,name="region_id") String region_id,@RequestParam(required=false,name="country_name") String country_name,@RequestParam(required=false,name="lng") String language_id,HttpServletResponse response) + { + if(language_id!=null && !language_id.equals("")) user.language_id=language_id; + logger.info("user.id="+user.id+" user.name="+user.name+" user.language_id="+user.language_id); + m_locale=user.language_id; + + String db_url = ""; + String db_login = ""; + String db_password = ""; + //Load DB configuration from "config.xml" + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("db-url")) + db_url = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-login")) + db_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-password")) + db_password = nl.item(i).getTextContent(); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + + Connection conn = null; + try { + Class.forName("org.postgresql.Driver"); + conn = DriverManager.getConnection(db_url, db_login, db_password); + if (conn != null) { + logger.info("Connect is OK!"); + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + + + //Return content QGIS file. + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + response.setContentType("application/octet-stream"); + response.setHeader("Content-Disposition", "attachment; filename="+name+".qgs"); + + String fileAsString=""; + //Pods (кубышки) + if(name!=null && (name.equals("frmlocust_pods_density") || name.equals("frmlocust_hoppers_density") || name.equals("frmlocust_bands") || name.equals("frmlocust_adults_density") || name.equals("frmlocust_swarms"))) + { + fileAsString = fileToString(context.getRealPath("/resources/QGIS/" + name + ".qgs")); + + //String country_id=request.getParameter("country_id"); + //String locust_type_id=request.getParameter("locust_type_id"); + //String date_start=request.getParameter("date_start"); + //String date_end=request.getParameter("date_end"); + //String registered=request.getParameter("registered"); + + //Make SQL + String sql = "1=1"; + String sql2 = "1=1"; + if(country_id!=null && !country_id.equals("")) + { + if(country_id.equals("-1")) + { + sql+=" and country_id in (7,3,4,2)"; + sql2+=" and country_id in (7,3,4,2)"; + }else if(country_id.equals("-2")) + { + sql+=" and country_id in (7,1,5,6,8,9,10)"; + sql2+=" and country_id in (7,1,5,6,8,9,10)"; + }else + { + sql+=" and country_id="+country_id; + sql2+=" and country_id="+country_id; + } + } + if(locust_type_id!=null && !locust_type_id.equals("")) + { + sql+=" and locust_type_id="+locust_type_id; + } + if(date_start!=null && !date_start.equals("")) + { + sql+=" and date>='"+date_start+"'"; + } + if(date_end!=null && !date_end.equals("")) + { + sql+=" and date<='"+date_end+"'"; + } + + if(registered!=null && registered.equals("1")) + { + sql+=" and registered=true"; + }else + if(registered!=null && registered.equals("0")) + { + sql+=" and registered=false"; + } + + //Apply variables to text + fileAsString=fileAsString.replaceAll("\\$\\{sql\\}",sql); + + fileAsString=fileAsString.replaceAll("\\$\\{sql2\\}",sql2); + + } + + if(name!=null && name.equals("frmlocustdel")) + { + fileAsString = fileToString(context.getRealPath("/resources/QGIS/" + name + ".qgs")); + + //String country_id=request.getParameter("country_id"); + //String date_start=request.getParameter("date_start"); + //String date_end=request.getParameter("date_end"); + //String registered=request.getParameter("registered"); + + //Make SQL + String sql = "1=1"; + String sql2 = "1=1"; + if(country_id!=null && !country_id.equals("")) + { + //sql+=" and country_id="+country_id; + if(country_id.equals("-1")) + { + sql+=" and country_id in (7,3,4,2)"; + sql2+=" and country_id in (7,3,4,2)"; + }else if(country_id.equals("-2")) + { + sql+=" and country_id in (7,1,5,6,8,9,10)"; + sql2+=" and country_id in (7,1,5,6,8,9,10)"; + }else + { + sql+=" and country_id="+country_id; + sql2+=" and country_id="+country_id; + } + } + if(date_start!=null && !date_start.equals("")) + { + sql+=" and date>='"+date_start+"'"; + } + if(date_end!=null && !date_end.equals("")) + { + sql+=" and date<='"+date_end+"'"; + } + + if(registered!=null && registered.equals("1")) + { + sql+=" and registered=true"; + }else + if(registered!=null && registered.equals("0")) + { + sql+=" and registered=false"; + } + + //Apply variables to text + fileAsString=fileAsString.replaceAll("\\$\\{sql\\}",sql); + + fileAsString=fileAsString.replaceAll("\\$\\{sql2\\}",sql2); + } + + if(name!=null && (name.equals("frmlocustinfo_p2") || name.equals("frmlocustinfo_p3") || name.equals("frmlocustinfo_p4"))) + { + //String country_id=request.getParameter("country_id"); + //String year=request.getParameter("year"); + //String locust_type_id=request.getParameter("locust_type_id"); + + //Make SQL + String sql = "1=1"; + if(country_id!=null && !country_id.equals("")) + { + if(country_id.equals("-1")) + { + sql+=" and country_id in (7,3,4,2)"; + }else if(country_id.equals("-2")) + { + sql+=" and country_id in (7,1,5,6,8,9,10)"; + }else + { + sql+=" and country_id="+country_id; + } + } + if(locust_type_id!=null && !locust_type_id.equals("")) + { + sql+=" and locust_type_id="+locust_type_id; + } + + fileAsString = fileToString(context.getRealPath("/resources/QGIS/" + name + ".qgs")); + //Apply variables to text + fileAsString=fileAsString.replaceAll("\\$\\{year\\}",year); + fileAsString=fileAsString.replaceAll("\\$\\{sql\\}",sql); + } + + if(name!=null && (name.equals("frmlocustinfo_p2r") || name.equals("frmlocustinfo_p3r") || name.equals("frmlocustinfo_p4r"))) + { + //String region_id=request.getParameter("region_id"); + //String year=request.getParameter("year"); + //String locust_type_id=request.getParameter("locust_type_id"); + + //Make SQL + String sql = "1=1"; + if(region_id!=null && !region_id.equals("")) + { + sql+=" and region_id="+region_id; + } + if(locust_type_id!=null && !locust_type_id.equals("")) + { + sql+=" and locust_type_id="+locust_type_id; + } + + fileAsString = fileToString(context.getRealPath("/resources/QGIS/" + name + ".qgs")); + //Apply variables to text + fileAsString=fileAsString.replaceAll("\\$\\{year\\}",year); + fileAsString=fileAsString.replaceAll("\\$\\{sql\\}",sql); + } + if(name!=null && name.equals("soil_temperature")) + { + //Make SQL + String sql2 = "1=1"; + if(country_id!=null && !country_id.equals("")) + { + if(country_id.equals("-1")) + { + sql2+=" and country_id in (7,3,4,2)"; + }else if(country_id.equals("-2")) + { + sql2+=" and country_id in (7,1,5,6,8,9,10)"; + }else + { + sql2+=" and country_id="+country_id; + } + } + + fileAsString = fileToString(context.getRealPath("/resources/QGIS/" + name + ".qgs")); + //Apply variables to text + fileAsString=fileAsString.replaceAll("\\$\\{country\\}",country_name); + fileAsString=fileAsString.replaceAll("\\$\\{sql2\\}",sql2); + fileAsString=fileAsString.replaceAll("\\$\\{time\\}",time); + } + if(name!=null && name.equals("air_temperature")) + { + //Make SQL + String sql2 = "1=1"; + if(country_id!=null && !country_id.equals("")) + { + if(country_id.equals("-1")) + { + sql2+=" and country_id in (7,3,4,2)"; + }else if(country_id.equals("-2")) + { + sql2+=" and country_id in (7,1,5,6,8,9,10)"; + }else + { + sql2+=" and country_id="+country_id; + } + } + + fileAsString = fileToString(context.getRealPath("/resources/QGIS/" + name + ".qgs")); + //Apply variables to text + fileAsString=fileAsString.replaceAll("\\$\\{country\\}",country_name); + fileAsString=fileAsString.replaceAll("\\$\\{sql2\\}",sql2); + fileAsString=fileAsString.replaceAll("\\$\\{time\\}",time); + } + if(name!=null && name.equals("precipitation")) + { + //Make SQL + String sql2 = "1=1"; + if(country_id!=null && !country_id.equals("")) + { + if(country_id.equals("-1")) + { + sql2+=" and country_id in (7,3,4,2)"; + }else if(country_id.equals("-2")) + { + sql2+=" and country_id in (7,1,5,6,8,9,10)"; + }else + { + sql2+=" and country_id="+country_id; + } + } + + fileAsString = fileToString(context.getRealPath("/resources/QGIS/" + name + ".qgs")); + //Apply variables to text + fileAsString=fileAsString.replaceAll("\\$\\{country\\}",country_name); + fileAsString=fileAsString.replaceAll("\\$\\{sql2\\}",sql2); + fileAsString=fileAsString.replaceAll("\\$\\{time\\}",time); + } + if(name!=null && name.equals("htc_selyaninov")) + { + //Make SQL + String sql2 = "1=1"; + if(country_id!=null && !country_id.equals("")) + { + if(country_id.equals("-1")) + { + sql2+=" and country_id in (7,3,4,2)"; + }else if(country_id.equals("-2")) + { + sql2+=" and country_id in (7,1,5,6,8,9,10)"; + }else + { + sql2+=" and country_id="+country_id; + } + } + + fileAsString = fileToString(context.getRealPath("/resources/QGIS/" + name + ".qgs")); + //Apply variables to text + fileAsString=fileAsString.replaceAll("\\$\\{country\\}",country_name); + fileAsString=fileAsString.replaceAll("\\$\\{sql2\\}",sql2); + fileAsString=fileAsString.replaceAll("\\$\\{time_start\\}",time_start); + fileAsString=fileAsString.replaceAll("\\$\\{time_end\\}",time_end); + } + if(name!=null && name.equals("NDVI")) + { + fileAsString = fileToString(context.getRealPath("/resources/QGIS/NDVI.qgs")); + if(day!=null && day.length()>0) + fileAsString = fileAsString.replaceAll("\\$\\{day\\}",day+"_"); + else + fileAsString = fileAsString.replaceAll("\\$\\{day\\}",""); + } + if(name!=null && name.equals("NDWI")) + { + fileAsString = fileToString(context.getRealPath("/resources/QGIS/NDWI.qgs")); + if(day!=null && day.length()>0) + fileAsString = fileAsString.replaceAll("\\$\\{day\\}",day+"_"); + else + fileAsString = fileAsString.replaceAll("\\$\\{day\\}",""); + } + if(name!=null && name.equals("IVI")) + { + fileAsString = fileToString(context.getRealPath("/resources/QGIS/IVI.qgs")); + if(year!=null && year.length()>0) + fileAsString = fileAsString.replaceAll("\\$\\{year\\}",year+"_"); + else + fileAsString = fileAsString.replaceAll("\\$\\{year\\}",""); + } + if(name!=null && name.equals("NDWI_CMP")) + { + fileAsString = fileToString(context.getRealPath("/resources/QGIS/NDWI_CMP.qgs")); + if(day!=null && day.length()>0) + fileAsString = fileAsString.replaceAll("\\$\\{day\\}",day+"_"); + else + fileAsString = fileAsString.replaceAll("\\$\\{day\\}",""); + } + if(name!=null && name.equals("NDSI")) + { + fileAsString = fileToString(context.getRealPath("/resources/QGIS/NDSI.qgs")); + if(day!=null && day.length()>0) + fileAsString = fileAsString.replaceAll("\\$\\{day\\}",day+"_"); + else + fileAsString = fileAsString.replaceAll("\\$\\{day\\}",""); + } + if(name!=null && name.equals("SMAP")) + { + fileAsString = fileToString(context.getRealPath("/resources/QGIS/SMAP.qgs")); + if(day!=null && day.length()>0) + fileAsString = fileAsString.replaceAll("\\$\\{day\\}",day+"_"); + else + fileAsString = fileAsString.replaceAll("\\$\\{day\\}",""); + } + + //Send data + fileAsString=getText(conn,fileAsString,user); + return new HttpEntity(fileAsString.getBytes(), headers); + } + + @Override + public void setServletContext(ServletContext servletContext) { + this.context=servletContext; + } + + public String fileToString(String fName) + { + StringBuilder sb = new StringBuilder(); + try + { + InputStream is = new FileInputStream(fName); + BufferedReader buf = new BufferedReader(new InputStreamReader(is)); + String line = buf.readLine(); + while(line != null) + { + sb.append(line).append("\n"); + line = buf.readLine(); + } + buf.close(); + } + catch (Exception e){ + System.out.println("Error: "+e.getMessage()); + } + return sb.toString(); + } + + public String trt(Connection conn,String key,User user) + { + String result=""; + ResultSet rs=null; + Statement st = null; + try { + st = conn.createStatement(); + String sql = "select case when '"+user.language_id+"'='666' then translation||'''\"' else translation end as translation from main._translations t where t.identifier='"+key+"' and (t.language_id='"+user.language_id+"' or ('"+user.language_id+"'='666' and t.language_id=1));"; + rs = st.executeQuery(sql); + if(rs != null) { + if (rs.next()) { + result = rs.getString(1); + } + } + } catch( SQLException ex ) + { + logger.info(ex.getMessage()); + }finally{ + if(st!=null) try{st.close();}catch(SQLException ex) {} + if(rs!=null) try{rs.close();}catch(SQLException ex) {} + } + if(result.equals("")) + { + result = Tools.replaceAll(key,"_", " "); + } + return result; + } + + //Translate text by patterns + public String getText(Connection conn,String text,User user) { + int pos1 = 0; + while (true) { + pos1 = text.indexOf("trt('", pos1); + if (pos1 == -1) + break; + int pos2 = text.indexOf("')", pos1); + if (pos2 == -1) + break; + + text = text.substring(0, pos1) + trt(conn,text.substring(pos1 + 5, pos2),user) + text.substring(pos2 + 2); + } + return text; + } + +} diff --git a/src/main/java/kz/locust/CCALM/SendMail.java b/src/main/java/kz/locust/CCALM/SendMail.java new file mode 100644 index 0000000..97e5e7f --- /dev/null +++ b/src/main/java/kz/locust/CCALM/SendMail.java @@ -0,0 +1,500 @@ +package kz.locust.CCALM; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.Properties; +import java.util.Calendar; +import java.util.Date; +import java.util.HashMap; +import java.text.SimpleDateFormat; +import java.sql.*; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.DocumentBuilder; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import tools.EmailUtility; +import tools.User; + +import javax.servlet.ServletContext; + +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.SessionAttributes; +import org.springframework.web.context.ServletContextAware; + +@Controller +@SessionAttributes( { "user" }) //Сесионный объект +public class SendMail implements ServletContextAware { + + private static final org.slf4j.Logger logger = LoggerFactory.getLogger(SendMail.class); + + private ServletContext context; + private Connection m_conn = null; + private User m_user = null; + + //private Properties m_props=null; + public String m_locale="en"; + + //private HashMap m_props = new HashMap< String, Properties>(); + + //If not created object "user", create him. + @ModelAttribute("user") + public User populatePerson() { + return new User("none"); + } + + @RequestMapping(value = "/SendMail",method = RequestMethod.GET,produces = "text/html;charset=UTF-8") + @ResponseBody + public Object send(@ModelAttribute User user,@RequestParam(required=false,name="lng") String language_id) { + + m_user = user; + if(language_id!=null && !language_id.equals("")) + user.language_id=language_id; + logger.info("user.id="+user.id+" user.name="+user.name+" user.language_id="+user.language_id+" user.country_id="+user.country_id); + + String result=""; + + //Load DB configuration from "config.xml" + String db_url = ""; + String db_login = ""; + String db_password = ""; + String mail_host = ""; + String mail_port = ""; + String mail_login = ""; + String mail_password = ""; + //String data_dir = ""; + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("db-url")) + db_url = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-login")) + db_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-password")) + db_password = nl.item(i).getTextContent(); + //if (nl.item(i).getNodeName().equals("data-dir")) + // data_dir = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("mail-host")) + mail_host = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("mail-port")) + mail_port = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("mail-login")) + mail_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("mail-password")) + mail_password = nl.item(i).getTextContent(); + + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + + //Connect to database + try{ + Class.forName("org.postgresql.Driver"); + m_conn = DriverManager.getConnection(db_url,db_login,db_password); + if(m_conn!=null) + { + logger.info("Connect is OK!"); + result+="Connect is OK!
"; + }else + { + logger.info("
Connect is ERROR
"); + result+="Connect is ERROR!
"; + } + }catch(Exception e) + { + logger.info("
Connect Exception:"+e.getMessage()+"
"); + result+="Connect Exception:"+e.getMessage()+"
"; + } + + /*String string = "2016-07-05"; + DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + Date date = format.parse(string);*/ + + //int Day_s,Day_e; + //int Month_s,Month_e; + //int Year_s,Year_e; + + Calendar calendar_s = Calendar.getInstance(); + //calendar_s.setTime(date); + calendar_s.set(Calendar.DATE, 1); + calendar_s.add(Calendar.MONTH, -1); //минус месяц + + Calendar calendar_e = Calendar.getInstance(); + //calendar_e.setTime(date); + calendar_e.set(Calendar.DATE, 1); + + String start_t = String.valueOf(calendar_s.getTimeInMillis()/1000); + String end_t = String.valueOf(calendar_e.getTimeInMillis()/1000); + + //Формирую сообщение для каждой страны потом присваиваю пользователям из данной страны + String sql1="select c.id,c.name,u.email,l.short_name as language from main.countries c join main._users u on u.country_id=c.id join main._languages l on l.id=u.language_id where u.del=false and u.mailing=true order by c.name;"; + Statement st1; + ResultSet rs1=null; + try { + st1 = m_conn.createStatement(); + rs1 = st1.executeQuery(sql1); + } catch (SQLException ex) { + result+="
Exec Exception:"+ex.getMessage()+"
"; + } + + + if(rs1!=null) + { + try { + while (rs1.next()) //Пробегаюсь по странам и генерю сообщение + { + String html=""; + + String country_id=rs1.getString("id"); + String country_name=rs1.getString("name"); + m_locale=rs1.getString("language"); + String email = rs1.getString("email"); + + html="

"+country_name+"

"; + result+=html+m_locale; + + //Build HTML and send it to e-mail + String sql="" + +"select cr.name region_name,coalesce(t1.danger,0) danger,coalesce(t2.attention,0) attention,coalesce(t3.quietly,0) quietly from\n" + +" main.countriesregions cr\n" + +" left join (SELECT region_id,sum(1) as danger from main.frmlocust fl join main.terminals t on t.serial=fl.device_id where fl.del=false and t.del=false and (fl.date>to_timestamp("+start_t+") and fl.date 1 group by region_id) t1 on cr.id=t1.region_id\n" + +" left join (SELECT region_id,sum(1) as attention from main.frmlocust fl join main.terminals t on t.serial=fl.device_id where fl.del=false and t.del=false and (fl.date>to_timestamp("+start_t+") and fl.date 0 and COALESCE(fl.eggs_capsules_density, fl.eggs_capsules_density_to)::double precision + COALESCE(fl.eggs_capsules_density_to, fl.eggs_capsules_density)::double precision / 2::double precision <= 1 group by region_id) t2 on cr.id=t2.region_id\n" + +" left join (SELECT region_id,sum(1) as quietly from main.frmlocust fl join main.terminals t on t.serial=fl.device_id where fl.del=false and t.del=false and (fl.date>to_timestamp("+start_t+") and fl.dateExec Exception:"+ex.getMessage()+"
"; + } + + html+="

"+trt("Egg_pods_density")+"

"; + + //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + + html+=trt("From_date")+": "+sdf.format(new Date(Long.parseLong(start_t)*1000)); + html+="
"+trt("To_date")+": "+sdf.format(new Date(Long.parseLong(end_t)*1000)); + + html+=""; + html+=""; + + boolean exists=false; + if(rs!=null) + { + while (rs.next()) + { + html+=""; + html+=""; + html+=""; + html+=""; + html+=""; + html+=""; + + exists=true; + } + } + st.close(); + if(!exists) html+=""; + html+="
"+trt("Oblast")+"\"\""+trt("Number_forms")+" \""+trt("Danger")+"\"
("+trt("Egg_pods_density")+" > 1)
\"\""+trt("Number_forms")+" \""+trt("Attention")+"\"
("+trt("Egg_pods_density")+" <= 1)
\"\""+trt("Number_forms")+" \""+trt("Quietly")+"\"
("+trt("Egg_pods_density")+" = 0)
"+rs.getString("region_name")+""+rs.getString("danger")+""+rs.getString("attention")+""+rs.getString("quietly")+"
"+trt("No_data")+"
"; + html+=""+trt("Open_data_on_the_map")+""; + html+="

"; + + //Adult_density + //плотности имаго + sql="" + +" select cr.name region_name,coalesce(t1.danger,0) danger,coalesce(t2.attention,0) attention,coalesce(t3.quietly,0) quietly from\n" + +" main.countriesregions cr\n" + +" left join (SELECT region_id,sum(1) as danger from main.frmlocust fl join main.terminals t on t.serial=fl.device_id where fl.del=false and t.del=false and (fl.date>to_timestamp("+start_t+") and fl.date= 5 group by region_id) t1 on cr.id=t1.region_id\n" + +" left join (SELECT region_id,sum(1) as attention from main.frmlocust fl join main.terminals t on t.serial=fl.device_id where fl.del=false and t.del=false and (fl.date>to_timestamp("+start_t+") and fl.date= 3 and imago_density < 5 group by region_id) t2 on cr.id=t2.region_id\n" + +" left join (SELECT region_id,sum(1) as quietly from main.frmlocust fl join main.terminals t on t.serial=fl.device_id where fl.del=false and t.del=false and (fl.date>to_timestamp("+start_t+") and fl.dateExec Exception:"+ex.getMessage()+"
"; + } + + html+="

"+trt("Adult_density")+"

"; + + html+=trt("From_date")+": "+sdf.format(new Date(Long.parseLong(start_t)*1000)); + html+="
"+trt("To_date")+": "+sdf.format(new Date(Long.parseLong(end_t)*1000)); + + html+=""; + html+=""; + + exists=false; + if(rs!=null) + { + while (rs.next()) + { + html+=""; + html+=""; + html+=""; + html+=""; + html+=""; + html+=""; + + exists=true; + } + } + st.close(); + if(!exists) html+=""; + html+="
"+trt("Oblast")+"\"\""+trt("Number_forms")+" \""+trt("Dangerous")+"\"
("+trt("Adult_density")+" >=5)
\"\""+trt("Number_forms")+" \""+trt("Attention")+"\"
("+trt("Adult_density")+" >=3 "+trt("and")+" <5)
\"\""+trt("Number_forms")+" \""+trt("Quietly")+"\"
("+trt("Adult_density")+" <=2)
"+rs.getString("region_name")+""+rs.getString("danger")+""+rs.getString("attention")+""+rs.getString("quietly")+"
"+trt("No_data")+"
"; + html+=""+trt("Open_data_on_the_map")+""; + html+="

"; + + + //Hopper_density + sql="" + +" select cr.name region_name,coalesce(t1.danger,0) danger,coalesce(t2.attention,0) attention,coalesce(t3.quietly,0) quietly from\n" + +" main.countriesregions cr\n" + +" left join (SELECT region_id,sum(1) as danger from main.frmlocust fl join main.terminals t on t.serial=fl.device_id where fl.del=false and t.del=false and (fl.date>to_timestamp("+start_t+") and fl.date= 5 group by region_id) t1 on cr.id=t1.region_id\n" + +" left join (SELECT region_id,sum(1) as attention from main.frmlocust fl join main.terminals t on t.serial=fl.device_id where fl.del=false and t.del=false and (fl.date>to_timestamp("+start_t+") and fl.date= 3 and COALESCE(fl.larva_density, fl.larva_density_to)::double precision + COALESCE(fl.larva_density_to, fl.larva_density)::double precision / 2::double precision < 5 group by region_id) t2 on cr.id=t2.region_id\n" + +" left join (SELECT region_id,sum(1) as quietly from main.frmlocust fl join main.terminals t on t.serial=fl.device_id where fl.del=false and t.del=false and (fl.date>to_timestamp("+start_t+") and fl.dateExec Exception:"+ex.getMessage()+"
"; + } + + html+="

"+trt("Hopper_density")+"

"; + + html+=trt("From_date")+": "+sdf.format(new Date(Long.parseLong(start_t)*1000)); + html+="
"+trt("To_date")+": "+sdf.format(new Date(Long.parseLong(end_t)*1000)); + + html+=""; + html+=""; + + exists=false; + if(rs!=null) + { + while (rs.next()) + { + html+=""; + html+=""; + html+=""; + html+=""; + html+=""; + html+=""; + + exists=true; + } + } + st.close(); + if(!exists) html+=""; + html+="
"+trt("Oblast")+"\"\""+trt("Number_forms")+" \""+trt("Dangerous")+"\"
("+trt("Hopper_density")+" >=5)
\"\""+trt("Number_forms")+" \""+trt("Attention")+"\"
("+trt("Hopper_density")+" >=3 "+trt("and")+" <5)
\"\""+trt("Number_forms")+" \""+trt("Quietly")+"\"
("+trt("Hopper_density")+" <=2)
"+rs.getString("region_name")+""+rs.getString("danger")+""+rs.getString("attention")+""+rs.getString("quietly")+"
"+trt("No_data")+"
"; + html+=""+trt("Open_data_on_the_map")+""; + html+="

"; + + sql="" + +" select cr.name region_name,coalesce(t1.danger,0) danger,coalesce(t3.quietly,0) quietly from\n" + +" main.countriesregions cr\n" + +" left join (SELECT region_id,sum(1) as danger from main.frmlocust fl join main.terminals t on t.serial=fl.device_id where fl.del=false and t.del=false and (fl.date>to_timestamp("+start_t+") and fl.date= 1 or kuliguli_density>=1 or kuliguli_density_to>=1) group by region_id) t1 on cr.id=t1.region_id\n" + +" left join (SELECT region_id,sum(1) as quietly from main.frmlocust fl join main.terminals t on t.serial=fl.device_id where fl.del=false and t.del=false and (fl.date>to_timestamp("+start_t+") and fl.dateExec Exception:"+ex.getMessage()+"
"; + } + + html+="

"+trt("Number_of_bands")+"

"; + html+=trt("From_date")+": "+sdf.format(new Date(Long.parseLong(start_t)*1000)); + html+="
"+trt("To_date")+": "+sdf.format(new Date(Long.parseLong(end_t)*1000)); + + html+=""; + html+=""; + + exists=false; + if(rs!=null) + { + while (rs.next()) + { + html+=""; + html+=""; + html+=""; + html+=""; + html+=""; + + exists=true; + } + } + st.close(); + if(!exists) html+=""; + html+="
"+trt("Oblast")+"\"\""+trt("Number_forms")+" \""+trt("Dangerous")+"\"
("+trt("Number_of_bands")+" >=1)
\"\""+trt("Number_forms")+" \""+trt("Quietly")+"\"
("+trt("Number_of_bands")+" <1)
"+rs.getString("region_name")+""+rs.getString("danger")+""+rs.getString("quietly")+"
"+trt("No_data")+"
"; + html+=""+trt("Open_data_on_the_map")+""; + html+="

"; + + sql="" + +" select cr.name region_name,coalesce(t1.danger,0) danger,coalesce(t3.quietly,0) quietly from\n" + +" main.countriesregions cr\n" + +" left join (SELECT region_id,sum(1) as danger from main.frmlocust fl join main.terminals t on t.serial=fl.device_id where fl.del=false and t.del=false and (fl.date>to_timestamp("+start_t+") and fl.dateto_timestamp("+start_t+") and fl.dateExec Exception:"+ex.getMessage()+"
"; + } + + html+="

"+trt("Number_of_swarms")+"

"; + html+=trt("From_date")+": "+sdf.format(new Date(Long.parseLong(start_t)*1000)); + html+="
"+trt("To_date")+": "+sdf.format(new Date(Long.parseLong(end_t)*1000)); + + html+=""; + html+=""; + + exists=false; + if(rs!=null) + { + while (rs.next()) + { + html+=""; + html+=""; + html+=""; + html+=""; + html+=""; + + exists=true; + } + } + st.close(); + if(!exists) html+=""; + html+="
"+trt("Oblast")+"\"\""+trt("Number_forms")+" \""+trt("Dangerous")+"\"
("+trt("Number_of_swarms")+" >=1)
\"\""+trt("Number_forms")+" \""+trt("Quietly")+"\"
("+trt("Number_of_swarms")+" <1)
"+rs.getString("region_name")+""+rs.getString("danger")+""+rs.getString("quietly")+"
"+trt("No_data")+"
"; + html+=""+trt("Open_data_on_the_map")+""; + html+="

"; + + html+=""; + + + /*String mail_host=""; + String mail_port=""; + String mail_login=""; + String mail_password="";*/ + + try { + EmailUtility.sendEmail(mail_host, mail_port, mail_login, mail_password, email, "Locust statistics", html); + //result = "The e-mail was sent successfully"; + } catch (Exception ex) { + ex.printStackTrace(); + //result = "There were an error: " + ex.getMessage(); + } finally { + //request.setAttribute("Message", resultMessage); + //getServletContext().getRequestDispatcher("/Result.jsp").forward(request, response); + } + html=""; + } + } catch (NumberFormatException ex) { + result+="
Exec Exception:"+ex.getMessage()+"
"; + } catch (SQLException ex) { + result+="
Exec Exception:"+ex.getMessage()+"
"; + } + } + + return result; + } + //--------------------------------------------------------------------------- + @Override + public void setServletContext(ServletContext servletContext) { + this.context=servletContext; + } + //--------------------------------------------------------------------------- + public String trt(String key) + { + String result=""; + if(m_conn!=null) { + ResultSet rs=null; + Statement st = null; + try { + st = m_conn.createStatement(); + String sql = "select case when '"+m_user.language_id+"'='666' then translation||'''\"' else translation end as translation from main._translations t where t.identifier='"+key+"' and (t.language_id='"+m_user.language_id+"' or ('"+m_user.language_id+"'='666' and t.language_id=1));"; + rs = st.executeQuery(sql); + if(rs != null) { + if (rs.next()) { + result = rs.getString(1); + } + } + } catch( SQLException ex ) + { + logger.info(ex.getMessage()); + }finally{ + if(st!=null) try{st.close();}catch(SQLException ex) {} + if(rs!=null) try{rs.close();}catch(SQLException ex) {} + } + } + if(result.equals("")) + { + result = key.replaceAll("_", " "); + } + return result; + } + //--------------------------------------------------------------------------- + //Translate text by patterns + public String getText(String text) { + int pos1 = 0; + while (true) { + pos1 = text.indexOf("trt('", pos1); + if (pos1 == -1) + break; + int pos2 = text.indexOf("')", pos1); + if (pos2 == -1) + break; + + text = text.substring(0, pos1) + trt(text.substring(pos1 + 5, pos2)) + text.substring(pos2 + 2); + } + return text; + } + //--------------------------------------------------------------------------- + +} diff --git a/src/main/java/kz/locust/CCALM/Session.java b/src/main/java/kz/locust/CCALM/Session.java new file mode 100644 index 0000000..ed94af2 --- /dev/null +++ b/src/main/java/kz/locust/CCALM/Session.java @@ -0,0 +1,47 @@ +package kz.locust.CCALM; + +import javax.servlet.http.HttpServletResponse; + +import org.json.JSONObject; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.SessionAttributes; + +import tools.User; + +@Controller +@SessionAttributes( { "user" }) +public class Session { + + //If not created object "user", create him. + @ModelAttribute("user") + public User populatePerson() { + return new User("none"); + } + + @RequestMapping(value = "/session", method = {RequestMethod.GET, RequestMethod.POST }) + @ResponseBody + public Object ajaxTest(@ModelAttribute User user,HttpServletResponse response) { + + response.setHeader("Cache-Control", "no-cache, no-store, max-age=0, must-revalidate"); + JSONObject obj = new JSONObject(); + if(user.id==null || user.id.equals("") || user.id.equals("null")) + obj.put("result", "ERROR"); + else { + obj.put("result", "OK"); + obj.put("user_id", user.id); + } + + return obj.toString(); + } + + /*class Result + { + public String result; + Result(String result){this.result=result;} + }*/ + +} diff --git a/src/main/java/kz/locust/CCALM/TestFiles.java b/src/main/java/kz/locust/CCALM/TestFiles.java new file mode 100644 index 0000000..219a8ec --- /dev/null +++ b/src/main/java/kz/locust/CCALM/TestFiles.java @@ -0,0 +1,202 @@ +package kz.locust.CCALM; + +import java.io.File; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Date; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.HttpEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.SessionAttributes; +import org.springframework.web.context.ServletContextAware; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +@Controller +public class TestFiles implements ServletContextAware { + + private static final org.slf4j.Logger logger = LoggerFactory.getLogger(SendMail.class); + + private ServletContext context; + + @RequestMapping(value = "/TestFiles",method = RequestMethod.GET,produces = "text/html;charset=UTF-8") + @ResponseBody + public Object ajaxTamer() + { + String result=""; + + //Load DB configuration from "config.xml" + String db_url = ""; + String db_login = ""; + String db_password = ""; + String mail_host = ""; + String mail_port = ""; + String mail_login = ""; + String mail_password = ""; + //String data_dir = ""; + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain = doc.getDocumentElement(); + NodeList nl = nMain.getChildNodes(); + for (int i = 0; i < nl.getLength(); i++) { + if (nl.item(i).getNodeName().equals("db-url")) + db_url = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-login")) + db_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("db-password")) + db_password = nl.item(i).getTextContent(); + //if (nl.item(i).getNodeName().equals("data-dir")) + // data_dir = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("mail-host")) + mail_host = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("mail-port")) + mail_port = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("mail-login")) + mail_login = nl.item(i).getTextContent(); + if (nl.item(i).getNodeName().equals("mail-password")) + mail_password = nl.item(i).getTextContent(); + + } + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + + //Connect to database + Connection conn = null; + try{ + Class.forName("org.postgresql.Driver"); + conn = DriverManager.getConnection(db_url,db_login,db_password); + if(conn!=null) + { + logger.info("Connect is OK!"); + result+="Connect is OK!
"; + }else + { + logger.info("
Connect is ERROR
"); + result+="Connect is ERROR!
"; + } + }catch(Exception e) + { + logger.info("
Connect Exception:"+e.getMessage()+"
"); + result+="Connect Exception:"+e.getMessage()+"
"; + } + + String sql; + Statement st; + ResultSet rs=null; + + result+="image_name1

"; + sql="select image_name1 as name from main.frmlocustdel where image_name1 is not null"; + try { + st = conn.createStatement(); + rs=null; + try { + rs = st.executeQuery(sql); + } catch( SQLException ex ) { + result+="
Exec Exception:"+ex.getMessage()+"
"; + } + + if(rs!=null) + { + while (rs.next()) + { + if(!(new File("/temp/CCALM/data/frmlocustdel/"+rs.getString("name"))).exists()) + { + logger.info("update main.frmlocustdel set image_name1=null where image_name1=\""+rs.getString("name")+"\""); + result+="update main.frmlocustdel set image_name1=null where image_name1='"+rs.getString("name")+"';"+"
"; + } + } + } + st.close(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + result+="image_name2

"; + sql="select image_name2 as name from main.frmlocustdel where image_name2 is not null"; + try { + st = conn.createStatement(); + rs=null; + try { + rs = st.executeQuery(sql); + } catch( SQLException ex ) { + result+="
Exec Exception:"+ex.getMessage()+"
"; + } + + if(rs!=null) + { + while (rs.next()) + { + if(!(new File("/temp/CCALM/data/frmlocustdel/"+rs.getString("name"))).exists()) + { + logger.info("update main.frmlocustdel set image_name2=null where image_name2=\""+rs.getString("name")+"\""); + result+="update main.frmlocustdel set image_name2=null where image_name2='"+rs.getString("name")+"';"+"
"; + } + } + } + st.close(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + + result+="image_name3

"; + sql="select image_name3 as name from main.frmlocustdel where image_name3 is not null"; + try { + st = conn.createStatement(); + rs=null; + try { + rs = st.executeQuery(sql); + } catch( SQLException ex ) { + result+="
Exec Exception:"+ex.getMessage()+"
"; + } + + if(rs!=null) + { + while (rs.next()) + { + if(!(new File("/temp/CCALM/data/frmlocustdel/"+rs.getString("name"))).exists()) + { + logger.info("update main.frmlocustdel set image_name3=null where image_name3=\""+rs.getString("name")+"\""); + result+="update main.frmlocustdel set image_name3=null where image_name3='"+rs.getString("name")+"';"+"
"; + } + } + } + st.close(); + + } catch (SQLException e) { + e.printStackTrace(); + } + + + return result; + } + //--------------------------------------------------------------------------- + @Override + public void setServletContext(ServletContext servletContext) { + this.context=servletContext; + } +} diff --git a/src/main/java/kz/locust/CCALM/Translation.java b/src/main/java/kz/locust/CCALM/Translation.java new file mode 100644 index 0000000..66e54fa --- /dev/null +++ b/src/main/java/kz/locust/CCALM/Translation.java @@ -0,0 +1,204 @@ +package kz.locust.CCALM; + +import java.io.DataInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; +import java.util.Set; + +import javax.xml.parsers.DocumentBuilderFactory; +import javax.servlet.ServletContext; +import javax.xml.parsers.DocumentBuilder; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.SessionAttributes; +import org.springframework.web.context.ServletContextAware; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import tools.User; + +/** + * Handles requests for the application home page. + */ +@Controller +@SessionAttributes( { "user" }) +public class Translation implements ServletContextAware { + + private static final Logger logger = LoggerFactory.getLogger(Translation.class); + private ServletContext context; + + //If not created object "user", create him. + @ModelAttribute("user") + public User populatePerson() { + return new User("none"); + } + + /*public static boolean loadTranslationFromXML(Properties props, InputStream isXML) + { + boolean result=false; + if(isXML!=null) + { + Document doc = null; + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + doc = dBuilder.parse(isXML); + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + Node reqNode = doc.getDocumentElement(); + + Node nextnode=reqNode.getFirstChild(); + while(nextnode!=null) + { + if(nextnode.getNodeName().equals("string")) + { + String name=nextnode.getAttributes().getNamedItem("name").getNodeValue(); + String val=""; + if(nextnode.getFirstChild()!=null) + val=nextnode.getFirstChild().getNodeValue(); + //if(props.getProperty(name,"").equals("") && !val.equals("")) + props.setProperty(name, val); + result=true; + } + nextnode = nextnode.getNextSibling(); + } + } + + + return result; + }*/ + + /** + * Simply selects the home view to render by returning its name. + */ + @RequestMapping(value = "/translation", method = RequestMethod.GET) + public String home(@ModelAttribute User user/*, Locale locale*/, Model model) { + + Properties props = new Properties(); + + String db_url=""; + String db_login=""; + String db_password=""; + //Load DB configuration from "config.xml" + try { + //String fullPath = context.getRealPath("/WEB-INF/config.xml"); + //File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain=doc.getDocumentElement(); + NodeList nl=nMain.getChildNodes(); + for (int i = 0; i Connect is ERROR
"); + } + }catch(Exception e) + { + System.out.println("
Connect Exception:"+e.getMessage()+"
"); + } + + try { + Statement st = conn.createStatement(); + ResultSet rs=null; + try { + String sql_query = "select identifier,case when '"+user.language_id+"'='666' then translation||'''\"' else translation end as translation from main._translations t where t.del=false and (t.language_id='"+user.language_id+"' or ('"+user.language_id+"'='666' and t.language_id=1)) and translation_type_id=1 order by identifier;"; + rs = st.executeQuery(sql_query); + } catch( SQLException ex ) + { + System.out.println("
SQLException:"+ex.getMessage()+"
"); + } + + if(rs!=null) + { + while (rs.next()) + { + if(rs.getString("translation")!=null) + props.setProperty(rs.getString("identifier"), rs.getString("translation")); + } + } + st.close(); + } catch( SQLException ex ) + { + System.out.println("
SQLException:"+ex.getMessage()+"
"); + } + try{ conn.close(); }catch(Exception e){} + + //Create JavaScript text + /* + InputStream utf8in = getClass().getClassLoader().getResourceAsStream("messages_"+user.lng+".properties"); + Reader reader; + try { + reader = new InputStreamReader(utf8in, "UTF-8"); + props.load(reader); + } catch (UnsupportedEncodingException e) { + }catch (IOException e) { + }*/ + + //Переписываю в JavaScript код + String result=""; + Set keys = props.keySet(); + for(Object k:keys){ + String key = ((String)k).trim(); + String val = props.getProperty(key,""); + + if(val.equals("")) + { + val = val.replaceAll("_", " "); + } + val = val.replaceAll("'", "`"); + result += " ,"+key+":'"+val+"'\n"; + } + + model.addAttribute("keys",result); + + return "translation"; + } + + @Override + public void setServletContext(ServletContext servletContext) { + this.context=servletContext; + } + +} \ No newline at end of file diff --git a/src/main/java/kz/locust/CCALM/WeatherDownload.java b/src/main/java/kz/locust/CCALM/WeatherDownload.java new file mode 100644 index 0000000..0c772f6 --- /dev/null +++ b/src/main/java/kz/locust/CCALM/WeatherDownload.java @@ -0,0 +1,128 @@ +package kz.locust.CCALM; + +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URL; + +/** + * + * @author ivanov.i + */ +public class WeatherDownload { + + private static final int BUFFER_SIZE = 4096; + + + + public boolean download(String strURL,String strFile,String posStart,String posEnd) + { + boolean result=true; + String rez = null; + String inputLine = null; + /*try + { + rez = new String("".getBytes(), "utf-8"); + inputLine = new String("".getBytes(), "utf-8"); + } catch (UnsupportedEncodingException e) + { + e.printStackTrace(); + }*/ + try + { + URL url = new URL(strURL); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setRequestProperty("Range","bytes=" + posStart + "-" + posEnd); + conn.connect(); + int responseCode = conn.getResponseCode(); + if (responseCode / 100 == 2) //Code 206 is "Partial Content" + { + InputStream inputStream = conn.getInputStream(); + FileOutputStream outputStream = new FileOutputStream(strFile); + int bytesRead; + byte[] buffer = new byte[BUFFER_SIZE]; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + outputStream.close(); + inputStream.close(); + } + conn.disconnect(); + } + catch (IOException e) + { + //e.printStackTrace(); + result=false; + } + return result; + } + + /** + * Downloads a file from a URL + * @param fileURL HTTP URL of the file to be downloaded + * @param saveDir path of the directory to save the file + * @throws IOException + */ + public static void downloadFile(String fileURL, String saveDir) + throws IOException { + URL url = new URL(fileURL); + HttpURLConnection httpConn = (HttpURLConnection) url.openConnection(); + int responseCode = httpConn.getResponseCode(); + + // always check HTTP response code first + if (responseCode == HttpURLConnection.HTTP_OK) { + String fileName = ""; + String disposition = httpConn.getHeaderField("Content-Disposition"); + String contentType = httpConn.getContentType(); + int contentLength = httpConn.getContentLength(); + + if (disposition != null) { + // extracts file name from header field + int index = disposition.indexOf("filename="); + if (index > 0) { + fileName = disposition.substring(index + 10, + disposition.length() - 1); + } + } else { + // extracts file name from URL + fileName = fileURL.substring(fileURL.lastIndexOf("/") + 1, + fileURL.length()); + } + + System.out.println("Content-Type = " + contentType); + System.out.println("Content-Disposition = " + disposition); + System.out.println("Content-Length = " + contentLength); + System.out.println("fileName = " + fileName); + + // opens input stream from the HTTP connection + InputStream inputStream = httpConn.getInputStream(); + String saveFilePath = saveDir + File.separator + fileName; + + // opens an output stream to save into file + FileOutputStream outputStream = new FileOutputStream(saveFilePath); + + int bytesRead = -1; + byte[] buffer = new byte[BUFFER_SIZE]; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + + outputStream.close(); + inputStream.close(); + + System.out.println("File downloaded"); + } else { + System.out.println("No file to download. Server replied HTTP code: " + responseCode); + } + httpConn.disconnect(); + } +} diff --git a/src/main/java/kz/locust/CCALM/engine/EngineController.java b/src/main/java/kz/locust/CCALM/engine/EngineController.java new file mode 100644 index 0000000..c427c15 --- /dev/null +++ b/src/main/java/kz/locust/CCALM/engine/EngineController.java @@ -0,0 +1,544 @@ +package kz.locust.CCALM.engine; + +import java.io.File; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Properties; +import java.util.Set; + +import javax.servlet.ServletContext; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.io.ClassPathResource; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.SessionAttributes; +import org.springframework.web.context.ServletContextAware; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +import tools.User; + +/** + * Handles requests for the application home page. + */ +@Controller +@SessionAttributes( { "user" }) +public class EngineController implements ServletContextAware { + + private static final Logger logger = LoggerFactory.getLogger(EngineController.class); + private ServletContext context; + private Properties m_props=null; + //private String m_props_loc=""; + + //If not created object "user", create him. + @ModelAttribute("user") + public User populatePerson() { + return new User("none"); + } + + /** + * Simply selects the home view to render by returning its name. + */ + @RequestMapping(value = "/engine", method = RequestMethod.GET) + public String home(@ModelAttribute User user, Model model,@RequestParam(required=false,name="lng") String language_id) { + + if(language_id!=null && !language_id.equals("")) user.language_id=language_id; + logger.info("user.id="+user.id+" user.name="+user.name+" user.language_id="+user.language_id); + + String db_url=""; + String db_login=""; + String db_password=""; + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + //Document doc = dBuilder.parse(fXmlFile); + Document doc = dBuilder.parse(new ClassPathResource("config.xml").getInputStream()); + Element nMain=doc.getDocumentElement(); + NodeList nl=nMain.getChildNodes(); + for (int i = 0; i Connect is ERROR
"); + } + }catch(Exception e) + { + System.out.println("
Connect Exception:"+e.getMessage()+"
"); + } + + try { + Statement st = conn.createStatement(); + ResultSet rs=null; + if(user.id!=null){ + + if(language_id!=null && !language_id.equals("")) + { + //Set the language for the current user if it is transferred. + user.language_id=language_id; + try { + st.execute("update main._users set language_id='"+user.language_id+"' where id="+user.id); + } catch( SQLException ex ) + { + System.out.println("
SQLException:"+ex.getMessage()+"
"); + } + } + + //Select language for current user + try { + String sql="select language_id,country_id from main._users where id="+String.valueOf(user.id)+";"; + rs = st.executeQuery(sql); + } catch( SQLException ex ) + { + System.out.println("
SQLException:"+ex.getMessage()+"
"); + } + + if(rs!=null) + { + while (rs.next()) + { + user.language_id = rs.getString("language_id"); + user.country_id = rs.getString("country_id"); + } + } + } + st.close(); + } catch( SQLException ex ) + { + System.out.println("
SQLException:"+ex.getMessage()+"
"); + } + + //Send user name and role + model.addAttribute("uName",user.name+" ("+user.role+")"); + model.addAttribute("m_locale",user.language_id); + model.addAttribute("country_id",user.country_id); + + + //Send translation to user + /*InputStream utf8in = getClass().getClassLoader().getResourceAsStream("messages_"+user.lng+".properties"); + if(utf8in!=null) + { + Properties props=new Properties(); + Reader reader; + try { + reader = new InputStreamReader(utf8in, "UTF-8"); + props.load(reader); + } catch (UnsupportedEncodingException e) { + }catch (IOException e) { + } + //Также подгружаю перевод из XML файла Android проекта + Translation.loadTranslationFromXML(props,getClass().getClassLoader().getResourceAsStream("strings_"+user.lng+".xml")); + + Set keys = props.keySet(); + for(Object k:keys){ + String key = (String)k; + String val=""; + //val = trt(conn,key,user); //Если есть то перевод беру из базы данных + if(val.equals("")) + { + val = props.getProperty(key,""); + if(val.equals("")) + { + val = val.replaceAll("_", " "); + } + } + + model.addAttribute(key,val); + } + }*/ + + //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + //TODO удалить нужно только для копирования языков в базу (если там их нет) + /*InputStream isXML = getClass().getClassLoader().getResourceAsStream("strings_"+user.lng+".xml"); + if(isXML!=null) + { + Document doc = null; + try { + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + doc = dBuilder.parse(isXML); + } catch (Exception ex) { + logger.info(ex.getMessage()); + } + Node reqNode = doc.getDocumentElement(); + + Node nextnode=reqNode.getFirstChild(); + while(nextnode!=null) + { + if(nextnode.getNodeName().equals("string")) + { + String name=nextnode.getAttributes().getNamedItem("name").getNodeValue(); + String val=""; + if(nextnode.getFirstChild()!=null) + val=nextnode.getFirstChild().getNodeValue(); + + //Если нет то добавляю + boolean exists=false; + try { + Statement st = conn.createStatement(); + ResultSet rs=null; + try { + String sql="select t.id from main._translations t join main._languages l on l.id=t.language_id where t.del=false and identifier='"+name+"' and l.short_name='"+user.lng+"';"; + rs = st.executeQuery(sql); + } catch( SQLException ex ) + { + logger.info(ex.getMessage()); + } + if(rs!=null) + { + while (rs.next()) + { + exists=true; + } + } + st.close(); + } catch( SQLException ex ) + { + logger.info(ex.getMessage()); + } + + if(exists) + { + logger.info(name+" = "+val+" exists"); + //Если идентификатор сушествует то проверяю совпадает ли сам перевод (просто для информации) + boolean equals=false; + try { + Statement st = conn.createStatement(); + ResultSet rs=null; + try { + String sql="select t.id from main._translations t join main._languages l on l.id=t.language_id where t.del=false and t.identifier='"+name+"' and t.translation='"+val+"' and l.short_name='"+user.lng+"';"; + rs = st.executeQuery(sql); + } catch( SQLException ex ) + { + logger.info(ex.getMessage()); + } + if(rs!=null) + { + while (rs.next()) + { + equals=true; + } + } + st.close(); + } catch( SQLException ex ) + { + logger.info(ex.getMessage()); + } + + if(equals) + { + logger.info(name+" = "+val+" equals"); + }else + { + logger.info(name+" = "+val+" not equals"); + } + + }else + { + logger.info(name+" = "+val+" not exists"); + + //Вставляю новую запись в базу + try { + Statement st = conn.createStatement(); + try { + String sql="insert into main._translations(language_id,identifier,translation,translation_type_id) select (select l.id from main._languages l where l.del=false and l.short_name='"+user.lng+"'),'"+name+"' as identifier,'"+val+"' as translation,3 as translation_type_id;"; + st.execute(sql); + } catch( SQLException ex ) + { + logger.info(ex.getMessage()); + } + } catch( SQLException ex ) + { + logger.info(ex.getMessage()); + } + + + + } + + } + nextnode = nextnode.getNextSibling(); + } + }*/ + //Читаю перевод из properties файлов и записываю в базу под номером 1 + /*InputStream utf8in = getClass().getClassLoader().getResourceAsStream("messages_"+user.lng+".properties"); + if(utf8in!=null) + { + Properties props=new Properties(); + Reader reader; + try { + reader = new InputStreamReader(utf8in, "UTF-8"); + props.load(reader); + } catch (UnsupportedEncodingException e) { + }catch (IOException e) { + } + //Также подгружаю перевод из XML файла Android проекта + //Translation.loadTranslationFromXML(props,getClass().getClassLoader().getResourceAsStream("strings_"+user.lng+".xml")); + + Set keys = props.keySet(); + for(Object k:keys){ + String key = (String)k; + String val = props.getProperty(key,""); + + + + //Если нет то добавляю + boolean exists=false; + try { + Statement st = conn.createStatement(); + ResultSet rs=null; + try { + String sql="select t.id from main._translations t join main._languages l on l.id=t.language_id where t.del=false and identifier='"+key+"' and l.short_name='"+user.lng+"' and translation_type_id=1;"; + rs = st.executeQuery(sql); + } catch( SQLException ex ) + { + logger.info(ex.getMessage()); + } + if(rs!=null) + { + while (rs.next()) + { + exists=true; + } + } + st.close(); + } catch( SQLException ex ) + { + logger.info(ex.getMessage()); + } + + if(exists) + { + logger.info(key+" = "+val+" exists"); + }else + { + logger.info(key+" = "+val+" not exists"); + //Вставляю новую запись в базу + try { + Statement st = conn.createStatement(); + try { + String sql="insert into main._translations(language_id,identifier,translation,translation_type_id) select (select l.id from main._languages l where l.del=false and l.short_name='"+user.lng+"'),'"+key+"' as identifier,'"+val+"' as translation,1 as translation_type_id;"; + st.execute(sql); + } catch( SQLException ex ) + { + logger.info(ex.getMessage()); + } + } catch( SQLException ex ) + { + logger.info(ex.getMessage()); + } + } + } + }*/ + + //Для перевода выбираю всё что под номером 1 в переводе + try { + m_props = new Properties(); + Statement stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + String sql_query = "select identifier,case when '"+user.language_id+"'='666' then translation||'''\"' else translation end as translation from main._translations t where t.del=false and (t.language_id='"+user.language_id+"' or ('"+user.language_id+"'='666' and t.language_id=1)) and translation_type_id=1;"; + ResultSet rs = stt.executeQuery(sql_query); + if (rs != null) { + while (rs.next()) + { + String identifier = rs.getString("identifier"); + String translation = rs.getString("translation"); + m_props.setProperty(identifier, translation); + } + rs.close(); + } + stt.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + Set keys = m_props.keySet(); + for(Object k:keys){ + String key = (String)k; + String val=""; + if(val.equals("")) + { + val = m_props.getProperty(key,""); + if(val.equals("")) + { + val = val.replaceAll("_", " "); + } + } + model.addAttribute(key,val); + } + + + //Подложка Substrate_head Substrate_tail + String Substrate_head=""; + String Substrate_tail=""; + if(!user.country_id.equals("")) + { + try { + Statement st = conn.createStatement(); + ResultSet rs=null; + try { + String sql="SELECT id,path,description,projection FROM main.layouts where del=false and country_id="+user.country_id+" order by description"; + rs = st.executeQuery(sql); + } catch( SQLException ex ) + { + } + if(rs!=null) + { + while (rs.next()) + { + Substrate_head+=" \n"; + + Substrate_tail+="g_Layouts[\""+rs.getString("id")+"\"] = new ol.source.XYZ({\n"; + Substrate_tail+=" url: '"+rs.getString("path")+"',\n"; + if(rs.getString("projection")!=null && rs.getString("projection").indexOf("EPSG:")!=-1) + Substrate_tail+=" projection: '"+rs.getString("projection")+"',\n"; + Substrate_tail+=" });\n"; + } + } + st.close(); + } catch( SQLException ex ) + { + } + } + model.addAttribute("Substrate_head",Substrate_head); + model.addAttribute("Substrate_tail",Substrate_tail); + + //Выбираю дату получения NDVI данных по номеру дня + /*{ + int maxNum=1; + try { + File folder = new File(ndvi_dir); + File[] listOfFiles = folder.listFiles(); + if(listOfFiles!=null) + { + for (int i = 0; i < listOfFiles.length; i++) + { if (listOfFiles[i].isFile()) + { + if(Tools.afterLast(listOfFiles[i].getName(),".").equals("json")) + { + int num=1; + try { + num=1+Integer.valueOf(Tools.beforeLast(listOfFiles[i].getName(),".")); + }catch(Exception ex) + { + System.out.println(ex.getMessage()); + } + if(num>maxNum) maxNum=num; + } + } + } + } + }catch(Exception ex) + { + System.out.println(ex.getMessage()); + } + Year y = Year.of( Calendar.getInstance().get(Calendar.YEAR) ) ; + model.addAttribute("NDVI_DATE",y.atDay( maxNum ).toString()); + model.addAttribute("NDVI_DAY",String.valueOf(maxNum)); + }*/ + + //Выбираю дату получения NDWI данных по номеру дня + /*{ + int maxNum=1; + try { + File folder = new File(ndwi_dir); + File[] listOfFiles = folder.listFiles(); + if(listOfFiles!=null) + { + for (int i = 0; i < listOfFiles.length; i++) + { if (listOfFiles[i].isFile()) + { + if(Tools.afterLast(listOfFiles[i].getName(),".").equals("json")) + { + int num=1; + try { + num=1+Integer.valueOf(Tools.beforeLast(listOfFiles[i].getName(),".")); + }catch(Exception ex) + { + System.out.println(ex.getMessage()); + } + if(num>maxNum) maxNum=num; + } + } + } + } + }catch(Exception ex) + { + System.out.println(ex.getMessage()); + } + Year y = Year.of( Calendar.getInstance().get(Calendar.YEAR) ) ; + model.addAttribute("NDWI_DATE",y.atDay( maxNum ).toString()); + model.addAttribute("NDWI_DAY",String.valueOf(maxNum)); + }*/ + + + try{ conn.close(); }catch(Exception e){} + return "engine/index"; + } + + @Override + public void setServletContext(ServletContext context){ + this.context=context; + } + + //Перевести слово по идентификатору из базы а если в базе нет то из файлов перевода + public String trt(Connection conn,String key,User user) + { + String result=""; + if(key.equals("")) + return result; + + try { + Statement stt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); + String sql_query = "select case when '"+user.language_id+"'='666' then translation||'''\"' else translation end as translation from main._translations t where t.del=false and identifier='"+key+"' and (t.language_id='"+user.language_id+"' or ('"+user.language_id+"'='666' and t.language_id=1));"; + ResultSet rs = stt.executeQuery(sql_query); + if (rs != null) { + try { + if (rs.next()) + result=rs.getString(1); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + rs.close(); + } + stt.close(); + } catch (SQLException ex) { + logger.info(ex.getMessage()); + } + + if(result.equals("")) + { + result = key.replaceAll("_", " "); + } + return result; + } + +} diff --git a/src/main/java/kz/locust/CCALM/recReq/RecReq.java b/src/main/java/kz/locust/CCALM/recReq/RecReq.java new file mode 100644 index 0000000..2078c7e --- /dev/null +++ b/src/main/java/kz/locust/CCALM/recReq/RecReq.java @@ -0,0 +1,21 @@ +package kz.locust.CCALM.recReq; + +import java.io.Serializable; + +public class RecReq implements Serializable { + + private static final long serialVersionUID = 1L; + + public int fn; + public int cmd; + + public int getFn() + { + return fn; + } + public int getCmd() + { + return cmd; + } + +} diff --git a/src/main/java/messages_az.properties_not_used b/src/main/java/messages_az.properties_not_used new file mode 100644 index 0000000..cd672c3 --- /dev/null +++ b/src/main/java/messages_az.properties_not_used @@ -0,0 +1,535 @@ +language = en +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Language = Language +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) + +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/src/main/java/messages_en.properties_not_used b/src/main/java/messages_en.properties_not_used new file mode 100644 index 0000000..4715ab4 --- /dev/null +++ b/src/main/java/messages_en.properties_not_used @@ -0,0 +1,534 @@ +language = en +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/src/main/java/messages_hy.properties_not_used b/src/main/java/messages_hy.properties_not_used new file mode 100644 index 0000000..f703777 --- /dev/null +++ b/src/main/java/messages_hy.properties_not_used @@ -0,0 +1,535 @@ +language = en +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) + +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/src/main/java/messages_ka.properties_not_used b/src/main/java/messages_ka.properties_not_used new file mode 100644 index 0000000..f703777 --- /dev/null +++ b/src/main/java/messages_ka.properties_not_used @@ -0,0 +1,535 @@ +language = en +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) + +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/src/main/java/messages_kg.properties_not_used b/src/main/java/messages_kg.properties_not_used new file mode 100644 index 0000000..f703777 --- /dev/null +++ b/src/main/java/messages_kg.properties_not_used @@ -0,0 +1,535 @@ +language = en +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) + +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/src/main/java/messages_ps.properties_not_used b/src/main/java/messages_ps.properties_not_used new file mode 100644 index 0000000..d4774ac --- /dev/null +++ b/src/main/java/messages_ps.properties_not_used @@ -0,0 +1,534 @@ +language = ps +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/src/main/java/messages_ru.properties_not_used b/src/main/java/messages_ru.properties_not_used new file mode 100644 index 0000000..655a64a --- /dev/null +++ b/src/main/java/messages_ru.properties_not_used @@ -0,0 +1,540 @@ +language = ru +Language = Язык +label_registration = Регистрация +label_login = Войти на сайт +From_DPA = С планшета +Days = Дней +Hours = Часов +Company_User = Компания -> Пользователь +Object_Geofence = Объект –> Геозона +Sensor_for_ComboBox = Датчик для выпадающего списка +The_boundary_values_of_the_sensors = Граничные значения датчиков. +CountriesRegions = Границы регионов +Types_of_locust = Виды саранчи +Help = Помощь +Unknown_function = Неизвестная функция! +Not_yet_implemented = Пока не реализовано! +Layout = Слой +Company = Компания +Path = Путь +Description = Описание +Layouts = Слои +Type_of_locust = Вид саранчи +Kind_of_locust = Вид саранчи +Sorting_index = Индекс сортировки +Name = Имя +Types_of_locust = Вид саранчи +Markings = Маркировка +Formulation = Препаративная форма +Vegetation = Растительность +Fledgling = Окрыление +Age = Возраст +Biotop = Биотоп +Capacity = Ёмкость +Capacities = Ёмкости +Borns = Отрождение +Сontainers = Контейнеры +Breeding = Поведение +Containers = Контейнеры +Types_of_operators = Типы операторов +Types_of_operator = Тип оператора +Density_of_vegetation = Густота растительного покрова +Height = Высота +Damage = Повреждения +Density = Плотность +Directions = Направления +Angle = Угол +Methods_of_calculating_mortality = Методы подсчёта смертности +Method_of_calculating_mortality = Метод подсчёта смертности +Phase = Фаза +Condition_of_vegetation = Состояние растительности +Actions_of_bands = Действия кулиги +Behaviors = Поведение +Paintings = Окраска +Painting = Окрас +Enemies = Наличие естественных врагов +Report_by_tablets = Отчёт по планшетам +Country = Страна +From_date = С даты +To_date = По дату +The_tabblet = Планшет +Forms_for_locust_survey = Формы обследования саранчи +Forms_for_spray_monitoring = Формы мониторинга противосаранчовых обработок +Completed_forms_by_tablets = Заполнение форм по планшетам +Filling_forms_by_countries = Заполнение форм по странам +Method_filling_form = Способ заполнения формы +The_tablet_registered = Планшет зарегистрирован +IDENTIFICATION_OF_THE_PLACE = ИДЕНТИФИКАЦИЯ МЕСТА +Region = Область +Regions = Области +Rayon = Район +Rual_district = Сельский округ +Name_of_the_village = Поселок +Farm_or_site = Хозяйство или местность +Name_of_survey_team_leader = Имя лидера команды обследования +Date = Дата +Latitude_of_point = Широта точки +Longitude_of_point = Долгота точки +Surveyed_area_ha = Обследованная площадь(га) +ECOLOGICAL_INFORMATION = ЭКОЛОГИЧЕСКАЯ ИНФОРМАЦИЯ +Type_of_biotope = Тип биотопа +Vegetation_cover = Густота растительного покрова +Air_temperature = Погода: температура воздуха(ºC) +Wind_m_s = Погода: ветер(м/с) +bio_wind = Погода: ветер(м/с) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = ИНФОРМАЦИЯ О САРАНЧОВЫХ (В Т.Ч. КУБЫШКИ) +Present = Присутствуют саранчовые +Locust_species = Вид саранчи +Area_infested_ha = Заселённая площадь(га) +EGGS = ЯЙЦА +Egg_bed_surface_in_ha = Залежь кубышек (площадь га) +Egg_pods_density_m2 = Плотность кубышек (/м²) +Egg_pods_density = Плотность кубышек +Egg_pod = Кубышки +to = до +Eggs_average_number_egg_pod = Яйца (в среднем в кубышке) +Eggs_viable = Яйца(% жизнеспособных) +Natural_enemies_present = Естественны враги +HOPPERS_SCATTERED = ЛИЧИНКИ (РАЗРЕЖЕННЫЕ) +Hatching = Отрождение +Hopper_stages = Возраст личинок +Appearance = Фаза +Behaviour = Поведение +Hopper_density_m2 = Плотность личинок (/м²) +Hopper_density = Плотность личинок +Hopper_density_m2_to = Плотность личинок (/м²) до +HOPPER_BANDS = КУЛИГИ +Minimum_density_in_the_band_in_m2 = Плотность минимальная в кулиге (/м²) +Maximum_density_in_the_band_in_m2 = Плотность максимальная в кулиге (/м²) +Band_sizes_m2 = Размер кулиг (м²) +Number_of_bands = Количество кулиг +Behavior = Поведение +ADULTS = ИМАГО +Fledging = Окрыление +Maturity = Половозрелость +Adult_density_ha = Плотность имаго /га +Adult_density_m2 = Имаго (плотность/м²) +Adult_density = Плотность имаго +Feeding_and_roosting = Питание и размещение на растениях +Copulating = Спаривание +Laying = Яйцекладка +Flying = Полёты +SWARMS = СТАИ +Density_of_swarm = Плотность в стае +Swarm_size_ha = Размер стаи (га) +Number_of_swarms = Число стай +Flying_direction = Направление полёта +Flying_height = Высота полёта +COMMENTS = КОММЕНТАРИИ +Locust_Survey_Form = Форма обследования саранчи +Locust_Survey_Forms = Формы обследования саранчи +From_the_tablet = С планшета +From_WEB_interface = С WEB интерфейса +User = Пользователь +Weather_air_temperature_C = Погода: температура воздуха(ºC) +Weather = Погода +larva_behavior = Поведение +Spray_Monitoring_Form = Форма противосаранчовых обработок +Rural_district = Сельский округ +Name_of_control_team_leader = Имя лидера команды по обработке +Latitude_center_portion = Широта (центр участка) +Longitude_center_portion = Долгота (центр участка) +Area_treated_ha = Обработанная площадь(га) +VEGETATION_DATA = РАСТИТЕЛЬНОСТЬ +Kind = Вид +Type = Тип +type = тип +types = типы +Height_cm = Высота (см) +Crop_name = Наименование сельхозкультуры +Damage_area_ha = Площадь повреждения (га) +INSECTICIDE_DATA = ИНФОРМАЦИЯ ОБ ИНСЕКТИЦИДАХ +Trade_name = Коммерческое название +The_active_substance = Действующее вещество +Concentration_A_S = Концентрация (%) +Dose_rate_l_of_commercial_product_ha = Норма расхода (л коммерческого продукта/гa) +Rate_of_working_solution_l_ha = Расход рабочей жидкости (л/га) +Total_volume_of_working_solution_actually_applied_l = Общий объем использованной рабочей жидкости (л) +Number_of_spores_ml = Концентрация спор(/мл) +WEATHER_CONDITIONS = ПОГОДНЫЕ УСЛОВИЯ +Time_start = Время начала обработки +Time_end = Время окончания обработки +Temperature_start = Температура нач.(°C) +Temperature_end = Температура кон.(°C) +Relative_humidity_start = Отн. влажность воздуха нач.(%) +Relative_humidity_end = Отн. влажность воздуха кон.(%) +Wind_speed_start_m_s = Скорость ветра нач. (м/с) +Wind_speed_end_m_s = Скорость ветра кон. (м/с) +Wind_direction_start = Направление ветра нач. +Wind_direction_end = Направление ветра кон. +Spray_direction_start = Направление опрыскивания нач. +Spray_direction_end = Направление опрыскивания кон. +LOCUST_INFORMATION = ИНФОРМАЦИЯ О САРАНЧОВЫХ (В Т.Ч. КУБЫШКИ) +Imago = Имаго +Density_m2 = Плотность на м² +Bands = Кулиги +Swarms = Стаи +Scattered = Разреженные +SPRAY_APPLICATION = СВЕДЕНИЯ ПО ОПРЫСКИВАНИЮ +Spray_platform = Способ опрыскивания +Aerial = Авиа +Ground = Наземное +Person = Ручное +Spray_type = Вид опрыскивания +Spray_manufacturer = Марка опрыскивателя +Model_sprayer = Модель опрыскивателя +Atomizer_height_above_ground_m = Высота распылителя над поверхностью почвы (м) +Barriers = Барьеры +Barrier_width_m = Ширина барьера (м) +Spacing_of_barriers_m = Промежуток барьера (м) +spray_height = Высота над поверхностью почвы (м) +Forward_speed_km_h = Средняя скорость движения (км/ч) +Antenna_DGPS_used = Антенна: DGPS использовалась +Ground_marking = Наземная маркировка +CONTROL_EFFICACY = КОНТРОЛЬ ЭФФЕКТИВНОСТИ +Biological_efficiency_of_treatment = Биологическая эффективность обработки (%) +Time_after_treatment_hours = Прошло времени после обработки (часов) +Method_of_biological_efficiency_estimation = Метод подсчета биологической эффективности +SAFETY_AND_ENVIRONMENT = БЕЗОПАСНОСТЬ И ОКРУЖАЮЩАЯ СРЕДА +Protective_clothing = Индивидуальные средства защиты +Goggles = Очки +Masks = Маска +Gloves = Перчатки +Overalls = Комбинезон +Caps = Шапка +Boots = Сапоги +Absent = Отсутствуют +Protective_clothing_clean_and_in_good_state = Защитная одежда чистая и в хорошем состоянии? +Operator_accidentally_exposed_to_insecticide_or_feeling_unwell = Оператор случайно подвергся воздействию инсектицида или плохое самочувствие +Inform_abaut_spraying = Оповещенные об обработках +Farmer = Фермер +Shepherd = Пастух +Official = Должностное лицо +Beekeeper = Пчеловод +Villager = Сельский житель +Other = Другие +Empty_containers = Пустые контейнеры +Effect_on_non_terget_organism = Воздействие на нецелевые организмы +If_yes_describe_what_happened_description = Если да, опишите, что произошло +if_Yes_type_of_organisms_and_effects_description = Если Да, тип организмов и эффекты (описание) +If_Yes_type_of_incident_and_reported_by_whom_description = Если Да, тип инцидента и кем сообщен (описание) +Other_environmental_or_health_incident_reported_that_might_have_been_caused_by_the_treatment = Другие инциденты по здоровью или окружающей среде, возникшие при обработке +Comments = Коментарии +Spray_Monitoring_Forms = Формы противосаранчовых обработок +Information_on_the_distribution_of_locust = Информация о распространении и борьбе со стадными саранчовыми +Year = Год +year = год +Inspect_thous_ha = Обследовано (тыс. га) +Infested_thous_ha = Заселено (тыс. га) +Infested_over_ETD_thous_ha = Заселено выше ЭПВ (тыс. га) +Treated_thous_ha = Обработано (тыс. га) +The_tablet = Планшеты +Organization = Организация +Phone_number = Номер телефона +Responsible_person = Ответственное лицо за планшет (инспектор) +Serial_number = Серийный номер +The_tablet_model = Модель планшета +The_tablets = Планшеты +Phone = Телефон +Responsible_person = Ответственное лицо +Change_password = Сменить пароль +Login = Логин +Password = Пароль +New_password = Новый пароль +Repeat_password = Повторить пароль +User_settings = Пользовательские настройки +Named = Наименование +Value = Значение +Values = Значения +Object = Объект +sensor = сенсор +Groups_of_objects = Группы объектов +Object_of_observation = Объект наблюдения +Access = Доступ +Identifier = Идентификатор +Allow = Разрешить +Sensor = Сенсор +objects = объекты +Sensor_values = Показание датчика +Terminal = Терминал +Units_of_measurement = Единицы измерения +Fix_date = Дата фиксации +Messages = Сообщения +Read = Прочтённые +Readed = Прочтённые +Content = Содержание +Date_read = Дата чтения +Date_create = Дата создания +Day_mileage_and_speed = Дневной пробег и скорость +Kilometers_distance = Дистанция км. +Kilometers_distance_without_signal = Дистанция км. без сигнала +Company_site = Сайт компании +Contact_phone = Контактный телефон +Organizations = Организации +Site = Сайт +Users = Пользователи +Terminal_model = Модель терминала +Models_of_terminals = Модели терминалов +Sensor_type = Тип датчика +Sensor_of_devices = Датчик оборудования +Measurement = Измерение +Sensor_model = Модель датчика +Rounded_to = Округлять до +Sensors_models = Модели датчиков +Count_objects = Количество объектов +Group = Группа +Terminals = Терминалы +Stationary = Стационарный +Latitude = Широта +Longitude = Долгота +Icon = Иконка +Objects_of_observation = Объекты наблюдения +Count_of_sensors = Количество датчиков +Icons = Иконки +name = имя +File = Файл +Size = Размер +byte = байт +Geofence = Геозона +Geofences = Геозоны +Coordinate = Координаты +Coordinates_Geofence = Координаты геозоны +Position = Должность +True_position = Правильное положение +outside = снаружи +inside = внутри +Boundary = Граничное +Inform = Информировать +Inside = Внутри +Sensor_of_object = Датчик объекта +Sensors_of_objects = Датчики объектов +Last_value = Последнее значение +Date_of_the_last_value = Дата посл. знач. +Readings = Показание +Devices = Устройства +Sensor_readings = Показание датчика +GPS_readings = GPS показание +Fixation_date = Дата фиксации +Speed = Скорость +Message = Сообщение +Subject = Тема +Creation_date = Дата создания +Contents = Содержимое +User_messages = Сообщения пользователя +Reading_date = Дата прочтения +Users_messages = Сообщения пользователей +Minimum_value = Минимальное значение +Maximum_value = Максимальное значение +Only_on_the_boundary = Только на границе +Action = Действие +Rule = Правило +Actions = Действия +Access_role = Роль доступа +Parental_role = Родительская роль +Role_name = Наименование роли +Role_description = Описание роли +Role = Роль +Surname = Фамилия +Patronymic = Отчество +Phones = Телефоны +Password_expiration = Срок действия пароля +Renewal_password = Продление пароля +days = дней +day = день +S_N_P = Ф.И.О. +Last_enter = Посл. заход +Roles = Роли +User_roles = Пользовательские роли +Synchronization_objects = Объекты синхронизации +Synchronization_service = Сервис синхронизации +Synchronization_order = Порядок синхронизации +The_interval_between_the_update_in_s = Интервал между обн. в (сек) +At_a_time = Записей за раз +Time_of_the_last_synchronization = Времени с последней синхронизации +Service = Сервис +Order = Порядок +Interval = Интервал +Limit = Лимит +Synchronization_services = Сервисы синхронизации +Host = Хост +History = История +Table = Таблица +Field = Поле +Data = Данные +Short_name = Короткое имя +Translation = Перевод +Sprayer_type = Вид опрыскивателя +Sprayers = Опрыскиватели +Sprayer = Опрыскиватель +SprayersTypes = Вид опрыскивателя +Sprayer_type_name = Наименование опрыскивателя +Countries = Страны +Regions = Районы +Automated_system_of_data_collection = Автоматизированная система сбора данных +Download_android_app_Inspector = Скачать андроид приложение инспектора +Run_the_application_of_the_situational_center = Запустить приложение ситуационного центра +For_any_questions_contact_us_at_tel_Fax = По всем интересующим вопросам обращаться по тел./факс +You_are_not_logged_in = Вы не авторизованы! +Not_found_the_requested_node: = Не найден запрошенный узел: +The_number_of_records_is_not_equal_to_one = Количество записей не равно одному! +Filter_options = Параметры фильтра +Time_and_date_of_generation = Время и дата генерации +Creator = Создатель +E_mail_already_exists_in_the_database = Адрес электронной почты уже существует в базе данных! +Registration_form = Форма регистрации +You_have_successfully_registered = Вы успешно зарегистрировались! +Password_sent_to_your_e_mail = Пароль отправлен на ваш е-mail. +Operator_registration_form = Форма регистрации оператора +Security_Code = Защитный код +Update = Обновить +image = рисунок +Registering = Регистрация +Failed_to_send_your_password_to_the_e_mail = Не удалось отправить пароль на электронную почту. +Failed_to_update_the_password = Не удалось обновить пароль. +configuration_section_s = Раздел конфигурации; %s +configuration_option_s = опция конфигурации; %s +Locust_survey = Обследования саранчи +Spray_monitoring = Противосаранчовые обработки +Reports = Отчёты +Report = Отчёт +Map_layers = Слои карты +Administration = Администрирование +Standard_survey_forms = Стандартные формы обследования +Companies = Компании +Report_by_countries = Отчёт по странам +Lists = Справочники +Members = Пользователи +Photo = Фотография +Indicator = Показатель +PDA_registered = Планшеты зарегистрированы +From_PDA = С планшета +From_WEB_interface = С WEB интерфейса +Open_in_a_table_format = Открыть в табличном виде +Request_data = Запросить данные +Not = Нет +Yes = Да +Attention = Внимание +Quietly = Спокойно +Number_forms = Количество форм +Open_data_on_the_map = Открыть данные на карте +No_data = Данные отсутствуют +From_date = С даты +To_date = По дату +or = или +Dangerous = Опасно +Distribution_of_locust = Распространение и борьба со стадными саранчовыми +Hide = Скрыть +For_what_year = За какой год +Displayed_data = Отображаемые данные +Automated_system_of_data_collection_ASDC = Автоматизированная система сбора данных (ASDC) +Invalid_username_and_or_password = Неверный логин и/или пароль! +CIT_Italian_locust = CIT - итальянский прус +DMA_Moroccan_locust = DMA - мароккская саранча +LMI_Asian_migratory_locust = LMI - азиатская перелетная саранча +Substrate = Подложка +Change_login_password = Изменить логин/пароль +Displaying_data = Отображение данных +Show_data = Отобразить данные +All_types = Все виды +All_kinds = Все виды +Maps_of_areas_infested_above_Economic_Threshold_ET = Карты площадей, заселенных с плотностями выше экономического порога вредоносности (ЭПВ) +Maps_of_treated_areas_above_ET = Карты обработанных площадей выше ЭПВ +Map_of_the_level_of_threat = Карта уровня угрозы +Download_QGIS_project = Скачать QGIS проект +Danger = Опасно +Caution = Внимание +Calm = Спокойно +Increase = Подъём +Decrease = Спад +On_the_same_level = На том же уровне +Normal_Multiyear_average_level = Нормальный/Среднемноголетний уровень +Device_id = Идентификатор устройства +All_countries_of_CCA = Страны КЦА +The_Caucasus_countries_and_Russia = Страны Кавказа и Россия +Countries_of_Central_Asia_and_Russia = Станы Центральной Азии и Россия +from = от +The_forecast_of_hatching_periods = Прогноз инкубационного периода +Weather_forecast = Прогноз погоды +soil_temperature = температура почвы +Soil_temperature = Температура почвы +Passwords_did_not_match = Пароли не совпадают! +The_s_is_not_Email = Логин «%s» не электронная почта! +Password_changed_successfully = Пароль успешно изменен. +Failed_to_change_password = Не удалось изменить пароль. +Check_the_entered_data = Проверьте введенные данные. +for_ = для +Earth_temperature = Температура земли +Point = Точка +Forecast_of_hours = Часы прогноза +hours = часов +Change_login_password = Сменить логин/пароль +Type = Тип +Legend = Легенда +Spraying = Опрыскивание +Chart = График +Average = Среднее +Percent = Процент +For_s_year = За %s год +and = и +Time_and_date_of_generation = Дата создания +Filter_options = Параметры фильтра +Export_to_Excel = Экспорт в Excel +Preparing_of_report = Подготовка отчёта +Download_report = Скачать отчёт +Old_password = Старый пароль +Not_filled_Email_address = Не заполнен email +Wrong_XML_document = Неверный XML-документ +Please_enter_a_valid_email_address = Пожалуйста, введите правильный адрес электронной почты +For_new_users = Для новых пользователей +For_returning_users = Для вернувшихся пользователей +Phone = Телефон +Log_in = Авторизоваться +Registration = Регистрация +Authorization = Авторизация +Password_recovery = Восстановление пароля +The_s_field_is_empty = Не заполнено поле "%s" +New_user_is_registered = Новый пользователь зарегистрирован. +The_password_has_been_sent_to_you_by_Email = Пароль отправлен вам на Email. +Others = Другие +District = Район +Districts = Районы +All = Всё +Region = Область +Edit = Редактировать +thous_ha = тыс. га +Thous_ha = Тыс. га +Average = Среднее +Year = Год +Deviation = Отклонение +Dev_of_average = Откл. от среднего +Cancel = Отмена +Responsible_person_for_data_verification = Ответственное лицо по верификации данных +Upload = Загрузить +Delete = Удалить +Download = Скачать +Repeat_the_addition_of_the_entry = Повторить добавление записи +Apply = Применить +Calcel = Закрыть +Hoppers = Личинки (разреженные) +Kuliguli = Кулиги +Adult = Имаго +Restore = Восстановить +Add_more = Добавить ещё +Successfully_added_data = Данные успешно добавлены +Are_you_sure_you_want_to_delete_the_entries = Вы действительно хотите удалить записи? +Increase_by_1 = Увеличить на 1 +Decrease_by_1 = Уменьшить на 1 +No_results_were_found_for_your_search = По вашему запросу ничего не найдено! +Selection = Выбор +Add_record = Добавить запись +Delete_record = Удалить записи +Filtering = Фильтровать +Invert_selection = Инвертировать выделение +No_locust = Нет саранчи + +Triple_rinsed=Трижды промытые +Punctured=Проколотые +Taken_back_to_base=Возвращенные на базу +Left_in_field=Оставленные в поле +Buried=Закопанные +Burned=Сожженные \ No newline at end of file diff --git a/src/main/java/messages_tg.properties_not_used b/src/main/java/messages_tg.properties_not_used new file mode 100644 index 0000000..f703777 --- /dev/null +++ b/src/main/java/messages_tg.properties_not_used @@ -0,0 +1,535 @@ +language = en +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) + +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/src/main/java/messages_tk.properties_not_used b/src/main/java/messages_tk.properties_not_used new file mode 100644 index 0000000..f703777 --- /dev/null +++ b/src/main/java/messages_tk.properties_not_used @@ -0,0 +1,535 @@ +language = en +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) + +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/src/main/java/messages_uz.properties_not_used b/src/main/java/messages_uz.properties_not_used new file mode 100644 index 0000000..f703777 --- /dev/null +++ b/src/main/java/messages_uz.properties_not_used @@ -0,0 +1,535 @@ +language = en +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) + +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/src/main/java/not_used b/src/main/java/not_used new file mode 100644 index 0000000..4715ab4 --- /dev/null +++ b/src/main/java/not_used @@ -0,0 +1,534 @@ +language = en +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/src/main/java/tools/EmailUtility.java b/src/main/java/tools/EmailUtility.java new file mode 100644 index 0000000..7bf90db --- /dev/null +++ b/src/main/java/tools/EmailUtility.java @@ -0,0 +1,65 @@ +//From: http://www.codejava.net/java-ee/jsp/sending-e-mail-with-jsp-servlet-and-javamail +package tools; + +import java.util.Date; +import java.util.Properties; + +import javax.mail.Authenticator; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.PasswordAuthentication; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.AddressException; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; + +/** + * A utility class for sending e-mail messages + * @author www.codejava.net + * + */ +public class EmailUtility { + + public static void sendEmail(String host, String port, + final String userName, final String password, String toAddress, + String subject, String message) throws AddressException, + MessagingException + { + // sets SMTP server properties + Properties properties = new Properties(); + + properties.put("mail.smtp.host", host); + properties.put("mail.smtp.port", port); + properties.put("mail.smtp.auth", "true"); + //properties.put("mail.smtp.starttls.enable","true"); STARTTLS requested but already using SSL + properties.put("mail.smtp.EnableSSL.enable","true"); + properties.put("mail.smtp.socketFactory.port", port); + properties.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory"); + //properties.put("mail.debug", "true"); + + + // creates a new session with an authenticator + Authenticator auth = new Authenticator() { + public PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(userName, password); + } + }; + + Session session = Session.getInstance(properties, auth); + + //creates a new e-mail message + Message msg = new MimeMessage(session); + + msg.setFrom(new InternetAddress(userName)); + InternetAddress[] toAddresses = { new InternetAddress(toAddress) }; + msg.setRecipients(Message.RecipientType.TO, toAddresses); + msg.setSubject(subject); + msg.setSentDate(new Date()); + //msg.setText(message); + msg.setContent(message, "text/html; charset=utf-8"); + + // sends the e-mail + Transport.send(msg); + } +} \ No newline at end of file diff --git a/src/main/java/tools/PreparedStatementNamed.java b/src/main/java/tools/PreparedStatementNamed.java new file mode 100644 index 0000000..84cd1e8 --- /dev/null +++ b/src/main/java/tools/PreparedStatementNamed.java @@ -0,0 +1,94 @@ +package tools; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Types; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class PreparedStatementNamed { + + private class HMap{ + public String name = ""; + public int pos = -1; + public HMap(String name,int pos) { + this.name = name; + this.pos = pos; + } + } + + private List< HMap > fields = new ArrayList< HMap >(); + private PreparedStatement m_prepStmt; + + public PreparedStatementNamed(Connection conn, String sql) throws SQLException { + int cnt=0; + int pos = 0; + while((pos = sql.indexOf("${")) != -1) { + int end = sql.substring(pos).indexOf("}"); + if (end == -1) + end = sql.length(); + else + end += pos+1; + cnt++; + fields.add(new HMap(sql.substring(pos+2,end-1),cnt)); + sql = sql.substring(0, pos) + "?" + sql.substring(end); //Removing a parameter from a string + } + m_prepStmt = conn.prepareStatement(sql); + } + + public void setInt(String name, int value) throws SQLException { + for(int i=0;i + + + + jdbc:postgresql://91.201.214.156:5432/CCALM + + + postgres + PasSecrKey1 + + smtp.yandex.ru + 465 + info@ccalm.org + fu2lpsoGPGiq1xlRm8ag + + + /temp/CCALM/ + + engine/metadata.xml + + diff --git a/src/main/resources/log4j.xml b/src/main/resources/log4j.xml new file mode 100644 index 0000000..9d5d730 --- /dev/null +++ b/src/main/resources/log4j.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/lib/commons-fileupload-1.3.3.jar b/src/main/webapp/WEB-INF/lib/commons-fileupload-1.3.3.jar new file mode 100644 index 0000000..915d87e Binary files /dev/null and b/src/main/webapp/WEB-INF/lib/commons-fileupload-1.3.3.jar differ diff --git a/src/main/webapp/WEB-INF/lib/commons-io-2.5.jar b/src/main/webapp/WEB-INF/lib/commons-io-2.5.jar new file mode 100644 index 0000000..1234918 Binary files /dev/null and b/src/main/webapp/WEB-INF/lib/commons-io-2.5.jar differ diff --git a/src/main/webapp/WEB-INF/lib/gdal.jar b/src/main/webapp/WEB-INF/lib/gdal.jar new file mode 100644 index 0000000..7fdd2f8 Binary files /dev/null and b/src/main/webapp/WEB-INF/lib/gdal.jar differ diff --git a/src/main/webapp/WEB-INF/lib/javax.mail.jar b/src/main/webapp/WEB-INF/lib/javax.mail.jar new file mode 100644 index 0000000..dd06a6a Binary files /dev/null and b/src/main/webapp/WEB-INF/lib/javax.mail.jar differ diff --git a/src/main/webapp/WEB-INF/lib/mail-1.4.7.jar b/src/main/webapp/WEB-INF/lib/mail-1.4.7.jar new file mode 100644 index 0000000..236fcdb Binary files /dev/null and b/src/main/webapp/WEB-INF/lib/mail-1.4.7.jar differ diff --git a/src/main/webapp/WEB-INF/lib/mailapi-1.4.4.jar b/src/main/webapp/WEB-INF/lib/mailapi-1.4.4.jar new file mode 100644 index 0000000..fc37e89 Binary files /dev/null and b/src/main/webapp/WEB-INF/lib/mailapi-1.4.4.jar differ diff --git a/src/main/webapp/WEB-INF/lib/mysql-connector-java-5.1.40-bin.jar b/src/main/webapp/WEB-INF/lib/mysql-connector-java-5.1.40-bin.jar new file mode 100644 index 0000000..60bef5c Binary files /dev/null and b/src/main/webapp/WEB-INF/lib/mysql-connector-java-5.1.40-bin.jar differ diff --git a/src/main/webapp/WEB-INF/lib/netcdfAll-4.6.8.jar b/src/main/webapp/WEB-INF/lib/netcdfAll-4.6.8.jar new file mode 100644 index 0000000..5f5c884 Binary files /dev/null and b/src/main/webapp/WEB-INF/lib/netcdfAll-4.6.8.jar differ diff --git a/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml b/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml new file mode 100644 index 0000000..2f13722 --- /dev/null +++ b/src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/spring/root-context.xml b/src/main/webapp/WEB-INF/spring/root-context.xml new file mode 100644 index 0000000..b7ef398 --- /dev/null +++ b/src/main/webapp/WEB-INF/spring/root-context.xml @@ -0,0 +1,11 @@ + + + + + + + + + diff --git a/src/main/webapp/WEB-INF/views/engine/index.jsp b/src/main/webapp/WEB-INF/views/engine/index.jsp new file mode 100644 index 0000000..957e554 --- /dev/null +++ b/src/main/webapp/WEB-INF/views/engine/index.jsp @@ -0,0 +1,1861 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ page session="false" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> + + + + + + ${Automated_system_of_data_collection_ASDC} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + +
+ + + + + + + + + +
${uName}${Language}Logconfighelpexit
+
+ + +
+ +
+ +
+ +
+ ${Substrate} + +
+ + +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
${Locust_survey}
${Country}
${Region}
${Type_of_locust}
${From_date}
${To_date}
${Method_filling_form}
${PDA_registered}
${Displayed_data}
${Download_QGIS_project}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
${Spray_monitoring}
${Country}
${Region}
${From_date}
${To_date}
${Method_filling_form}
${PDA_registered}
${Download_QGIS_project}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
${Distribution_of_locust}
${Country}
${Region}
${For_what_year}
${Kind_of_locust}
${Displayed_data} + +
${Download_QGIS_project}
+
+ + +
+ + + +
+
+ + + + + + + + + + + + + + + + + + + +
${Weather_forecast} (${Soil_temperature})
${Country}
${Date} +
+
${Download_QGIS_project}
+
+ + +
+ + + + + + + + + + + + + + + + + + + +
${Air_temperature_2m_above_the_ground}
${Country}
${Date} +
+
${Download_QGIS_project}
+
+ + +
+ + + + + + + + + + + + + + + + + + + +
${Accumulated_precipitation_in_24_hours}
${Country}
${Date} +
+
${Download_QGIS_project}
+
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + +
${Hydrothermal_coefficient_of_Selyaninov}
${Country}
${Start_date} +
+
${End_date} +
+
${Download_QGIS_project}
+
+ + + +
+ + + + + + + + + + + + + + + +
NDVI (${Normalized_difference_vegetation_index})
${Date} + +
${Download_QGIS_project}
+
+ +
+ + + + + + + + + + + + + + + +
IVI (${Integral_vegetation_index})
${Year} + +
${Download_QGIS_project}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
NDWI (${Normalized_difference_water_index})
${Date} + +
${Compare_with} + +
${Download_QGIS_project}
+
+ +
+ + + + + + + + + + + + + + + +
NDSI (${Normalised_difference_snow_index})
${Date} + +
${Download_QGIS_project}
+
+ +
+ + + + + + + + + + + + + + + +
SMAP L4 9km (${Soil_Moisture_Active_Passive})
${Date} + +
${Download_QGIS_project}
+
+ + + +
+ +
+ + + ${Reports} + + + + +
${Devices}
+ + + + ${Standard_survey_forms} + + + + +
${Companies}
+ + +
${Administration}
+ + + + + + + +
${Language}
+ + + +
${Weather}
+ + + +
${Lists}
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + +
+ +
+ + + + + + + + +
+ + + + + + + + + + +
+ + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/views/excel.jsp b/src/main/webapp/WEB-INF/views/excel.jsp new file mode 100644 index 0000000..32211f6 --- /dev/null +++ b/src/main/webapp/WEB-INF/views/excel.jsp @@ -0,0 +1,26 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> + + + + Select the file with CSV to upload and parsing. + + + + +
+ Select CSV UTF-8 file to upload and export: +
+ Skip first line
+ +
+

+ + ${PreviewTable} + +


+ +


+ + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/views/index.jsp b/src/main/webapp/WEB-INF/views/index.jsp new file mode 100644 index 0000000..fce5384 --- /dev/null +++ b/src/main/webapp/WEB-INF/views/index.jsp @@ -0,0 +1,91 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ page session="false" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> + + + + + Automated system of data collection + + + + + + + + + +
+ +
+ +
+

Caucasus and Central Asia Locusts Management system (CCALM)

+

+ + According to the implementation of the Road Map "program to improve national and regional locust control in the Caucasus and Central Asia (CCA)" developed a system of monitoring and analysis designed to control locusts in the CCA using a geographic information system and remote sensing technology. +

+ + + +
+
+
Automated system of data collection (ASDC)
+
+
+
Caucasus and Central Asia Locusts Management system (CCALM)
+
+
+
+ +
+
For any questions contact us at tel./Fax 8(727)3967038, E-mail: info@ccalm.org.
+ +
+
+ + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/views/json.jsp b/src/main/webapp/WEB-INF/views/json.jsp new file mode 100644 index 0000000..ec2b237 --- /dev/null +++ b/src/main/webapp/WEB-INF/views/json.jsp @@ -0,0 +1,25 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> + + + + Select the file with CSV to upload and parsing. + + + + +
+ Select CSV UTF-8 file to upload and export: +
+ +
+

+ + ${PreviewTable} + + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/views/privacy.html b/src/main/webapp/WEB-INF/views/privacy.html new file mode 100644 index 0000000..d19f350 --- /dev/null +++ b/src/main/webapp/WEB-INF/views/privacy.html @@ -0,0 +1,102 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ page session="false" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> + + + + + Automated system of data collection + + + + + + + + + +
+ +

Политика конфиденциальности

+ +

Компания ДТОО "Институт космической техники и технологий" (в дальнейшем ИКТТ) заботится о конфиденциальности данных своих клиентов. Для этих целей была разработана политика конфиденциальности, включающая правила сбора, использования, раскрытия, передачи и хранения Вашей информации. Ознакомьтесь с нашими правилами соблюдения.

+ +

Сбор и использование личной информации

+ +

Личной информацией являются данные, которые можно использовать для установления личности человека или для связи с ним. + Если вы обратитесь в ИКТТ, вас могут попросить предоставить личную информацию. ИКТТ использует ее в соответствии с данной политикой конфиденциальности. Эти сведения могут быть объединены с другими в целях предоставления наших товаров, услуг, материалов и рекламы. Вы не обязаны предоставлять личную информацию, которую мы запросили, но если вы ее не предоставите, во многих случаях мы не сможем предоставить вам свои товары или услуги, а также ответить на ваши запросы. + Вот несколько примеров того, какую личную информацию может собирать и использовать ИКТТ.

+

Какую личную информацию мы собираем

+
    +
  • Когда вы создаете BFT ID, регистрируете свои продукты, обращаетесь для получения кредита, приобретаете продукт, связываетесь с нами или принимаете участие в онлайн-исследовании, мы можем собирать различные сведения, включая ваше имя, почтовый адрес, номер телефона, адрес электронной почты, предпочтительные способы связи, а также данные кредитной карты.
  • +
  • Когда вы отправляете подарочные сертификаты и товары, а также приглашаете других пользователей на форумы ИКТТ, мы можем собирать предоставленную вами информацию об этих людях, включая их имена, почтовые адреса, адреса электронной почты и номера телефонов.
  • +
  • Мы можем запросить данные удостоверения личности для рассмотрения возможности предоставления кредита или выставления платежного поручения для оплаты товаров через банковское отделение.
  • +
+ +

Как мы используем личную информацию

+
    +
  • Мы можем использовать личную информацию для внутренних целей, например при проведении аудита, анализа данных и исследований, направленных на улучшение продуктов и услуг, а также способов общения с клиентами.
  • +
  • Периодически мы используем собранную личную информацию для рассылки важных уведомлений, например сообщений о покупках и об изменениях в условиях и политиках.
  • +
  • Если вы принимаете участие в лотерее, конкурсе или аналогичном мероприятии, мы можем использовать предоставленную вами информацию при организации этих событий.
  • +
+ +

Сбор и использование информации, не являющейся личной

+

Мы также осуществляем сбор данных, которые не указывают непосредственно на конкретного человека. Мы можем собирать, использовать, передавать и раскрывать такие сведения с любой целью. Вот несколько примеров того, какую информацию, не являющуюся личной, мы собираем и используем.

+
    +
  • Для того чтобы лучше понимать поведение клиентов и улучшать наши продукты, услуги и рекламу, мы можем собирать такие сведения, как род деятельности, язык, почтовый индекс, телефонный код, идентификатор устройства, местоположение, в котором используется купленный товар.
  • +
  • Мы можем также собирать информацию о том, чем интересуются пользователи на нашем веб-сайте, на официальных социальных страницах компании. Данные сведения позволяют нам предоставлять клиентам более полезную информацию, а также понять, какие разделы веб-сайта, продукты и сервисы пользуются повышенным интересом. В контексте данной политики конфиденциальности обобщенные данные рассматриваются в качестве информации, не являющейся личной.
  • +
+

При объединении информации, не являющейся личной, с личной информацией объединенные данные будут считаться личными, пока они остаются объединенными.

+

Раскрытие информации третьим лицам

+

Эта информация не передается третьим лицам.

+

Поставщики услуг

+

ИКТТ обменивается личными данными пользователей с компаниями, которые предоставляют такие услуги, как обработка информации, выдача или продление срока кредита, выполнение заказов клиентов, доставка продуктов, управление данными клиентов и их расширение, обслуживание клиентов, оценка заинтересованности пользователей в наших продуктах и услугах, а также проведение исследований и опросов с целью определения степени удовлетворенности. Эти компании обязуются защищать ваши данные и могут быть расположены только на территории Республики Казахстан.

+

Прочее

+

Компания ИКТТ может быть обязана раскрыть вашу личную информацию в соответствии с законодательством, требованиями судопроизводства, судебного разбирательства или по запросу государственных органов страны вашего пребывания или других стран. Мы также можем раскрыть вашу личную информацию, если это будет необходимо в целях национальной безопасности, исполнения закона или в иных общественно важных целях.

+

Мы также можем раскрыть вашу личную информацию, если это будет необходимо для выполнения наших условий или защиты наших операций или пользователей. Кроме того, в случае реорганизации, слияния или продажи компаний мы можем передавать личные данные соответствующей третьей стороне.

+

Защита личной информации

+

ИКТТ очень серьезно относится к защите вашей личной информации. Онлайн-сервисы ИКТТ, такие как Корзина и Личный кабинет, защищают вашу личную информацию во время передачи при помощи шифрования, например по протоколу SSL. Для хранения вашей личной информации ИКТТ использует компьютерные системы с ограниченным доступом, расположенные в помещениях с физическими средствами охраны. Данные Личного кабинета хранятся в зашифрованном виде, в том числе при использовании сторонних хранилищ.

+

Когда вы пользуетесь некоторыми продуктами, услугами или приложениями Apple, публикуете сообщения в социальных сервисах, ведете переписку в чате, публикуемую вами личную информацию могут видеть, читать, собирать и использовать другие пользователи. Вы несете ответственность за то, какую информацию вы раскрываете в таких случаях. Например, если вы указываете свои имя и адрес электронной почты в обсуждении на форуме или блоге, такая информация становится общедоступной. Проявляйте осторожность в таких ситуациях.

+

Целостность и хранение личной информации

+

С помощью ИКТТ вы легко сможете обеспечить точность, полноту и актуальность своей личной информации. Мы будем хранить вашу личную информацию в течение срока, необходимого для исполнения обязательств, которые указаны в данной политике конфиденциальности, если иное не предусмотрено законом.

+

Доступ к личной информации

+

Вы можете помочь нам обеспечить точность, полноту и актуальность вашей контактной информации и личных предпочтений, выполнив вход в учетную запись на сайте ccalm.org. Что касается остальных данных, мы обеспечим вам доступ к вашей личной информации, чтобы вы, в частности, могли подать запрос об исправлении или удалении данных, кроме случаев, когда хранение информации предусмотрено законом или необходимо компании ИКТТ для осуществления деятельности в рамках действующего законодательства. Мы можем отказать в исполнении запросов, которые необоснованны либо обременительны, нарушают конфиденциальность других пользователей, не имеют смысла или доступ к которым в соответствии с локальным законодательством не является обязательным. Запросы на доступ к данным, исправление или удаление данных можно подать по электронной почте.

+

Глобальные обязательства по конфиденциальности

+

В целях защиты личной информации мы знакомим сотрудников ИКТТ с рекомендациями по безопасности и конфиденциальности и обеспечиваем их строгое исполнение в компании.

+

Вопросы о конфиденциальности

+

Если у вас возникли вопросы или сомнения по поводу политики конфиденциальности ИКТТ или обработки данных либо вы хотите сообщить о предполагаемом нарушении местных законов о конфиденциальности, свяжитесь с нами по почте info@ccalm.org. Вы можете в любой момент связаться с нами по телефону +7 (727) 229-44-81.

+

Мы проверяем все обращения и стараемся отвечать на них в кратчайшие сроки. Если вы недовольны полученным ответом, направьте жалобу в соответствующий регулятивный орган своей страны. Если вы хотите получить исчерпывающую информацию о способах подать жалобу, уместных в ваших обстоятельствах, обратитесь к нам.

+

Компания ИКТТ периодически обновляет политику конфиденциальности. При изменении политики мы размещаем уведомление об этом на нашем веб-сайте вместе с новым текстом политики конфиденциальности.

+

ДТОО "Институт космической техники и технологий", Almaty, Kazakhstan

+ +
+ + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/views/privacy.jsp b/src/main/webapp/WEB-INF/views/privacy.jsp new file mode 100644 index 0000000..d19f350 --- /dev/null +++ b/src/main/webapp/WEB-INF/views/privacy.jsp @@ -0,0 +1,102 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ page session="false" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> + + + + + Automated system of data collection + + + + + + + + + +
+ +

Политика конфиденциальности

+ +

Компания ДТОО "Институт космической техники и технологий" (в дальнейшем ИКТТ) заботится о конфиденциальности данных своих клиентов. Для этих целей была разработана политика конфиденциальности, включающая правила сбора, использования, раскрытия, передачи и хранения Вашей информации. Ознакомьтесь с нашими правилами соблюдения.

+ +

Сбор и использование личной информации

+ +

Личной информацией являются данные, которые можно использовать для установления личности человека или для связи с ним. + Если вы обратитесь в ИКТТ, вас могут попросить предоставить личную информацию. ИКТТ использует ее в соответствии с данной политикой конфиденциальности. Эти сведения могут быть объединены с другими в целях предоставления наших товаров, услуг, материалов и рекламы. Вы не обязаны предоставлять личную информацию, которую мы запросили, но если вы ее не предоставите, во многих случаях мы не сможем предоставить вам свои товары или услуги, а также ответить на ваши запросы. + Вот несколько примеров того, какую личную информацию может собирать и использовать ИКТТ.

+

Какую личную информацию мы собираем

+
    +
  • Когда вы создаете BFT ID, регистрируете свои продукты, обращаетесь для получения кредита, приобретаете продукт, связываетесь с нами или принимаете участие в онлайн-исследовании, мы можем собирать различные сведения, включая ваше имя, почтовый адрес, номер телефона, адрес электронной почты, предпочтительные способы связи, а также данные кредитной карты.
  • +
  • Когда вы отправляете подарочные сертификаты и товары, а также приглашаете других пользователей на форумы ИКТТ, мы можем собирать предоставленную вами информацию об этих людях, включая их имена, почтовые адреса, адреса электронной почты и номера телефонов.
  • +
  • Мы можем запросить данные удостоверения личности для рассмотрения возможности предоставления кредита или выставления платежного поручения для оплаты товаров через банковское отделение.
  • +
+ +

Как мы используем личную информацию

+
    +
  • Мы можем использовать личную информацию для внутренних целей, например при проведении аудита, анализа данных и исследований, направленных на улучшение продуктов и услуг, а также способов общения с клиентами.
  • +
  • Периодически мы используем собранную личную информацию для рассылки важных уведомлений, например сообщений о покупках и об изменениях в условиях и политиках.
  • +
  • Если вы принимаете участие в лотерее, конкурсе или аналогичном мероприятии, мы можем использовать предоставленную вами информацию при организации этих событий.
  • +
+ +

Сбор и использование информации, не являющейся личной

+

Мы также осуществляем сбор данных, которые не указывают непосредственно на конкретного человека. Мы можем собирать, использовать, передавать и раскрывать такие сведения с любой целью. Вот несколько примеров того, какую информацию, не являющуюся личной, мы собираем и используем.

+
    +
  • Для того чтобы лучше понимать поведение клиентов и улучшать наши продукты, услуги и рекламу, мы можем собирать такие сведения, как род деятельности, язык, почтовый индекс, телефонный код, идентификатор устройства, местоположение, в котором используется купленный товар.
  • +
  • Мы можем также собирать информацию о том, чем интересуются пользователи на нашем веб-сайте, на официальных социальных страницах компании. Данные сведения позволяют нам предоставлять клиентам более полезную информацию, а также понять, какие разделы веб-сайта, продукты и сервисы пользуются повышенным интересом. В контексте данной политики конфиденциальности обобщенные данные рассматриваются в качестве информации, не являющейся личной.
  • +
+

При объединении информации, не являющейся личной, с личной информацией объединенные данные будут считаться личными, пока они остаются объединенными.

+

Раскрытие информации третьим лицам

+

Эта информация не передается третьим лицам.

+

Поставщики услуг

+

ИКТТ обменивается личными данными пользователей с компаниями, которые предоставляют такие услуги, как обработка информации, выдача или продление срока кредита, выполнение заказов клиентов, доставка продуктов, управление данными клиентов и их расширение, обслуживание клиентов, оценка заинтересованности пользователей в наших продуктах и услугах, а также проведение исследований и опросов с целью определения степени удовлетворенности. Эти компании обязуются защищать ваши данные и могут быть расположены только на территории Республики Казахстан.

+

Прочее

+

Компания ИКТТ может быть обязана раскрыть вашу личную информацию в соответствии с законодательством, требованиями судопроизводства, судебного разбирательства или по запросу государственных органов страны вашего пребывания или других стран. Мы также можем раскрыть вашу личную информацию, если это будет необходимо в целях национальной безопасности, исполнения закона или в иных общественно важных целях.

+

Мы также можем раскрыть вашу личную информацию, если это будет необходимо для выполнения наших условий или защиты наших операций или пользователей. Кроме того, в случае реорганизации, слияния или продажи компаний мы можем передавать личные данные соответствующей третьей стороне.

+

Защита личной информации

+

ИКТТ очень серьезно относится к защите вашей личной информации. Онлайн-сервисы ИКТТ, такие как Корзина и Личный кабинет, защищают вашу личную информацию во время передачи при помощи шифрования, например по протоколу SSL. Для хранения вашей личной информации ИКТТ использует компьютерные системы с ограниченным доступом, расположенные в помещениях с физическими средствами охраны. Данные Личного кабинета хранятся в зашифрованном виде, в том числе при использовании сторонних хранилищ.

+

Когда вы пользуетесь некоторыми продуктами, услугами или приложениями Apple, публикуете сообщения в социальных сервисах, ведете переписку в чате, публикуемую вами личную информацию могут видеть, читать, собирать и использовать другие пользователи. Вы несете ответственность за то, какую информацию вы раскрываете в таких случаях. Например, если вы указываете свои имя и адрес электронной почты в обсуждении на форуме или блоге, такая информация становится общедоступной. Проявляйте осторожность в таких ситуациях.

+

Целостность и хранение личной информации

+

С помощью ИКТТ вы легко сможете обеспечить точность, полноту и актуальность своей личной информации. Мы будем хранить вашу личную информацию в течение срока, необходимого для исполнения обязательств, которые указаны в данной политике конфиденциальности, если иное не предусмотрено законом.

+

Доступ к личной информации

+

Вы можете помочь нам обеспечить точность, полноту и актуальность вашей контактной информации и личных предпочтений, выполнив вход в учетную запись на сайте ccalm.org. Что касается остальных данных, мы обеспечим вам доступ к вашей личной информации, чтобы вы, в частности, могли подать запрос об исправлении или удалении данных, кроме случаев, когда хранение информации предусмотрено законом или необходимо компании ИКТТ для осуществления деятельности в рамках действующего законодательства. Мы можем отказать в исполнении запросов, которые необоснованны либо обременительны, нарушают конфиденциальность других пользователей, не имеют смысла или доступ к которым в соответствии с локальным законодательством не является обязательным. Запросы на доступ к данным, исправление или удаление данных можно подать по электронной почте.

+

Глобальные обязательства по конфиденциальности

+

В целях защиты личной информации мы знакомим сотрудников ИКТТ с рекомендациями по безопасности и конфиденциальности и обеспечиваем их строгое исполнение в компании.

+

Вопросы о конфиденциальности

+

Если у вас возникли вопросы или сомнения по поводу политики конфиденциальности ИКТТ или обработки данных либо вы хотите сообщить о предполагаемом нарушении местных законов о конфиденциальности, свяжитесь с нами по почте info@ccalm.org. Вы можете в любой момент связаться с нами по телефону +7 (727) 229-44-81.

+

Мы проверяем все обращения и стараемся отвечать на них в кратчайшие сроки. Если вы недовольны полученным ответом, направьте жалобу в соответствующий регулятивный орган своей страны. Если вы хотите получить исчерпывающую информацию о способах подать жалобу, уместных в ваших обстоятельствах, обратитесь к нам.

+

Компания ИКТТ периодически обновляет политику конфиденциальности. При изменении политики мы размещаем уведомление об этом на нашем веб-сайте вместе с новым текстом политики конфиденциальности.

+

ДТОО "Институт космической техники и технологий", Almaty, Kazakhstan

+ +
+ + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/views/test.jsp b/src/main/webapp/WEB-INF/views/test.jsp new file mode 100644 index 0000000..5ecbe26 --- /dev/null +++ b/src/main/webapp/WEB-INF/views/test.jsp @@ -0,0 +1,673 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ page session="false" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> + + + + + Caucasus and Central Asia Locusts Management system (CCALM) + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+
+ +
+
+
+
${Caucasus_and_Central_Asia_Locusts_Management_system} (CCALM)
+ + + +
+ + + + + + + + + + + + +
ASDCCCALM
+
+
+ +
+ + +
+ + + + +
+
+
+
+

${Locust_Data} ${with} ___ ${to} ___

+
+
+ +
+
+ + + + +
+
+
+ + + + + + + +
${Adult}
${Hoppers}
${Egg_pod}
${Spraying}
${Not_infected}
+
+
+ +
+
+ + + + + +
+ + +
+ + + +
+
+

${ASDC_Field_Data}

+
+
+
+
${Locust_survey}
+
+ +
+
+
${Spray_monitoring}
+
+
+
+
${Safety_and_environment}
+
+
+
+
+ +
+
+

${CALM_and_other_data}

+
+ +
+
+
${Soil_temperature_at_a_depth_of_10_cm}
+
+ +
+
+
${Air_temperature_2m_above_the_ground}
+
+ +
+
+
${Accumulated_precipitation_in_24_hours}
+
+ +
+
+
${Hydrothermal_coefficient_of_Selyaninov}
+
+ +
+
+
NDVI ${Normalized_difference_vegetation_index}
+
+ +
+
+
IVI ${Integral_vegetation_index}
+
+ +
+
+
NDWI ${Normalized_difference_water_index}
+
+
+
+
NDSI ${Normalised_difference_snow_index}
+
+ +
+
+
+ + + + +
+ + +
+ + + + + + +
+
+ + + + + +
+

${ASDC_User_Guides}

+ ASDC_for_Android_ENG_v2.23.pdf
+ ASDC_for_Android_RUS_v2.23.pdf +
+

${CCALM_User_Guides}

+ CCALM_help_ENG_v3.3.pdf
+ CCALM_help_RUS_v3.4.pdf +
+
+
+ + + + +
+ + +
+ + + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/views/translation.jsp b/src/main/webapp/WEB-INF/views/translation.jsp new file mode 100644 index 0000000..5c2dec6 --- /dev/null +++ b/src/main/webapp/WEB-INF/views/translation.jsp @@ -0,0 +1,33 @@ +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ page session="false" contentType="text/javascript; charset=UTF-8" pageEncoding="UTF-8" %> + +//В tools.js функция trt(key) есть +function _(key) +{ + if(key==null || key===undefined) return ''; + let val=g_translations[key]; + if(val==null || val===undefined) + { + for(let item in g_translations) { + if(item.toLowerCase()==key.toLowerCase()) + { + val=g_translations[item]; + break; + } + } + } + if(val==null || val===undefined) return key.replace(/_/g, ' '); + else return val; +} + +function __(key) +{ + var val=g_translations[key]; + if(val===undefined) return key.replace(/_/g, ' '); + else return val; +} + +var g_translations = { + '':'' +${keys} +}; \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..cee05e3 --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,23 @@ + + + + contextConfigLocation + /WEB-INF/spring/root-context.xml + + + org.springframework.web.context.ContextLoaderListener + + + appServlet + org.springframework.web.servlet.DispatcherServlet + + contextConfigLocation + /WEB-INF/spring/appServlet/servlet-context.xml + + 1 + + + appServlet + / + + \ No newline at end of file diff --git a/src/main/webapp/resources/QGIS/IVI.qgs b/src/main/webapp/resources/QGIS/IVI.qgs new file mode 100644 index 0000000..0459ad8 --- /dev/null +++ b/src/main/webapp/resources/QGIS/IVI.qgs @@ -0,0 +1,326 @@ + + + + + + + + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + WGS84 + false + + + + + + + + + + + + OpenStreetMap_b190df4b_967b_471d_9b9c_3cb1d5e3b416 + h23v05_h23v04_h23v03_h22v05_h22v04_h22v03_h21v05_h21v04_h21v03_h20v04_h20v03_9603ac31_1df8_4ac6_a749_7b7e66bb658b + + + + + + + + meters + + 2465883.50908621679991484 + 264579.77565301861613989 + 12985575.38905057311058044 + 10784271.65561737865209579 + + 0 + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + WGS84 + false + + + 0 + + + + + + + + + + + + + + + + + -20037508.34278924390673637 + -20037508.34278925508260727 + 20037508.34278924390673637 + 20037508.34278924390673637 + + OpenStreetMap_b190df4b_967b_471d_9b9c_3cb1d5e3b416 + crs=EPSG:3857&format&type=xyz&url=http://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png + + + + OpenStreetMap + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + WGS84 + false + + + + + + + + + + + + + + + + 0 + 0 + + + + + true + + + + + wms + + + + + + + + 1 + 1 + 1 + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + + 0 + + + + 2906345.494111736305058 + 3503584.68813749961555004 + 13358323.19605071656405926 + 8399737.88861873932182789 + + h23v05_h23v04_h23v03_h22v05_h22v04_h22v03_h21v05_h21v04_h21v03_h20v04_h20v03_9603ac31_1df8_4ac6_a749_7b7e66bb658b + contextualWMSLegend=0&crs=EPSG:3857&dpiMode=7&featureCount=10&format=image/png&layers=IVI:${year}IVI_h20v03&layers=IVI:${year}IVI_h20v04&layers=IVI:${year}IVI_h21v03&layers=IVI:${year}IVI_h21v04&layers=IVI:${year}IVI_h21v05&layers=IVI:${year}IVI_h22v03&layers=IVI:${year}IVI_h22v04&layers=IVI:${year}IVI_h22v05&layers=IVI:${year}IVI_h23v03&layers=IVI:${year}IVI_h23v04&layers=IVI:${year}IVI_h23v05&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&url=http://geoserver2.ccalm.org/wms + + + + ${year}IVI + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + WGS84 + false + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + + + + + + + + + wms + + + + + + + + 1 + 1 + 1 + + + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + + 0 + + + + + + + + + true + 2 + + + false + + + WGS84 + + + 255 + 255 + 255 + 0 + 255 + 255 + 255 + + + false + + + true + false + 0 + 30 + 16 + 50 + 0 + false + true + false + + + 1 + + + m2 + meters + + + + + + + + + + + + + ������ �. + 2019-06-10T14:55:55 + + + + diff --git a/src/main/webapp/resources/QGIS/NDSI.qgs b/src/main/webapp/resources/QGIS/NDSI.qgs new file mode 100644 index 0000000..dce4f18 --- /dev/null +++ b/src/main/webapp/resources/QGIS/NDSI.qgs @@ -0,0 +1,354 @@ + + + + + + + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["unknown"],AREA["World - 85°S to 85°N"],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + OpenStreetMap_b190df4b_967b_471d_9b9c_3cb1d5e3b416 + h23v05_h23v04_h23v03_h22v05_h22v04_h22v03_h21v05_h21v04_h21v03_h20v04_h20v03_9603ac31_1df8_4ac6_a749_7b7e66bb658b + + + + + + + + meters + + 3863030.08689398271963 + 3270963.49336460698395967 + 9122876.02687616087496281 + 8530809.43334678560495377 + + 0 + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["unknown"],AREA["World - 85°S to 85°N"],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + 0 + + + + + + + + + + + + + + + + + -20037508.34278924390673637 + -20037508.34278925508260727 + 20037508.34278924390673637 + 20037508.34278924390673637 + + OpenStreetMap_b190df4b_967b_471d_9b9c_3cb1d5e3b416 + crs=EPSG:3857&format&type=xyz&url=http://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png + + + + OpenStreetMap + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["unknown"],AREA["World - 85°S to 85°N"],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + wms + + + + + + + + 1 + 1 + 1 + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + + 0 + + + + 2906345.49411173490807414 + 3503584.68813749961555004 + 13358323.19605071656405926 + 8399737.88861873932182789 + + h23v05_h23v04_h23v03_h22v05_h22v04_h22v03_h21v05_h21v04_h21v03_h20v04_h20v03_9603ac31_1df8_4ac6_a749_7b7e66bb658b + contextualWMSLegend=0&crs=EPSG:3857&dpiMode=7&featureCount=10&format=image/png&layers=NDSI:${day}NDSI_h20v03&layers=NDSI:${day}NDSI_h20v04&layers=NDSI:${day}NDSI_h21v03&layers=NDSI:${day}NDSI_h21v04&layers=NDSI:${day}NDSI_h21v05&layers=NDSI:${day}NDSI_h22v03&layers=NDSI:${day}NDSI_h22v04&layers=NDSI:${day}NDSI_h22v05&layers=NDSI:${day}NDSI_h23v03&layers=NDSI:${day}NDSI_h23v04&layers=NDSI:${day}NDSI_h23v05&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&url=http://geoserver2.ccalm.org/wms + + + + ${day}NDSI + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["unknown"],AREA["World - 85°S to 85°N"],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + true + + + + + + + + + + + + + wms + + + + + + + + 1 + 1 + 1 + + + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + + 0 + + + + + + + + + 255 + 255 + 255 + 255 + 0 + 255 + 255 + + + false + + + WGS84 + + + m2 + meters + + + 50 + 5 + 16 + 30 + 2.5 + true + false + false + 0 + 0 + false + false + true + 0 + 255,0,0,255 + + + false + + + true + 2 + + + 1 + + + + + + + + + + + + + ������ �. + 2019-06-10T14:55:55 + + + + + + + + + + + + + diff --git a/src/main/webapp/resources/QGIS/NDVI.qgs b/src/main/webapp/resources/QGIS/NDVI.qgs new file mode 100644 index 0000000..2959c3a --- /dev/null +++ b/src/main/webapp/resources/QGIS/NDVI.qgs @@ -0,0 +1,326 @@ + + + + + + + + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + WGS84 + false + + + + + + + + + + + + OpenStreetMap_b190df4b_967b_471d_9b9c_3cb1d5e3b416 + h23v05_h23v04_h23v03_h22v05_h22v04_h22v03_h21v05_h21v04_h21v03_h20v04_h20v03_9603ac31_1df8_4ac6_a749_7b7e66bb658b + + + + + + + + meters + + 2465883.50908621679991484 + 264579.77565301861613989 + 12985575.38905057311058044 + 10784271.65561737865209579 + + 0 + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + WGS84 + false + + + 0 + + + + + + + + + + + + + + + + + -20037508.34278924390673637 + -20037508.34278925508260727 + 20037508.34278924390673637 + 20037508.34278924390673637 + + OpenStreetMap_b190df4b_967b_471d_9b9c_3cb1d5e3b416 + crs=EPSG:3857&format&type=xyz&url=http://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png + + + + OpenStreetMap + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + WGS84 + false + + + + + + + + + + + + + + + + 0 + 0 + + + + + true + + + + + wms + + + + + + + + 1 + 1 + 1 + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + + 0 + + + + 2906345.494111736305058 + 3503584.68813749961555004 + 13358323.19605071656405926 + 8399737.88861873932182789 + + h23v05_h23v04_h23v03_h22v05_h22v04_h22v03_h21v05_h21v04_h21v03_h20v04_h20v03_9603ac31_1df8_4ac6_a749_7b7e66bb658b + contextualWMSLegend=0&crs=EPSG:3857&dpiMode=7&featureCount=10&format=image/png&layers=NDVI:${day}NDVI_h20v03&layers=NDVI:${day}NDVI_h20v04&layers=NDVI:${day}NDVI_h21v03&layers=NDVI:${day}NDVI_h21v04&layers=NDVI:${day}NDVI_h21v05&layers=NDVI:${day}NDVI_h22v03&layers=NDVI:${day}NDVI_h22v04&layers=NDVI:${day}NDVI_h22v05&layers=NDVI:${day}NDVI_h23v03&layers=NDVI:${day}NDVI_h23v04&layers=NDVI:${day}NDVI_h23v05&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&url=http://geoserver2.ccalm.org/wms + + + + ${day}NDVI + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + WGS84 + false + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + + + + + + + + + wms + + + + + + + + 1 + 1 + 1 + + + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + + 0 + + + + + + + + + true + 2 + + + false + + + WGS84 + + + 255 + 255 + 255 + 0 + 255 + 255 + 255 + + + false + + + true + false + 0 + 30 + 16 + 50 + 0 + false + true + false + + + 1 + + + m2 + meters + + + + + + + + + + + + + ������ �. + 2019-06-10T14:55:55 + + + + diff --git a/src/main/webapp/resources/QGIS/NDWI.qgs b/src/main/webapp/resources/QGIS/NDWI.qgs new file mode 100644 index 0000000..8691d78 --- /dev/null +++ b/src/main/webapp/resources/QGIS/NDWI.qgs @@ -0,0 +1,354 @@ + + + + + + + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["unknown"],AREA["World - 85°S to 85°N"],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + OpenStreetMap_b190df4b_967b_471d_9b9c_3cb1d5e3b416 + h23v05_h23v04_h23v03_h22v05_h22v04_h22v03_h21v05_h21v04_h21v03_h20v04_h20v03_9603ac31_1df8_4ac6_a749_7b7e66bb658b + + + + + + + + meters + + 3863030.08689398271963 + 3270963.49336460698395967 + 9122876.02687616087496281 + 8530809.43334678560495377 + + 0 + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["unknown"],AREA["World - 85°S to 85°N"],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + 0 + + + + + + + + + + + + + + + + + -20037508.34278924390673637 + -20037508.34278925508260727 + 20037508.34278924390673637 + 20037508.34278924390673637 + + OpenStreetMap_b190df4b_967b_471d_9b9c_3cb1d5e3b416 + crs=EPSG:3857&format&type=xyz&url=http://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png + + + + OpenStreetMap + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["unknown"],AREA["World - 85°S to 85°N"],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + wms + + + + + + + + 1 + 1 + 1 + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + + 0 + + + + 2906345.49411173490807414 + 3503584.68813749961555004 + 13358323.19605071656405926 + 8399737.88861873932182789 + + h23v05_h23v04_h23v03_h22v05_h22v04_h22v03_h21v05_h21v04_h21v03_h20v04_h20v03_9603ac31_1df8_4ac6_a749_7b7e66bb658b + contextualWMSLegend=0&crs=EPSG:3857&dpiMode=7&featureCount=10&format=image/png&layers=NDWI:${day}NDWI_h20v03&layers=NDWI:${day}NDWI_h20v04&layers=NDWI:${day}NDWI_h21v03&layers=NDWI:${day}NDWI_h21v04&layers=NDWI:${day}NDWI_h21v05&layers=NDWI:${day}NDWI_h22v03&layers=NDWI:${day}NDWI_h22v04&layers=NDWI:${day}NDWI_h22v05&layers=NDWI:${day}NDWI_h23v03&layers=NDWI:${day}NDWI_h23v04&layers=NDWI:${day}NDWI_h23v05&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&url=http://geoserver2.ccalm.org/wms + + + + ${day}NDWI + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["unknown"],AREA["World - 85°S to 85°N"],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + true + + + + + + + + + + + + + wms + + + + + + + + 1 + 1 + 1 + + + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + + 0 + + + + + + + + + 255 + 255 + 255 + 255 + 0 + 255 + 255 + + + false + + + WGS84 + + + m2 + meters + + + 50 + 5 + 16 + 30 + 2.5 + true + false + false + 0 + 0 + false + false + true + 0 + 255,0,0,255 + + + false + + + true + 2 + + + 1 + + + + + + + + + + + + + ������ �. + 2019-06-10T14:55:55 + + + + + + + + + + + + + diff --git a/src/main/webapp/resources/QGIS/NDWI_CMP.qgs b/src/main/webapp/resources/QGIS/NDWI_CMP.qgs new file mode 100644 index 0000000..c087c8e --- /dev/null +++ b/src/main/webapp/resources/QGIS/NDWI_CMP.qgs @@ -0,0 +1,354 @@ + + + + + + + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["unknown"],AREA["World - 85°S to 85°N"],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + OpenStreetMap_b190df4b_967b_471d_9b9c_3cb1d5e3b416 + h23v05_h23v04_h23v03_h22v05_h22v04_h22v03_h21v05_h21v04_h21v03_h20v04_h20v03_9603ac31_1df8_4ac6_a749_7b7e66bb658b + + + + + + + + meters + + 3863030.08689398271963 + 3270963.49336460698395967 + 9122876.02687616087496281 + 8530809.43334678560495377 + + 0 + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["unknown"],AREA["World - 85°S to 85°N"],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + 0 + + + + + + + + + + + + + + + + + -20037508.34278924390673637 + -20037508.34278925508260727 + 20037508.34278924390673637 + 20037508.34278924390673637 + + OpenStreetMap_b190df4b_967b_471d_9b9c_3cb1d5e3b416 + crs=EPSG:3857&format&type=xyz&url=http://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png + + + + OpenStreetMap + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["unknown"],AREA["World - 85°S to 85°N"],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + wms + + + + + + + + 1 + 1 + 1 + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + + 0 + + + + 2906345.49411173490807414 + 3503584.68813749961555004 + 13358323.19605071656405926 + 8399737.88861873932182789 + + h23v05_h23v04_h23v03_h22v05_h22v04_h22v03_h21v05_h21v04_h21v03_h20v04_h20v03_9603ac31_1df8_4ac6_a749_7b7e66bb658b + contextualWMSLegend=0&crs=EPSG:3857&dpiMode=7&featureCount=10&format=image/png&layers=NDWI_CMP:${day}NDWI_CMP_h20v03&layers=NDWI_CMP:${day}NDWI_CMP_h20v04&layers=NDWI_CMP:${day}NDWI_CMP_h21v03&layers=NDWI_CMP:${day}NDWI_CMP_h21v04&layers=NDWI_CMP:${day}NDWI_CMP_h21v05&layers=NDWI_CMP:${day}NDWI_CMP_h22v03&layers=NDWI_CMP:${day}NDWI_CMP_h22v04&layers=NDWI_CMP:${day}NDWI_CMP_h22v05&layers=NDWI_CMP:${day}NDWI_CMP_h23v03&layers=NDWI_CMP:${day}NDWI_CMP_h23v04&layers=NDWI_CMP:${day}NDWI_CMP_h23v05&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&styles=&url=http://geoserver2.ccalm.org/wms + + + + ${day}NDWI_CMP + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",DATUM["World Geodetic System 1984",ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["unknown"],AREA["World - 85°S to 85°N"],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + true + + + + + + + + + + + + + wms + + + + + + + + 1 + 1 + 1 + + + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + + 0 + + + + + + + + + 255 + 255 + 255 + 255 + 0 + 255 + 255 + + + false + + + WGS84 + + + m2 + meters + + + 50 + 5 + 16 + 30 + 2.5 + true + false + false + 0 + 0 + false + false + true + 0 + 255,0,0,255 + + + false + + + true + 2 + + + 1 + + + + + + + + + + + + + ������ �. + 2019-06-10T14:55:55 + + + + + + + + + + + + + diff --git a/src/main/webapp/resources/QGIS/SMAP.qgs b/src/main/webapp/resources/QGIS/SMAP.qgs new file mode 100644 index 0000000..3d75dd4 --- /dev/null +++ b/src/main/webapp/resources/QGIS/SMAP.qgs @@ -0,0 +1,724 @@ + + + + + + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + OpenStreetMap_3eefb26a_f2d2_4a0b_b3e0_3ed661cbbc5d + _8357e0b1_ef46_4436_ac52_f7a1b071a7a1 + + + + + + + + + meters + + -21039383.75992870703339577 + -21039383.75992871075868607 + 21039383.75992870703339577 + 21039383.75992876291275024 + + 0 + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + 0 + + + + + + + + + + + + + + degrees + + 0 + 0 + 0 + 0 + + 0 + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + 0 + + + + __________558d9f32_96f4_4271_9cb4_b90b4ebc6580 + + + + + Аннотации + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + + + 1 + 1 + 1 + 0 + + + + 1 + 0 + + + + + + -20037508.34278924390673637 + -20037508.34278924763202667 + 20037508.34278924390673637 + 20037508.34278924763202667 + + + -180 + -85.05112877980660357 + 179.99999999999997158 + 85.05112877980660357 + + OpenStreetMap_3eefb26a_f2d2_4a0b_b3e0_3ed661cbbc5d + type=xyz&url=http://tile.openstreetmap.org/{z}/{x}/{y}.png + + + + OpenStreetMap + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + Тайлы OpenStreetMap + + + dataset + Тайлы OpenStreetMap + Проект OpenStreetMap создан картографическим сообществом, создающим и распространяющим данные о дорогах, территориях, границах и многом другом по всему миру. + + + + + + Базовая карта и данные подготовлены сообществом OpenStreetMap (CC-BY-SA). © https://www.openstreetmap.org and contributors. + Лицензия Open Data Commons Open Database (ODbL) + Creative Commons Attribution-ShareAlike (CC-BY-SA) + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + wms + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + resamplingFilter + + 0 + + + + -20037508.33720675110816956 + -19983484.6311938650906086 + 20037055.05812187492847443 + 20028962.62836629152297974 + + + -179.99999994985159901 + -85.00908611398735104 + 179.99592807455246657 + 85.04450187956545903 + + _8357e0b1_ef46_4436_ac52_f7a1b071a7a1 + IgnoreGetMapUrl=1&contextualWMSLegend=0&crs=EPSG:3857&dpiMode=7&featureCount=10&format=image/png&layers=SMAP:${day}SMAP&styles&tilePixelRatio=0&url=http://geoserver2.ccalm.org/wms?viewparams%3Dtime_start:1667260800;time_end%3D1665532800; + + + + ${day}SMAP + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + wms + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + resamplingFilter + + 0 + + + + + + + + + 0 + + + 255 + 255 + 255 + 255 + 0 + 255 + 255 + + + false + + + EPSG:7030 + + + m2 + meters + + + 5 + 2.5 + false + false + false + 1 + 0 + false + false + true + 0 + 255,0,0,255 + + + false + + + true + 2 + + + 1 + + + + + + + + + + + + + + + + + + + Иванов И. + 2023-09-08T15:00:38 + + + + + + + + + + + + + + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + diff --git a/src/main/webapp/resources/QGIS/air_temperature.qgs b/src/main/webapp/resources/QGIS/air_temperature.qgs new file mode 100644 index 0000000..a951e62 --- /dev/null +++ b/src/main/webapp/resources/QGIS/air_temperature.qgs @@ -0,0 +1,1924 @@ + + + + + + + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + countriesdistricts20170803132507662 + countriesregions20170803132506793 + countries20170803132508430 + OpenStreetMap_9da8fe98_9174_4b23_b8e4_8d0c9fbf90ce + air_temperature_${country}_ffb52ce7_928b_45d1_867b_6d839c3c062b + + + + + + + + + meters + + 3396315.6506110280752182 + 1061190.67332473304122686 + 13916007.53057394921779633 + 9755055.02208343148231506 + + 0 + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + Annotations_c88afc0a_8ca0_4f92_9f48_101ecee4c81a + + + + + + + + + + 0 + 0 + + + + + false + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + + 1 + 0 + + + + + + -20037508.34278924390673637 + -20037508.34278924763202667 + 20037508.34278924390673637 + 20037508.34278924763202667 + + + -180 + -85.05112877980660357 + 179.99999999999997158 + 85.05112877980660357 + + OpenStreetMap_9da8fe98_9174_4b23_b8e4_8d0c9fbf90ce + crs=EPSG:3857&format&type=xyz&url=http://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png&zmax=18&zmin=0 + + + + OpenStreetMap + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + OpenStreetMap tiles + + + dataset + OpenStreetMap tiles + OpenStreetMap is built by a community of mappers that contribute and maintain data about roads, trails, cafés, railway stations, and much more, all over the world. + + + + + Base map and data from OpenStreetMap and OpenStreetMap Foundation (CC-BY-SA). © https://www.openstreetmap.org and contributors. + Open Data Commons Open Database License (ODbL) + Creative Commons Attribution-ShareAlike (CC-BY-SA) + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + wms + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + resamplingFilter + + 0 + + + + 60.51760340000009819 + 29.37720000000010145 + 74.88986199999999371 + 38.48992170000010304 + + + 60.51760340000009819 + 29.37720000000010145 + 74.88986199999999371 + 38.48992170000010304 + + countries20170803132508430 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='country_id' srid=4326 type=MultiPolygon checkPrimaryKeyUnicity='1' table="main"."view_countries" (geom) sql=${sql2} + + + + Country + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + postgres + + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0.7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + "name" + + + + + 60.47208339733759885 + 29.37706453607049895 + 74.88945114815180659 + 38.49079207558700233 + + + 60.47208339733759885 + 29.37706453607049895 + 74.88945114815180659 + 38.49079207558700233 + + countriesdistricts20170803132507662 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon checkPrimaryKeyUnicity='1' table="main"."view_countriesdistricts" (geom) sql=${sql2} + + + + Districts + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + postgres + + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0.7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + "name" + + + + + 60.51760339999999871 + 29.37719999999999843 + 74.88986199999999371 + 38.48992169999999646 + + + 60.51760339999999871 + 29.37719999999999843 + 74.88986199999999371 + 38.48992169999999646 + + countriesregions20170803132506793 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon checkPrimaryKeyUnicity='1' table="main"."view_countriesregions" (geom) sql=${sql2} + + + + Regions + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + postgres + + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0.7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + "name" + + + + + 6762659.06569136958569288 + 3439440.06073126150295138 + 8293302.06409887876361609 + 4614802.87514934223145247 + + + 60.75 + 29.50000000000000355 + 74.49999999999994316 + 38.25 + + air_temperature_${country}_ffb52ce7_928b_45d1_867b_6d839c3c062b + IgnoreGetMapUrl=1&contextualWMSLegend=0&crs=EPSG:3857&dpiMode=7&featureCount=10&format=image/png&layers=cite:air_temperature_${country}&styles&url=http://geoserver2.ccalm.org/wms?viewparams=p1:${time}; + + + + air_temperature_${country} + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + wms + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + resamplingFilter + + 0 + + + + + + + + + + + + + 2 + 0 + 2 + off + + + + + + current_layer + + + 255 + 255 + 255 + 255 + 0 + 255 + 255 + + + false + + + m2 + meters + + + 5 + 2.5 + false + false + 0 + 0 + false + false + true + 0 + 255,0,0,255 + + + false + + + true + 2 + + + 3857 + +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 +wktext +no_defs + EPSG:3857 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + diff --git a/src/main/webapp/resources/QGIS/frmlocust_adults_density.qgs b/src/main/webapp/resources/QGIS/frmlocust_adults_density.qgs new file mode 100644 index 0000000..9f6a1b7 --- /dev/null +++ b/src/main/webapp/resources/QGIS/frmlocust_adults_density.qgs @@ -0,0 +1,1630 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + meters + + 4606484.6726676719263196 + 3728012.39886604063212872 + 9866330.61264913156628609 + 8074944.57324538938701153 + + 0 + 1 + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + 0 + + + + + + + + + + + view_frmlocust_adults_density20170412100319671 + countriesdistricts20170803132507662 + countriesregions20170803132506793 + countries20170803132508430 + OpenLayers_plugin_layer20170821155911549 + + + + + + + + + + + + + + + + + + + + + + + + + + + -20037508.33999999985098839 + -20037508.33999999985098839 + 20037508.33999999985098839 + 20037508.33999999985098839 + + OpenLayers_plugin_layer20170821155911549 + + + + + Bing Aerial with labels + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + + + + + + + view_frmlocust_adults_density20170412100319671 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=Point table="main"."view_frmlocust_adults_density" (geom) sql=${sql} + + + + trt('Adult_density') + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + 0 + generatedlayout + + + + + + + + + + + + + + + + + + + + + 69.26495230000000447 + 39.17284370000000138 + 80.22957929999999749 + 43.26679709999999801 + + countries20170803132508430 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='country_id' srid=4326 type=MultiPolygon table="main"."view_countries" (geom) sql=${sql2} + + + + Country + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + countriesdistricts20170803132507662 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon table="main"."view_countriesdistricts" (geom) sql=${sql2} + + + + Districts + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + countriesregions20170803132506793 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon table="main"."view_countriesregions" (geom) sql=${sql2} + + + + Regions + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + false + + + + + + + + 2 + true + MU + + + false + + + + false + + WGS84 + + 8 + false + + + + + + + 0 + 255 + 255 + 255 + 255 + 255 + 255 + + + 2 + + + current_layer + + + + off + 0 + + + + + + + + + None + + + false + + + +proj=longlat +datum=WGS84 +no_defs + EPSG:4326 + 3452 + 1 + + + + + + true + 255 + + + conditions unknown + 90 + + meters + m2 + + + + + diff --git a/src/main/webapp/resources/QGIS/frmlocust_bands.qgs b/src/main/webapp/resources/QGIS/frmlocust_bands.qgs new file mode 100644 index 0000000..c0adb53 --- /dev/null +++ b/src/main/webapp/resources/QGIS/frmlocust_bands.qgs @@ -0,0 +1,1620 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + meters + + 4606484.6726676719263196 + 3728012.39886604063212872 + 9866330.61264913156628609 + 8074944.57324538938701153 + + 0 + 1 + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + 0 + + + + + + + + + + + view_frmlocust_bands20170217175159425 + countriesdistricts20170803132507662 + countriesregions20170803132506793 + countries20170803132508430 + OpenStreetMap20170217113330254 + + + + + + + + + + + + + + + + + + + + + + + + + + + + -20037508.33999999985098839 + -20037508.33999999985098839 + 20037508.33999999985098839 + 20037508.33999999985098839 + + OpenLayers_plugin_layer20170821155911549 + + + + + Bing Aerial with labels + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + + + + + + + + view_frmlocust_bands20170217175159425 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' estimatedmetadata=true table="main"."view_frmlocust_bands" (geom) sql=${sql} + + + + trt('Number_of_bands') + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + 69.26495230000000447 + 39.17284370000000138 + 80.22957929999999749 + 43.26679709999999801 + + countries20170803132508430 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='country_id' srid=4326 type=MultiPolygon table="main"."view_countries" (geom) sql=${sql2} + + + + Country + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + countriesdistricts20170803132507662 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon table="main"."view_countriesdistricts" (geom) sql=${sql2} + + + + Districts + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + countriesregions20170803132506793 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon table="main"."view_countriesregions" (geom) sql=${sql2} + + + + Regions + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + false + + + + + + + + 2 + true + MU + + + false + + + + false + + WGS84 + + 8 + false + + + + + + + 0 + 255 + 255 + 255 + 255 + 255 + 255 + + + 2 + + view_frmlocust_bands20170217175159425 + + + disabled + + current_layer + + + 2 + + + to_vertex_and_segment + + off + 0 + + 0.000000 + + + + + + + + + None + + + false + + + +proj=longlat +datum=WGS84 +no_defs + EPSG:4326 + 3452 + 1 + + + + + + true + 255 + + + conditions unknown + 90 + + meters + m2 + + + + + diff --git a/src/main/webapp/resources/QGIS/frmlocust_hoppers_density.qgs b/src/main/webapp/resources/QGIS/frmlocust_hoppers_density.qgs new file mode 100644 index 0000000..54fb7ab --- /dev/null +++ b/src/main/webapp/resources/QGIS/frmlocust_hoppers_density.qgs @@ -0,0 +1,1637 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + meters + + 4606484.6726676719263196 + 3728012.39886604063212872 + 9866330.61264913156628609 + 8074944.57324538938701153 + + 0 + 1 + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + 0 + + + + + + + + + + + view_frmlocust_hoppers_density20170217163015793 + countriesdistricts20170803132507662 + countriesregions20170803132506793 + countries20170803132508430 + OpenStreetMap20170217113330254 + + + + + + + + + + + + + + + + + + + + + + + + + + + + -20037508.33999999985098839 + -20037508.33999999985098839 + 20037508.33999999985098839 + 20037508.33999999985098839 + + OpenLayers_plugin_layer20170821155911549 + + + + + Bing Aerial with labels + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + + + + + + + view_frmlocust_hoppers_density20170217163015793 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' estimatedmetadata=true table="main"."view_frmlocust_hoppers_density" (geom) sql=${sql} + + + + trt('Hopper_density') + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + COALESCE( "terrain", '<NULL>' ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + 69.26495230000000447 + 39.17284370000000138 + 80.22957929999999749 + 43.26679709999999801 + + countries20170803132508430 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='country_id' srid=4326 type=MultiPolygon table="main"."view_countries" (geom) sql=${sql2} + + + + Country + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + countriesdistricts20170803132507662 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon table="main"."view_countriesdistricts" (geom) sql=${sql2} + + + + Districts + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + countriesregions20170803132506793 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon table="main"."view_countriesregions" (geom) sql=${sql2} + + + + Regions + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + false + + + + + + + + 2 + true + MU + + + false + + + + false + + WGS84 + + 8 + false + + + + + + + 0 + 255 + 255 + 255 + 255 + 255 + 255 + + + 2 + + view_frmlocust_hoppers_density20170217163015793 + + + disabled + + current_layer + + + 2 + + + to_vertex_and_segment + + off + 0 + + 0.000000 + + + + + + + + + None + + + false + + + +proj=longlat +datum=WGS84 +no_defs + EPSG:4326 + 3452 + 1 + + + + + + true + 255 + + + conditions unknown + 90 + + meters + m2 + + + + + diff --git a/src/main/webapp/resources/QGIS/frmlocust_pods_density.qgs b/src/main/webapp/resources/QGIS/frmlocust_pods_density.qgs new file mode 100644 index 0000000..1f14106 --- /dev/null +++ b/src/main/webapp/resources/QGIS/frmlocust_pods_density.qgs @@ -0,0 +1,1574 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + meters + + 4606484.6726676719263196 + 3728012.39886604063212872 + 9866330.61264913156628609 + 8074944.57324538938701153 + + 0 + 1 + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + 0 + + + + + + + + + + + view_frmlocust_pods_density20170220095821682 + + countriesdistricts20170803132507662 + countriesregions20170803132506793 + countries20170803132508430 + + OpenStreetMap20170220110923709 + + + + + + + + + + + + + + + + + + + + + + + + + + + -20037508.33999999985098839 + -20037508.33999999985098839 + 20037508.33999999985098839 + 20037508.33999999985098839 + + OpenLayers_plugin_layer20170821155911549 + + + + + Bing Aerial with labels + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + + + + + + + + 0 + 0 + 72.49960000000000093 + 52.2862000000000009 + + view_frmlocust_pods_density20170220095821682 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' estimatedmetadata=true table="main"."view_frmlocust_pods_density" (geom) sql=${sql} + + + + trt('Egg_pods_density_m2') + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + C:/Users/IVANOV~1.IST/AppData/Local/Temp + + + + + + + + + + + + + + + + C:/Users/IVANOV~1.IST/AppData/Local/Temp + + 0 + C:/Users/IVANOV~1.IST/AppData/Local/Temp + + 0 + generatedlayout + + + + + + + + + + + + + + COALESCE( "terrain", '<NULL>' ) + + + + + + 69.26495230000000447 + 39.17284370000000138 + 80.22957929999999749 + 43.26679709999999801 + + countries20170803132508430 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='country_id' srid=4326 type=MultiPolygon table="main"."view_countries" (geom) sql=${sql2} + + + + Country + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + countriesdistricts20170803132507662 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon table="main"."view_countriesdistricts" (geom) sql=${sql2} + + + + Districts + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + countriesregions20170803132506793 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon table="main"."view_countriesregions" (geom) sql=${sql2} + + + + Regions + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + + + + + + + meters + m2 + + + +proj=longlat +datum=WGS84 +no_defs + EPSG:4326 + 3452 + 1 + + + false + + + 0 + 255 + 255 + 255 + 255 + 255 + 255 + + + 2 + current_layer + off + 0 + + + 2 + true + + + false + + + + diff --git a/src/main/webapp/resources/QGIS/frmlocust_swarms.qgs b/src/main/webapp/resources/QGIS/frmlocust_swarms.qgs new file mode 100644 index 0000000..84c975d --- /dev/null +++ b/src/main/webapp/resources/QGIS/frmlocust_swarms.qgs @@ -0,0 +1,1614 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + meters + + 4606484.6726676719263196 + 3728012.39886604063212872 + 9866330.61264913156628609 + 8074944.57324538938701153 + + 0 + 1 + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + 0 + + + + + + + + + + + view_frmlocust_swarms20170217175826615 + countriesdistricts20170803132507662 + countriesregions20170803132506793 + countries20170803132508430 + OpenStreetMap20170217113330254 + + + + + + + + + + + + + + + + + + + + + + + + -20037508.33999999985098839 + -20037508.33999999985098839 + 20037508.33999999985098839 + 20037508.33999999985098839 + + OpenLayers_plugin_layer20170821155911549 + + + + + Bing Aerial with labels + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + + + + + + + view_frmlocust_swarms20170217175826615 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' estimatedmetadata=true table="main"."view_frmlocust_swarms" (geom) sql=${sql} + + + + trt('Swarms') + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + 69.26495230000000447 + 39.17284370000000138 + 80.22957929999999749 + 43.26679709999999801 + + countries20170803132508430 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='country_id' srid=4326 type=MultiPolygon table="main"."view_countries" (geom) sql=${sql2} + + + + Country + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + countriesdistricts20170803132507662 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon table="main"."view_countriesdistricts" (geom) sql=${sql2} + + + + Districts + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + countriesregions20170803132506793 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon table="main"."view_countriesregions" (geom) sql=${sql2} + + + + Regions + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + false + + + + + + + + 2 + true + MU + + + false + + + + false + + WGS84 + + 8 + false + + + + + + + 0 + 255 + 255 + 255 + 255 + 255 + 255 + + + 2 + + view_frmlocust_swarms20170217175826615 + + + disabled + + current_layer + + + 2 + + + to_vertex_and_segment + + off + 0 + + 0.000000 + + + + + + + + + None + + + false + + + +proj=longlat +datum=WGS84 +no_defs + EPSG:4326 + 3452 + 1 + + + + + + true + 255 + + + conditions unknown + 90 + + meters + m2 + + + + + diff --git a/src/main/webapp/resources/QGIS/frmlocustdel.qgs b/src/main/webapp/resources/QGIS/frmlocustdel.qgs new file mode 100644 index 0000000..a68fb1d --- /dev/null +++ b/src/main/webapp/resources/QGIS/frmlocustdel.qgs @@ -0,0 +1,1498 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + meters + + 4606484.6726676719263196 + 3728012.39886604063212872 + 9866330.61264913156628609 + 8074944.57324538938701153 + + 0 + 1 + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + 0 + + + + + + + + + + + view_frmlocustdel20170220111910253 + countriesdistricts20170803132507662 + countriesregions20170803132506793 + countries20170803132508430 + OpenStreetMap20170220112057673 + + + + + + + + + + + + + + + + + + + + + + + + + + + -20037508.33999999985098839 + -20037508.33999999985098839 + 20037508.33999999985098839 + 20037508.33999999985098839 + + OpenLayers_plugin_layer20170821155911549 + + + + + Bing Aerial with labels + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + + + + + + + + 0 + 0 + 72.03010000000000446 + 41.36939999999999884 + + view_frmlocustdel20170220111910253 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' estimatedmetadata=true table="main"."view_frmlocustdel" (geom) sql=${sql} + + + + trt('Distribution_of_locust') + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + 69.26495230000000447 + 39.17284370000000138 + 80.22957929999999749 + 43.26679709999999801 + + countries20170803132508430 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='country_id' srid=4326 type=MultiPolygon table="main"."view_countries" (geom) sql=${sql2} + + + + Country + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + countriesdistricts20170803132507662 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon table="main"."view_countriesdistricts" (geom) sql=${sql2} + + + + Districts + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + countriesregions20170803132506793 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon table="main"."view_countriesregions" (geom) sql=${sql2} + + + + Regions + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 30 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + + + + + + + meters + m2 + + + +proj=longlat +datum=WGS84 +no_defs + EPSG:4326 + 3452 + 1 + + + false + + + 0 + 255 + 255 + 255 + 255 + 255 + 255 + + + 2 + current_layer + off + 0 + + + 2 + true + + + false + + + + diff --git a/src/main/webapp/resources/QGIS/frmlocustinfo_p2.qgs b/src/main/webapp/resources/QGIS/frmlocustinfo_p2.qgs new file mode 100644 index 0000000..f5ad4b7 --- /dev/null +++ b/src/main/webapp/resources/QGIS/frmlocustinfo_p2.qgs @@ -0,0 +1,539 @@ + + + + + + + + + + + + + + + + + meters + + 4606484.6726676719263196 + 3728012.39886604063212872 + 9866330.61264913156628609 + 8074944.57324538938701153 + + 0 + 1 + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + 0 + + + + + + + + view_frmlocustinfo_p2_${year}20170221133600806 + OpenStreetMap20170221155223210 + + + + + + + + + + + + + + + + -20037508.33999999985098839 + -20037508.33999999985098839 + 20037508.33999999985098839 + 20037508.33999999985098839 + + OpenLayers_plugin_layer20170821155911549 + + + + + Bing Aerial with labels + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + + + + + + + + -180 + 38.39295510000000178 + 180 + 82.05862320000009902 + + view_frmlocustinfo_p2_${year}20170221133600806 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='region_id' estimatedmetadata=true srid=4326 type=MultiPolygon table="main"."view_frmlocustinfo_p2_${year}" (geom) sql=${sql} + + + + trt('Maps_of_areas_infested_above_Economic_Threshold_(ET)') + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + + meters + m2 + + + +proj=longlat +datum=WGS84 +no_defs + EPSG:4326 + 3452 + 1 + + + 0 + false + 30 + false + false + true + 50 + 16 + true + false + + + false + + + 0 + 255 + 255 + 255 + 255 + 255 + 255 + + + 2 + + view_frmlocustinfo_p2_${year}20170221133600806 + + + disabled + + current_layer + + + 2 + + + to_vertex_and_segment + + off + 0 + + 0.000000 + + + + 2 + true + + + false + + + + diff --git a/src/main/webapp/resources/QGIS/frmlocustinfo_p2r.qgs b/src/main/webapp/resources/QGIS/frmlocustinfo_p2r.qgs new file mode 100644 index 0000000..7e995b1 --- /dev/null +++ b/src/main/webapp/resources/QGIS/frmlocustinfo_p2r.qgs @@ -0,0 +1,509 @@ + + + + + + + + + + + + + + + + + meters + + 4606484.6726676719263196 + 3728012.39886604063212872 + 9866330.61264913156628609 + 8074944.57324538938701153 + + 0 + 1 + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + 0 + + + + + + + + view_frmlocustinfo_p2r_${year}20170221133600806 + OpenStreetMap20170221155223210 + + + + + + + + + + + + + + + + -180 + 38.39295510000000178 + 180 + 82.05862320000009902 + + view_frmlocustinfo_p2r_${year}20170221133600806 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='region_id' estimatedmetadata=true srid=4326 type=MultiPolygon table="main"."view_frmlocustinfo_p2r_${year}" (geom) sql=${sql} + + + + trt('Maps_of_areas_infested_above_Economic_Threshold_(ET)') + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + + + + + + + + + meters + m2 + + + +proj=longlat +datum=WGS84 +no_defs + EPSG:4326 + 3452 + 1 + + + 0 + false + 30 + false + false + true + 50 + 16 + true + false + + + false + + + 0 + 255 + 255 + 255 + 255 + 255 + 255 + + + 2 + + view_frmlocustinfo_p2r_${year}20170221133600806 + + + disabled + + current_layer + + + 2 + + + to_vertex_and_segment + + off + 0 + + 0.000000 + + + + 2 + true + + + false + + + + diff --git a/src/main/webapp/resources/QGIS/frmlocustinfo_p3.qgs b/src/main/webapp/resources/QGIS/frmlocustinfo_p3.qgs new file mode 100644 index 0000000..97d3191 --- /dev/null +++ b/src/main/webapp/resources/QGIS/frmlocustinfo_p3.qgs @@ -0,0 +1,478 @@ + + + + + + + + + + + + + + + + + meters + + 4606484.6726676719263196 + 3728012.39886604063212872 + 9866330.61264913156628609 + 8074944.57324538938701153 + + 0 + 1 + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + 0 + + + + + + + + view_frmlocustinfo_p3_201520170221141235646 + OpenStreetMap20170221162957823 + + + + + + + + + + + + + + + -180 + 38.39295510000000178 + 180 + 82.05862320000009902 + + view_frmlocustinfo_p3_201520170221141235646 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='region_id' estimatedmetadata=true srid=4326 type=MultiPolygon table="main"."view_frmlocustinfo_p3_${year}" (geom) sql=${sql} + + + + trt('Maps_of_treated_areas_above_ET') + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + COALESCE( "name", '<NULL>' ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + meters + m2 + + + +proj=longlat +datum=WGS84 +no_defs + EPSG:4326 + 3452 + 1 + + + false + + + 0 + 255 + 255 + 255 + 255 + 255 + 255 + + + 2 + current_layer + off + 0 + + + 2 + true + + + false + + + + diff --git a/src/main/webapp/resources/QGIS/frmlocustinfo_p3r.qgs b/src/main/webapp/resources/QGIS/frmlocustinfo_p3r.qgs new file mode 100644 index 0000000..0fdd379 --- /dev/null +++ b/src/main/webapp/resources/QGIS/frmlocustinfo_p3r.qgs @@ -0,0 +1,508 @@ + + + + + + + + + + + + + + + + + meters + + 4606484.6726676719263196 + 3728012.39886604063212872 + 9866330.61264913156628609 + 8074944.57324538938701153 + + 0 + 1 + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + 0 + + + + + + + + view_frmlocustinfo_p3r_201520170221141235646 + OpenStreetMap20170221162957823 + + + + + + + + + + + + + + + -20037508.33999999985098839 + -20037508.33999999985098839 + 20037508.33999999985098839 + 20037508.33999999985098839 + + OpenLayers_plugin_layer20170821155911549 + + + + + Bing Aerial with labels + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + + + + + + + + -180 + 38.39295510000000178 + 180 + 82.05862320000009902 + + view_frmlocustinfo_p3r_201520170221141235646 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='region_id' estimatedmetadata=true srid=4326 type=MultiPolygon table="main"."view_frmlocustinfo_p3r_${year}" (geom) sql=${sql} + + + + trt('Maps_of_treated_areas_above_ET') + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + COALESCE( "name", '<NULL>' ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + meters + m2 + + + +proj=longlat +datum=WGS84 +no_defs + EPSG:4326 + 3452 + 1 + + + false + + + 0 + 255 + 255 + 255 + 255 + 255 + 255 + + + 2 + current_layer + off + 0 + + + 2 + true + + + false + + + + diff --git a/src/main/webapp/resources/QGIS/frmlocustinfo_p4.qgs b/src/main/webapp/resources/QGIS/frmlocustinfo_p4.qgs new file mode 100644 index 0000000..8ca08b9 --- /dev/null +++ b/src/main/webapp/resources/QGIS/frmlocustinfo_p4.qgs @@ -0,0 +1,508 @@ + + + + + + + + + + + + + + + + + meters + + 4606484.6726676719263196 + 3728012.39886604063212872 + 9866330.61264913156628609 + 8074944.57324538938701153 + + 0 + 1 + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + 0 + + + + + + + + view_frmlocustinfo_p4_201520170221164520581 + OpenStreetMap20170221170817493 + + + + + + + + + + + + + + + -20037508.33999999985098839 + -20037508.33999999985098839 + 20037508.33999999985098839 + 20037508.33999999985098839 + + OpenLayers_plugin_layer20170821155911549 + + + + + Bing Aerial with labels + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + + + + + + + + -180 + 38.39295510000000178 + 180 + 82.05862320000009902 + + view_frmlocustinfo_p4_201520170221164520581 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='region_id' estimatedmetadata=true srid=4326 type=MultiPolygon table="main"."view_frmlocustinfo_p4_${year}" (geom) sql=${sql} + + + + trt('Map_of_the_level_of_threat') + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + meters + m2 + + + +proj=longlat +datum=WGS84 +no_defs + EPSG:4326 + 3452 + 1 + + + false + + + 0 + 255 + 255 + 255 + 255 + 255 + 255 + + + 2 + + view_frmlocustinfo_p4_201520170221164520581 + + + disabled + + current_layer + + + 2 + + + to_vertex_and_segment + + off + 0 + + 0.000000 + + + + 2 + true + + + false + + + + diff --git a/src/main/webapp/resources/QGIS/frmlocustinfo_p4r.qgs b/src/main/webapp/resources/QGIS/frmlocustinfo_p4r.qgs new file mode 100644 index 0000000..202469f --- /dev/null +++ b/src/main/webapp/resources/QGIS/frmlocustinfo_p4r.qgs @@ -0,0 +1,509 @@ + + + + + + + + + + + + + + + + + meters + + 4606484.6726676719263196 + 3728012.39886604063212872 + 9866330.61264913156628609 + 8074944.57324538938701153 + + 0 + 1 + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + 0 + + + + + + + + view_frmlocustinfo_p4r_201520170221164520581 + OpenStreetMap20170221170817493 + + + + + + + + + + + + + + + + -20037508.33999999985098839 + -20037508.33999999985098839 + 20037508.33999999985098839 + 20037508.33999999985098839 + + OpenLayers_plugin_layer20170821155911549 + + + + + Bing Aerial with labels + + + +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 +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo Mercator + merc + WGS84 + false + + + + + + + + + + -180 + 38.39295510000000178 + 180 + 82.05862320000009902 + + view_frmlocustinfo_p4r_201520170221164520581 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='region_id' estimatedmetadata=true srid=4326 type=MultiPolygon table="main"."view_frmlocustinfo_p4r_${year}" (geom) sql=${sql} + + + + trt('Map_of_the_level_of_threat') + + + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + WGS84 + true + + + postgres + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0 + name + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + + + + + meters + m2 + + + +proj=longlat +datum=WGS84 +no_defs + EPSG:4326 + 3452 + 1 + + + false + + + 0 + 255 + 255 + 255 + 255 + 255 + 255 + + + 2 + + view_frmlocustinfo_p4r_201520170221164520581 + + + disabled + + current_layer + + + 2 + + + to_vertex_and_segment + + off + 0 + + 0.000000 + + + + 2 + true + + + false + + + + diff --git a/src/main/webapp/resources/QGIS/htc_selyaninov.qgs b/src/main/webapp/resources/QGIS/htc_selyaninov.qgs new file mode 100644 index 0000000..8e74367 --- /dev/null +++ b/src/main/webapp/resources/QGIS/htc_selyaninov.qgs @@ -0,0 +1,1924 @@ + + + + + + + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + countriesdistricts20170803132507662 + countriesregions20170803132506793 + countries20170803132508430 + OpenStreetMap_9da8fe98_9174_4b23_b8e4_8d0c9fbf90ce + htc_selyaninov_${country}_ffb52ce7_928b_45d1_867b_6d839c3c062b + + + + + + + + + meters + + 3396315.6506110280752182 + 1061190.67332473304122686 + 13916007.53057394921779633 + 9755055.02208343148231506 + + 0 + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + Annotations_c88afc0a_8ca0_4f92_9f48_101ecee4c81a + + + + + + + + + + 0 + 0 + + + + + false + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + + 1 + 0 + + + + + + -20037508.34278924390673637 + -20037508.34278924763202667 + 20037508.34278924390673637 + 20037508.34278924763202667 + + + -180 + -85.05112877980660357 + 179.99999999999997158 + 85.05112877980660357 + + OpenStreetMap_9da8fe98_9174_4b23_b8e4_8d0c9fbf90ce + crs=EPSG:3857&format&type=xyz&url=http://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png&zmax=18&zmin=0 + + + + OpenStreetMap + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + OpenStreetMap tiles + + + dataset + OpenStreetMap tiles + OpenStreetMap is built by a community of mappers that contribute and maintain data about roads, trails, cafés, railway stations, and much more, all over the world. + + + + + Base map and data from OpenStreetMap and OpenStreetMap Foundation (CC-BY-SA). © https://www.openstreetmap.org and contributors. + Open Data Commons Open Database License (ODbL) + Creative Commons Attribution-ShareAlike (CC-BY-SA) + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + wms + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + resamplingFilter + + 0 + + + + 60.51760340000009819 + 29.37720000000010145 + 74.88986199999999371 + 38.48992170000010304 + + + 60.51760340000009819 + 29.37720000000010145 + 74.88986199999999371 + 38.48992170000010304 + + countries20170803132508430 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='country_id' srid=4326 type=MultiPolygon checkPrimaryKeyUnicity='1' table="main"."view_countries" (geom) sql=${sql2} + + + + Country + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + postgres + + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0.7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + "name" + + + + + 60.47208339733759885 + 29.37706453607049895 + 74.88945114815180659 + 38.49079207558700233 + + + 60.47208339733759885 + 29.37706453607049895 + 74.88945114815180659 + 38.49079207558700233 + + countriesdistricts20170803132507662 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon checkPrimaryKeyUnicity='1' table="main"."view_countriesdistricts" (geom) sql=${sql2} + + + + Districts + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + postgres + + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0.7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + "name" + + + + + 60.51760339999999871 + 29.37719999999999843 + 74.88986199999999371 + 38.48992169999999646 + + + 60.51760339999999871 + 29.37719999999999843 + 74.88986199999999371 + 38.48992169999999646 + + countriesregions20170803132506793 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon checkPrimaryKeyUnicity='1' table="main"."view_countriesregions" (geom) sql=${sql2} + + + + Regions + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + postgres + + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0.7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + "name" + + + + + 6762659.06569136958569288 + 3439440.06073126150295138 + 8293302.06409887876361609 + 4614802.87514934223145247 + + + 60.75 + 29.50000000000000355 + 74.49999999999994316 + 38.25 + + htc_selyaninov_${country}_ffb52ce7_928b_45d1_867b_6d839c3c062b + IgnoreGetMapUrl=1&contextualWMSLegend=0&crs=EPSG:3857&dpiMode=7&featureCount=10&format=image/png&layers=cite:htc_selyaninov_${country}&styles&url=http://geoserver2.ccalm.org/wms?viewparams%3Dtime_start:${time_start};time_end%3D${time_end}; + + + + htc_selyaninov_${country} + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + wms + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + resamplingFilter + + 0 + + + + + + + + + + + + + 2 + 0 + 2 + off + + + + + + current_layer + + + 255 + 255 + 255 + 255 + 0 + 255 + 255 + + + false + + + m2 + meters + + + 5 + 2.5 + false + false + 0 + 0 + false + false + true + 0 + 255,0,0,255 + + + false + + + true + 2 + + + 3857 + +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 +wktext +no_defs + EPSG:3857 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + diff --git a/src/main/webapp/resources/QGIS/index.jsp b/src/main/webapp/resources/QGIS/index.jsp new file mode 100644 index 0000000..8fe5280 --- /dev/null +++ b/src/main/webapp/resources/QGIS/index.jsp @@ -0,0 +1,373 @@ +<%@ page language="java" contentType="application/octet-stream" pageEncoding="UTF-8"%> +<%@ page session="true" %> + +<%@page import="java.sql.*"%> +<%@page import="java.io.FileReader"%> +<%@page import="java.io.InputStreamReader"%> +<%@page import="java.io.InputStream"%> +<%@page import="java.io.FileInputStream"%> +<%@page import="java.io.BufferedReader"%> +<%@page import="java.util.Locale"%> +<%@page import="java.util.ResourceBundle"%> + +<%@ page import="java.io.File" %> +<%@page import="javax.xml.parsers.DocumentBuilderFactory"%> +<%@page import="javax.xml.parsers.DocumentBuilder"%> +<%@page import="org.w3c.dom.Document"%> +<%@page import="org.w3c.dom.Element"%> +<%@page import="org.w3c.dom.NamedNodeMap"%> +<%@page import="org.w3c.dom.Node"%> +<%@page import="org.w3c.dom.NodeList"%> +<%@page import="org.w3c.dom.ls.DOMImplementationLS"%> +<%@page import="org.w3c.dom.ls.LSSerializer"%> +<%@page import="org.w3c.dom.ls.LSOutput"%> +<%@page import="org.w3c.dom.CDATASection"%> +<%@page import="org.w3c.dom.CharacterData"%> + +<%! +//application/octet-stream + +public String m_locale = "en"; + +/*public String trt(String val) +{ + String locale = m_locale; + try + { + ResourceBundle rb = ResourceBundle.getBundle("messages", new Locale(locale)); + val=rb.getString(val); + val=new String(val.getBytes("ISO-8859-1"), "UTF-8"); + return val; + }catch(Exception exception){ + System.out.println("Exception: "+exception.getMessage()); + } + return val.replaceAll("_", " "); +} + +//Translate text by patterns +public String getText(String text) +{ + int pos1=0; + while(true) + { + pos1=text.indexOf("trt('",pos1); + if(pos1==-1) break; + int pos2=text.indexOf("')",pos1); + if(pos2==-1) break; + + text=text.substring(0,pos1)+trt(text.substring(pos1+3,pos2))+text.substring(pos2+2); + } + return text; +}*/ + +public String fileToString(String fName) +{ + StringBuilder sb = new StringBuilder(); + try + { + InputStream is = new FileInputStream(fName); + BufferedReader buf = new BufferedReader(new InputStreamReader(is)); + String line = buf.readLine(); + while(line != null) + { + sb.append(line).append("\n"); + line = buf.readLine(); + } + buf.close(); + } + catch (Exception e){ + System.out.println("Error: "+e.getMessage()); + } + return sb.toString(); +} +%> +<% + +String db_url=""; +String db_login=""; +String db_password=""; +//Load DB configuration from "config.xml" +try { + String fullPath = pageContext.getServletContext().getRealPath("/WEB-INF/config.xml"); + File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(fXmlFile); + Element nMain=doc.getDocumentElement(); + NodeList nl=nMain.getChildNodes(); + for (int i = 0; i Connect is ERROR
"); + } + }catch(Exception e) + { + out.write("
Connect Exception:"+e.getMessage()+"
"); +} + + +//Select language for current user +String user_id = (String)request.getSession().getAttribute("USER_ID"); +if(user_id==null) user_id="null"; + +Statement st = conn.createStatement(); +ResultSet rs=null; +try { + String sql="select l.short_name lng from main._users u LEFT JOIN main._languages l ON l.id = u.language_id where u.id="+user_id+";"; + rs = st.executeQuery(sql); +} catch( SQLException ex ) +{ + out.write("
SQLException:"+ex.getMessage()+"
"); +} + +if(rs!=null) +{ + while (rs.next()) + { + m_locale = rs.getString("lng"); + } +} +st.close(); + +String jspPath = application.getRealPath("/")+"QGIS/"; + +String fileAsString=""; +String name=request.getParameter("name"); + +//Pods (кубышки) +if(name!=null && (name.equals("frmlocust_pods_density") || name.equals("frmlocust_hoppers_density") || name.equals("frmlocust_bands") || name.equals("frmlocust_adults_density") || name.equals("frmlocust_swarms"))) +{ + fileAsString = fileToString(jspPath + name + ".qgs"); + + String country_id=request.getParameter("country_id"); + String locust_type_id=request.getParameter("locust_type_id"); + String date_start=request.getParameter("date_start"); + String date_end=request.getParameter("date_end"); + String registered=request.getParameter("registered"); + + //Make SQL + String sql = "1=1"; + String sql2 = "1=1"; + if(country_id!=null && !country_id.equals("")) + { + if(country_id.equals("-1")) + { + sql+=" and country_id in (7,3,4,2)"; + sql2+=" and country_id in (7,3,4,2)"; + }else if(country_id.equals("-2")) + { + sql+=" and country_id in (7,1,5,6,8,9,10)"; + sql2+=" and country_id in (7,1,5,6,8,9,10)"; + }else + { + sql+=" and country_id="+country_id; + sql2+=" and country_id="+country_id; + } + } + if(locust_type_id!=null && !locust_type_id.equals("")) + { + sql+=" and locust_type_id="+locust_type_id; + } + if(date_start!=null && !date_start.equals("")) + { + sql+=" and date>='"+date_start+"'"; + } + if(date_end!=null && !date_end.equals("")) + { + sql+=" and date<='"+date_end+"'"; + } + + if(registered!=null && registered.equals("1")) + { + sql+=" and registered=true"; + }else + if(registered!=null && registered.equals("0")) + { + sql+=" and registered=false"; + } + + //Apply variables to text + fileAsString=fileAsString.replaceAll("\\$\\{sql\\}",sql); + + fileAsString=fileAsString.replaceAll("\\$\\{sql2\\}",sql2); + +} + +if(name!=null && name.equals("frmlocustdel")) +{ + fileAsString = fileToString(jspPath + name + ".qgs"); + + String country_id=request.getParameter("country_id"); + String date_start=request.getParameter("date_start"); + String date_end=request.getParameter("date_end"); + String registered=request.getParameter("registered"); + + //Make SQL + String sql = "1=1"; + String sql2 = "1=1"; + if(country_id!=null && !country_id.equals("")) + { + //sql+=" and country_id="+country_id; + if(country_id.equals("-1")) + { + sql+=" and country_id in (7,3,4,2)"; + sql2+=" and country_id in (7,3,4,2)"; + }else if(country_id.equals("-2")) + { + sql+=" and country_id in (7,1,5,6,8,9,10)"; + sql2+=" and country_id in (7,1,5,6,8,9,10)"; + }else + { + sql+=" and country_id="+country_id; + sql2+=" and country_id="+country_id; + } + } + if(date_start!=null && !date_start.equals("")) + { + sql+=" and date>='"+date_start+"'"; + } + if(date_end!=null && !date_end.equals("")) + { + sql+=" and date<='"+date_end+"'"; + } + + if(registered!=null && registered.equals("1")) + { + sql+=" and registered=true"; + }else + if(registered!=null && registered.equals("0")) + { + sql+=" and registered=false"; + } + + //Apply variables to text + fileAsString=fileAsString.replaceAll("\\$\\{sql\\}",sql); + + fileAsString=fileAsString.replaceAll("\\$\\{sql2\\}",sql2); +} + +if(name!=null && (name.equals("frmlocustinfo_p2") || name.equals("frmlocustinfo_p3") || name.equals("frmlocustinfo_p4"))) +{ + String country_id=request.getParameter("country_id"); + String year=request.getParameter("year"); + String locust_type_id=request.getParameter("locust_type_id"); + + //Make SQL + String sql = "1=1"; + if(country_id!=null && !country_id.equals("")) + { + if(country_id.equals("-1")) + { + sql+=" and country_id in (7,3,4,2)"; + }else if(country_id.equals("-2")) + { + sql+=" and country_id in (7,1,5,6,8,9,10)"; + }else + { + sql+=" and country_id="+country_id; + } + } + if(locust_type_id!=null && !locust_type_id.equals("")) + { + sql+=" and locust_type_id="+locust_type_id; + } + + String fileName = jspPath + name + ".qgs"; + fileAsString = fileToString(fileName); + //Apply variables to text + fileAsString=fileAsString.replaceAll("\\$\\{year\\}",year); + fileAsString=fileAsString.replaceAll("\\$\\{sql\\}",sql); +} + +if(name!=null && (name.equals("frmlocustinfo_p2r") || name.equals("frmlocustinfo_p3r") || name.equals("frmlocustinfo_p4r"))) +{ + String region_id=request.getParameter("region_id"); + String year=request.getParameter("year"); + String locust_type_id=request.getParameter("locust_type_id"); + + //Make SQL + String sql = "1=1"; + if(region_id!=null && !region_id.equals("")) + { + sql+=" and region_id="+region_id; + } + if(locust_type_id!=null && !locust_type_id.equals("")) + { + sql+=" and locust_type_id="+locust_type_id; + } + + String fileName = jspPath + name + ".qgs"; + fileAsString = fileToString(fileName); + //Apply variables to text + fileAsString=fileAsString.replaceAll("\\$\\{year\\}",year); + fileAsString=fileAsString.replaceAll("\\$\\{sql\\}",sql); +} + +if(name!=null && name.equals("weather")) +{ + String country_id=request.getParameter("country_id"); + String country_name=request.getParameter("country_name"); + + //Make SQL + String sql2 = "1=1"; + if(country_id!=null && !country_id.equals("")) + { + //sql+=" and country_id="+country_id; + if(country_id.equals("-1")) + { + sql2+=" and country_id in (7,3,4,2)"; + }else if(country_id.equals("-2")) + { + sql2+=" and country_id in (7,1,5,6,8,9,10)"; + }else + { + sql2+=" and country_id="+country_id; + } + } + + String fileName = jspPath + name + ".qgs"; + fileAsString = fileToString(fileName); + //Apply variables to text + fileAsString=fileAsString.replaceAll("\\$\\{country\\}",country_name); + + fileAsString=fileAsString.replaceAll("\\$\\{sql2\\}",sql2); +} +if(name!=null && name.equals("NDVI")) +{ + + String fileName = jspPath + "NDVI.qgs"; + fileAsString = fileToString(fileName); +} +if(name!=null && name.equals("NDWI")) +{ + + String fileName = jspPath + "NDWI.qgs"; + fileAsString = fileToString(fileName); +} + +//Send file to client. +response.setHeader("Content-Disposition", "attachment;filename=Locust.qgs"); +out.write(fileAsString); //out.write(getText(fileAsString)); + +%> \ No newline at end of file diff --git a/src/main/webapp/resources/QGIS/precipitation.qgs b/src/main/webapp/resources/QGIS/precipitation.qgs new file mode 100644 index 0000000..4befaf7 --- /dev/null +++ b/src/main/webapp/resources/QGIS/precipitation.qgs @@ -0,0 +1,1924 @@ + + + + + + + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + countriesdistricts20170803132507662 + countriesregions20170803132506793 + countries20170803132508430 + OpenStreetMap_9da8fe98_9174_4b23_b8e4_8d0c9fbf90ce + precipitation_${country}_ffb52ce7_928b_45d1_867b_6d839c3c062b + + + + + + + + + meters + + 3396315.6506110280752182 + 1061190.67332473304122686 + 13916007.53057394921779633 + 9755055.02208343148231506 + + 0 + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + Annotations_c88afc0a_8ca0_4f92_9f48_101ecee4c81a + + + + + + + + + + 0 + 0 + + + + + false + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + + 1 + 0 + + + + + + -20037508.34278924390673637 + -20037508.34278924763202667 + 20037508.34278924390673637 + 20037508.34278924763202667 + + + -180 + -85.05112877980660357 + 179.99999999999997158 + 85.05112877980660357 + + OpenStreetMap_9da8fe98_9174_4b23_b8e4_8d0c9fbf90ce + crs=EPSG:3857&format&type=xyz&url=http://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png&zmax=18&zmin=0 + + + + OpenStreetMap + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + OpenStreetMap tiles + + + dataset + OpenStreetMap tiles + OpenStreetMap is built by a community of mappers that contribute and maintain data about roads, trails, cafés, railway stations, and much more, all over the world. + + + + + Base map and data from OpenStreetMap and OpenStreetMap Foundation (CC-BY-SA). © https://www.openstreetmap.org and contributors. + Open Data Commons Open Database License (ODbL) + Creative Commons Attribution-ShareAlike (CC-BY-SA) + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + wms + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + resamplingFilter + + 0 + + + + 60.51760340000009819 + 29.37720000000010145 + 74.88986199999999371 + 38.48992170000010304 + + + 60.51760340000009819 + 29.37720000000010145 + 74.88986199999999371 + 38.48992170000010304 + + countries20170803132508430 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='country_id' srid=4326 type=MultiPolygon checkPrimaryKeyUnicity='1' table="main"."view_countries" (geom) sql=${sql2} + + + + Country + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + postgres + + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0.7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + "name" + + + + + 60.47208339733759885 + 29.37706453607049895 + 74.88945114815180659 + 38.49079207558700233 + + + 60.47208339733759885 + 29.37706453607049895 + 74.88945114815180659 + 38.49079207558700233 + + countriesdistricts20170803132507662 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon checkPrimaryKeyUnicity='1' table="main"."view_countriesdistricts" (geom) sql=${sql2} + + + + Districts + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + postgres + + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0.7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + "name" + + + + + 60.51760339999999871 + 29.37719999999999843 + 74.88986199999999371 + 38.48992169999999646 + + + 60.51760339999999871 + 29.37719999999999843 + 74.88986199999999371 + 38.48992169999999646 + + countriesregions20170803132506793 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon checkPrimaryKeyUnicity='1' table="main"."view_countriesregions" (geom) sql=${sql2} + + + + Regions + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + postgres + + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0.7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + "name" + + + + + 6762659.06569136958569288 + 3439440.06073126150295138 + 8293302.06409887876361609 + 4614802.87514934223145247 + + + 60.75 + 29.50000000000000355 + 74.49999999999994316 + 38.25 + + precipitation_${country}_ffb52ce7_928b_45d1_867b_6d839c3c062b + IgnoreGetMapUrl=1&contextualWMSLegend=0&crs=EPSG:3857&dpiMode=7&featureCount=10&format=image/png&layers=cite:precipitation_${country}&styles&url=http://geoserver2.ccalm.org/wms?viewparams=p1:${time}; + + + + precipitation_${country} + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + wms + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + resamplingFilter + + 0 + + + + + + + + + + + + + 2 + 0 + 2 + off + + + + + + current_layer + + + 255 + 255 + 255 + 255 + 0 + 255 + 255 + + + false + + + m2 + meters + + + 5 + 2.5 + false + false + 0 + 0 + false + false + true + 0 + 255,0,0,255 + + + false + + + true + 2 + + + 3857 + +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 +wktext +no_defs + EPSG:3857 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + diff --git a/src/main/webapp/resources/QGIS/soil_temperature.qgs b/src/main/webapp/resources/QGIS/soil_temperature.qgs new file mode 100644 index 0000000..1bace8b --- /dev/null +++ b/src/main/webapp/resources/QGIS/soil_temperature.qgs @@ -0,0 +1,1924 @@ + + + + + + + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + countriesdistricts20170803132507662 + countriesregions20170803132506793 + countries20170803132508430 + OpenStreetMap_9da8fe98_9174_4b23_b8e4_8d0c9fbf90ce + soil_temperature_${country}_ffb52ce7_928b_45d1_867b_6d839c3c062b + + + + + + + + + meters + + 3396315.6506110280752182 + 1061190.67332473304122686 + 13916007.53057394921779633 + 9755055.02208343148231506 + + 0 + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + Annotations_c88afc0a_8ca0_4f92_9f48_101ecee4c81a + + + + + + + + + + 0 + 0 + + + + + false + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + + 1 + 0 + + + + + + -20037508.34278924390673637 + -20037508.34278924763202667 + 20037508.34278924390673637 + 20037508.34278924763202667 + + + -180 + -85.05112877980660357 + 179.99999999999997158 + 85.05112877980660357 + + OpenStreetMap_9da8fe98_9174_4b23_b8e4_8d0c9fbf90ce + crs=EPSG:3857&format&type=xyz&url=http://tile.openstreetmap.org/%7Bz%7D/%7Bx%7D/%7By%7D.png&zmax=18&zmin=0 + + + + OpenStreetMap + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + OpenStreetMap tiles + + + dataset + OpenStreetMap tiles + OpenStreetMap is built by a community of mappers that contribute and maintain data about roads, trails, cafés, railway stations, and much more, all over the world. + + + + + Base map and data from OpenStreetMap and OpenStreetMap Foundation (CC-BY-SA). © https://www.openstreetmap.org and contributors. + Open Data Commons Open Database License (ODbL) + Creative Commons Attribution-ShareAlike (CC-BY-SA) + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + wms + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + resamplingFilter + + 0 + + + + 60.51760340000009819 + 29.37720000000010145 + 74.88986199999999371 + 38.48992170000010304 + + + 60.51760340000009819 + 29.37720000000010145 + 74.88986199999999371 + 38.48992170000010304 + + countries20170803132508430 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='country_id' srid=4326 type=MultiPolygon checkPrimaryKeyUnicity='1' table="main"."view_countries" (geom) sql=${sql2} + + + + Country + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + postgres + + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0.7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + "name" + + + + + 60.47208339733759885 + 29.37706453607049895 + 74.88945114815180659 + 38.49079207558700233 + + + 60.47208339733759885 + 29.37706453607049895 + 74.88945114815180659 + 38.49079207558700233 + + countriesdistricts20170803132507662 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon checkPrimaryKeyUnicity='1' table="main"."view_countriesdistricts" (geom) sql=${sql2} + + + + Districts + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + postgres + + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0.7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + "name" + + + + + 60.51760339999999871 + 29.37719999999999843 + 74.88986199999999371 + 38.48992169999999646 + + + 60.51760339999999871 + 29.37719999999999843 + 74.88986199999999371 + 38.48992169999999646 + + countriesregions20170803132506793 + dbname='CCALM' host=ccalm.org port=5432 user='guest' password='guest' sslmode=disable key='id' srid=4326 type=MultiPolygon checkPrimaryKeyUnicity='1' table="main"."view_countriesregions" (geom) sql=${sql2} + + + + Regions + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + + + + + + + + + + + GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]] + +proj=longlat +datum=WGS84 +no_defs + 3452 + 4326 + EPSG:4326 + WGS 84 + longlat + EPSG:7030 + true + + + + + postgres + + + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + 0.7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + 0 + . + + 0 + generatedlayout + + + + + + "name" + + + + + 6762659.06569136958569288 + 3439440.06073126150295138 + 8293302.06409887876361609 + 4614802.87514934223145247 + + + 60.75 + 29.50000000000000355 + 74.49999999999994316 + 38.25 + + soil_temperature_${country}_ffb52ce7_928b_45d1_867b_6d839c3c062b + IgnoreGetMapUrl=1&contextualWMSLegend=0&crs=EPSG:3857&dpiMode=7&featureCount=10&format=image/png&layers=cite:soil_temperature_${country}&styles&url=http://geoserver2.ccalm.org/wms?viewparams=p1:${time}; + + + + soil_temperature_${country} + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + + + + + + + + 0 + 0 + + + + + false + + + + + wms + + + + + + + + + 1 + 1 + 1 + 0 + + + + + + + + + + + + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + resamplingFilter + + 0 + + + + + + + + + + + + + 2 + 0 + 2 + off + + + + + + current_layer + + + 255 + 255 + 255 + 255 + 0 + 255 + 255 + + + false + + + m2 + meters + + + 5 + 2.5 + false + false + 0 + 0 + false + false + true + 0 + 255,0,0,255 + + + false + + + true + 2 + + + 3857 + +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 +wktext +no_defs + EPSG:3857 + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]] + +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs + 3857 + 3857 + EPSG:3857 + WGS 84 / Pseudo-Mercator + merc + EPSG:7030 + false + + + + + + + + + + diff --git a/src/main/webapp/resources/engine/b.png b/src/main/webapp/resources/engine/b.png new file mode 100644 index 0000000..3ee6e77 Binary files /dev/null and b/src/main/webapp/resources/engine/b.png differ diff --git a/src/main/webapp/resources/engine/buttons.css b/src/main/webapp/resources/engine/buttons.css new file mode 100644 index 0000000..3beb136 --- /dev/null +++ b/src/main/webapp/resources/engine/buttons.css @@ -0,0 +1,93 @@ +/*https://1stwebdesigner.com/free-code-snippets-css-buttons/*/ + +:root{ + --btn-color: #d9d9cc; /*Цвет кнопки*/ + --btn-color2: #E0E0FF; /*Цвет кнопки при наведении на неё мышкой*/ +} + +/* Normal white Button as seen on Google.com*/ +button, +.button-secondary{ + color: #444444; + background: var(--btn-color); + border: 1px #AAAAAA solid; + padding: 5px 10px; + border-radius: 2px; + font-weight: bold; + font-size: 9pt; + outline: none; +} + +button:hover { + border: 1px #C6C6C6 solid; + box-shadow: 1px 1px 1px #EAEAEA; + color: #333333; + background: var(--btn-color2); +} + +button:active { + box-shadow: inset 1px 1px 1px #DFDFDF; +} + +/* Blue button as seen on translate.google.com*/ +button.blue { + color: white; + background: #4C8FFB; + border: 1px #3079ED solid; + box-shadow: inset 0 1px 0 #80B0FB; +} + +button.blue:hover { + border: 1px #2F5BB7 solid; + box-shadow: 0 1px 1px #EAEAEA, inset 0 1px 0 #5A94F1; + background: #3F83F1; +} + +button.blue:active { + box-shadow: inset 0 2px 5px #2370FE; +} + +/* Orange button as seen on blogger.com*/ +button.orange { + color: white; + border: 1px solid #FB8F3D; + background: -webkit-linear-gradient(top, #FDA251, #FB8F3D); + background: -moz-linear-gradient(top, #FDA251, #FB8F3D); + background: -ms-linear-gradient(top, #FDA251, #FB8F3D); +} + +button.orange:hover { + border: 1px solid #EB5200; + background: -webkit-linear-gradient(top, #FD924C, #F9760B); + background: -moz-linear-gradient(top, #FD924C, #F9760B); + background: -ms-linear-gradient(top, #FD924C, #F9760B); + box-shadow: 0 1px #EFEFEF; +} + +button.orange:active { + box-shadow: inset 0 1px 1px rgba(0,0,0,0.3); +} + +/* Red Google Button as seen on drive.google.com */ +button.red { + background: -webkit-linear-gradient(top, #DD4B39, #D14836); + background: -moz-linear-gradient(top, #DD4B39, #D14836); + background: -ms-linear-gradient(top, #DD4B39, #D14836); + border: 1px solid #DD4B39; + color: white; + text-shadow: 0 1px 0 #C04131; +} + +button.red:hover { + background: -webkit-linear-gradient(top, #DD4B39, #C53727); + background: -moz-linear-gradient(top, #DD4B39, #C53727); + background: -ms-linear-gradient(top, #DD4B39, #C53727); + border: 1px solid #AF301F; +} + +button.red:active { + box-shadow: inset 0 1px 1px rgba(0,0,0,0.2); + background: -webkit-linear-gradient(top, #D74736, #AD2719); + background: -moz-linear-gradient(top, #D74736, #AD2719); + background: -ms-linear-gradient(top, #D74736, #AD2719); +} diff --git a/src/main/webapp/resources/engine/config.png b/src/main/webapp/resources/engine/config.png new file mode 100644 index 0000000..613d8d4 Binary files /dev/null and b/src/main/webapp/resources/engine/config.png differ diff --git a/src/main/webapp/resources/engine/exit.png b/src/main/webapp/resources/engine/exit.png new file mode 100644 index 0000000..6ad33b0 Binary files /dev/null and b/src/main/webapp/resources/engine/exit.png differ diff --git a/src/main/webapp/resources/engine/g.png b/src/main/webapp/resources/engine/g.png new file mode 100644 index 0000000..9a98469 Binary files /dev/null and b/src/main/webapp/resources/engine/g.png differ diff --git a/src/main/webapp/resources/engine/geo_json.jsp b/src/main/webapp/resources/engine/geo_json.jsp new file mode 100644 index 0000000..97b2a60 --- /dev/null +++ b/src/main/webapp/resources/engine/geo_json.jsp @@ -0,0 +1,96 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@page import="java.io.*"%> +<%@ page import="java.sql.*"%> +<%@ page import="java.util.ResourceBundle"%> +<%@page import="javax.xml.parsers.DocumentBuilderFactory"%> +<%@page import="javax.xml.parsers.DocumentBuilder"%> +<%@page import="org.w3c.dom.Document"%> +<%@page import="org.w3c.dom.Element"%> +<%@page import="org.w3c.dom.NamedNodeMap"%> +<%@page import="org.w3c.dom.Node"%> +<%@page import="org.w3c.dom.NodeList"%> +<%@page import="org.w3c.dom.ls.DOMImplementationLS"%> +<%@page import="org.w3c.dom.ls.LSSerializer"%> +<%@page import="org.w3c.dom.ls.LSOutput"%> +<%@page import="org.w3c.dom.CDATASection"%> +<%@page import="org.w3c.dom.CharacterData"%> +<% + +String db_url=""; +String db_login=""; +String db_password=""; +//Load DB configuration from "config.xml" +try { + String fullPath = pageContext.getServletContext().getRealPath("/WEB-INF/config.xml"); + File fXmlFile = new File(fullPath); + DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); + Document doc = dBuilder.parse(fXmlFile); + Element nMain=doc.getDocumentElement(); + NodeList nl=nMain.getChildNodes(); + for (int i = 0; i Connect is ERROR
"); + } +}catch(Exception e) +{ + out.write("
Connect Exception:"+e.getMessage()+"
"); +} + +Statement st = conn.createStatement(); +ResultSet rs=null; +try { + String sql="select id,name,ST_AsGeoJSON(geom,3,0) as geom from main."+table+" where id="+id+";"; + rs = st.executeQuery(sql); +} catch( SQLException ex ) +{ + out.write("
SQLException:"+ex.getMessage()+"
"); +} + +if(rs!=null) +{ + while (rs.next()) + { + String geom=null; + try { + geom=rs.getString("geom"); + } catch( Exception ex ) + { + out.write("
SQLException:"+ex.getMessage()+"
"); + System.out.println("Error: "+ex.getMessage()); + } + if(geom==null) geom=""; + out.write(geom); + } +} +st.close(); + + +conn.close(); + +%> diff --git a/src/main/webapp/resources/engine/help.png b/src/main/webapp/resources/engine/help.png new file mode 100644 index 0000000..604dbd4 Binary files /dev/null and b/src/main/webapp/resources/engine/help.png differ diff --git a/src/main/webapp/resources/engine/help/ASDC_for_Android_ENG.docx b/src/main/webapp/resources/engine/help/ASDC_for_Android_ENG.docx new file mode 100644 index 0000000..b28a071 Binary files /dev/null and b/src/main/webapp/resources/engine/help/ASDC_for_Android_ENG.docx differ diff --git a/src/main/webapp/resources/engine/help/ASDC_for_Android_ENG.pdf b/src/main/webapp/resources/engine/help/ASDC_for_Android_ENG.pdf new file mode 100644 index 0000000..a5883d5 Binary files /dev/null and b/src/main/webapp/resources/engine/help/ASDC_for_Android_ENG.pdf differ diff --git a/src/main/webapp/resources/engine/help/ASDC_for_Android_RUS.docx b/src/main/webapp/resources/engine/help/ASDC_for_Android_RUS.docx new file mode 100644 index 0000000..efdcde4 Binary files /dev/null and b/src/main/webapp/resources/engine/help/ASDC_for_Android_RUS.docx differ diff --git a/src/main/webapp/resources/engine/help/ASDC_for_Android_RUS.pdf b/src/main/webapp/resources/engine/help/ASDC_for_Android_RUS.pdf new file mode 100644 index 0000000..e0234e8 Binary files /dev/null and b/src/main/webapp/resources/engine/help/ASDC_for_Android_RUS.pdf differ diff --git a/src/main/webapp/resources/engine/help/Administration CCALM v 0.3_ENG.doc b/src/main/webapp/resources/engine/help/Administration CCALM v 0.3_ENG.doc new file mode 100644 index 0000000..3eec553 Binary files /dev/null and b/src/main/webapp/resources/engine/help/Administration CCALM v 0.3_ENG.doc differ diff --git a/src/main/webapp/resources/engine/help/Administration CCALM v 0.3_RUS.doc b/src/main/webapp/resources/engine/help/Administration CCALM v 0.3_RUS.doc new file mode 100644 index 0000000..88de428 Binary files /dev/null and b/src/main/webapp/resources/engine/help/Administration CCALM v 0.3_RUS.doc differ diff --git a/src/main/webapp/resources/engine/help/CCALM_help_ENG.doc b/src/main/webapp/resources/engine/help/CCALM_help_ENG.doc new file mode 100644 index 0000000..f451210 Binary files /dev/null and b/src/main/webapp/resources/engine/help/CCALM_help_ENG.doc differ diff --git a/src/main/webapp/resources/engine/help/CCALM_help_ENG.pdf b/src/main/webapp/resources/engine/help/CCALM_help_ENG.pdf new file mode 100644 index 0000000..1ec6c19 Binary files /dev/null and b/src/main/webapp/resources/engine/help/CCALM_help_ENG.pdf differ diff --git a/src/main/webapp/resources/engine/help/CCALM_help_RUS.docx b/src/main/webapp/resources/engine/help/CCALM_help_RUS.docx new file mode 100644 index 0000000..6dee44f Binary files /dev/null and b/src/main/webapp/resources/engine/help/CCALM_help_RUS.docx differ diff --git a/src/main/webapp/resources/engine/help/CCALM_help_RUS.pdf b/src/main/webapp/resources/engine/help/CCALM_help_RUS.pdf new file mode 100644 index 0000000..5098141 Binary files /dev/null and b/src/main/webapp/resources/engine/help/CCALM_help_RUS.pdf differ diff --git a/src/main/webapp/resources/engine/help/OLD/ASDC_User_Manual_Inspector_DRAFT_EN.doc b/src/main/webapp/resources/engine/help/OLD/ASDC_User_Manual_Inspector_DRAFT_EN.doc new file mode 100644 index 0000000..f613656 Binary files /dev/null and b/src/main/webapp/resources/engine/help/OLD/ASDC_User_Manual_Inspector_DRAFT_EN.doc differ diff --git a/src/main/webapp/resources/engine/help/OLD/ASDC_User_Manual_Inspector_DRAFT_RU.doc b/src/main/webapp/resources/engine/help/OLD/ASDC_User_Manual_Inspector_DRAFT_RU.doc new file mode 100644 index 0000000..bc9fc96 Binary files /dev/null and b/src/main/webapp/resources/engine/help/OLD/ASDC_User_Manual_Inspector_DRAFT_RU.doc differ diff --git a/src/main/webapp/resources/engine/help/OLD/ASDC_User_Manual_Operator_DRAFT_EN.doc b/src/main/webapp/resources/engine/help/OLD/ASDC_User_Manual_Operator_DRAFT_EN.doc new file mode 100644 index 0000000..4450290 Binary files /dev/null and b/src/main/webapp/resources/engine/help/OLD/ASDC_User_Manual_Operator_DRAFT_EN.doc differ diff --git a/src/main/webapp/resources/engine/help/OLD/ASDC_User_Manual_Operator_DRAFT_RU.doc b/src/main/webapp/resources/engine/help/OLD/ASDC_User_Manual_Operator_DRAFT_RU.doc new file mode 100644 index 0000000..18ac6f4 Binary files /dev/null and b/src/main/webapp/resources/engine/help/OLD/ASDC_User_Manual_Operator_DRAFT_RU.doc differ diff --git a/src/main/webapp/resources/engine/help/OLD/Application_Inspector_ASDC_RU.doc b/src/main/webapp/resources/engine/help/OLD/Application_Inspector_ASDC_RU.doc new file mode 100644 index 0000000..7bb291e Binary files /dev/null and b/src/main/webapp/resources/engine/help/OLD/Application_Inspector_ASDC_RU.doc differ diff --git a/src/main/webapp/resources/engine/help/OLD/How_to_configure_the_Internet_connection_via_the_operator_Beeline_RU.doc b/src/main/webapp/resources/engine/help/OLD/How_to_configure_the_Internet_connection_via_the_operator_Beeline_RU.doc new file mode 100644 index 0000000..1ab0234 Binary files /dev/null and b/src/main/webapp/resources/engine/help/OLD/How_to_configure_the_Internet_connection_via_the_operator_Beeline_RU.doc differ diff --git a/src/main/webapp/resources/engine/help/OLD/How_to_set_up_WIFI_connection_on_your_Android_tablet_RU.doc b/src/main/webapp/resources/engine/help/OLD/How_to_set_up_WIFI_connection_on_your_Android_tablet_RU.doc new file mode 100644 index 0000000..58ff22f Binary files /dev/null and b/src/main/webapp/resources/engine/help/OLD/How_to_set_up_WIFI_connection_on_your_Android_tablet_RU.doc differ diff --git a/src/main/webapp/resources/engine/help/OLD/MultiLing_Keyboard.doc b/src/main/webapp/resources/engine/help/OLD/MultiLing_Keyboard.doc new file mode 100644 index 0000000..6e27778 Binary files /dev/null and b/src/main/webapp/resources/engine/help/OLD/MultiLing_Keyboard.doc differ diff --git a/src/main/webapp/resources/engine/help/QGIS_Guide_ENG.doc b/src/main/webapp/resources/engine/help/QGIS_Guide_ENG.doc new file mode 100644 index 0000000..30fc08f Binary files /dev/null and b/src/main/webapp/resources/engine/help/QGIS_Guide_ENG.doc differ diff --git a/src/main/webapp/resources/engine/help/QGIS_Guide_RUS.doc b/src/main/webapp/resources/engine/help/QGIS_Guide_RUS.doc new file mode 100644 index 0000000..878f6ea Binary files /dev/null and b/src/main/webapp/resources/engine/help/QGIS_Guide_RUS.doc differ diff --git a/src/main/webapp/resources/engine/help/index.html b/src/main/webapp/resources/engine/help/index.html new file mode 100644 index 0000000..0988198 --- /dev/null +++ b/src/main/webapp/resources/engine/help/index.html @@ -0,0 +1,37 @@ + + + + HELP + + + + + +

ASDC Guidelines

+ ASDC_for_Android_ENG_v2.3.pdf
+ ASDC_for_Android_RUS_v2.3.pdf + +

CCALM Guidelines

+ CCALM_help_ENG.pdf
+ CCALM_help_RUS.pdf + +

QGIS Guidelines

+ QGIS_Guide_ENG.doc
+ QGIS_Guide_RUS.doc + +

Technical support and administration.

+ Administration CCALM v 0.3_ENG.doc
+ Administration CCALM v 0.3_RUS.doc + + + \ No newline at end of file diff --git a/src/main/webapp/resources/engine/help/~$ALM_help_ENG.doc b/src/main/webapp/resources/engine/help/~$ALM_help_ENG.doc new file mode 100644 index 0000000..a5d3144 Binary files /dev/null and b/src/main/webapp/resources/engine/help/~$ALM_help_ENG.doc differ diff --git a/src/main/webapp/resources/engine/help/~$ALM_help_RUS.docx b/src/main/webapp/resources/engine/help/~$ALM_help_RUS.docx new file mode 100644 index 0000000..a5d3144 Binary files /dev/null and b/src/main/webapp/resources/engine/help/~$ALM_help_RUS.docx differ diff --git a/src/main/webapp/resources/engine/horizontal.png b/src/main/webapp/resources/engine/horizontal.png new file mode 100644 index 0000000..c4a96ff Binary files /dev/null and b/src/main/webapp/resources/engine/horizontal.png differ diff --git a/src/main/webapp/resources/engine/images/1x32.gif b/src/main/webapp/resources/engine/images/1x32.gif new file mode 100644 index 0000000..ff93312 Binary files /dev/null and b/src/main/webapp/resources/engine/images/1x32.gif differ diff --git a/src/main/webapp/resources/engine/images/2px.gif b/src/main/webapp/resources/engine/images/2px.gif new file mode 100644 index 0000000..486cf56 Binary files /dev/null and b/src/main/webapp/resources/engine/images/2px.gif differ diff --git a/src/main/webapp/resources/engine/images/blank.png b/src/main/webapp/resources/engine/images/blank.png new file mode 100644 index 0000000..9bf2261 Binary files /dev/null and b/src/main/webapp/resources/engine/images/blank.png differ diff --git a/src/main/webapp/resources/engine/images/closed.png b/src/main/webapp/resources/engine/images/closed.png new file mode 100644 index 0000000..4ece7a6 Binary files /dev/null and b/src/main/webapp/resources/engine/images/closed.png differ diff --git a/src/main/webapp/resources/engine/images/datepicker.jpg b/src/main/webapp/resources/engine/images/datepicker.jpg new file mode 100644 index 0000000..2df6fe7 Binary files /dev/null and b/src/main/webapp/resources/engine/images/datepicker.jpg differ diff --git a/src/main/webapp/resources/engine/images/document.png b/src/main/webapp/resources/engine/images/document.png new file mode 100644 index 0000000..a96516a Binary files /dev/null and b/src/main/webapp/resources/engine/images/document.png differ diff --git a/src/main/webapp/resources/engine/images/excel.png b/src/main/webapp/resources/engine/images/excel.png new file mode 100644 index 0000000..15bf4a0 Binary files /dev/null and b/src/main/webapp/resources/engine/images/excel.png differ diff --git a/src/main/webapp/resources/engine/images/g.png b/src/main/webapp/resources/engine/images/g.png new file mode 100644 index 0000000..38cfc48 Binary files /dev/null and b/src/main/webapp/resources/engine/images/g.png differ diff --git a/src/main/webapp/resources/engine/images/icons/cloud.svg b/src/main/webapp/resources/engine/images/icons/cloud.svg new file mode 100644 index 0000000..8bdab2f --- /dev/null +++ b/src/main/webapp/resources/engine/images/icons/cloud.svg @@ -0,0 +1,61 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/main/webapp/resources/engine/images/icons/cloud24.png b/src/main/webapp/resources/engine/images/icons/cloud24.png new file mode 100644 index 0000000..82a247d Binary files /dev/null and b/src/main/webapp/resources/engine/images/icons/cloud24.png differ diff --git a/src/main/webapp/resources/engine/images/icons/cloud24b.png b/src/main/webapp/resources/engine/images/icons/cloud24b.png new file mode 100644 index 0000000..05efc01 Binary files /dev/null and b/src/main/webapp/resources/engine/images/icons/cloud24b.png differ diff --git a/src/main/webapp/resources/engine/images/icons/empty.svg b/src/main/webapp/resources/engine/images/icons/empty.svg new file mode 100644 index 0000000..375df3c --- /dev/null +++ b/src/main/webapp/resources/engine/images/icons/empty.svg @@ -0,0 +1,96 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/src/main/webapp/resources/engine/images/icons/flag.png b/src/main/webapp/resources/engine/images/icons/flag.png new file mode 100644 index 0000000..ddf5be6 Binary files /dev/null and b/src/main/webapp/resources/engine/images/icons/flag.png differ diff --git a/src/main/webapp/resources/engine/images/icons/flag.svg b/src/main/webapp/resources/engine/images/icons/flag.svg new file mode 100644 index 0000000..9adfd53 --- /dev/null +++ b/src/main/webapp/resources/engine/images/icons/flag.svg @@ -0,0 +1,63 @@ + + + +image/svg+xml + + + \ No newline at end of file diff --git a/src/main/webapp/resources/engine/images/icons/flag_backup.svg b/src/main/webapp/resources/engine/images/icons/flag_backup.svg new file mode 100644 index 0000000..9adfd53 --- /dev/null +++ b/src/main/webapp/resources/engine/images/icons/flag_backup.svg @@ -0,0 +1,63 @@ + + + +image/svg+xml + + + \ No newline at end of file diff --git a/src/main/webapp/resources/engine/images/icons/green.svg b/src/main/webapp/resources/engine/images/icons/green.svg new file mode 100644 index 0000000..e4c9653 --- /dev/null +++ b/src/main/webapp/resources/engine/images/icons/green.svg @@ -0,0 +1,64 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/src/main/webapp/resources/engine/images/icons/marker_a.png b/src/main/webapp/resources/engine/images/icons/marker_a.png new file mode 100644 index 0000000..75d49f8 Binary files /dev/null and b/src/main/webapp/resources/engine/images/icons/marker_a.png differ diff --git a/src/main/webapp/resources/engine/images/icons/marker_e.png b/src/main/webapp/resources/engine/images/icons/marker_e.png new file mode 100644 index 0000000..614e3c3 Binary files /dev/null and b/src/main/webapp/resources/engine/images/icons/marker_e.png differ diff --git a/src/main/webapp/resources/engine/images/icons/marker_g.png b/src/main/webapp/resources/engine/images/icons/marker_g.png new file mode 100644 index 0000000..715ca96 Binary files /dev/null and b/src/main/webapp/resources/engine/images/icons/marker_g.png differ diff --git a/src/main/webapp/resources/engine/images/icons/marker_r.png b/src/main/webapp/resources/engine/images/icons/marker_r.png new file mode 100644 index 0000000..724be3c Binary files /dev/null and b/src/main/webapp/resources/engine/images/icons/marker_r.png differ diff --git a/src/main/webapp/resources/engine/images/icons/marker_y.png b/src/main/webapp/resources/engine/images/icons/marker_y.png new file mode 100644 index 0000000..348162f Binary files /dev/null and b/src/main/webapp/resources/engine/images/icons/marker_y.png differ diff --git a/src/main/webapp/resources/engine/images/icons/red.svg b/src/main/webapp/resources/engine/images/icons/red.svg new file mode 100644 index 0000000..77cef3c --- /dev/null +++ b/src/main/webapp/resources/engine/images/icons/red.svg @@ -0,0 +1,150 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/resources/engine/images/icons/yellow.svg b/src/main/webapp/resources/engine/images/icons/yellow.svg new file mode 100644 index 0000000..f3e084b --- /dev/null +++ b/src/main/webapp/resources/engine/images/icons/yellow.svg @@ -0,0 +1,147 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/resources/engine/images/loading.gif b/src/main/webapp/resources/engine/images/loading.gif new file mode 100644 index 0000000..d84f653 Binary files /dev/null and b/src/main/webapp/resources/engine/images/loading.gif differ diff --git a/src/main/webapp/resources/engine/images/loading2.gif b/src/main/webapp/resources/engine/images/loading2.gif new file mode 100644 index 0000000..cc6cb28 Binary files /dev/null and b/src/main/webapp/resources/engine/images/loading2.gif differ diff --git a/src/main/webapp/resources/engine/images/minus.png b/src/main/webapp/resources/engine/images/minus.png new file mode 100644 index 0000000..f56db1c Binary files /dev/null and b/src/main/webapp/resources/engine/images/minus.png differ diff --git a/src/main/webapp/resources/engine/images/pdf.gif b/src/main/webapp/resources/engine/images/pdf.gif new file mode 100644 index 0000000..95c4ce0 Binary files /dev/null and b/src/main/webapp/resources/engine/images/pdf.gif differ diff --git a/src/main/webapp/resources/engine/images/plus.png b/src/main/webapp/resources/engine/images/plus.png new file mode 100644 index 0000000..d903607 Binary files /dev/null and b/src/main/webapp/resources/engine/images/plus.png differ diff --git a/src/main/webapp/resources/engine/images/rdel.png b/src/main/webapp/resources/engine/images/rdel.png new file mode 100644 index 0000000..9f63a08 Binary files /dev/null and b/src/main/webapp/resources/engine/images/rdel.png differ diff --git a/src/main/webapp/resources/engine/images/refresh.png b/src/main/webapp/resources/engine/images/refresh.png new file mode 100644 index 0000000..316f36c Binary files /dev/null and b/src/main/webapp/resources/engine/images/refresh.png differ diff --git a/src/main/webapp/resources/engine/images/rplus.png b/src/main/webapp/resources/engine/images/rplus.png new file mode 100644 index 0000000..e83f4c1 Binary files /dev/null and b/src/main/webapp/resources/engine/images/rplus.png differ diff --git a/src/main/webapp/resources/engine/index.css b/src/main/webapp/resources/engine/index.css new file mode 100644 index 0000000..f077e62 --- /dev/null +++ b/src/main/webapp/resources/engine/index.css @@ -0,0 +1,26 @@ +@charset "UTF-8"; + +/* Variables for customizing colors */ +:root{ + --box-shadow-color: rgba(0,0,0,0.7); /*Window shadow color */ + --header-color: #dadada; /*Table header color #505050*/ + --back-color: #f1f1f1;/*Table body color #3a3a3a;*/ + --back-color3: #ffffff; /* #454555 (Color of text input fields) */ + --main-font-color: #000000; /*The main text color is white or black. */ + --inactive-font-color: #656565; /* The color of inactive text. #afafaf*/ + + --row-color-1: white; + --row-color-2: whitesmoke; + --text-color-1: #000000; + --back-color-1: #ffffff; + --back-color-2: #ffffff; + --back-color-3: #ffffff; /* TextEdit */ + --path-grad: url('../resources/metadata/dbms/form/g_w.gif'); + --path-X: url('../resources/metadata/dbms/form/x_b.gif'); +} + +table +{ + font-size: 14px; + font-family: Arial; +} diff --git a/src/main/webapp/resources/engine/index.js b/src/main/webapp/resources/engine/index.js new file mode 100644 index 0000000..3febd67 --- /dev/null +++ b/src/main/webapp/resources/engine/index.js @@ -0,0 +1,3122 @@ +/** + * Igor Ivanov ivanov.i@istt.kz + * [^\x00-\x7F] + */ + +//import * as proj4 from "./proj4js/lib/proj4js.js"; + + +//var ScriptName='../metadata/dbms/records.jsp'; +var ScriptName='../records'; +var ScriptDName='../download'; +var ScriptUName='../upload'; +var ScriptRName='../reports'; //For download reports (?file=name) +var ScriptSName='../session'; + + +var g_rowColor1='#ffffff'; //Grey +var g_rowColor2='#f0f0f0'; //DimGray +var g_backColor1= '#ffffff'; //#3a3a3a +var g_backColor2= '#ffffff'; //#000000 +var g_backColor3= '#ffffff'; //#454555 +var g_textColor1= '#000000'; //#ffffff + + +//rec.request.callServer(ScriptName,''); TODO: delete this line! +function showIFrameWindow(title,url) +{ + var win=new TWin(); + win.BuildGUI(10,10); + win.setCaption(title); + win.setContent(''); + win.setSize("550px","500px"); + win.setCenter(); + win.shadow=true; + win.hide(false); +} + +function showConfigWidget() +{ + this.win=new TWin(); + this.win.BuildGUI(10,10); + this.win.setCaption(trt('Settings')); + + let str=`
+ + + + + + + + + + +
+
+ +
+ + +
+
`; + + this.win.setSize("420px","50px"); + this.win.setContent(str); + this.win.setCenter(); + this.win.shadow=true; + this.win.hide(false); + + let obj = document.getElementById('transliteration_'+this.win.uid); + obj.onchange=function() { + g_user.sendSettings('translit', this.value); + }; + obj.value=g_user.getSettings('translit',''); +} + +function makeGreenArea(data,userData) +{ + var vectorSource = new ol.source.Vector({ + features: (new ol.format.GeoJSON()).readFeatures(data,{featureProjection: 'EPSG:3857'}) + //features: (new ol.format.GeoJSON()).readFeatures(data,{featureProjection: 'EPSG:4326'}) + }); + var features = vectorSource.getFeatures(); + for(i=0;i \n\ + \n\ + \n\ + \n\ + \n\ + \n\ +
'+trt('Year')+' '+trt('Average')+' '+trt('Thous_ha')+' '+trt('Dev_of_average')+'
2005
3
2006230
20072300
\n\ +
 
\n\ +
 
\n\ + '; + + this.m_win.setContent(str); + this.m_win.hideProgressBar(); + } + + this.addField = function(year,val) + { + this.m_arr[year]=val; + } + + this.buildTable = function(year,currVal) + { + var tbl=document.getElementById("tbl_"+this.m_uid); + var tblb=document.getElementById("tblb_"+this.m_uid); + for(var i = 0; i < tblb.rows.length;) + { + tblb.deleteRow(i); + } + //tbl.innerHTML=''+trt('Year')+' .2. '+trt('Value')+''; + + var max=currVal; + var average=0; + var cnt=0; + + //Calculating average value + for (var key in this.m_arr) + { + if (this.m_arr.hasOwnProperty(key) && /^0$|^[1-9]\d*$/.test(key) && key <= 4294967294) + { + //log.info(this.m_arr[key]); + if(max'+trt('Deviation')+': '+(Math.round(p * 10) / 10)+'%'; + + //var crd=ElemCoords(tbl); + + var eLin=document.getElementById("lin_"+this.m_uid); + eLin.style.top = (tbl.offsetTop + (tbl.offsetHeight/(cnt+1)))+"px"; + eLin.style.left = td2.offsetLeft+(average*pr)+"px"; + + eLin.style.height = (tbl.offsetHeight - 2*(tbl.offsetHeight/(cnt+1)))+"px"; + } + + this.prepareData = function(obj) + { + for(let i=0;i\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + }else if (typeof this.userData.district_id != 'undefined' ) + { + xs='\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + } + var request=new TRequest(this); + if(request.callServer(ScriptName,xs)) + { + this.m_win.showProgressBar(); + } + + this.m_win.hide(false); + }; + + this.applyReq = function(req,fn,node) + { + if(node.errorCode>0) { + let fullText = node.errorMessage; + let smallText = ''; + let pos1=fullText.indexOf('[['); + let pos2=fullText.indexOf(']]'); + if(pos1>=0 && pos2>=0 && pos1=0){ //Если есть идентификатор того что это перезапись + let okFunc=()=>{ + this.setValue('seq',0); + this.sendData(); //Применить ещё раз + }; + if (smallText != '') + confirm2(trt('Warning'),smallText, fullText, okFunc, null); + else + confirm2(trt('Warning'),smallText, '', okFunc, null); + }else { + if (smallText != '') + alert2(trt('Alert'), smallText, fullText); + else + alert2(trt('Alert'), fullText); + } + return; + } + + if (fn==4) + { + if(node.n=="SysFrmLocustInfoR" || node.n=="SysFrmLocustInfoD") + { + this.prepareData(node); + } + }else + alert("Unknown function! fn=\""+fn+"\""); + }; + + this.name='TChartFRMLocustInfo'; + this.userData = userData; + this.m_win=null; + this.m_arr = new Array() + this.m_uid = getUID(); + + this.callData(); +} + +//Customize the visual elements on the access level. +function configGUIbyAccessLevel() +{ + g_user.loadAccess(); + g_user.onLoadAccess=function(user) + { + if(GET['cmd']!='' && typeof GET['cmd']!='undefined') + { + if(GET['cmd']=='FrmLocust') + { + var input; + input = document.getElementById('filter_X1_country_id'); + if(input!=null) typeof GET['country_id']!='undefined' ? input.value=GET['country_id'] : input.value=''; + input = document.getElementById('filter_X1_locust_type_id'); + if(input!=null) typeof GET['locust_type_id']!='undefined' ? input.value=GET['locust_type_id'] : input.value=''; + input = document.getElementById('filter_X1_date_start'); + if(input!=null) typeof GET['date_start']!='undefined' ? input.value=GET['date_start'] : input.value=''; + input = document.getElementById('filter_X1_date_end'); + if(input!=null) typeof GET['date_end']!='undefined' ? input.value=GET['date_end'] : input.value=''; + input = document.getElementById('filter_X1_device_id'); + if(input!=null) typeof GET['device_id']!='undefined' ? input.value=GET['device_id'] : input.value=''; + input = document.getElementById('filter_X1_registered'); + if(input!=null) typeof GET['registered']!='undefined' ? input.value=GET['registered'] : input.value=''; + input = document.getElementById('filter_X1_indicator'); + if(input!=null) typeof GET['indicator']!='undefined' ? input.value=GET['indicator'] : input.value=''; + + callFrmLocustData(); + } + } + + var showT; + //Devices + showT=false; + if(!user.getAccess("Update_Terminals")) deleteHTML(document.getElementById('btnTerminalsShow')); else showT=true; + //if(!user.getAccess("Update_TerminalsModels")) deleteHTML(document.getElementById('btnTerminalsModelsShow')); else showT=true; + if(!showT) + { + deleteHTML(document.getElementById('lblDevices')); + } + //Administration + showT=false; + if(!user.getAccess("Update__Actions")) deleteHTML('btnActionsShow'); else showT=true; + if(!user.getAccess("Update__Access")) deleteHTML('btnAccessShow'); else showT=true; + if(!user.getAccess("Update__Groups")) deleteHTML('btnGroupsShow'); else showT=true; + //if(!(user.getAccess("Update__Users") || user.getAccess("set_role_operator"))) deleteHTML('btnUsersShow'); else showT=true; + + if(!user.getAccess("Update__History")) deleteHTML('btnHistoryShow'); else showT=true; + if(!user.getAccess("Update__Metadata")) deleteHTML('btnMetadataShow'); else showT=true; + + if(!showT) + { + deleteHTML(document.getElementById('lblAdministration')); + } + + //Language + showT=false; + if(!user.getAccess("Update__Languages")) deleteHTML(document.getElementById('btnLanguage')); else showT=true; + if(!user.getAccess("Update__Translations")) deleteHTML(document.getElementById('btnTranslation')); else showT=true; + if(!showT) + { + deleteHTML(document.getElementById('lblLanguage')); + } + + showT=false; + if(!user.getAccess("Update_Companies")) deleteHTML(document.getElementById('btnCompaniesShow')); else showT=true; + if(!showT) + { + deleteHTML(document.getElementById('lblCompanies')); + } + + + //Weather + showT=false; + if(!user.getAccess("Update_Weather")) deleteHTML(document.getElementById('btnWeather')); else showT=true; + if(!user.getAccess("Update_WeatherTypes")) deleteHTML(document.getElementById('btnWeatherType')); else showT=true; + if(!showT) + { + deleteHTML(document.getElementById('lblWeather')); + } + + + showT=false; + if(!user.getAccess("Update_Countries")) deleteHTML(document.getElementById('btnCountries')); else showT=true; + if(!user.getAccess("Update_Sprayers")) deleteHTML(document.getElementById('btnSprayers')); else showT=true; + if(!user.getAccess("Update_List_Age")) deleteHTML(document.getElementById('btnListAge')); else showT=true; + if(!user.getAccess("Update_List_Biotope")) deleteHTML(document.getElementById('btnListBiotope')); else showT=true; + if(!user.getAccess("Update_List_Cover")) deleteHTML(document.getElementById('btnListCover')); else showT=true; + if(!user.getAccess("Update_List_Damage")) deleteHTML(document.getElementById('btnListDamage')); else showT=true; + if(!user.getAccess("Update_List_Density")) deleteHTML(document.getElementById('btnListDensity')); else showT=true; + if(!user.getAccess("Update_List_Directions")) deleteHTML(document.getElementById('btnListDirections')); else showT=true; + if(!user.getAccess("Update_List_Mortality")) deleteHTML(document.getElementById('btnListMortality')); else showT=true; + if(!user.getAccess("Update_List_Phase")) deleteHTML(document.getElementById('btnListPhase')); else showT=true; + if(!user.getAccess("Update_List_Greenery")) deleteHTML(document.getElementById('btnListGreenery')); else showT=true; + if(!user.getAccess("Update_LocustsTypes")) deleteHTML(document.getElementById('btnListLocustType')); else showT=true; + if(!user.getAccess("Update_List_OperatorsTypes")) deleteHTML(document.getElementById('btnListOperatorsTypes')); else showT=true; + if(!user.getAccess("Update_List_Actions")) deleteHTML(document.getElementById('btnListActions')); else showT=true; + if(!user.getAccess("Update_List_Behaviors")) deleteHTML(document.getElementById('btnListBehaviors')); else showT=true; + if(!user.getAccess("Update_List_Paintings")) deleteHTML(document.getElementById('btnListPaintings')); else showT=true; + if(!user.getAccess("Update_Fledgling")) deleteHTML(document.getElementById('btnFledgling')); else showT=true; + if(!user.getAccess("Update_List_Capacities")) deleteHTML(document.getElementById('btnListCapacities')); else showT=true; + if(!user.getAccess("Update_List_Containers")) deleteHTML(document.getElementById('btnListСontainers')); else showT=true; + if(!user.getAccess("Update_List_Markings")) deleteHTML(document.getElementById('btnListMarkings')); else showT=true; + if(!user.getAccess("Update_Borns")) deleteHTML(document.getElementById('btnBorns')); else showT=true; + if(!user.getAccess("Update_List_Breeding")) deleteHTML(document.getElementById('btnListBreeding')); else showT=true; + if(!user.getAccess("Update_List_Vegetation")) deleteHTML(document.getElementById('btnListVegetation')); else showT=true; + if(!user.getAccess("Update_List_Formulation")) deleteHTML(document.getElementById('btnListFormulation')); else showT=true; + if(!user.getAccess("Update_List_Height")) deleteHTML(document.getElementById('btnListHeight')); else showT=true; + if(!user.getAccess("Update_List_Enemies")) deleteHTML(document.getElementById('btnListEnemies')); else showT=true; + if(!showT) + { + deleteHTML(document.getElementById('lblLists')); + } + } +} + +//Open window to show report by countries +function showReportCountries() +{ + let rec=new SRec() + //rec.create('../metadata/dbms/form/') + rec.create(null); + rec.f_TypeName="ReportCountries"; + rec.f_Settings=''; + + rec.f_Settings+=""; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=""; + + //alert(rec.f_Settings); + + rec.win.setSize("800px","500px"); + //rec.win.setLeftTop(300,40); + rec.win.setCenter(); + rec.request.callServer(ScriptName,''); +} + +//Open window to show report by inspectors +function showReportInspectors() +{ + let rec=new SRec(); + rec.create(null); + rec.f_TypeName="ReportInspectors"; + + rec.f_Settings=''; + rec.f_Settings+=""; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=""; + + //alert(rec.f_Settings); + + rec.win.setSize("800px","500px"); + //rec.win.setHeight(500); + //rec.win.setLeftTop(300,40); + rec.win.setCenter(); + rec.request.callServer(ScriptName,''); +} + +function showReportTabletsStatistics() +{ + let rec=new SRec(); + rec.create(null); + rec.f_TypeName="ReportTabletsStatistics"; + + rec.f_Settings=''; + rec.f_Settings+=""; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=" "; + rec.f_Settings+=""; + + //alert(rec.f_Settings); + + rec.win.setSize("800px","500px"); + //rec.win.setHeight(500); + //rec.win.setLeftTop(300,40); + rec.win.setCenter(); + rec.request.callServer(ScriptName,''); +} + + + +//Green style (norm) +function createFatypeStyleG(feature) +{ + return function(){ + var zoom = map.getView().getZoom(); + var text = zoom > 12 ? feature.get('name') : ''; + + var iconStyleG = new ol.style.Style({ + image: new ol.style.Icon(({ + anchor: [0.5, 24], + anchorXUnits: 'fraction', + anchorYUnits: 'pixels', + opacity: 0.75, + src: '../resources/engine/images/icons/marker_g.png' + })), + text: new ol.style.Text({ + font: '12px helvetica,sans-serif', + offsetY: 10, + text: text, + fill: new ol.style.Fill({color: '#000'}), + stroke: new ol.style.Stroke({color: '#fff', width: 2}) + }) + }); + return iconStyleG; + } +} + +//Yellow (attention) +function createFatypeStyleY(feature) +{ + return function(){ + var zoom = map.getView().getZoom(); + var text = zoom > 12 ? feature.get('name') : ''; + + var iconStyleG = new ol.style.Style({ + image: new ol.style.Icon(({ + anchor: [0.5, 24], + anchorXUnits: 'fraction', + anchorYUnits: 'pixels', + opacity: 0.75, + src: '../resources/engine/images/icons/marker_y.png' + })), + text: new ol.style.Text({ + font: '12px helvetica,sans-serif', + text: text, + fill: new ol.style.Fill({color: '#000'}), + stroke: new ol.style.Stroke({color: '#fff', width: 2}) + }) + }); + return iconStyleG; + } +} + +//Red (dangerous) +function createFatypeStyleR(feature) +{ + return function(){ + var zoom = map.getView().getZoom(); + var text = zoom > 12 ? feature.get('name') : ''; + + var iconStyleG = new ol.style.Style({ + image: new ol.style.Icon(({ + anchor: [0.5, 24], + anchorXUnits: 'fraction', + anchorYUnits: 'pixels', + opacity: 0.75, + src: '../resources/engine/images/icons/marker_r.png' + })), + text: new ol.style.Text({ + font: '12px helvetica,sans-serif', + text: text, + fill: new ol.style.Fill({color: '#000'}), + stroke: new ol.style.Stroke({color: '#fff', width: 2}) + }) + }); + return iconStyleG; + } +} + +//Red (dangerous) +function createFatypeStyleNone(feature) +{ + return function(){ + var zoom = map.getView().getZoom(); + var text = zoom > 12 ? feature.get('name') : ''; + + var iconStyleG = new ol.style.Style({ + image: new ol.style.Icon(({ + anchor: [0.5, 24], + anchorXUnits: 'fraction', + anchorYUnits: 'pixels', + opacity: 0.75, + src: '../resources/engine/images/icons/marker_e.png' + })), + text: new ol.style.Text({ + font: '12px helvetica,sans-serif', + text: text, + fill: new ol.style.Fill({color: '#000'}), + stroke: new ol.style.Stroke({color: '#fff', width: 2}) + }) + }); + return iconStyleG; + } +} + +//Style for the destruction of locusts. +function createFatypeStyleDel(feature,red) +{ + return function(){ + var zoom = map.getView().getZoom(); + var text = zoom > 12 ? feature.get('name') : ''; + + var iconStyleG; + if(red) + { + iconStyleG = new ol.style.Style({ + image: new ol.style.Icon(({ + anchor: [0.5, 25], + anchorXUnits: 'fraction', + anchorYUnits: 'pixels', + opacity: 0.75, + src: '../resources/engine/images/icons/flag.png' + })), + text: new ol.style.Text({ + font: '12px helvetica,sans-serif', + text: text, + fill: new ol.style.Fill({color: '#000'}), + stroke: new ol.style.Stroke({color: '#fff', width: 2}) + }) + }); + }else + { + iconStyleG = new ol.style.Style({ + image: new ol.style.Icon(({ + anchor: [0.5, 25], + anchorXUnits: 'fraction', + anchorYUnits: 'pixels', + opacity: 0.75, + src: '../resources/engine/images/icons/flag.png' + })), + text: new ol.style.Text({ + font: '12px helvetica,sans-serif', + text: text, + fill: new ol.style.Fill({color: '#000'}), + stroke: new ol.style.Stroke({color: '#fff', width: 2}) + }) + }); + } + return iconStyleG; + } +} + +//Hide map: country regions. +function hideFrmLocustInfoData() +{ + vectorSourceArea.clear(false); + //Hide legend + if(typeof g_WinLegend3 != "undefined" && g_WinLegend3!=null) + { + g_WinLegend3.hide(true); + } +} +// Call data for build map by country regions. +function callFrmLocustInfoData() +{ + var country_id=""; + var region_id=""; + var locust_type_id=""; + var year=""; + var product_id = ""; + + var input; + input = document.getElementById('filter_X3_country_id'); + if(input!=null) country_id=input.value; + input = document.getElementById('filter_X3_region_id'); + if(input!=null) region_id=input.value; + input = document.getElementById('filter_X3_locust_type_id'); + if(input!=null) locust_type_id=input.value; + input = document.getElementById('filter_X3_year'); + if(input!=null) year=input.value; + input = document.getElementById('filter_X3_indicator'); + if(input!=null) product_id=input.value; + + var xs=''; + if(product_id==2) //Product N 2 + { + if(region_id=='') + { + xs='\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + + var request=new TRequest(this); + request.userData="FrmLocustInfoData"; + }else + { + xs='\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + + var request=new TRequest(this); + request.userData="FrmLocustInfoData_r"; + } + + }else + if(product_id==3) //Product N 3 + { + if(region_id=='') + { + xs='\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + + var request=new TRequest(this); + request.userData="FrmLocustInfoData"; + }else + { + xs='\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + + var request=new TRequest(this); + request.userData="FrmLocustInfoData_r"; + } + }else + if(product_id==4) //Product N 4 "Карта уровня угроз" + { + if(region_id=='') + { + xs='\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + + var request=new TRequest(this); + request.userData="FrmLocustInfoData4"; + }else + { + xs='\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + + var request=new TRequest(this); + request.userData="FrmLocustInfoData4_r"; + + } + } + + if(request.callServer(ScriptName,xs)) + { + showProgressBar("FrmLocustInfoData"); + } + + //Show legend + if(typeof g_WinLegend3 == "undefined" || g_WinLegend3==null || g_WinLegend3.closed) + { + g_WinLegend3=new TWin(); + g_WinLegend3.BuildGUI(window.innerWidth-285,40); + } + g_WinLegend3.setCaption(trt('Legend')); + g_WinLegend3.setSize("100px","80px"); + if(product_id==2) + { + g_WinLegend3.setContent('
    >15%'+trt('Increase')+'
    >=15% '+trt('and')+' <=15%'+trt('On_the_same_level')+'
    <15%'+trt('Decrease')+'
     '+trt('No_data')+'
'); + } + if(product_id==3) + { + g_WinLegend3.setContent('
    >15%'+trt('Increase')+'
    >=15% '+trt('and')+' <=15%'+trt('On_the_same_level')+'
    <15%'+trt('Decrease')+'
     '+trt('No_data')+'
'); + } + if(product_id==4) + { + g_WinLegend3.setContent('
    >-25% '+trt('and')+' <25%'+trt('Normal_Multiyear_average_level')+'
    <=-25% '+trt('or')+' >=25%'+trt('Danger')+'
     '+trt('No_data')+'
'); + } + g_WinLegend3.hide(false); + g_WinLegend3.setLeftTop(window.innerWidth-g_WinLegend3.getWidth()-20,40); + setTimeout(function() { g_WinLegend3.setLeftTop(window.innerWidth-g_WinLegend3.getWidth()-20,40); }, 1000); +} + +function openFrmLocustData() +{ + var input; + + var country_id=""; + var date_start=""; + var date_end=""; + var device_id=""; + var registered=""; + var test=""; + + input = document.getElementById('filter_X1_country_id'); + if(input!=null) country_id=input.value; + var region_id = $('#filter_X1_region_id').val(); + input = document.getElementById('filter_X1_date_start'); + if(input!=null) + { + date = new Date(input.value.replace(/-/g, "/")) + date_start=date.getTime()/1000; + if(isNaN(date_start)) date_start=''; + } + input = document.getElementById('filter_X1_date_end'); + if(input!=null) + { + date = new Date(input.value.replace(/-/g, "/")) + date_end=date.getTime()/1000; + if(isNaN(date_end)) date_end=''; + } + input = document.getElementById('filter_X1_device_id'); + if(input!=null){ + if(input.value=="2") test="1"; + else device_id=input.value; + } + input = document.getElementById('filter_X1_registered'); + if(input!=null) registered=input.value; + + rec=new SRec(); + rec.create(null); + rec.f_TypeName="FrmLocust"; + + rec.f_Settings='\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + + //alert("config: "+rec.f_Settings); + + //rec.win.setSize("400px","100px"); + rec.win.setHeight(500); + //rec.win.setLeftTop(300,40); + rec.win.setCenter(); + rec.request.callServer(ScriptName,''); +} + +function openLayoutsWin() +{ + var input; + + rec=new SRec(); + rec.create(null); + rec.f_TypeName="Layouts"; + + rec.win.setHeight(500); + rec.win.setCenter(); + rec.request.callServer(ScriptName,''); +} + +function openFrmLocustDelData() +{ + var input; + + var country_id=""; + var date_start=""; + var date_end=""; + var device_id=""; + var registered=""; + var test=""; + + input = document.getElementById('filter_X2_country_id'); + if(input!=null) country_id=input.value; + var region_id = $('#filter_X2_region_id').val(); + input = document.getElementById('filter_X2_date_start'); + if(input!=null) + { + date = new Date(input.value.replace(/-/g, "/")); + date_start=date.getTime()/1000;// - date.getTimezoneOffset()*60; + if(isNaN(date_start)) date_start=''; + } + input = document.getElementById('filter_X2_date_end'); + if(input!=null) + { + date = new Date(input.value.replace(/-/g, "/")); + date_end=date.getTime()/1000;// - date.getTimezoneOffset()*60; + if(isNaN(date_end)) date_end=''; + } + input = document.getElementById('filter_X2_device_id'); + if(input!=null){ + if(input.value=="2") test="1"; + else device_id=input.value; + } + input = document.getElementById('filter_X2_registered'); + if(input!=null) registered=input.value; + + rec=new SRec(); + rec.create(null); + rec.f_TypeName="FrmLocustDel"; + + rec.f_Settings='\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + + //rec.win.setSize("400px","100px"); + rec.win.setHeight(500); + //rec.win.setLeftTop(300,40); + rec.win.setCenter(); + rec.request.callServer(ScriptName,''); +} + +function hideFrmLocustData() +{ + vectorSource.clear(false); + vectorSourceV.clear(false); + //Hide legend + if(typeof g_WinLegend1 != "undefined" && g_WinLegend1!=null) + { + g_WinLegend1.hide(true); + } +} + +//Call data for create markers +function callFrmLocustData() +{ + let input; let value; + + let rData = { + country_id: null, + region_id: null, + locust_type_id: null, + date_start: null, + date_end: null, + device_id: null, + registered: null, + indicator: null, + test: null + }; + value = $('#filter_X1_country_id').val(); + if(value!='') rData.country_id = parseInt(value); + value = $('#filter_X1_region_id').val(); + if(value!='') rData.region_id = parseInt(value); + + value = $('#filter_X1_locust_type_id').val(); + if(value!='') rData.locust_type_id = parseInt(value); + + input = document.getElementById('filter_X1_date_start'); + if(input!=null) + { + let date = new Date(input.value.replace(/-/g, "/")); + rData.date_start=date.getTime()/1000;// - date.getTimezoneOffset()*60; + if(isNaN(rData.date_start)) rData.date_start=null; + } + input = document.getElementById('filter_X1_date_end'); + if(input!=null) + { + let date = new Date(input.value.replace(/-/g, "/")); + rData.date_end=date.getTime()/1000;// - date.getTimezoneOffset()*60; + if(isNaN(rData.date_end)) rData.date_end=null; + } + + value = $('#filter_X1_device_id').val(); + if(value!=''){ + if(value=="2") rData.test="1"; + else rData.device_id = parseInt(value); + } + + value = $('#filter_X1_registered').val(); + if(value!='') rData.registered = parseInt(value); + + input = document.getElementById('filter_X1_indicator'); + if(input!=null) rData.indicator=input.value; + + $.ajax({ + url: '../get_survey', + data: JSON.stringify(rData), + contentType: 'application/json; charset=utf-8', + type: "POST", + dataType: "json", + success: function(data,status){ + if(status=='success') + { + if(data.errorCode=='0') + { + updatePOILocust(data.data,data.indicator); + }else + { + alert2(trt('Error'),data.errorMessage); + } + }else{ + alert2(trt('Alert'),status); + } + hideProgressBar('FrmLocustData'); + }, + error: function(jqXHR, exception) { + alert2(trt('Alert'),jqXHR.responseText); + hideProgressBar("FrmLocustData"); + } + }); + showProgressBar("FrmLocustData"); + +/* + var request=new TRequest(this); + request.userData="FrmLocustData"; + request.userIndicator=indicator; + if(request.callServer(ScriptName,xs)) + { + showProgressBar("FrmLocustData"); + } +*/ + //Show legend + if(typeof g_WinLegend1 == "undefined" || g_WinLegend1==null || g_WinLegend1.closed) + { + g_WinLegend1=new TWin(); + g_WinLegend1.BuildGUI(window.innerWidth-150,40); + } + g_WinLegend1.setCaption(trt('Legend')); + g_WinLegend1.setSize("100px","80px"); + + if(rData.indicator=="1") + { + g_WinLegend1.setContent('
>1'+trt('Danger')+'
<=1'+trt('Attention')+'
=0'+trt('Quietly')+'
'+trt('No_data')+'
'); + } + if(rData.indicator=="2") + { + g_WinLegend1.setContent('
>=5'+trt('Danger')+'
>=3 ... <5'+trt('Caution')+'
<=2'+trt('Calm')+'
'+trt('No_data')+'
'); + } + if(rData.indicator=="3") + { + g_WinLegend1.setLeftTop(window.innerWidth-200,40) + g_WinLegend1.setContent('
>=1'+trt('Danger')+'
<1'+trt('Calm')+'
'+trt('No_data')+'
'); + } + if(rData.indicator=="4") + { + g_WinLegend1.setContent('
>=5'+trt('Danger')+'
>=3 ... <5'+trt('Caution')+'
<=2'+trt('Calm')+'
'+trt('No_data')+'
'); + } + if(rData.indicator=="5") + { + g_WinLegend1.setContent('
>=1'+trt('Danger')+'
<1'+trt('Calm')+'
'+trt('No_data')+'
'); + } + g_WinLegend1.hide(false); + g_WinLegend1.setLeftTop(window.innerWidth-g_WinLegend1.getWidth()-20,40); + setTimeout(function() { g_WinLegend1.setLeftTop(window.innerWidth-g_WinLegend1.getWidth()-20,40); }, 1000); +} + +//Hide data for create markers +function hideFrmLocustDelData() +{ + vectorSourceDel.clear(false); + vectorSourceDelV.clear(false); + //Hide legend + if(typeof g_WinLegend0 != "undefined" && g_WinLegend0!=null) + { + g_WinLegend0.hide(true); + } +} +//Call data for create markers +function callFrmLocustDelData() +{ + let input; let value; + + let rData = { + country_id: null, + region_id: null, + date_start: null, + date_end: null, + device_id: null, + registered: null, + test: null + }; + value = $('#filter_X2_country_id').val(); + if(value!='') rData.country_id = parseInt(value); + value = $('#filter_X2_region_id').val(); + if(value!='') rData.region_id = parseInt(value); + input = document.getElementById('filter_X2_date_start'); + if(input!=null) + { + let date = new Date(input.value.replace(/-/g, "/")); + rData.date_start=date.getTime()/1000;// - date.getTimezoneOffset()*60; + if(isNaN(rData.date_start)) rData.date_start=null; + } + input = document.getElementById('filter_X2_date_end'); + if(input!=null) + { + let date = new Date(input.value.replace(/-/g, "/")); + rData.date_end=date.getTime()/1000;// - date.getTimezoneOffset()*60; + if(isNaN(rData.date_end)) rData.date_end=null; + } + value = $('#filter_X2_device_id').val(); + if(value!=''){ + if(value=="2") rData.test="1"; + else rData.device_id = parseInt(value); + } + + value = $('#filter_X2_registered').val(); + if(value!='') rData.registered = parseInt(value); + + $.ajax({ + url: '../get_spray', + data: JSON.stringify(rData), + contentType: 'application/json; charset=utf-8', + type: "POST", + dataType: "json", + success: function(data,status){ + if(status=='success') + { + if(data.errorCode=='0') + { + updatePOILocustDel(data.data); + }else + { + alert2(trt('Error'),data.errorMessage); + } + }else{ + alert2(trt('Alert'),status); + } + hideProgressBar('FrmLocustDelData'); + }, + error: function(jqXHR, exception) { + alert2(trt('Alert'),jqXHR.responseText); + hideProgressBar("FrmLocustData"); + } + }); + showProgressBar("FrmLocustDelData"); + +/* + var xs=''; + xs='\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + + //alert('xs='+xs); + + var request=new TRequest(this); + request.userData="FrmLocustDelData"; + + if(request.callServer(ScriptName,xs)) + { + showProgressBar("FrmLocustDelData"); + } +*/ + //Show legend + if(typeof g_WinLegend0 == "undefined" || g_WinLegend0==null || g_WinLegend0.closed) + { + g_WinLegend0=new TWin(); + g_WinLegend0.BuildGUI(window.innerWidth-150,40); + } + g_WinLegend0.setCaption(trt('Legend')); + g_WinLegend0.setSize("145px","65px"); + g_WinLegend0.setContent('
'+trt('Spraying')+'
'); + g_WinLegend0.hide(false); + g_WinLegend0.setLeftTop(window.innerWidth-g_WinLegend0.getWidth()-20,40); + setTimeout(function() { g_WinLegend0.setLeftTop(window.innerWidth-g_WinLegend0.getWidth()-20,40); }, 1000); +} + +function openFrmLocustInfo() +{ + var input; + + var country_id=""; + var year=""; + var locust_type_id=''; + + input = document.getElementById('filter_X3_country_id'); + if(input!=null) country_id=input.value; + input = document.getElementById('filter_X3_year'); + if(input!=null) year=input.value; + input = document.getElementById('filter_X3_locust_type_id'); + if(input!=null) locust_type_id=input.value; + + + rec=new SRec(); + rec.create(null); + rec.f_TypeName="FrmLocustInfo"; + + rec.f_Settings='\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + + //rec.win.setSize("400px","100px"); + rec.win.setHeight(500); + //rec.win.setLeftTop(300,40); + rec.win.setCenter(); + rec.request.callServer(ScriptName,''); +} + +function openWeather() +{ + var input; + + var country_id=""; + + input = document.getElementById('filter_soil_country_id'); + if(input!=null) country_id=input.value; + + rec=new SRec(); + rec.create(null); + rec.f_TypeName="Weather"; + + rec.f_Settings='\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + + //rec.win.setSize("400px","100px"); + rec.win.setHeight(500); + //rec.win.setLeftTop(300,40); + rec.win.setCenter(); + rec.request.callServer(ScriptName,''); +} + +//Call WMS NDVI data from GeoServer +function callNDVIData() +{ + let day = document.getElementById("filter_ndvi_day").value; + day=day.padStart(3, "0"); + + //Stavropol + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDVI:'+day+'_NDVI_h20v03'} + }); + wms_h20v03.setSource(wms_source); + wms_h20v03.setVisible(true); + + //Krim + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDVI:'+day+'_NDVI_h20v04'} + }); + wms_h20v04.setSource(wms_source); + wms_h20v04.setVisible(true); + + //Stavropol + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDVI:'+day+'_NDVI_h21v03'} + }); + wms_h21v03.setSource(wms_source); + wms_h21v03.setVisible(true); + + //Caspi sea + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDVI:'+day+'_NDVI_h21v04'} + }); + wms_h21v04.setSource(wms_source); + wms_h21v04.setVisible(true); + + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDVI:'+day+'_NDVI_h21v05'} + }); + wms_h21v05.setSource(wms_source); + wms_h21v05.setVisible(true); + + // + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDVI:'+day+'_NDVI_h22v03'} + }); + wms_h22v03.setSource(wms_source); + wms_h22v03.setVisible(true); + + //Aral Sea + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDVI:'+day+'_NDVI_h22v04'} + }); + wms_h22v04.setSource(wms_source); + wms_h22v04.setVisible(true); + + //Turmenistan + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDVI:'+day+'_NDVI_h22v05'} + }); + wms_h22v05.setSource(wms_source); + wms_h22v05.setVisible(true); + + //Sever + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDVI:'+day+'_NDVI_h23v03'} + }); + wms_h23v03.setSource(wms_source); + wms_h23v03.setVisible(true); + + //Kiegizstan + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDVI:'+day+'_NDVI_h23v04'} + }); + wms_h23v04.setSource(wms_source); + wms_h23v04.setVisible(true); + + //Afganistan + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDVI:'+day+'_NDVI_h23v05'} + }); + wms_h23v05.setSource(wms_source); + wms_h23v05.setVisible(true); + + + //Show legend + if(typeof g_WinLegend == "undefined" || g_WinLegend == null || g_WinLegend.closed) + { + g_WinLegend=new TWin(); + g_WinLegend.BuildGUI(window.innerWidth-290,40); + } + g_WinLegend.setCaption(trt('Legend')); + g_WinLegend.setSize("110px","313px"); + g_WinLegend.setContent(''); + g_WinLegend.hide(false); + g_WinLegend.setLeftTop(window.innerWidth-g_WinLegend.getWidth()-30,40); + setTimeout(function() { g_WinLegend.setLeftTop(window.innerWidth-g_WinLegend.getWidth()-30,40); }, 1000); + + g_boundaryTile.setVisible(true); +} + +//Call WMS IVI data from GeoServer +function callIVIData() +{ + let year = document.getElementById("filter_ivi_year").value; + //year=year.padStart(3, "0"); + + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'IVI:'+year+'_IVI_h20v03'} + }); + wms_h20v03.setSource(wms_source); + wms_h20v03.setVisible(true); + + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'IVI:'+year+'_IVI_h20v04'} + }); + wms_h20v04.setSource(wms_source); + wms_h20v04.setVisible(true); + + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'IVI:'+year+'_IVI_h21v03'} + }); + wms_h21v03.setSource(wms_source); + wms_h21v03.setVisible(true); + + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'IVI:'+year+'_IVI_h21v04'} + }); + wms_h21v04.setSource(wms_source); + wms_h21v04.setVisible(true); + + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'IVI:'+year+'_IVI_h21v05'} + }); + wms_h21v05.setSource(wms_source); + wms_h21v05.setVisible(true); + + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'IVI:'+year+'_IVI_h22v03'} + }); + wms_h22v03.setSource(wms_source); + wms_h22v03.setVisible(true); + + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'IVI:'+year+'_IVI_h22v04'} + }); + wms_h22v04.setSource(wms_source); + wms_h22v04.setVisible(true); + + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'IVI:'+year+'_IVI_h22v05'} + }); + wms_h22v05.setSource(wms_source); + wms_h22v05.setVisible(true); + + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'IVI:'+year+'_IVI_h23v03'} + }); + wms_h23v03.setSource(wms_source); + wms_h23v03.setVisible(true); + + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'IVI:'+year+'_IVI_h23v04'} + }); + wms_h23v04.setSource(wms_source); + wms_h23v04.setVisible(true); + + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'IVI:'+year+'_IVI_h23v05'} + }); + wms_h23v05.setSource(wms_source); + wms_h23v05.setVisible(true); + + //Show legend + if(typeof g_WinLegend == "undefined" || g_WinLegend==null || g_WinLegend.closed) + { + g_WinLegend=new TWin(); + g_WinLegend.BuildGUI(window.innerWidth-290,40); + } + g_WinLegend.setCaption(trt('Legend')); + g_WinLegend.setSize("110px","313px"); + g_WinLegend.setContent(''); + g_WinLegend.hide(false); + g_WinLegend.setLeftTop(window.innerWidth-g_WinLegend.getWidth()-30,40); + setTimeout(function() { g_WinLegend.setLeftTop(window.innerWidth-g_WinLegend.getWidth()-30,40); }, 1000); + + g_boundaryTile.setVisible(true); +} + +//Call WMS NDWI data from GeoServer +function callNDWIData() +{ + let day; + + day = document.getElementById("filter_ndwi_day_compare").value; + if(day!=''){ + + if(day%10!==0){ + day=""; + }else{ + day=day.padStart(3, "0")+"_"; + } + + log.info("layers = "+'NDWI_CMP:'+day+'NDWI_CMP_hxxvxx'); + + //Stavropol + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI_CMP:'+day+'NDWI_CMP_h20v03'} + }); + wms_h20v03.setSource(wms_source); + wms_h20v03.setVisible(true); + + //Krim + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI_CMP:'+day+'NDWI_CMP_h20v04'} + }); + wms_h20v04.setSource(wms_source); + wms_h20v04.setVisible(true); + + //Stavropol + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI_CMP:'+day+'NDWI_CMP_h21v03'} + }); + wms_h21v03.setSource(wms_source); + wms_h21v03.setVisible(true); + + //Caspi sea + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI_CMP:'+day+'NDWI_CMP_h21v04'} + }); + wms_h21v04.setSource(wms_source); + wms_h21v04.setVisible(true); + + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI_CMP:'+day+'NDWI_CMP_h21v05'} + }); + wms_h21v05.setSource(wms_source); + wms_h21v05.setVisible(true); + + // + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI_CMP:'+day+'NDWI_CMP_h22v03'} + }); + wms_h22v03.setSource(wms_source); + wms_h22v03.setVisible(true); + + //Aral Sea + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI_CMP:'+day+'NDWI_CMP_h22v04'} + }); + wms_h22v04.setSource(wms_source); + wms_h22v04.setVisible(true); + + //Turmenistan + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI_CMP:'+day+'NDWI_CMP_h22v05'} + }); + wms_h22v05.setSource(wms_source); + wms_h22v05.setVisible(true); + + //Sever + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI_CMP:'+day+'NDWI_CMP_h23v03'} + }); + wms_h23v03.setSource(wms_source); + wms_h23v03.setVisible(true); + + //Kiegizstan + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI_CMP:'+day+'NDWI_CMP_h23v04'} + }); + wms_h23v04.setSource(wms_source); + wms_h23v04.setVisible(true); + + //Afganistan + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI_CMP:'+day+'NDWI_CMP_h23v05'} + }); + wms_h23v05.setSource(wms_source); + wms_h23v05.setVisible(true); + + //Show legend + if(typeof g_WinLegend == "undefined" || g_WinLegend == null || g_WinLegend.closed) + { + g_WinLegend = new TWin(); + g_WinLegend.BuildGUI(window.innerWidth-290,40); + } + g_WinLegend.setCaption(trt('Legend')); + g_WinLegend.setSize("90px","140px"); + g_WinLegend.setContent(''); + g_WinLegend.hide(false); + g_WinLegend.setLeftTop(window.innerWidth-g_WinLegend.getWidth()-30,40); + setTimeout(function() { g_WinLegend.setLeftTop(window.innerWidth-g_WinLegend.getWidth()-30,40); }, 1000); + + g_boundaryTile.setVisible(true); + + }else{ + day = document.getElementById("filter_ndwi_day").value; + if(day%10!==0){ + day=""; + }else{ + day=day.padStart(3, "0")+"_"; + } + log.info("layers = "+'NDWI:'+day+'NDWI_hxxvxx'); + + //Stavropol + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI:'+day+'NDWI_h20v03'} + }); + wms_h20v03.setSource(wms_source); + wms_h20v03.setVisible(true); + + //Krim + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI:'+day+'NDWI_h20v04'} + }); + wms_h20v04.setSource(wms_source); + wms_h20v04.setVisible(true); + + //Stavropol + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI:'+day+'NDWI_h21v03'} + }); + wms_h21v03.setSource(wms_source); + wms_h21v03.setVisible(true); + + //Caspi sea + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI:'+day+'NDWI_h21v04'} + }); + wms_h21v04.setSource(wms_source); + wms_h21v04.setVisible(true); + + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI:'+day+'NDWI_h21v05'} + }); + wms_h21v05.setSource(wms_source); + wms_h21v05.setVisible(true); + + // + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI:'+day+'NDWI_h22v03'} + }); + wms_h22v03.setSource(wms_source); + wms_h22v03.setVisible(true); + + //Aral Sea + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI:'+day+'NDWI_h22v04'} + }); + wms_h22v04.setSource(wms_source); + wms_h22v04.setVisible(true); + + //Turmenistan + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI:'+day+'NDWI_h22v05'} + }); + wms_h22v05.setSource(wms_source); + wms_h22v05.setVisible(true); + + //Sever + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI:'+day+'NDWI_h23v03'} + }); + wms_h23v03.setSource(wms_source); + wms_h23v03.setVisible(true); + + //Kiegizstan + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI:'+day+'NDWI_h23v04'} + }); + wms_h23v04.setSource(wms_source); + wms_h23v04.setVisible(true); + + //Afganistan + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDWI:'+day+'NDWI_h23v05'} + }); + wms_h23v05.setSource(wms_source); + wms_h23v05.setVisible(true); + + //Show legend + if(typeof g_WinLegend == "undefined" || g_WinLegend == null || g_WinLegend.closed) + { + g_WinLegend = new TWin(); + g_WinLegend.BuildGUI(window.innerWidth-290,40); + } + g_WinLegend.setCaption(trt('Legend')); + g_WinLegend.setSize("90px","140px"); + g_WinLegend.setContent(''); + g_WinLegend.hide(false); + g_WinLegend.setLeftTop(window.innerWidth-g_WinLegend.getWidth()-30,40); + setTimeout(function() { g_WinLegend.setLeftTop(window.innerWidth-g_WinLegend.getWidth()-30,40); }, 1000); + + g_boundaryTile.setVisible(true); + } +} + +//Call WMS NDSI data from GeoServer +function callNDSIData() +{ + let day = document.getElementById("filter_ndsi_day").value; + if(day%10!==0){ + day=""; + }else{ + day=day.padStart(3, "0")+"_"; + } + + let layers = ""; + + //Stavropol + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDSI:'+day+'NDSI_h20v03'} + }); + wms_h20v03.setSource(wms_source); + wms_h20v03.setVisible(true); + + //Krim + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDSI:'+day+'NDSI_h20v04'} + }); + wms_h20v04.setSource(wms_source); + wms_h20v04.setVisible(true); + + //Stavropol + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDSI:'+day+'NDSI_h21v03'} + }); + wms_h21v03.setSource(wms_source); + wms_h21v03.setVisible(true); + + //Caspi sea + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDSI:'+day+'NDSI_h21v04'} + }); + wms_h21v04.setSource(wms_source); + wms_h21v04.setVisible(true); + + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDSI:'+day+'NDSI_h21v05'} + }); + wms_h21v05.setSource(wms_source); + wms_h21v05.setVisible(true); + + // + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDSI:'+day+'NDSI_h22v03'} + }); + wms_h22v03.setSource(wms_source); + wms_h22v03.setVisible(true); + + //Aral Sea + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDSI:'+day+'NDSI_h22v04'} + }); + wms_h22v04.setSource(wms_source); + wms_h22v04.setVisible(true); + + //Turmenistan + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDSI:'+day+'NDSI_h22v05'} + }); + wms_h22v05.setSource(wms_source); + wms_h22v05.setVisible(true); + + //Sever + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDSI:'+day+'NDSI_h23v03'} + }); + wms_h23v03.setSource(wms_source); + wms_h23v03.setVisible(true); + + //Kiegizstan + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDSI:'+day+'NDSI_h23v04'} + }); + wms_h23v04.setSource(wms_source); + wms_h23v04.setVisible(true); + + //Afganistan + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'NDSI:'+day+'NDSI_h23v05'} + }); + wms_h23v05.setSource(wms_source); + wms_h23v05.setVisible(true); + + + //Show legend + if(typeof g_WinLegend == "undefined" || g_WinLegend == null || g_WinLegend.closed) + { + g_WinLegend=new TWin(); + g_WinLegend.BuildGUI(window.innerWidth-290,40); + } + g_WinLegend.setCaption(trt('Legend')); + g_WinLegend.setSize("90px","140px"); + g_WinLegend.setContent(''); + g_WinLegend.hide(false); + g_WinLegend.setLeftTop(window.innerWidth-g_WinLegend.getWidth()-30,40); + setTimeout(function() { g_WinLegend.setLeftTop(window.innerWidth-g_WinLegend.getWidth()-30,40); }, 1000); + + g_boundaryTile.setVisible(true); +} + +//Call WMS SMAP data from GeoServer +function callSMAPData() +{ + let day = document.getElementById("filter_smap_day").value; + if(day%10!==0){ + day=""; + }else{ + day=day.padStart(3, "0")+"_"; + } + + let layers = ""; + + //Stavropol + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms', + params: {'LAYERS': 'SMAP:'+day+'SMAP'} + }); + wms_h20v03.setSource(wms_source); + wms_h20v03.setVisible(true); + + + //Show legend + if(typeof g_WinLegend == "undefined" || g_WinLegend == null || g_WinLegend.closed) + { + g_WinLegend=new TWin(); + g_WinLegend.BuildGUI(window.innerWidth-290,40); + } + g_WinLegend.setCaption(trt('Legend')); + g_WinLegend.setSize("90px","150px"); + g_WinLegend.setContent(''); + g_WinLegend.hide(false); + g_WinLegend.setLeftTop(window.innerWidth-g_WinLegend.getWidth()-30,40); + setTimeout(function() { g_WinLegend.setLeftTop(window.innerWidth-g_WinLegend.getWidth()-30,40); }, 1000); + + g_boundaryTile.setVisible(true); +} + +function hideGeoTIFFData() +{ + wms_h20v03.setVisible(false); //Stavropol + wms_h20v04.setVisible(false); //Krim + wms_h21v03.setVisible(false); //Stavropol + wms_h21v04.setVisible(false); //Caspi sea + wms_h21v05.setVisible(false); + wms_h22v03.setVisible(false); // + wms_h22v04.setVisible(false); //Aral Sea + wms_h22v05.setVisible(false); //Turmenistan + wms_h23v03.setVisible(false); //Sever + wms_h23v04.setVisible(false); //Kiegizstan + wms_h23v05.setVisible(false); //Afganistan + + //Hide legend + if(typeof g_WinLegend != "undefined" && g_WinLegend!=null) g_WinLegend.hide(true); + + g_boundaryTile.setVisible(false); +} + +function callWeatherData() +{ + let country_id=document.getElementById('filter_soil_country_id').value; + let time = document.getElementById('filter_soil_day').value; + time=Math.floor(new Date(time).getTime() / 1000); + + let layers=""; + if(country_id==1) + { + layers = 'cite:soil_temperature_afghanistan'; + }else if(country_id==2) + { + layers = 'cite:soil_temperature_armenia'; + }else if(country_id==3) + { + layers = 'cite:soil_temperature_azerbaijan'; + }else if(country_id==4) + { + layers = 'cite:soil_temperature_georgia'; + }else if(country_id==5) + { + layers = 'cite:soil_temperature_kazakhstan'; + }else if(country_id==6) + { + layers = 'cite:soil_temperature_kyrgyzstan'; + }else if(country_id==7) + { + layers = 'cite:soil_temperature_russia'; + }else if(country_id==8) + { + layers = 'cite:soil_temperature_tajikistan'; + }else if(country_id==9) + { + layers = 'cite:soil_temperature_turkmenistan'; + }else if(country_id==10) + { + layers = 'cite:soil_temperature_uzbekistan'; + }else + { + alert2(trt("Alert"),trt("No_data")); + } + + log.info("layers = "+layers+' p1='+time); + + let wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms?viewparams=p1:'+time, + params: {'LAYERS': layers} + }); + + wms_layer.setSource(wms_source); + wms_layer.setVisible(true); + + //Show legend + if(typeof g_WeaLegend == "undefined" || g_WeaLegend==null || g_WeaLegend.closed) + { + g_WeaLegend=new TWin(); + g_WeaLegend.BuildGUI(window.innerWidth-120,40); + } + g_WeaLegend.setCaption(trt('Legend')); + g_WeaLegend.setSize("92px","313px"); + g_WeaLegend.setContent(''); + g_WeaLegend.hide(false); + g_WeaLegend.setLeftTop(window.innerWidth-g_WeaLegend.getWidth()-20,40); + setTimeout(function() { g_WeaLegend.setLeftTop(window.innerWidth-g_WeaLegend.getWidth()-20,40); }, 1000); +} + +function hideWeatherData() +{ + wms_layer.setVisible(false); + if(typeof g_WeaLegend != "undefined" && g_WeaLegend!=null) + { + g_WeaLegend.hide(true); + } +} + +function callAirData() +{ + let country_id=document.getElementById('filter_air_country_id').value; + let time = document.getElementById('filter_air_day').value; + time=Math.floor(new Date(time).getTime() / 1000); + + let layers=""; + if(country_id==1){ + layers = 'cite:air_temperature_afghanistan'; + }else if(country_id==2){ + layers = 'cite:air_temperature_armenia'; + }else if(country_id==3){ + layers = 'cite:air_temperature_azerbaijan'; + }else if(country_id==4){ + layers = 'cite:air_temperature_georgia'; + }else if(country_id==5){ + layers = 'cite:air_temperature_kazakhstan'; + }else if(country_id==6){ + layers = 'cite:air_temperature_kyrgyzstan'; + }else if(country_id==7){ + layers = 'cite:air_temperature_russia'; + }else if(country_id==8){ + layers = 'cite:air_temperature_tajikistan'; + }else if(country_id==9){ + layers = 'cite:air_temperature_turkmenistan'; + }else if(country_id==10){ + layers = 'cite:air_temperature_uzbekistan'; + }else{ + alert2(trt("Alert"),trt("No_data")); + } + + log.info("layers = "+layers+' p1='+time); + + let wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms?viewparams=p1:'+time, + params: {'LAYERS': layers} + }); + + wms_layer.setSource(wms_source); + wms_layer.setVisible(true); + + //Show legend + if(typeof g_AirLegend == "undefined" || g_AirLegend==null || g_AirLegend.closed) + { + g_AirLegend=new TWin(); + g_AirLegend.BuildGUI(window.innerWidth-120,40); + } + g_AirLegend.setCaption(trt('Legend')); + g_AirLegend.setSize("77px","223px"); + g_AirLegend.setContent(''); + g_AirLegend.hide(false); + g_AirLegend.setLeftTop(window.innerWidth-g_AirLegend.getWidth()-20,40); + setTimeout(function() { g_AirLegend.setLeftTop(window.innerWidth-g_AirLegend.getWidth()-20,40); }, 1000); +} + +function hideAirData() +{ + wms_layer.setVisible(false); + if(typeof g_AirLegend != "undefined" && g_AirLegend!=null) + { + g_AirLegend.hide(true); + } +} + +function callPrecipitationData() +{ + let country_id=document.getElementById('filter_precipitation_country_id').value; + let time = document.getElementById('filter_precipitation_day').value; + time=Math.floor(new Date(time).getTime() / 1000); + + let layers=""; + if(country_id==1){ + layers = 'cite:precipitation_afghanistan'; + }else if(country_id==2){ + layers = 'cite:precipitation_armenia'; + }else if(country_id==3){ + layers = 'cite:precipitation_azerbaijan'; + }else if(country_id==4){ + layers = 'cite:precipitation_georgia'; + }else if(country_id==5){ + layers = 'cite:precipitation_kazakhstan'; + }else if(country_id==6){ + layers = 'cite:precipitation_kyrgyzstan'; + }else if(country_id==7){ + layers = 'cite:precipitation_russia'; + }else if(country_id==8){ + layers = 'cite:precipitation_tajikistan'; + }else if(country_id==9){ + layers = 'cite:precipitation_turkmenistan'; + }else if(country_id==10){ + layers = 'cite:precipitation_uzbekistan'; + }else{ + alert2(trt("Alert"),trt("No_data")); + } + + log.info("layers = "+layers+' p1='+time); + + let wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms?viewparams=p1:'+time, + params: {'LAYERS': layers} + }); + + wms_layer.setSource(wms_source); + wms_layer.setVisible(true); + + //Show legend + if(typeof g_PreLegend == "undefined" || g_PreLegend==null || g_PreLegend.closed) + { + g_PreLegend=new TWin(); + g_PreLegend.BuildGUI(window.innerWidth-120,40); + } + g_PreLegend.setCaption(trt('Legend')); + g_PreLegend.setSize("77px","223px"); + g_PreLegend.setContent(''); + g_PreLegend.hide(false); + g_PreLegend.setLeftTop(window.innerWidth-g_PreLegend.getWidth()-20,40); + setTimeout(function() { g_PreLegend.setLeftTop(window.innerWidth-g_PreLegend.getWidth()-20,40); }, 1000); +} + +function hidePrecipitationData() +{ + wms_layer.setVisible(false); + if(typeof g_PreLegend != "undefined" && g_PreLegend!=null) + { + g_PreLegend.hide(true); + } +} + +function callHTCSelyaninovData() +{ + + let country_id=document.getElementById('filter_htc_selyaninov_country_id').value; + let time_start = document.getElementById('filter_htc_selyaninov_time_start').value; + time_start=Math.floor(new Date(time_start).getTime() / 1000); + let time_end = document.getElementById('filter_htc_selyaninov_time_end').value; + time_end=Math.floor(new Date(time_end).getTime() / 1000); + + let wms_source=null; + + let layers=""; + if(country_id==1){ + layers = 'cite:htc_selyaninov_afghanistan'; + }else if(country_id==2){ + layers = 'cite:htc_selyaninov_armenia'; + }else if(country_id==3){ + layers = 'cite:htc_selyaninov_azerbaijan'; + }else if(country_id==4){ + layers = 'cite:htc_selyaninov_georgia'; + }else if(country_id==5){ + layers = 'cite:htc_selyaninov_kazakhstan'; + }else if(country_id==6){ + layers = 'cite:htc_selyaninov_kyrgyzstan'; + }else if(country_id==7){ + layers = 'cite:htc_selyaninov_russia'; + }else if(country_id==8){ + layers = 'cite:htc_selyaninov_tajikistan'; + }else if(country_id==9){ + layers = 'cite:htc_selyaninov_turkmenistan'; + }else if(country_id==10){ + layers = 'cite:htc_selyaninov_uzbekistan'; + }else{ + alert2(trt("Alert"),trt("No_data")); + } + + log.info("layers = "+layers+" time_start = "+time_start+" time_end = "+time_end); + + wms_source = new ol.source.TileWMS({ + url: 'https://geoserver2.ccalm.org/wms?viewparams=time_start:'+time_start+';time_end='+time_end+';', + params: {'LAYERS': layers} + }); + + wms_layer.setSource(wms_source); + wms_layer.setVisible(true); + + //Show legend + if(typeof g_HTCLegend == "undefined" || g_HTCLegend==null || g_HTCLegend.closed) + { + g_HTCLegend=new TWin(); + g_HTCLegend.BuildGUI(window.innerWidth-120,40); + } + g_HTCLegend.setCaption(trt('Legend')); + g_HTCLegend.setSize("77px","223px"); + g_HTCLegend.setContent(''); + g_HTCLegend.hide(false); + g_HTCLegend.setLeftTop(window.innerWidth-g_HTCLegend.getWidth()-20,40); + setTimeout(function() { g_HTCLegend.setLeftTop(window.innerWidth-g_HTCLegend.getWidth()-20,40); }, 1000); +} + +function hideHTCSelyaninovData() +{ + wms_layer.setVisible(false); + if(typeof g_HTCLegend != "undefined" && g_HTCLegend!=null) + { + g_HTCLegend.hide(true); + } +} + +function updatePOILocust(data,indicator) +{ + let lat, lon, geom, feature, features = [], featuresV = []; + let terrain=""; + let locust_populated=0; + + let eggs_capsules_density=0; + let eggs_capsules_density_to=0; + let imago_density=0; + let larva_density=0; + let larva_density_to=0; + let kuliguli_size=0; + let swarm_maturity=""; + let swarm_density_id=""; + + for(let i=0;itreated_area) //red icon + { + feature = new ol.Feature({geometry: new ol.geom.Point(ol.proj.transform([lon, lat], 'EPSG:4326','EPSG:3857')),name: terrain}); + feature.userType="FrmLocustDel"; + feature.userName=terrain; + feature.userID=data[i].id; + + feature.setStyle(createFatypeStyleDel(feature,true)); + features.push(feature); + }else //Green icon + { + feature = new ol.Feature({geometry: new ol.geom.Point(ol.proj.transform([lon, lat], 'EPSG:4326','EPSG:3857')),name: terrain}); + feature.userType="FrmLocustDel"; + feature.userName=terrain; + feature.userID=data[i].id; + + feature.setStyle(createFatypeStyleDel(feature,false)); + features.push(feature); + } + } + } + + vectorSourceDel.clear(false); + vectorSourceDel.addFeatures(features); + + vectorSourceDelV.clear(false); + vectorSourceDelV.addFeatures(featuresV); + return features; +} + +//Product N 2 and 3 +function updateRegionPolygons(obj) +{ + vectorSourceArea.clear(false); + + let id=""; + let percent=""; + let region_id=""; + let name=""; + let year=""; + let locust_type_id=""; + + for(let j=0;j15) + { + $.getJSON('../geojson?table=countriesregions&id='+id,{},function(userData){return function(data){makeRedArea(data,userData);};}({region_id:region_id,name:name,percent:percent,year:year,locust_type_id:locust_type_id,type:obj.n})); + }else if(percent<-15) + { + $.getJSON('../geojson?table=countriesregions&id='+id,{},function(userData){return function(data){makeGreenArea(data,userData);};}({region_id:region_id,name:name,percent:percent,year:year,locust_type_id:locust_type_id,type:obj.n})); + }else + { + $.getJSON('../geojson?table=countriesregions&id='+id,{},function(userData){return function(data){makeYellowArea(data,userData);};}({region_id:region_id,name:name,percent:percent,year:year,locust_type_id:locust_type_id,type:obj.n})); + } + }else //If there is no data + { + $.getJSON('../geojson?table=countriesregions&id='+id,{},function(userData){return function(data){makeGrayArea(data,userData);};}({region_id:region_id,name:name,percent:''/*percent*/,year:year,locust_type_id:locust_type_id,type:obj.n})); + } + } + return; +} + +function updateRegionPolygons_r(obj) +{ + vectorSourceArea.clear(false); + + let id=""; + let percent=""; + let district_id=""; + let name=""; + let year=""; + let locust_type_id=""; + + for(let j=0;j15) + { + $.getJSON('../geojson?table=countriesdistricts&id='+id,{},function(userData){return function(data){makeRedArea(data,userData);};}({district_id:district_id,name:name,percent:percent,year:year,locust_type_id:locust_type_id,type:obj.n})); + }else if(percent<-15) + { + $.getJSON('../geojson?table=countriesdistricts&id='+id,{},function(userData){return function(data){makeGreenArea(data,userData);};}({district_id:district_id,name:name,percent:percent,year:year,locust_type_id:locust_type_id,type:obj.n})); + }else + { + $.getJSON('../geojson?table=countriesdistricts&id='+id,{},function(userData){return function(data){makeYellowArea(data,userData);};}({district_id:district_id,name:name,percent:percent,year:year,locust_type_id:locust_type_id,type:obj.n})); + } + }else //If there is no data + { + $.getJSON('../geojson?table=countriesdistricts&id='+id,{},function(userData){return function(data){makeGrayArea(data,userData);};}({district_id:district_id,name:name,percent:'',year:year,locust_type_id:locust_type_id,type:obj.n})); + } + } + + return; +} + +// Product N 4 +function updateRegionPolygons4(obj) +{ + vectorSourceArea.clear(false); + let id=""; + let percent=""; + let region_id=""; + let name=""; + let year=""; + let locust_type_id=""; + let treated=""; + let infested_etd=""; + for(let j=0;j=-25 && percent<=25) + { + $.getJSON('../geojson?table=countriesregions&id='+id,{},function(userData){return function(data){makeGreenArea(data,userData);};}({region_id:region_id,name:name,percent:percent,text:""+trt("Treatedtrt_(thous._ha)")+": "+treated+"
\n"+trt("Infested_(thous._ha)")+": "+infested_etd+"
\n"+trt("Percent")+": "+percent+"%",year:year,locust_type_id:locust_type_id,type:obj.n})); + }else + { + $.getJSON('../geojson?table=countriesregions&id='+id,{},function(userData){return function(data){makeRedArea(data,userData);};}({region_id:region_id,name:name,percent:percent,text:""+trt("Treated_(thous._ha)")+": "+treated+"
\n"+trt("Infested_(thous._ha)")+": "+infested_etd+"
\n"+trt("Percent")+": "+percent+"%",year:year,locust_type_id:locust_type_id,type:obj.n})); + } + }else //If there is no data + { + $.getJSON('../geojson?table=countriesregions&id='+id,{},function(userData){return function(data){makeGrayArea(data,userData);};}({region_id:region_id,name:name,percent:'',text:'',year:year,locust_type_id:locust_type_id,type:obj.n})); + } + } + return; +} + +function updateRegionPolygons4_r(obj) +{ + vectorSourceArea.clear(false); + let id=""; + let percent=""; + let district_id=""; + let name=""; + let year=""; + let locust_type_id=""; + let treated=""; + let infested_etd=""; + for(let j=0;j=-25 && percent<=25) + { + $.getJSON('../geojson?table=countriesdistricts&id='+id,{},function(userData){return function(data){makeGreenArea(data,userData);};}({district_id:district_id,name:name,percent:percent,text:""+trt("Treated_(thous._ha)")+": "+treated+"
\n"+trt("Infested_(thous._ha)")+""+": "+infested_etd+"
\n"+trt("Percent")+": "+percent+"%",year:year,locust_type_id:locust_type_id,type:obj.n})); + }else + { + $.getJSON('../geojson?table=countriesdistricts&id='+id,{},function(userData){return function(data){makeRedArea(data,userData);};}({district_id:district_id,name:name,percent:percent,text:""+trt("Treated_(thous._ha)")+""+": "+treated+"
\n"+trt("Infested_(thous._ha)")+""+": "+infested_etd+"
\n"+trt("Percent")+": "+percent+"%",year:year,locust_type_id:locust_type_id,type:obj.n})); + } + }else //If there is no data + { + $.getJSON('../geojson?table=countriesdistricts&id='+id,{},function(userData){return function(data){makeGrayArea(data,userData);};}({district_id:district_id,name:name,percent:'',year:year,locust_type_id:locust_type_id,type:obj.n})); + } + } + return; +} + +function applyReq(req,fn,node) +{ + if(node.errorCode>0) { + let fullText = node.errorMessage; + let smallText = ''; + let pos1=fullText.indexOf('[['); + let pos2=fullText.indexOf(']]'); + if(pos1>=0 && pos2>=0 && pos1=0){ //Если есть идентификатор того что это перезапись + let okFunc=()=>{ + this.setValue('seq',0); + this.sendData(); //Применить ещё раз + }; + if (smallText != '') + confirm2(trt('Warning'),smallText, fullText, okFunc, null); + else + confirm2(trt('Warning'),smallText, '', okFunc, null); + }else { + if (smallText != '') + alert2(trt('Alert'), smallText, fullText); + else + alert2(trt('Alert'), fullText); + } + return; + } + + if (fn==0) + { + //alert('fn==0'); + if(req.userData=="FrmLocustDataPopupInterface") + { + m_winPP.hideProgressBar(); + updateFrmLocustDataPopupInterface(node,req.userDataID); + } + if(req.userData=="FrmLocustDelDataPopupInterface") + { + m_winPP.hideProgressBar(); + updateFrmLocustDelDataPopupInterface(node,req.userDataID); + } + + }else if (fn==1) + { + alert("Your message has been sent!"); + deleteHTML(this.wdiv); + qMnu.expand(false); + }else if (fn==11) + { + alert('fn==11'); + }else if (fn==3) + { + alert('fn==3'); + }else if (fn==4) + { + /*if(req.userData=="FrmLocustData") //For create markers + { + hideProgressBar("FrmLocustData"); + updatePOILocust(node,req.userIndicator); + }else *//*if(req.userData=="FrmLocustDelData") //For create markers + { + hideProgressBar("FrmLocustDelData"); + updatePOILocustDel(node); + }else */if(req.userData=="FrmLocustDataPopup") + { + m_winPP.hideProgressBar(); + updatePopupLocust(node); + }else if(req.userData=="FrmLocustDelDataPopup") + { + m_winPP.hideProgressBar(); + updatePopupLocustDel(node); + }else if(req.userData=="FrmLocustInfoData") + { + hideProgressBar("FrmLocustInfoData"); + updateRegionPolygons(node); + }else if(req.userData=="FrmLocustInfoData_r") + { + hideProgressBar("FrmLocustInfoData"); + updateRegionPolygons_r(node); + }else if(req.userData=="FrmLocustInfoData4") + { + hideProgressBar("FrmLocustInfoData"); + updateRegionPolygons4(node); + }else if(req.userData=="FrmLocustInfoData4_r") + { + hideProgressBar("FrmLocustInfoData"); + updateRegionPolygons4_r(node); + } + }else if (fn==6) + { + alert('fn==6'); + }else if (fn==8) + { + alert('fn==8'); + }else + alert("Unknown function! fn=\""+fn+"\"" ); +} \ No newline at end of file diff --git a/src/main/webapp/resources/engine/jsfiddle.html b/src/main/webapp/resources/engine/jsfiddle.html new file mode 100644 index 0000000..1eaec8b --- /dev/null +++ b/src/main/webapp/resources/engine/jsfiddle.html @@ -0,0 +1,76 @@ + + + + Split.js + + + + + + +
+
+ 1 +
+
+ 2 +
+
+ + + + + + diff --git a/src/main/webapp/resources/engine/log.png b/src/main/webapp/resources/engine/log.png new file mode 100644 index 0000000..34644ee Binary files /dev/null and b/src/main/webapp/resources/engine/log.png differ diff --git a/src/main/webapp/resources/engine/metadata.xsl b/src/main/webapp/resources/engine/metadata.xsl new file mode 100644 index 0000000..61267bb --- /dev/null +++ b/src/main/webapp/resources/engine/metadata.xsl @@ -0,0 +1,73 @@ + + + + + + + + + <xsl:value-of select="@name"/> + + + + + + + + + + + + + + + + + +
ОписаниеНазваниеID объекта
+ +
+ + + + + + + + + + + + + + +
ОписаниеНазваниеID объекта
+ + +
+ + +
Поля= + +
Поле=
+
+ +
+ + +
Колонки= + +
Колонка=
+
+ +
+ + + +
+ + + + +
+
\ No newline at end of file diff --git a/src/main/webapp/resources/engine/mgrs/.npmignore b/src/main/webapp/resources/engine/mgrs/.npmignore new file mode 100644 index 0000000..8226f2b --- /dev/null +++ b/src/main/webapp/resources/engine/mgrs/.npmignore @@ -0,0 +1,4 @@ +*~ +node_modules +.DS_STORE +coverage diff --git a/src/main/webapp/resources/engine/mgrs/PUBLISHING.md b/src/main/webapp/resources/engine/mgrs/PUBLISHING.md new file mode 100644 index 0000000..2a74804 --- /dev/null +++ b/src/main/webapp/resources/engine/mgrs/PUBLISHING.md @@ -0,0 +1,17 @@ +Publishing +=== + +Use `tin` to update the version number in `package.json`. + + tin -v x.y.z + +Then run the publish script + + ./publish.sh + +afterwards don't forget to update the versions to be a prerelease of the next version, so if you just published 1.1.1 then: + + tin -v 1.1.2-alpha + git add package.json + git commit -m 'update version to 1.1.2-alpha' + git push origin master diff --git a/src/main/webapp/resources/engine/mgrs/dist/mgrs.js b/src/main/webapp/resources/engine/mgrs/dist/mgrs.js new file mode 100644 index 0000000..a272923 --- /dev/null +++ b/src/main/webapp/resources/engine/mgrs/dist/mgrs.js @@ -0,0 +1,758 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.mgrs = global.mgrs || {}))); +}(this, (function (exports) { 'use strict'; + +/** + * UTM zones are grouped, and assigned to one of a group of 6 + * sets. + * + * {int} @private + */ +var NUM_100K_SETS = 6; + +/** + * The column letters (for easting) of the lower left value, per + * set. + * + * {string} @private + */ +var SET_ORIGIN_COLUMN_LETTERS = 'AJSAJS'; + +/** + * The row letters (for northing) of the lower left value, per + * set. + * + * {string} @private + */ +var SET_ORIGIN_ROW_LETTERS = 'AFAFAF'; + +var A = 65; // A +var I = 73; // I +var O = 79; // O +var V = 86; // V +var Z = 90; // Z +var mgrs = { + forward: forward, + inverse: inverse, + toPoint: toPoint +}; +/** + * Conversion of lat/lon to MGRS. + * + * @param {object} ll Object literal with lat and lon properties on a + * WGS84 ellipsoid. + * @param {int} accuracy Accuracy in digits (5 for 1 m, 4 for 10 m, 3 for + * 100 m, 2 for 1000 m or 1 for 10000 m). Optional, default is 5. + * @return {string} the MGRS string for the given location and accuracy. + */ +function forward(ll, accuracy) { + accuracy = accuracy || 5; // default accuracy 1m + return encode(LLtoUTM({ + lat: ll[1], + lon: ll[0] + }), accuracy); +} + +/** + * Conversion of MGRS to lat/lon. + * + * @param {string} mgrs MGRS string. + * @return {array} An array with left (longitude), bottom (latitude), right + * (longitude) and top (latitude) values in WGS84, representing the + * bounding box for the provided MGRS reference. + */ +function inverse(mgrs) { + var bbox = UTMtoLL(decode(mgrs.toUpperCase())); + if (bbox.lat && bbox.lon) { + return [bbox.lon, bbox.lat, bbox.lon, bbox.lat]; + } + return [bbox.left, bbox.bottom, bbox.right, bbox.top]; +} + +function toPoint(mgrs) { + var bbox = UTMtoLL(decode(mgrs.toUpperCase())); + if (bbox.lat && bbox.lon) { + return [bbox.lon, bbox.lat]; + } + return [(bbox.left + bbox.right) / 2, (bbox.top + bbox.bottom) / 2]; +} +/** + * Conversion from degrees to radians. + * + * @private + * @param {number} deg the angle in degrees. + * @return {number} the angle in radians. + */ +function degToRad(deg) { + return (deg * (Math.PI / 180.0)); +} + +/** + * Conversion from radians to degrees. + * + * @private + * @param {number} rad the angle in radians. + * @return {number} the angle in degrees. + */ +function radToDeg(rad) { + return (180.0 * (rad / Math.PI)); +} + +/** + * Converts a set of Longitude and Latitude co-ordinates to UTM + * using the WGS84 ellipsoid. + * + * @private + * @param {object} ll Object literal with lat and lon properties + * representing the WGS84 coordinate to be converted. + * @return {object} Object literal containing the UTM value with easting, + * northing, zoneNumber and zoneLetter properties, and an optional + * accuracy property in digits. Returns null if the conversion failed. + */ +function LLtoUTM(ll) { + var Lat = ll.lat; + var Long = ll.lon; + var a = 6378137.0; //ellip.radius; + var eccSquared = 0.00669438; //ellip.eccsq; + 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; + // (int) + ZoneNumber = Math.floor((Long + 180) / 6) + 1; + + //Make sure the longitude 180.00 is in Zone 60 + if (Long === 180) { + ZoneNumber = 60; + } + + // Special zone for Norway + if (Lat >= 56.0 && Lat < 64.0 && Long >= 3.0 && Long < 12.0) { + ZoneNumber = 32; + } + + // Special zones for Svalbard + if (Lat >= 72.0 && Lat < 84.0) { + if (Long >= 0.0 && Long < 9.0) { + ZoneNumber = 31; + } + else if (Long >= 9.0 && Long < 21.0) { + ZoneNumber = 33; + } + else if (Long >= 21.0 && Long < 33.0) { + ZoneNumber = 35; + } + else if (Long >= 33.0 && Long < 42.0) { + ZoneNumber = 37; + } + } + + LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3; //+3 puts origin + // in middle of + // zone + 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.0 + (5 - 18 * T + T * T + 72 * C - 58 * eccPrimeSquared) * A * A * A * A * A / 120.0) + 500000.0); + + var UTMNorthing = (k0 * (M + N * Math.tan(LatRad) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24.0 + (61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) * A * A * A * A * A * A / 720.0))); + if (Lat < 0.0) { + UTMNorthing += 10000000.0; //10000000 meter offset for + // southern hemisphere + } + + return { + northing: Math.round(UTMNorthing), + easting: Math.round(UTMEasting), + zoneNumber: ZoneNumber, + zoneLetter: getLetterDesignator(Lat) + }; +} + +/** + * Converts UTM coords to lat/long, using the WGS84 ellipsoid. This is a convenience + * class where the Zone can be specified as a single string eg."60N" which + * is then broken down into the ZoneNumber and ZoneLetter. + * + * @private + * @param {object} utm An object literal with northing, easting, zoneNumber + * and zoneLetter properties. If an optional accuracy property is + * provided (in meters), a bounding box will be returned instead of + * latitude and longitude. + * @return {object} An object literal containing either lat and lon values + * (if no accuracy was provided), or top, right, bottom and left values + * for the bounding box calculated according to the provided accuracy. + * Returns null if the conversion failed. + */ +function UTMtoLL(utm) { + + var UTMNorthing = utm.northing; + var UTMEasting = utm.easting; + var zoneLetter = utm.zoneLetter; + var zoneNumber = utm.zoneNumber; + // check the ZoneNummber is valid + if (zoneNumber < 0 || zoneNumber > 60) { + return null; + } + + var k0 = 0.9996; + var a = 6378137.0; //ellip.radius; + var eccSquared = 0.00669438; //ellip.eccsq; + 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; + + // remove 500,000 meter offset for longitude + var x = UTMEasting - 500000.0; + var y = UTMNorthing; + + // We must know somehow if we are in the Northern or Southern + // hemisphere, this is the only time we use the letter So even + // if the Zone letter isn't exactly correct it should indicate + // the hemisphere correctly + if (zoneLetter < 'N') { + y -= 10000000.0; // remove 10,000,000 meter offset used + // for southern hemisphere + } + + // There are 60 zones with zone 1 being at West -180 to -174 + LongOrigin = (zoneNumber - 1) * 6 - 180 + 3; // +3 puts origin + // in middle of + // zone + + 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); + // double phi1 = ProjMath.radToDeg(phi1Rad); + + 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; +} + +/** + * Calculates the MGRS letter designator for the given latitude. + * + * @private + * @param {number} lat The latitude in WGS84 to get the letter designator + * for. + * @return {char} The letter designator. + */ +function getLetterDesignator(lat) { + //This is here as an error flag to show that the Latitude is + //outside MGRS limits + 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; +} + +/** + * Encodes a UTM location as MGRS string. + * + * @private + * @param {object} utm An object literal with easting, northing, + * zoneLetter, zoneNumber + * @param {number} accuracy Accuracy in digits (1-5). + * @return {string} MGRS string for the given UTM location. + */ +function encode(utm, accuracy) { + // prepend with leading zeroes + var seasting = "00000" + utm.easting, + snorthing = "00000" + 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); +} + +/** + * Get the two letter 100k designator for a given UTM easting, + * northing and zone number value. + * + * @private + * @param {number} easting + * @param {number} northing + * @param {number} zoneNumber + * @return the two letter 100k designator for the given UTM location. + */ +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); +} + +/** + * Given a UTM zone number, figure out the MGRS 100K set it is in. + * + * @private + * @param {number} i An UTM zone number. + * @return {number} the 100k set the UTM zone is in. + */ +function get100kSetForZone(i) { + var setParm = i % NUM_100K_SETS; + if (setParm === 0) { + setParm = NUM_100K_SETS; + } + + return setParm; +} + +/** + * Get the two-letter MGRS 100k designator given information + * translated from the UTM northing, easting and zone number. + * + * @private + * @param {number} column the column index as it relates to the MGRS + * 100k set spreadsheet, created from the UTM easting. + * Values are 1-8. + * @param {number} row the row index as it relates to the MGRS 100k set + * spreadsheet, created from the UTM northing value. Values + * are from 0-19. + * @param {number} parm the set block, as it relates to the MGRS 100k set + * spreadsheet, created from the UTM zone. Values are from + * 1-60. + * @return two letter MGRS 100k code. + */ +function getLetter100kID(column, row, parm) { + // colOrigin and rowOrigin are the letters at the origin of the set + var index = parm - 1; + var colOrigin = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(index); + var rowOrigin = SET_ORIGIN_ROW_LETTERS.charCodeAt(index); + + // colInt and rowInt are the letters to build to return + 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; +} + +/** + * Decode the UTM parameters from a MGRS string. + * + * @private + * @param {string} mgrsString an UPPERCASE coordinate string is expected. + * @return {object} An object literal with easting, northing, zoneLetter, + * zoneNumber and accuracy (in meters) properties. + */ +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; + + // get Zone number + 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) { + // A good MGRS string has to be 4-5 digits long, + // ##AAA/#AAA at least. + throw ("MGRSPoint bad conversion from: " + mgrsString); + } + + var zoneLetter = mgrsString.charAt(i++); + + // Should we check the zone letter here? Why not. + 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); + + // We have a bug where the northing may be 2000000 too low. + // How + // do we know when to roll over? + + while (north100k < getMinNorthing(zoneLetter)) { + north100k += 2000000; + } + + // calculate the char index for easting/northing separator + 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.0; + var sepNorthing = 0.0; + var accuracyBonus, sepEastingString, sepNorthingString, easting, northing; + if (sep > 0) { + accuracyBonus = 100000.0 / 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 + }; +} + +/** + * Given the first letter from a two-letter MGRS 100k zone, and given the + * MGRS table set for the zone number, figure out the easting value that + * should be added to the other, secondary easting value. + * + * @private + * @param {char} e The first letter from a two-letter MGRS 100´k zone. + * @param {number} set The MGRS table set for the zone number. + * @return {number} The easting value for the given letter and set. + */ +function getEastingFromChar(e, set) { + // colOrigin is the letter at the origin of the set for the + // column + var curCol = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(set - 1); + var eastingValue = 100000.0; + 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.0; + } + + return eastingValue; +} + +/** + * Given the second letter from a two-letter MGRS 100k zone, and given the + * MGRS table set for the zone number, figure out the northing value that + * should be added to the other, secondary northing value. You have to + * remember that Northings are determined from the equator, and the vertical + * cycle of letters mean a 2000000 additional northing meters. This happens + * approx. every 18 degrees of latitude. This method does *NOT* count any + * additional northings. You have to figure out how many 2000000 meters need + * to be added for the zone letter of the MGRS coordinate. + * + * @private + * @param {char} n Second letter of the MGRS 100k zone + * @param {number} set The MGRS table set number, which is dependent on the + * UTM zone number. + * @return {number} The northing value for the given letter and set. + */ +function getNorthingFromChar(n, set) { + + if (n > 'V') { + throw ("MGRSPoint given invalid Northing " + n); + } + + // rowOrigin is the letter at the origin of the set for the + // column + var curRow = SET_ORIGIN_ROW_LETTERS.charCodeAt(set - 1); + var northingValue = 0.0; + var rewindMarker = false; + + while (curRow !== n.charCodeAt(0)) { + curRow++; + if (curRow === I) { + curRow++; + } + if (curRow === O) { + curRow++; + } + // fixing a bug making whole application hang in this loop + // when 'n' is a wrong character + if (curRow > V) { + if (rewindMarker) { // making sure that this loop ends + throw ("Bad character: " + n); + } + curRow = A; + rewindMarker = true; + } + northingValue += 100000.0; + } + + return northingValue; +} + +/** + * The function getMinNorthing returns the minimum northing value of a MGRS + * zone. + * + * Ported from Geotrans' c Lattitude_Band_Value structure table. + * + * @private + * @param {char} zoneLetter The MGRS zone to get the min northing for. + * @return {number} + */ +function getMinNorthing(zoneLetter) { + var northing; + switch (zoneLetter) { + case 'C': + northing = 1100000.0; + break; + case 'D': + northing = 2000000.0; + break; + case 'E': + northing = 2800000.0; + break; + case 'F': + northing = 3700000.0; + break; + case 'G': + northing = 4600000.0; + break; + case 'H': + northing = 5500000.0; + break; + case 'J': + northing = 6400000.0; + break; + case 'K': + northing = 7300000.0; + break; + case 'L': + northing = 8200000.0; + break; + case 'M': + northing = 9100000.0; + break; + case 'N': + northing = 0.0; + break; + case 'P': + northing = 800000.0; + break; + case 'Q': + northing = 1700000.0; + break; + case 'R': + northing = 2600000.0; + break; + case 'S': + northing = 3500000.0; + break; + case 'T': + northing = 4400000.0; + break; + case 'U': + northing = 5300000.0; + break; + case 'V': + northing = 6200000.0; + break; + case 'W': + northing = 7000000.0; + break; + case 'X': + northing = 7900000.0; + break; + default: + northing = -1.0; + } + if (northing >= 0.0) { + return northing; + } + else { + throw ("Invalid zone letter: " + zoneLetter); + } + +} + +exports['default'] = mgrs; +exports.forward = forward; +exports.inverse = inverse; +exports.toPoint = toPoint; + +Object.defineProperty(exports, '__esModule', { value: true }); + +}))); diff --git a/src/main/webapp/resources/engine/mgrs/license.md b/src/main/webapp/resources/engine/mgrs/license.md new file mode 100644 index 0000000..f999ce2 --- /dev/null +++ b/src/main/webapp/resources/engine/mgrs/license.md @@ -0,0 +1,19 @@ +Copyright (c) 2012, Mike Adair, Richard Greenwood, Didier Richard, Stephen Irons, Olivier Terral, 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._ \ No newline at end of file diff --git a/src/main/webapp/resources/engine/mgrs/mgrs.js b/src/main/webapp/resources/engine/mgrs/mgrs.js new file mode 100644 index 0000000..bb08a56 --- /dev/null +++ b/src/main/webapp/resources/engine/mgrs/mgrs.js @@ -0,0 +1,746 @@ + + + +/** + * UTM zones are grouped, and assigned to one of a group of 6 + * sets. + * + * {int} @private + */ +var NUM_100K_SETS = 6; + +/** + * The column letters (for easting) of the lower left value, per + * set. + * + * {string} @private + */ +var SET_ORIGIN_COLUMN_LETTERS = 'AJSAJS'; + +/** + * The row letters (for northing) of the lower left value, per + * set. + * + * {string} @private + */ +var SET_ORIGIN_ROW_LETTERS = 'AFAFAF'; + +var A = 65; // A +var I = 73; // I +var O = 79; // O +var V = 86; // V +var Z = 90; // Z +export default { + forward: forward, + inverse: inverse, + toPoint: toPoint +}; +/** + * Conversion of lat/lon to MGRS. + * + * @param {object} ll Object literal with lat and lon properties on a + * WGS84 ellipsoid. + * @param {int} accuracy Accuracy in digits (5 for 1 m, 4 for 10 m, 3 for + * 100 m, 2 for 1000 m or 1 for 10000 m). Optional, default is 5. + * @return {string} the MGRS string for the given location and accuracy. + */ +export function forward(ll, accuracy) { + accuracy = accuracy || 5; // default accuracy 1m + return encode(LLtoUTM({ + lat: ll[1], + lon: ll[0] + }), accuracy); +}; + +/** + * Conversion of MGRS to lat/lon. + * + * @param {string} mgrs MGRS string. + * @return {array} An array with left (longitude), bottom (latitude), right + * (longitude) and top (latitude) values in WGS84, representing the + * bounding box for the provided MGRS reference. + */ +export function inverse(mgrs) { + var bbox = UTMtoLL(decode(mgrs.toUpperCase())); + if (bbox.lat && bbox.lon) { + return [bbox.lon, bbox.lat, bbox.lon, bbox.lat]; + } + return [bbox.left, bbox.bottom, bbox.right, bbox.top]; +}; + +export function toPoint(mgrs) { + var bbox = UTMtoLL(decode(mgrs.toUpperCase())); + if (bbox.lat && bbox.lon) { + return [bbox.lon, bbox.lat]; + } + return [(bbox.left + bbox.right) / 2, (bbox.top + bbox.bottom) / 2]; +}; +/** + * Conversion from degrees to radians. + * + * @private + * @param {number} deg the angle in degrees. + * @return {number} the angle in radians. + */ +function degToRad(deg) { + return (deg * (Math.PI / 180.0)); +} + +/** + * Conversion from radians to degrees. + * + * @private + * @param {number} rad the angle in radians. + * @return {number} the angle in degrees. + */ +function radToDeg(rad) { + return (180.0 * (rad / Math.PI)); +} + +/** + * Converts a set of Longitude and Latitude co-ordinates to UTM + * using the WGS84 ellipsoid. + * + * @private + * @param {object} ll Object literal with lat and lon properties + * representing the WGS84 coordinate to be converted. + * @return {object} Object literal containing the UTM value with easting, + * northing, zoneNumber and zoneLetter properties, and an optional + * accuracy property in digits. Returns null if the conversion failed. + */ +function LLtoUTM(ll) { + var Lat = ll.lat; + var Long = ll.lon; + var a = 6378137.0; //ellip.radius; + var eccSquared = 0.00669438; //ellip.eccsq; + 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; + // (int) + ZoneNumber = Math.floor((Long + 180) / 6) + 1; + + //Make sure the longitude 180.00 is in Zone 60 + if (Long === 180) { + ZoneNumber = 60; + } + + // Special zone for Norway + if (Lat >= 56.0 && Lat < 64.0 && Long >= 3.0 && Long < 12.0) { + ZoneNumber = 32; + } + + // Special zones for Svalbard + if (Lat >= 72.0 && Lat < 84.0) { + if (Long >= 0.0 && Long < 9.0) { + ZoneNumber = 31; + } + else if (Long >= 9.0 && Long < 21.0) { + ZoneNumber = 33; + } + else if (Long >= 21.0 && Long < 33.0) { + ZoneNumber = 35; + } + else if (Long >= 33.0 && Long < 42.0) { + ZoneNumber = 37; + } + } + + LongOrigin = (ZoneNumber - 1) * 6 - 180 + 3; //+3 puts origin + // in middle of + // zone + 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.0 + (5 - 18 * T + T * T + 72 * C - 58 * eccPrimeSquared) * A * A * A * A * A / 120.0) + 500000.0); + + var UTMNorthing = (k0 * (M + N * Math.tan(LatRad) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * A * A * A * A / 24.0 + (61 - 58 * T + T * T + 600 * C - 330 * eccPrimeSquared) * A * A * A * A * A * A / 720.0))); + if (Lat < 0.0) { + UTMNorthing += 10000000.0; //10000000 meter offset for + // southern hemisphere + } + + return { + northing: Math.round(UTMNorthing), + easting: Math.round(UTMEasting), + zoneNumber: ZoneNumber, + zoneLetter: getLetterDesignator(Lat) + }; +} + +/** + * Converts UTM coords to lat/long, using the WGS84 ellipsoid. This is a convenience + * class where the Zone can be specified as a single string eg."60N" which + * is then broken down into the ZoneNumber and ZoneLetter. + * + * @private + * @param {object} utm An object literal with northing, easting, zoneNumber + * and zoneLetter properties. If an optional accuracy property is + * provided (in meters), a bounding box will be returned instead of + * latitude and longitude. + * @return {object} An object literal containing either lat and lon values + * (if no accuracy was provided), or top, right, bottom and left values + * for the bounding box calculated according to the provided accuracy. + * Returns null if the conversion failed. + */ +function UTMtoLL(utm) { + + var UTMNorthing = utm.northing; + var UTMEasting = utm.easting; + var zoneLetter = utm.zoneLetter; + var zoneNumber = utm.zoneNumber; + // check the ZoneNummber is valid + if (zoneNumber < 0 || zoneNumber > 60) { + return null; + } + + var k0 = 0.9996; + var a = 6378137.0; //ellip.radius; + var eccSquared = 0.00669438; //ellip.eccsq; + 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; + + // remove 500,000 meter offset for longitude + var x = UTMEasting - 500000.0; + var y = UTMNorthing; + + // We must know somehow if we are in the Northern or Southern + // hemisphere, this is the only time we use the letter So even + // if the Zone letter isn't exactly correct it should indicate + // the hemisphere correctly + if (zoneLetter < 'N') { + y -= 10000000.0; // remove 10,000,000 meter offset used + // for southern hemisphere + } + + // There are 60 zones with zone 1 being at West -180 to -174 + LongOrigin = (zoneNumber - 1) * 6 - 180 + 3; // +3 puts origin + // in middle of + // zone + + 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); + // double phi1 = ProjMath.radToDeg(phi1Rad); + + 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; +} + +/** + * Calculates the MGRS letter designator for the given latitude. + * + * @private + * @param {number} lat The latitude in WGS84 to get the letter designator + * for. + * @return {char} The letter designator. + */ +function getLetterDesignator(lat) { + //This is here as an error flag to show that the Latitude is + //outside MGRS limits + 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; +} + +/** + * Encodes a UTM location as MGRS string. + * + * @private + * @param {object} utm An object literal with easting, northing, + * zoneLetter, zoneNumber + * @param {number} accuracy Accuracy in digits (1-5). + * @return {string} MGRS string for the given UTM location. + */ +function encode(utm, accuracy) { + // prepend with leading zeroes + var seasting = "00000" + utm.easting, + snorthing = "00000" + 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); +} + +/** + * Get the two letter 100k designator for a given UTM easting, + * northing and zone number value. + * + * @private + * @param {number} easting + * @param {number} northing + * @param {number} zoneNumber + * @return the two letter 100k designator for the given UTM location. + */ +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); +} + +/** + * Given a UTM zone number, figure out the MGRS 100K set it is in. + * + * @private + * @param {number} i An UTM zone number. + * @return {number} the 100k set the UTM zone is in. + */ +function get100kSetForZone(i) { + var setParm = i % NUM_100K_SETS; + if (setParm === 0) { + setParm = NUM_100K_SETS; + } + + return setParm; +} + +/** + * Get the two-letter MGRS 100k designator given information + * translated from the UTM northing, easting and zone number. + * + * @private + * @param {number} column the column index as it relates to the MGRS + * 100k set spreadsheet, created from the UTM easting. + * Values are 1-8. + * @param {number} row the row index as it relates to the MGRS 100k set + * spreadsheet, created from the UTM northing value. Values + * are from 0-19. + * @param {number} parm the set block, as it relates to the MGRS 100k set + * spreadsheet, created from the UTM zone. Values are from + * 1-60. + * @return two letter MGRS 100k code. + */ +function getLetter100kID(column, row, parm) { + // colOrigin and rowOrigin are the letters at the origin of the set + var index = parm - 1; + var colOrigin = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(index); + var rowOrigin = SET_ORIGIN_ROW_LETTERS.charCodeAt(index); + + // colInt and rowInt are the letters to build to return + 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; +} + +/** + * Decode the UTM parameters from a MGRS string. + * + * @private + * @param {string} mgrsString an UPPERCASE coordinate string is expected. + * @return {object} An object literal with easting, northing, zoneLetter, + * zoneNumber and accuracy (in meters) properties. + */ +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; + + // get Zone number + 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) { + // A good MGRS string has to be 4-5 digits long, + // ##AAA/#AAA at least. + throw ("MGRSPoint bad conversion from: " + mgrsString); + } + + var zoneLetter = mgrsString.charAt(i++); + + // Should we check the zone letter here? Why not. + 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); + + // We have a bug where the northing may be 2000000 too low. + // How + // do we know when to roll over? + + while (north100k < getMinNorthing(zoneLetter)) { + north100k += 2000000; + } + + // calculate the char index for easting/northing separator + 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.0; + var sepNorthing = 0.0; + var accuracyBonus, sepEastingString, sepNorthingString, easting, northing; + if (sep > 0) { + accuracyBonus = 100000.0 / 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 + }; +} + +/** + * Given the first letter from a two-letter MGRS 100k zone, and given the + * MGRS table set for the zone number, figure out the easting value that + * should be added to the other, secondary easting value. + * + * @private + * @param {char} e The first letter from a two-letter MGRS 100´k zone. + * @param {number} set The MGRS table set for the zone number. + * @return {number} The easting value for the given letter and set. + */ +function getEastingFromChar(e, set) { + // colOrigin is the letter at the origin of the set for the + // column + var curCol = SET_ORIGIN_COLUMN_LETTERS.charCodeAt(set - 1); + var eastingValue = 100000.0; + 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.0; + } + + return eastingValue; +} + +/** + * Given the second letter from a two-letter MGRS 100k zone, and given the + * MGRS table set for the zone number, figure out the northing value that + * should be added to the other, secondary northing value. You have to + * remember that Northings are determined from the equator, and the vertical + * cycle of letters mean a 2000000 additional northing meters. This happens + * approx. every 18 degrees of latitude. This method does *NOT* count any + * additional northings. You have to figure out how many 2000000 meters need + * to be added for the zone letter of the MGRS coordinate. + * + * @private + * @param {char} n Second letter of the MGRS 100k zone + * @param {number} set The MGRS table set number, which is dependent on the + * UTM zone number. + * @return {number} The northing value for the given letter and set. + */ +function getNorthingFromChar(n, set) { + + if (n > 'V') { + throw ("MGRSPoint given invalid Northing " + n); + } + + // rowOrigin is the letter at the origin of the set for the + // column + var curRow = SET_ORIGIN_ROW_LETTERS.charCodeAt(set - 1); + var northingValue = 0.0; + var rewindMarker = false; + + while (curRow !== n.charCodeAt(0)) { + curRow++; + if (curRow === I) { + curRow++; + } + if (curRow === O) { + curRow++; + } + // fixing a bug making whole application hang in this loop + // when 'n' is a wrong character + if (curRow > V) { + if (rewindMarker) { // making sure that this loop ends + throw ("Bad character: " + n); + } + curRow = A; + rewindMarker = true; + } + northingValue += 100000.0; + } + + return northingValue; +} + +/** + * The function getMinNorthing returns the minimum northing value of a MGRS + * zone. + * + * Ported from Geotrans' c Lattitude_Band_Value structure table. + * + * @private + * @param {char} zoneLetter The MGRS zone to get the min northing for. + * @return {number} + */ +function getMinNorthing(zoneLetter) { + var northing; + switch (zoneLetter) { + case 'C': + northing = 1100000.0; + break; + case 'D': + northing = 2000000.0; + break; + case 'E': + northing = 2800000.0; + break; + case 'F': + northing = 3700000.0; + break; + case 'G': + northing = 4600000.0; + break; + case 'H': + northing = 5500000.0; + break; + case 'J': + northing = 6400000.0; + break; + case 'K': + northing = 7300000.0; + break; + case 'L': + northing = 8200000.0; + break; + case 'M': + northing = 9100000.0; + break; + case 'N': + northing = 0.0; + break; + case 'P': + northing = 800000.0; + break; + case 'Q': + northing = 1700000.0; + break; + case 'R': + northing = 2600000.0; + break; + case 'S': + northing = 3500000.0; + break; + case 'T': + northing = 4400000.0; + break; + case 'U': + northing = 5300000.0; + break; + case 'V': + northing = 6200000.0; + break; + case 'W': + northing = 7000000.0; + break; + case 'X': + northing = 7900000.0; + break; + default: + northing = -1.0; + } + if (northing >= 0.0) { + return northing; + } + else { + throw ("Invalid zone letter: " + zoneLetter); + } + +} diff --git a/src/main/webapp/resources/engine/mgrs/openmap.md b/src/main/webapp/resources/engine/mgrs/openmap.md new file mode 100644 index 0000000..cba0d76 --- /dev/null +++ b/src/main/webapp/resources/engine/mgrs/openmap.md @@ -0,0 +1,145 @@ +OpenMap Software License Agreement +====== + +This Agreement sets forth the terms and conditions under which +the software known as OpenMap(tm) will be licensed by BBN +Technologies ("BBN") to you ("Licensee"), and by which Derivative +Works (as hereafter defined) of OpenMap will be licensed by you to BBN. + +Definitions: + +- "Derivative Work(s)" shall mean any revision, enhancement, + modification, translation, abridgement, condensation or + expansion created by Licensee or BBN that is based upon the + Software or a portion thereof that would be a copyright + infringement if prepared without the authorization of the + copyright owners of the Software or portion thereof. + +- "OpenMap" shall mean a programmer's toolkit for building map + based applications as originally created by BBN, and any + Derivative Works thereof as created by either BBN or Licensee, + but shall include only those Derivative Works BBN has approved + for inclusion into, and BBN has integrated into OpenMap. + +- "Standard Version" shall mean OpenMap, as originally created by + BBN. + +- "Software" shall mean OpenMap and the Derivative Works created + by Licensee and the collection of files distributed by the + Licensee with OpenMap, and the collection of files created + through textual modifications. + +- "Copyright Holder" is whoever is named in the copyright or + copyrights for the Derivative Works. + +- "Licensee" is you, only if you agree to be bound by the terms + and conditions set forth in this Agreement. + +- "Reasonable copying fee" is whatever you can justify on the + basis of media cost, duplication charges, time of people + involved. + +- "Freely Available" means that no fee is charged for the item + itself, though there may be fees involved in handling the item. + It also means that recipients of the item may redistribute it + under the same conditions that they received it. + +1. BBN maintains all rights, title and interest in and to +OpenMap, including all applicable copyrights, trade secrets, +patents and other intellectual rights therein. Licensee hereby +grants to BBN all right, title and interest into the compilation +of OpenMap. Licensee shall own all rights, title and interest +into the Derivative Works created by Licensee (subject to the +compilation ownership by BBN). + +2. BBN hereby grants to Licensee a royalty free, worldwide right +and license to use, copy, distribute and make Derivative Works of +OpenMap, and sublicensing rights of any of the foregoing in +accordance with the terms and conditions of this Agreement, +provided that you duplicate all of the original copyright notices +and associated disclaimers. + +3. Licensee hereby grants to BBN a royalty free, worldwide right +and license to use, copy, distribute and make Derivative Works of +Derivative Works created by Licensee and sublicensing rights of +any of the foregoing. + +4. Licensee's right to create Derivative Works in the Software is +subject to Licensee agreement to insert a prominent notice in +each changed file stating how and when you changed that file, and +provided that you do at least ONE of the following: + + - a) place your modifications in the Public Domain or otherwise + make them Freely Available, such as by posting said + modifications to Usenet or an equivalent medium, or + placing the modifications on a major archive site and by + providing your modifications to the Copyright Holder. + + - b) use the modified Package only within your corporation or + organization. + + - c) rename any non-standard executables so the names do not + conflict with standard executables, which must also be + provided, and provide a separate manual page for each + non-standard executable that clearly documents how it + differs from OpenMap. + + - d) make other distribution arrangements with the Copyright + Holder. +5. Licensee may distribute the programs of this Software in +object code or executable form, provided that you do at least ONE +of the following: + + - a) distribute an OpenMap version of the executables and + library files, together with instructions (in the manual + page or equivalent) on where to get OpenMap. + + - b) accompany the distribution with the machine-readable + source code with your modifications. + + - c) accompany any non-standard executables with their + corresponding OpenMap executables, giving the non-standard + executables non-standard names, and clearly documenting + the differences in manual pages (or equivalent), together + with instructions on where to get OpenMap. + + - d) make other distribution arrangements with the Copyright + Holder. +6. You may charge a reasonable copying fee for any distribution +of this Software. You may charge any fee you choose for support +of this Software. You may not charge a fee for this Software +itself. However, you may distribute this Software in aggregate +with other (possibly commercial) programs as part of a larger +(possibly commercial) software distribution provided that you do +not advertise this Software as a product of your own. + +7. The data and images supplied as input to or produced as output +from the Software do not automatically fall under the copyright +of this Software, but belong to whomever generated them, and may +be sold commercially, and may be aggregated with this Software. + +8. BBN makes no representation about the suitability of OpenMap +for any purposes. BBN shall have no duty or requirement to +include any Derivative Works into OpenMap. + +9. Each party hereto represents and warrants that they have the +full unrestricted right to grant all rights and licenses granted +to the other party herein. + +10. THIS PACKAGE IS PROVIDED "AS IS" WITHOUT WARRANTIES OF ANY +KIND, WHETHER EXPRESS OR IMPLIED, INCLUDING (BUT NOT LIMITED TO) +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND +WITHOUT ANY WARRANTIES AS TO NONINFRINGEMENT. + +11. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, +SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES WHATSOEVER RESULTING +FROM LOSS OF USE OF DATA OR PROFITS, WHETHER IN AN ACTION OF +CONTRACT, NEGLIGENCE OR OTHER TORTIOUS CONDUCT, ARISING OUT OF OR +IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PACKAGE. + +12. Without limitation of the foregoing, You agree to commit no +act which, directly or indirectly, would violate any U.S. law, +regulation, or treaty, or any other international treaty or +agreement to which the United States adheres or with which the +United States complies, relating to the export or re-export of +any commodities, software, or technical data. \ No newline at end of file diff --git a/src/main/webapp/resources/engine/mgrs/package.json b/src/main/webapp/resources/engine/mgrs/package.json new file mode 100644 index 0000000..202c26e --- /dev/null +++ b/src/main/webapp/resources/engine/mgrs/package.json @@ -0,0 +1,59 @@ +{ + "_from": "mgrs@1.0.0", + "_id": "mgrs@1.0.0", + "_inBundle": false, + "_integrity": "sha1-+5FYjnjJACVnI5XLQLJffNatGCk=", + "_location": "/mgrs", + "_phantomChildren": {}, + "_requested": { + "type": "version", + "registry": true, + "raw": "mgrs@1.0.0", + "name": "mgrs", + "escapedName": "mgrs", + "rawSpec": "1.0.0", + "saveSpec": null, + "fetchSpec": "1.0.0" + }, + "_requiredBy": [ + "/proj4" + ], + "_resolved": "https://registry.npmjs.org/mgrs/-/mgrs-1.0.0.tgz", + "_shasum": "fb91588e78c90025672395cb40b25f7cd6ad1829", + "_spec": "mgrs@1.0.0", + "_where": "O:\\temp\\node_modules\\proj4", + "author": { + "name": "proj4 team" + }, + "bugs": { + "url": "https://github.com/proj4js/mgrs/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Utility for converting between WGS84 lat/lng and MGRS coordinates", + "devDependencies": { + "chai": "~1.8.1", + "istanbul": "~0.1.46", + "mocha": "~1.15.1", + "rollup": "^0.41.4" + }, + "homepage": "https://github.com/proj4js/mgrs#readme", + "keywords": [ + "mgrs", + "proj4", + "gis" + ], + "license": "MIT", + "main": "dist/mgrs.js", + "module": "mgrs.js", + "name": "mgrs", + "repository": { + "type": "git", + "url": "git://github.com/proj4js/mgrs.git" + }, + "scripts": { + "build": "mkdir -p dist && rollup -c", + "test": "npm run build && istanbul test _mocha test/test.js" + }, + "version": "1.0.0" +} diff --git a/src/main/webapp/resources/engine/mgrs/publish.sh b/src/main/webapp/resources/engine/mgrs/publish.sh new file mode 100644 index 0000000..b96e6d0 --- /dev/null +++ b/src/main/webapp/resources/engine/mgrs/publish.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# get current version +VERSION=$(npm ls --json=true mgrs | grep version | awk '{ print $2}'| sed -e 's/^"//' -e 's/"$//') + +# Build +git checkout -b build +npm run build +git add dist -f +git commit -m "build $VERSION" + +# Tag and push +git tag $VERSION +git push --tags git@github.com:proj4js/mgrs.git $VERSION + +# Publish +npm publish + +# Cleanup +git checkout master +git branch -D build diff --git a/src/main/webapp/resources/engine/mgrs/readme.md b/src/main/webapp/resources/engine/mgrs/readme.md new file mode 100644 index 0000000..1106c1f --- /dev/null +++ b/src/main/webapp/resources/engine/mgrs/readme.md @@ -0,0 +1,44 @@ +mgrs +==== + +Utility for converting between WGS84 lat/lng and MGRS coordinates, spunoff from [proj4js](https://github.com/proj4js/proj4js) + +has 3 methods + +- forward, takes an array of `[lon,lat]` and optional accuracy and returns an mgrs string +- inverse, takes an mgrs string and returns a bbox. +- toPoint, takes an mgrs string, returns an array of '[lon,lat]' + +install dev dependencies with + +```bash +npm install +``` + +test with + +```bash +npm test +``` + +test coverage with + +```bash +npm test --coverage +``` + +build with + +```bash +npm run build +``` + + +Licensed under the MIT license except: + +Portions of this software are based on a port of components from the OpenMap +com.bbn.openmap.proj.coords Java package. An initial port was initially created +by Patrice G. Cappelaere and included in Community Mapbuilder +(http://svn.codehaus.org/mapbuilder/), which is licensed under the LGPL license +as per http://www.gnu.org/copyleft/lesser.html. OpenMap is licensed under the +[following license agreement](openmap.md): diff --git a/src/main/webapp/resources/engine/mgrs/rollup.config.js b/src/main/webapp/resources/engine/mgrs/rollup.config.js new file mode 100644 index 0000000..e60eab9 --- /dev/null +++ b/src/main/webapp/resources/engine/mgrs/rollup.config.js @@ -0,0 +1,8 @@ + +export default { + entry: 'mgrs.js', + dest: 'dist/mgrs.js', + format: 'umd', + moduleName: 'mgrs', + exports: 'named' +}; diff --git a/src/main/webapp/resources/engine/mgrs/test/test.js b/src/main/webapp/resources/engine/mgrs/test/test.js new file mode 100644 index 0000000..3bc5b5f --- /dev/null +++ b/src/main/webapp/resources/engine/mgrs/test/test.js @@ -0,0 +1,37 @@ +var should = require('chai').should(); +var mgrs = require('../dist/mgrs'); +describe('First MGRS set', function() { + var mgrsStr = "33UXP04"; + var point = mgrs.toPoint(mgrsStr); + it('Longitude of point from MGRS correct.', function() { + point[0].should.be.closeTo(16.41450, 0.000001); + }); + it('Latitude of point from MGRS correct.', function() { + point[1].should.be.closeTo(48.24949, 0.000001); + }); + it('MGRS reference with highest accuracy correct.', function() { + mgrs.forward(point).should.equal("33UXP0500444998"); + }); + it('MGRS reference with 1-digit accuracy correct.', function() { + mgrs.forward(point,1).should.equal(mgrsStr); + }); +}); +describe('Second MGRS set', function() { + var mgrsStr = "24XWT783908"; // near UTM zone border, so there are two ways to reference this + var point = mgrs.toPoint(mgrsStr); + it('Longitude of point from MGRS correct.', function() { + point[0].should.be.closeTo(-32.66433, 0.00001); + }); + it('Latitude of point from MGRS correct.', function() { + point[1].should.be.closeTo(83.62778, 0.00001); + }); + it('MGRS reference with 1-digit accuracy correct.', function() { + mgrs.forward(point,3).should.equal('25XEN041865'); + }); + it('MGRS reference with 5-digit accuracy, northing all zeros', function(){ + mgrs.forward([0,0],5).should.equal('31NAA6602100000'); + }); + it('MGRS reference with 5-digit accuracy, northing one digit', function(){ + mgrs.forward([0,0.00001],5).should.equal('31NAA6602100001'); + }); +}) \ No newline at end of file diff --git a/src/main/webapp/resources/engine/normalize.css b/src/main/webapp/resources/engine/normalize.css new file mode 100644 index 0000000..5e5e3c8 --- /dev/null +++ b/src/main/webapp/resources/engine/normalize.css @@ -0,0 +1,424 @@ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ + +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS and IE text size adjust after device orientation change, + * without disabling user zoom. + */ + +html { + font-family: sans-serif; /* 1 */ + -ms-text-size-adjust: 100%; /* 2 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/** + * Remove default margin. + */ + +body { + margin: 0; +} + +/* HTML5 display definitions + ========================================================================== */ + +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ + +audio, +canvas, +progress, +video { + display: inline-block; /* 1 */ + vertical-align: baseline; /* 2 */ +} + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ + +audio:not([controls]) { + display: none; + height: 0; +} + +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22. + */ + +[hidden], +template { + display: none; +} + +/* Links + ========================================================================== */ + +/** + * Remove the gray background color from active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * Improve readability of focused elements when they are also in an + * active/hover state. + */ + +a:active, +a:hover { + outline: 0; +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ + +abbr[title] { + border-bottom: 1px dotted; +} + +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ + +b, +strong { + font-weight: bold; +} + +/** + * Address styling not present in Safari and Chrome. + */ + +dfn { + font-style: italic; +} + +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/** + * Address styling not present in IE 8/9. + */ + +mark { + background: #ff0; + color: #000; +} + +/** + * Address inconsistent and variable font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove border when inside `a` element in IE 8/9/10. + */ + +img { + border: 0; +} + +/** + * Correct overflow not hidden in IE 9/10/11. + */ + +svg:not(:root) { + overflow: hidden; +} + +/* Grouping content + ========================================================================== */ + +/** + * Address margin not present in IE 8/9 and Safari. + */ + +figure { + margin: 1em 40px; +} + +/** + * Address differences between Firefox and other browsers. + */ + +hr { + box-sizing: content-box; + height: 0; +} + +/** + * Contain overflow in all browsers. + */ + +pre { + overflow: auto; +} + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ + +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} + +/* Forms + ========================================================================== */ + +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ + +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ + +button, +input, +optgroup, +select, +textarea { + color: inherit; /* 1 */ + font: inherit; /* 2 */ + margin: 0; /* 3 */ +} + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ + +button { + overflow: visible; +} + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ + +button, +select { + text-transform: none; +} + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ + +button, +html input[type="button"], /* 1 */ +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; /* 2 */ + cursor: pointer; /* 3 */ +} + +/** + * Re-set default cursor for disabled elements. + */ + +button[disabled], +html input[disabled] { + cursor: default; +} + +/** + * Remove inner padding and border in Firefox 4+. + */ + +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ + +input { + line-height: normal; +} + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ + +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome. + */ + +input[type="search"] { + -webkit-appearance: textfield; /* 1 */ + box-sizing: content-box; /* 2 */ +} + +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ + +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * Define consistent border, margin, and padding. + */ + +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} + +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ + +legend { + border: 0; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ + +textarea { + overflow: auto; +} + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ + +optgroup { + font-weight: bold; +} + +/* Tables + ========================================================================== */ + +/** + * Remove most spacing between table cells. + */ + +table { + border-collapse: collapse; + border-spacing: 0; +} + +td, +th { + padding: 0; +} diff --git a/src/main/webapp/resources/engine/openlayers/ol.css b/src/main/webapp/resources/engine/openlayers/ol.css new file mode 100644 index 0000000..88c7018 --- /dev/null +++ b/src/main/webapp/resources/engine/openlayers/ol.css @@ -0,0 +1,2 @@ +.ol-box{box-sizing:border-box;border-radius:2px;border:1.5px solid #b3c5db;background-color:rgba(255,255,255,.4)}.ol-mouse-position{top:8px;right:8px;position:absolute}.ol-scale-line{background:rgba(0,60,136,.3);border-radius:4px;bottom:8px;left:8px;padding:2px;position:absolute}.ol-scale-line-inner{border:1px solid #eee;border-top:none;color:#eee;font-size:10px;text-align:center;margin:1px;will-change:contents,width;transition:all .25s}.ol-scale-singlebar-even{background-color:#000}.ol-scale-singlebar-odd{background-color:#fff}.ol-scale-bar{position:absolute;bottom:8px;left:8px}.ol-scale-step-marker{width:1px;height:15px;background-color:#000;float:right;z-index:10}.ol-scale-step-text{position:absolute;bottom:-5px;font-size:12px;z-index:11;color:#000;text-shadow:-2px 0 #fff,0 2px #fff,2px 0 #fff,0 -2px #fff}.ol-scale-text{position:absolute;font-size:14px;text-align:center;bottom:25px;color:#000;text-shadow:-2px 0 #fff,0 2px #fff,2px 0 #fff,0 -2px #fff}.ol-scale-singlebar{position:relative;height:10px;z-index:9;box-sizing:border-box;border:1px solid #000}.ol-unsupported{display:none}.ol-unselectable,.ol-viewport{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.ol-viewport canvas{all:unset}.ol-selectable{-webkit-touch-callout:default;-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}.ol-grabbing{cursor:-webkit-grabbing;cursor:-moz-grabbing;cursor:grabbing}.ol-grab{cursor:move;cursor:-webkit-grab;cursor:-moz-grab;cursor:grab}.ol-control{position:absolute;background-color:rgba(255,255,255,.4);border-radius:4px;padding:2px}.ol-control:hover{background-color:rgba(255,255,255,.6)}.ol-zoom{top:.5em;left:.5em}.ol-rotate{top:.5em;right:.5em;transition:opacity .25s linear,visibility 0s linear}.ol-rotate.ol-hidden{opacity:0;visibility:hidden;transition:opacity .25s linear,visibility 0s linear .25s}.ol-zoom-extent{top:4.643em;left:.5em}.ol-full-screen{right:.5em;top:.5em}.ol-control button{display:block;margin:1px;padding:0;color:#fff;font-weight:700;text-decoration:none;font-size:inherit;text-align:center;height:1.375em;width:1.375em;line-height:.4em;background-color:rgba(0,60,136,.5);border:none;border-radius:2px}.ol-control button::-moz-focus-inner{border:none;padding:0}.ol-zoom-extent button{line-height:1.4em}.ol-compass{display:block;font-weight:400;font-size:1.2em;will-change:transform}.ol-touch .ol-control button{font-size:1.5em}.ol-touch .ol-zoom-extent{top:5.5em}.ol-control button:focus,.ol-control button:hover{text-decoration:none;background-color:rgba(0,60,136,.7)}.ol-zoom .ol-zoom-in{border-radius:2px 2px 0 0}.ol-zoom .ol-zoom-out{border-radius:0 0 2px 2px}.ol-attribution{text-align:right;bottom:.5em;right:.5em;max-width:calc(100% - 1.3em);display:flex;flex-flow:row-reverse;align-items:center}.ol-attribution a{color:rgba(0,60,136,.7);text-decoration:none}.ol-attribution ul{margin:0;padding:1px .5em;color:#000;text-shadow:0 0 2px #fff;font-size:12px}.ol-attribution li{display:inline;list-style:none}.ol-attribution li:not(:last-child):after{content:" "}.ol-attribution img{max-height:2em;max-width:inherit;vertical-align:middle}.ol-attribution button{flex-shrink:0}.ol-attribution.ol-collapsed ul{display:none}.ol-attribution:not(.ol-collapsed){background:rgba(255,255,255,.8)}.ol-attribution.ol-uncollapsible{bottom:0;right:0;border-radius:4px 0 0}.ol-attribution.ol-uncollapsible img{margin-top:-.2em;max-height:1.6em}.ol-attribution.ol-uncollapsible button{display:none}.ol-zoomslider{top:4.5em;left:.5em;height:200px}.ol-zoomslider button{position:relative;height:10px}.ol-touch .ol-zoomslider{top:5.5em}.ol-overviewmap{left:.5em;bottom:.5em}.ol-overviewmap.ol-uncollapsible{bottom:0;left:0;border-radius:0 4px 0 0}.ol-overviewmap .ol-overviewmap-map,.ol-overviewmap button{display:block}.ol-overviewmap .ol-overviewmap-map{border:1px solid #7b98bc;height:150px;margin:2px;width:150px}.ol-overviewmap:not(.ol-collapsed) button{bottom:2px;left:2px;position:absolute}.ol-overviewmap.ol-collapsed .ol-overviewmap-map,.ol-overviewmap.ol-uncollapsible button{display:none}.ol-overviewmap:not(.ol-collapsed){background:rgba(255,255,255,.8)}.ol-overviewmap-box{border:2px dotted rgba(0,60,136,.7)}.ol-overviewmap .ol-overviewmap-box:hover{cursor:move} +/*# sourceMappingURL=ol.css.map */ \ No newline at end of file diff --git a/src/main/webapp/resources/engine/openlayers/ol.css.map b/src/main/webapp/resources/engine/openlayers/ol.css.map new file mode 100644 index 0000000..e430caf --- /dev/null +++ b/src/main/webapp/resources/engine/openlayers/ol.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["src/ol/ol.css"],"names":[],"mappings":"AAAA,QACE,WAAY,WACZ,cAAe,IACf,OAAQ,MAAM,MAAM,QACpB,iBAAkB,qBAGpB,mBACE,IAAK,IACL,MAAO,IACP,SAAU,SAGZ,eACE,WAAY,kBACZ,cAAe,IACf,OAAQ,IACR,KAAM,IACN,QAAS,IACT,SAAU,SAEZ,qBACE,OAAQ,IAAI,MAAM,KAClB,WAAY,KACZ,MAAO,KACP,UAAW,KACX,WAAY,OACZ,OAAQ,IACR,YAAa,QAAQ,CAAE,MACvB,WAAY,IAAI,KAElB,yBACE,iBAAkB,KAEpB,wBACE,iBAAkB,KAEpB,cACE,SAAU,SACV,OAAQ,IACR,KAAM,IAER,sBACE,MAAO,IACP,OAAQ,KACR,iBAAkB,KAClB,MAAO,MACP,QAAS,GAEX,oBACE,SAAU,SACV,OAAQ,KACR,UAAW,KACX,QAAS,GACT,MAAO,KACP,YAAa,KAAK,EAAE,IAAO,CAAE,EAAE,IAAI,IAAO,CAAE,IAAI,EAAE,IAAO,CAAE,EAAE,KAAK,KAEpE,eACE,SAAU,SACV,UAAW,KACX,WAAY,OACZ,OAAQ,KACR,MAAO,KACP,YAAa,KAAK,EAAE,IAAO,CAAE,EAAE,IAAI,IAAO,CAAE,IAAI,EAAE,IAAO,CAAE,EAAE,KAAK,KAEpE,oBACE,SAAU,SACV,OAAQ,KACR,QAAS,EACT,WAAY,WACZ,OAAQ,IAAI,MAAM,KAGpB,gBACE,QAAS,KAEG,iBAAd,aACE,sBAAuB,KACvB,oBAAqB,KACrB,iBAAkB,KAClB,gBAAiB,KACjB,YAAa,KACb,4BAA6B,YAE/B,oBACE,IAAK,MAEP,eACE,sBAAuB,QACvB,oBAAqB,KACrB,iBAAkB,KAClB,gBAAiB,KACjB,YAAa,KAEf,aACE,OAAQ,iBACR,OAAQ,cACR,OAAQ,SAEV,SACE,OAAQ,KACR,OAAQ,aACR,OAAQ,UACR,OAAQ,KAEV,YACE,SAAU,SACV,iBAAkB,qBAClB,cAAe,IACf,QAAS,IAEX,kBACE,iBAAkB,qBAEpB,SACE,IAAK,KACL,KAAM,KAER,WACE,IAAK,KACL,MAAO,KACP,WAAY,QAAQ,KAAK,MAAM,CAAE,WAAW,GAAG,OAEjD,qBACE,QAAS,EACT,WAAY,OACZ,WAAY,QAAQ,KAAK,MAAM,CAAE,WAAW,GAAG,OAAO,KAExD,gBACE,IAAK,QACL,KAAM,KAER,gBACE,MAAO,KACP,IAAK,KAGP,mBACE,QAAS,MACT,OAAQ,IACR,QAAS,EACT,MAAO,KACP,YAAa,IACb,gBAAiB,KACjB,UAAW,QACX,WAAY,OACZ,OAAQ,QACR,MAAO,QACP,YAAa,KACb,iBAAkB,kBAClB,OAAQ,KACR,cAAe,IAEjB,qCACE,OAAQ,KACR,QAAS,EAEX,uBACE,YAAa,MAEf,YACE,QAAS,MACT,YAAa,IACb,UAAW,MACX,YAAa,UAEf,6BACE,UAAW,MAEb,0BACE,IAAK,MAGP,yBADA,yBAEE,gBAAiB,KACjB,iBAAkB,kBAEpB,qBACE,cAAe,IAAI,IAAI,EAAE,EAE3B,sBACE,cAAe,EAAE,EAAE,IAAI,IAIzB,gBACE,WAAY,MACZ,OAAQ,KACR,MAAO,KACP,UAAW,mBACX,QAAS,KACT,UAAW,YACX,YAAa,OAEf,kBACE,MAAO,kBACP,gBAAiB,KAEnB,mBACE,OAAQ,EACR,QAAS,IAAI,KACb,MAAO,KACP,YAAa,EAAE,EAAE,IAAI,KACrB,UAAW,KAEb,mBACE,QAAS,OACT,WAAY,KAEd,0CACE,QAAS,IAEX,oBACE,WAAY,IACZ,UAAW,QACX,eAAgB,OAElB,uBACE,YAAa,EAEf,gCACE,QAAS,KAEX,mCACE,WAAY,qBAEd,iCACE,OAAQ,EACR,MAAO,EACP,cAAe,IAAI,EAAE,EAEvB,qCACE,WAAY,MACZ,WAAY,MAEd,wCACE,QAAS,KAGX,eACE,IAAK,MACL,KAAM,KACN,OAAQ,MAEV,sBACE,SAAU,SACV,OAAQ,KAGV,yBACE,IAAK,MAGP,gBACE,KAAM,KACN,OAAQ,KAEV,iCACE,OAAQ,EACR,KAAM,EACN,cAAe,EAAE,IAAI,EAAE,EAEzB,oCACA,uBACE,QAAS,MAEX,oCACE,OAAQ,IAAI,MAAM,QAClB,OAAQ,MACR,OAAQ,IACR,MAAO,MAET,0CACE,OAAQ,IACR,KAAM,IACN,SAAU,SAEZ,iDACA,wCACE,QAAS,KAEX,mCACE,WAAY,qBAEd,oBACE,OAAQ,IAAI,OAAO,kBAGrB,0CACE,OAAQ"} \ No newline at end of file diff --git a/src/main/webapp/resources/engine/openlayers/ol.js b/src/main/webapp/resources/engine/openlayers/ol.js new file mode 100644 index 0000000..937fbdb --- /dev/null +++ b/src/main/webapp/resources/engine/openlayers/ol.js @@ -0,0 +1,3 @@ +/*! v6.15.0-dist.zip For license information please see ol.js.LICENSE.txt */ +!function(t,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.ol=n():t.ol=n()}(self,(function(){return function(){var t,n={226:function(t,n){n.read=function(t,n,i,r,e){var o,s,u=8*e-r-1,a=(1<>1,f=-7,c=i?e-1:0,l=i?-1:1,v=t[n+c];for(c+=l,o=v&(1<<-f)-1,v>>=-f,f+=u;f>0;o=256*o+t[n+c],c+=l,f-=8);for(s=o&(1<<-f)-1,o>>=-f,f+=r;f>0;s=256*s+t[n+c],c+=l,f-=8);if(0===o)o=1-h;else{if(o===a)return s?NaN:1/0*(v?-1:1);s+=Math.pow(2,r),o-=h}return(v?-1:1)*s*Math.pow(2,o-r)},n.write=function(t,n,i,r,e,o){var s,u,a,h=8*o-e-1,f=(1<>1,l=23===e?Math.pow(2,-24)-Math.pow(2,-77):0,v=r?0:o-1,d=r?1:-1,p=n<0||0===n&&1/n<0?1:0;for(n=Math.abs(n),isNaN(n)||n===1/0?(u=isNaN(n)?1:0,s=f):(s=Math.floor(Math.log(n)/Math.LN2),n*(a=Math.pow(2,-s))<1&&(s--,a*=2),(n+=s+c>=1?l/a:l*Math.pow(2,1-c))*a>=2&&(s++,a/=2),s+c>=f?(u=0,s=f):s+c>=1?(u=(n*a-1)*Math.pow(2,e),s+=c):(u=n*Math.pow(2,c-1)*Math.pow(2,e),s=0));e>=8;t[i+v]=255&u,v+=d,u/=256,e-=8);for(s=s<0;t[i+v]=255&s,v+=d,s/=256,h-=8);t[i+v-d]|=128*p}},875:function(t,n,i){"use strict";const r=i(692),e=Symbol("max"),o=Symbol("length"),s=Symbol("lengthCalculator"),u=Symbol("allowStale"),a=Symbol("maxAge"),h=Symbol("dispose"),f=Symbol("noDisposeOnSet"),c=Symbol("lruList"),l=Symbol("cache"),v=Symbol("updateAgeOnGet"),d=()=>1;const p=(t,n,i)=>{const r=t[l].get(n);if(r){const n=r.value;if(y(t,n)){if(w(t,r),!t[u])return}else i&&(t[v]&&(r.value.now=Date.now()),t[c].unshiftNode(r));return n.value}},y=(t,n)=>{if(!n||!n.maxAge&&!t[a])return!1;const i=Date.now()-n.now;return n.maxAge?i>n.maxAge:t[a]&&i>t[a]},m=t=>{if(t[o]>t[e])for(let n=t[c].tail;t[o]>t[e]&&null!==n;){const i=n.prev;w(t,n),n=i}},w=(t,n)=>{if(n){const i=n.value;t[h]&&t[h](i.key,i.value),t[o]-=i.length,t[l].delete(i.key),t[c].removeNode(n)}};class g{constructor(t,n,i,r,e){this.key=t,this.value=n,this.length=i,this.now=r,this.maxAge=e||0}}const b=(t,n,i,r)=>{let e=i.value;y(t,e)&&(w(t,i),t[u]||(e=void 0)),e&&n.call(r,e.value,e.key,t)};t.exports=class{constructor(t){if("number"==typeof t&&(t={max:t}),t||(t={}),t.max&&("number"!=typeof t.max||t.max<0))throw new TypeError("max must be a non-negative number");this[e]=t.max||1/0;const n=t.length||d;if(this[s]="function"!=typeof n?d:n,this[u]=t.stale||!1,t.maxAge&&"number"!=typeof t.maxAge)throw new TypeError("maxAge must be a number");this[a]=t.maxAge||0,this[h]=t.dispose,this[f]=t.noDisposeOnSet||!1,this[v]=t.updateAgeOnGet||!1,this.reset()}set max(t){if("number"!=typeof t||t<0)throw new TypeError("max must be a non-negative number");this[e]=t||1/0,m(this)}get max(){return this[e]}set allowStale(t){this[u]=!!t}get allowStale(){return this[u]}set maxAge(t){if("number"!=typeof t)throw new TypeError("maxAge must be a non-negative number");this[a]=t,m(this)}get maxAge(){return this[a]}set lengthCalculator(t){"function"!=typeof t&&(t=d),t!==this[s]&&(this[s]=t,this[o]=0,this[c].forEach((t=>{t.length=this[s](t.value,t.key),this[o]+=t.length}))),m(this)}get lengthCalculator(){return this[s]}get length(){return this[o]}get itemCount(){return this[c].length}rforEach(t,n){n=n||this;for(let i=this[c].tail;null!==i;){const r=i.prev;b(this,t,i,n),i=r}}forEach(t,n){n=n||this;for(let i=this[c].head;null!==i;){const r=i.next;b(this,t,i,n),i=r}}keys(){return this[c].toArray().map((t=>t.key))}values(){return this[c].toArray().map((t=>t.value))}reset(){this[h]&&this[c]&&this[c].length&&this[c].forEach((t=>this[h](t.key,t.value))),this[l]=new Map,this[c]=new r,this[o]=0}dump(){return this[c].map((t=>!y(this,t)&&{k:t.key,v:t.value,e:t.now+(t.maxAge||0)})).toArray().filter((t=>t))}dumpLru(){return this[c]}set(t,n,i){if((i=i||this[a])&&"number"!=typeof i)throw new TypeError("maxAge must be a number");const r=i?Date.now():0,u=this[s](n,t);if(this[l].has(t)){if(u>this[e])return w(this,this[l].get(t)),!1;const s=this[l].get(t).value;return this[h]&&(this[f]||this[h](t,s.value)),s.now=r,s.maxAge=i,s.value=n,this[o]+=u-s.length,s.length=u,this.get(t),m(this),!0}const v=new g(t,n,u,r,i);return v.length>this[e]?(this[h]&&this[h](t,n),!1):(this[o]+=v.length,this[c].unshift(v),this[l].set(t,this[c].head),m(this),!0)}has(t){if(!this[l].has(t))return!1;const n=this[l].get(t).value;return!y(this,n)}get(t){return p(this,t,!0)}peek(t){return p(this,t,!1)}pop(){const t=this[c].tail;return t?(w(this,t),t.value):null}del(t){w(this,this[l].get(t))}load(t){this.reset();const n=Date.now();for(let i=t.length-1;i>=0;i--){const r=t[i],e=r.e||0;if(0===e)this.set(r.k,r.v);else{const t=e-n;t>0&&this.set(r.k,r.v,t)}}}prune(){this[l].forEach(((t,n)=>p(this,n,!1)))}}},98:function(t,n,i){"use strict";t.exports=e;var r=i(226);function e(t){this.buf=ArrayBuffer.isView&&ArrayBuffer.isView(t)?t:new Uint8Array(t||0),this.pos=0,this.type=0,this.length=this.buf.length}e.Varint=0,e.Fixed64=1,e.Bytes=2,e.Fixed32=5;var o=4294967296,s=1/o,u="undefined"==typeof TextDecoder?null:new TextDecoder("utf8");function a(t){return t.type===e.Bytes?t.readVarint()+t.pos:t.pos+1}function h(t,n,i){return i?4294967296*n+(t>>>0):4294967296*(n>>>0)+(t>>>0)}function f(t,n,i){var r=n<=16383?1:n<=2097151?2:n<=268435455?3:Math.floor(Math.log(n)/(7*Math.LN2));i.realloc(r);for(var e=i.pos-1;e>=t;e--)i.buf[e+r]=i.buf[e]}function c(t,n){for(var i=0;i>>8,t[i+2]=n>>>16,t[i+3]=n>>>24}function M(t,n){return(t[n]|t[n+1]<<8|t[n+2]<<16)+(t[n+3]<<24)}e.prototype={destroy:function(){this.buf=null},readFields:function(t,n,i){for(i=i||this.length;this.pos>3,o=this.pos;this.type=7&r,t(e,n,this),this.pos===o&&this.skip(r)}return n},readMessage:function(t,n){return this.readFields(t,n,this.readVarint()+this.pos)},readFixed32:function(){var t=b(this.buf,this.pos);return this.pos+=4,t},readSFixed32:function(){var t=M(this.buf,this.pos);return this.pos+=4,t},readFixed64:function(){var t=b(this.buf,this.pos)+b(this.buf,this.pos+4)*o;return this.pos+=8,t},readSFixed64:function(){var t=b(this.buf,this.pos)+M(this.buf,this.pos+4)*o;return this.pos+=8,t},readFloat:function(){var t=r.read(this.buf,this.pos,!0,23,4);return this.pos+=4,t},readDouble:function(){var t=r.read(this.buf,this.pos,!0,52,8);return this.pos+=8,t},readVarint:function(t){var n,i,r=this.buf;return n=127&(i=r[this.pos++]),i<128?n:(n|=(127&(i=r[this.pos++]))<<7,i<128?n:(n|=(127&(i=r[this.pos++]))<<14,i<128?n:(n|=(127&(i=r[this.pos++]))<<21,i<128?n:function(t,n,i){var r,e,o=i.buf;if(e=o[i.pos++],r=(112&e)>>4,e<128)return h(t,r,n);if(e=o[i.pos++],r|=(127&e)<<3,e<128)return h(t,r,n);if(e=o[i.pos++],r|=(127&e)<<10,e<128)return h(t,r,n);if(e=o[i.pos++],r|=(127&e)<<17,e<128)return h(t,r,n);if(e=o[i.pos++],r|=(127&e)<<24,e<128)return h(t,r,n);if(e=o[i.pos++],r|=(1&e)<<31,e<128)return h(t,r,n);throw new Error("Expected varint not more than 10 bytes")}(n|=(15&(i=r[this.pos]))<<28,t,this))))},readVarint64:function(){return this.readVarint(!0)},readSVarint:function(){var t=this.readVarint();return t%2==1?(t+1)/-2:t/2},readBoolean:function(){return Boolean(this.readVarint())},readString:function(){var t=this.readVarint()+this.pos,n=this.pos;return this.pos=t,t-n>=12&&u?function(t,n,i){return u.decode(t.subarray(n,i))}(this.buf,n,t):function(t,n,i){var r="",e=n;for(;e239?4:a>223?3:a>191?2:1;if(e+f>i)break;1===f?a<128&&(h=a):2===f?128==(192&(o=t[e+1]))&&(h=(31&a)<<6|63&o)<=127&&(h=null):3===f?(o=t[e+1],s=t[e+2],128==(192&o)&&128==(192&s)&&((h=(15&a)<<12|(63&o)<<6|63&s)<=2047||h>=55296&&h<=57343)&&(h=null)):4===f&&(o=t[e+1],s=t[e+2],u=t[e+3],128==(192&o)&&128==(192&s)&&128==(192&u)&&((h=(15&a)<<18|(63&o)<<12|(63&s)<<6|63&u)<=65535||h>=1114112)&&(h=null)),null===h?(h=65533,f=1):h>65535&&(h-=65536,r+=String.fromCharCode(h>>>10&1023|55296),h=56320|1023&h),r+=String.fromCharCode(h),e+=f}return r}(this.buf,n,t)},readBytes:function(){var t=this.readVarint()+this.pos,n=this.buf.subarray(this.pos,t);return this.pos=t,n},readPackedVarint:function(t,n){if(this.type!==e.Bytes)return t.push(this.readVarint(n));var i=a(this);for(t=t||[];this.pos127;);else if(n===e.Bytes)this.pos=this.readVarint()+this.pos;else if(n===e.Fixed32)this.pos+=4;else{if(n!==e.Fixed64)throw new Error("Unimplemented type: "+n);this.pos+=8}},writeTag:function(t,n){this.writeVarint(t<<3|n)},realloc:function(t){for(var n=this.length||16;n268435455||t<0?function(t,n){var i,r;t>=0?(i=t%4294967296|0,r=t/4294967296|0):(r=~(-t/4294967296),4294967295^(i=~(-t%4294967296))?i=i+1|0:(i=0,r=r+1|0));if(t>=0x10000000000000000||t<-0x10000000000000000)throw new Error("Given varint doesn't fit into 10 bytes");n.realloc(10),function(t,n,i){i.buf[i.pos++]=127&t|128,t>>>=7,i.buf[i.pos++]=127&t|128,t>>>=7,i.buf[i.pos++]=127&t|128,t>>>=7,i.buf[i.pos++]=127&t|128,t>>>=7,i.buf[i.pos]=127&t}(i,0,n),function(t,n){var i=(7&t)<<4;if(n.buf[n.pos++]|=i|((t>>>=3)?128:0),!t)return;if(n.buf[n.pos++]=127&t|((t>>>=7)?128:0),!t)return;if(n.buf[n.pos++]=127&t|((t>>>=7)?128:0),!t)return;if(n.buf[n.pos++]=127&t|((t>>>=7)?128:0),!t)return;if(n.buf[n.pos++]=127&t|((t>>>=7)?128:0),!t)return;n.buf[n.pos++]=127&t}(r,n)}(t,this):(this.realloc(4),this.buf[this.pos++]=127&t|(t>127?128:0),t<=127||(this.buf[this.pos++]=127&(t>>>=7)|(t>127?128:0),t<=127||(this.buf[this.pos++]=127&(t>>>=7)|(t>127?128:0),t<=127||(this.buf[this.pos++]=t>>>7&127))))},writeSVarint:function(t){this.writeVarint(t<0?2*-t-1:2*t)},writeBoolean:function(t){this.writeVarint(Boolean(t))},writeString:function(t){t=String(t),this.realloc(4*t.length),this.pos++;var n=this.pos;this.pos=function(t,n,i){for(var r,e,o=0;o55295&&r<57344){if(!e){r>56319||o+1===n.length?(t[i++]=239,t[i++]=191,t[i++]=189):e=r;continue}if(r<56320){t[i++]=239,t[i++]=191,t[i++]=189,e=r;continue}r=e-55296<<10|r-56320|65536,e=null}else e&&(t[i++]=239,t[i++]=191,t[i++]=189,e=null);r<128?t[i++]=r:(r<2048?t[i++]=r>>6|192:(r<65536?t[i++]=r>>12|224:(t[i++]=r>>18|240,t[i++]=r>>12&63|128),t[i++]=r>>6&63|128),t[i++]=63&r|128)}return i}(this.buf,t,this.pos);var i=this.pos-n;i>=128&&f(n,i,this),this.pos=n-1,this.writeVarint(i),this.pos+=i},writeFloat:function(t){this.realloc(4),r.write(this.buf,t,this.pos,!0,23,4),this.pos+=4},writeDouble:function(t){this.realloc(8),r.write(this.buf,t,this.pos,!0,52,8),this.pos+=8},writeBytes:function(t){var n=t.length;this.writeVarint(n),this.realloc(n);for(var i=0;i=128&&f(i,r,this),this.pos=i-1,this.writeVarint(r),this.pos+=r},writeMessage:function(t,n,i){this.writeTag(t,e.Bytes),this.writeRawMessage(n,i)},writePackedVarint:function(t,n){n.length&&this.writeMessage(t,c,n)},writePackedSVarint:function(t,n){n.length&&this.writeMessage(t,l,n)},writePackedBoolean:function(t,n){n.length&&this.writeMessage(t,p,n)},writePackedFloat:function(t,n){n.length&&this.writeMessage(t,v,n)},writePackedDouble:function(t,n){n.length&&this.writeMessage(t,d,n)},writePackedFixed32:function(t,n){n.length&&this.writeMessage(t,y,n)},writePackedSFixed32:function(t,n){n.length&&this.writeMessage(t,m,n)},writePackedFixed64:function(t,n){n.length&&this.writeMessage(t,w,n)},writePackedSFixed64:function(t,n){n.length&&this.writeMessage(t,g,n)},writeBytesField:function(t,n){this.writeTag(t,e.Bytes),this.writeBytes(n)},writeFixed32Field:function(t,n){this.writeTag(t,e.Fixed32),this.writeFixed32(n)},writeSFixed32Field:function(t,n){this.writeTag(t,e.Fixed32),this.writeSFixed32(n)},writeFixed64Field:function(t,n){this.writeTag(t,e.Fixed64),this.writeFixed64(n)},writeSFixed64Field:function(t,n){this.writeTag(t,e.Fixed64),this.writeSFixed64(n)},writeVarintField:function(t,n){this.writeTag(t,e.Varint),this.writeVarint(n)},writeSVarintField:function(t,n){this.writeTag(t,e.Varint),this.writeSVarint(n)},writeStringField:function(t,n){this.writeTag(t,e.Bytes),this.writeString(n)},writeFloatField:function(t,n){this.writeTag(t,e.Fixed32),this.writeFloat(n)},writeDoubleField:function(t,n){this.writeTag(t,e.Fixed64),this.writeDouble(n)},writeBooleanField:function(t,n){this.writeVarintField(t,Boolean(n))}}},72:function(t){t.exports=function(){"use strict";function t(t,r,e,o,s){!function t(i,r,e,o,s){for(;o>e;){if(o-e>600){var u=o-e+1,a=r-e+1,h=Math.log(u),f=.5*Math.exp(2*h/3),c=.5*Math.sqrt(h*f*(u-f)/u)*(a-u/2<0?-1:1);t(i,r,Math.max(e,Math.floor(r-a*f/u+c)),Math.min(o,Math.floor(r+(u-a)*f/u+c)),s)}var l=i[r],v=e,d=o;for(n(i,e,r),s(i[o],l)>0&&n(i,e,o);v0;)d--}0===s(i[e],l)?n(i,e,d):n(i,++d,o),d<=r&&(e=d+1),r<=d&&(o=d-1)}}(t,r,e||0,o||t.length-1,s||i)}function n(t,n,i){var r=t[n];t[n]=t[i],t[i]=r}function i(t,n){return tn?1:0}var r=function(t){void 0===t&&(t=9),this._maxEntries=Math.max(4,t),this._minEntries=Math.max(2,Math.ceil(.4*this._maxEntries)),this.clear()};function e(t,n,i){if(!i)return n.indexOf(t);for(var r=0;r=t.minX&&n.maxY>=t.minY}function d(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function p(n,i,r,e,o){for(var s=[i,r];s.length;)if(!((r=s.pop())-(i=s.pop())<=e)){var u=i+Math.ceil((r-i)/e/2)*e;t(n,u,i,r,o),s.push(i,u,u,r)}}return r.prototype.all=function(){return this._all(this.data,[])},r.prototype.search=function(t){var n=this.data,i=[];if(!v(t,n))return i;for(var r=this.toBBox,e=[];n;){for(var o=0;o=0&&e[n].children.length>this._maxEntries;)this._split(e,n),n--;this._adjustParentBBoxes(r,e,n)},r.prototype._split=function(t,n){var i=t[n],r=i.children.length,e=this._minEntries;this._chooseSplitAxis(i,e,r);var s=this._chooseSplitIndex(i,e,r),u=d(i.children.splice(s,i.children.length-s));u.height=i.height,u.leaf=i.leaf,o(i,this.toBBox),o(u,this.toBBox),n?t[n-1].children.push(u):this._splitRoot(i,u)},r.prototype._splitRoot=function(t,n){this.data=d([t,n]),this.data.height=t.height+1,this.data.leaf=!1,o(this.data,this.toBBox)},r.prototype._chooseSplitIndex=function(t,n,i){for(var r,e,o,u,a,h,c,l=1/0,v=1/0,d=n;d<=i-n;d++){var p=s(t,0,d,this.toBBox),y=s(t,d,i,this.toBBox),m=(e=p,o=y,u=void 0,a=void 0,h=void 0,c=void 0,u=Math.max(e.minX,o.minX),a=Math.max(e.minY,o.minY),h=Math.min(e.maxX,o.maxX),c=Math.min(e.maxY,o.maxY),Math.max(0,h-u)*Math.max(0,c-a)),w=f(p)+f(y);m=n;v--){var d=t.children[v];u(a,t.leaf?e(d):d),h+=c(a)}return h},r.prototype._adjustParentBBoxes=function(t,n,i){for(var r=i;r>=0;r--)u(n[r],t)},r.prototype._condense=function(t){for(var n=t.length-1,i=void 0;n>=0;n--)0===t[n].children.length?n>0?(i=t[n-1].children).splice(i.indexOf(t[n]),1):this.clear():o(t[n],this.toBBox)},r}()},760:function(t){var n=function(t){"use strict";var n,i=Object.prototype,r=i.hasOwnProperty,e="function"==typeof Symbol?Symbol:{},o=e.iterator||"@@iterator",s=e.asyncIterator||"@@asyncIterator",u=e.toStringTag||"@@toStringTag";function a(t,n,i){return Object.defineProperty(t,n,{value:i,enumerable:!0,configurable:!0,writable:!0}),t[n]}try{a({},"")}catch(t){a=function(t,n,i){return t[n]=i}}function h(t,n,i,r){var e=n&&n.prototype instanceof y?n:y,o=Object.create(e.prototype),s=new T(r||[]);return o._invoke=function(t,n,i){var r=c;return function(e,o){if(r===v)throw new Error("Generator is already running");if(r===d){if("throw"===e)throw o;return P()}for(i.method=e,i.arg=o;;){var s=i.delegate;if(s){var u=O(s,i);if(u){if(u===p)continue;return u}}if("next"===i.method)i.sent=i._sent=i.arg;else if("throw"===i.method){if(r===c)throw r=d,i.arg;i.dispatchException(i.arg)}else"return"===i.method&&i.abrupt("return",i.arg);r=v;var a=f(t,n,i);if("normal"===a.type){if(r=i.done?d:l,a.arg===p)continue;return{value:a.arg,done:i.done}}"throw"===a.type&&(r=d,i.method="throw",i.arg=a.arg)}}}(t,i,s),o}function f(t,n,i){try{return{type:"normal",arg:t.call(n,i)}}catch(t){return{type:"throw",arg:t}}}t.wrap=h;var c="suspendedStart",l="suspendedYield",v="executing",d="completed",p={};function y(){}function m(){}function w(){}var g={};a(g,o,(function(){return this}));var b=Object.getPrototypeOf,x=b&&b(b(A([])));x&&x!==i&&r.call(x,o)&&(g=x);var M=w.prototype=y.prototype=Object.create(g);function _(t){["next","throw","return"].forEach((function(n){a(t,n,(function(t){return this._invoke(n,t)}))}))}function S(t,n){function i(e,o,s,u){var a=f(t[e],t,o);if("throw"!==a.type){var h=a.arg,c=h.value;return c&&"object"==typeof c&&r.call(c,"__await")?n.resolve(c.__await).then((function(t){i("next",t,s,u)}),(function(t){i("throw",t,s,u)})):n.resolve(c).then((function(t){h.value=t,s(h)}),(function(t){return i("throw",t,s,u)}))}u(a.arg)}var e;this._invoke=function(t,r){function o(){return new n((function(n,e){i(t,r,n,e)}))}return e=e?e.then(o,o):o()}}function O(t,i){var r=t.iterator[i.method];if(r===n){if(i.delegate=null,"throw"===i.method){if(t.iterator.return&&(i.method="return",i.arg=n,O(t,i),"throw"===i.method))return p;i.method="throw",i.arg=new TypeError("The iterator does not provide a 'throw' method")}return p}var e=f(r,t.iterator,i.arg);if("throw"===e.type)return i.method="throw",i.arg=e.arg,i.delegate=null,p;var o=e.arg;return o?o.done?(i[t.resultName]=o.value,i.next=t.nextLoc,"return"!==i.method&&(i.method="next",i.arg=n),i.delegate=null,p):o:(i.method="throw",i.arg=new TypeError("iterator result is not an object"),i.delegate=null,p)}function j(t){var n={tryLoc:t[0]};1 in t&&(n.catchLoc=t[1]),2 in t&&(n.finallyLoc=t[2],n.afterLoc=t[3]),this.tryEntries.push(n)}function E(t){var n=t.completion||{};n.type="normal",delete n.arg,t.completion=n}function T(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(j,this),this.reset(!0)}function A(t){if(t){var i=t[o];if(i)return i.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var e=-1,s=function i(){for(;++e=0;--o){var s=this.tryEntries[o],u=s.completion;if("root"===s.tryLoc)return e("end");if(s.tryLoc<=this.prev){var a=r.call(s,"catchLoc"),h=r.call(s,"finallyLoc");if(a&&h){if(this.prev=0;--i){var e=this.tryEntries[i];if(e.tryLoc<=this.prev&&r.call(e,"finallyLoc")&&this.prev=0;--n){var i=this.tryEntries[n];if(i.finallyLoc===t)return this.complete(i.completion,i.afterLoc),E(i),p}},catch:function(t){for(var n=this.tryEntries.length-1;n>=0;--n){var i=this.tryEntries[n];if(i.tryLoc===t){var r=i.completion;if("throw"===r.type){var e=r.arg;E(i)}return e}}throw new Error("illegal catch attempt")},delegateYield:function(t,i,r){return this.delegate={iterator:A(t),resultName:i,nextLoc:r},"next"===this.method&&(this.arg=n),p}},t}(t.exports);try{regeneratorRuntime=n}catch(t){"object"==typeof globalThis?globalThis.regeneratorRuntime=n:Function("r","regeneratorRuntime = r")(n)}},617:function(t,n,i){const r=i(279);t.exports=function(t,n,i){const e=i&&i.debug||!1,o=i&&i.startIndex||0;e&&console.log("starting findTagByName with",n," and ",i);const s=r(t,`<${n}[ >]`,o);if(e&&console.log("start:",s),-1===s)return;const u=t.slice(s+n.length);let a=r(u,"[ /]"+n+">",0);const h=-1===a;h&&(a=r(u,"[ /]>",0));const f=s+n.length+a+1+(h?0:n.length)+1;if(e&&console.log("end:",f),-1===f)return;const c=t.slice(s,f);let l;return l=h?null:c.slice(c.indexOf(">")+1,c.lastIndexOf("<")),{inner:l,outer:c,start:s,end:f}}},51:function(t,n,i){const r=i(617);t.exports=function(t,n,i){const e=[],o=i&&i.debug||!1;let s,u=i&&i.startIndex||0;for(;s=r(t,n,{debug:o,startIndex:u});)u=s.end,e.push(s);return o&&console.log("findTagsByName found",e.length,"tags"),e}},802:function(t){t.exports=function(t,n,i){const r=i&&i.debug||!1;r&&console.log("getting "+n+" in "+t);const e="object"==typeof t?t.outer:t,o=`${n}\\="([^"]*)"`;r&&console.log("pattern:",o);const s=new RegExp(o).exec(e);if(r&&console.log("match:",s),s)return s[1]}},279:function(t){t.exports=function(t,n,i){const r=new RegExp(n).exec(t.slice(i));return r?i+r.index:-1}},518:function(t){"use strict";t.exports=function(t){t.prototype[Symbol.iterator]=function*(){for(let t=this.head;t;t=t.next)yield t.value}}},692:function(t,n,i){"use strict";function r(t){var n=this;if(n instanceof r||(n=new r),n.tail=null,n.head=null,n.length=0,t&&"function"==typeof t.forEach)t.forEach((function(t){n.push(t)}));else if(arguments.length>0)for(var i=0,e=arguments.length;i1)i=n;else{if(!this.head)throw new TypeError("Reduce of empty list with no initial value");r=this.head.next,i=this.head.value}for(var e=0;null!==r;e++)i=t(i,r.value,e),r=r.next;return i},r.prototype.reduceReverse=function(t,n){var i,r=this.tail;if(arguments.length>1)i=n;else{if(!this.tail)throw new TypeError("Reduce of empty list with no initial value");r=this.tail.prev,i=this.tail.value}for(var e=this.length-1;null!==r;e--)i=t(i,r.value,e),r=r.prev;return i},r.prototype.toArray=function(){for(var t=new Array(this.length),n=0,i=this.head;null!==i;n++)t[n]=i.value,i=i.next;return t},r.prototype.toArrayReverse=function(){for(var t=new Array(this.length),n=0,i=this.tail;null!==i;n++)t[n]=i.value,i=i.prev;return t},r.prototype.slice=function(t,n){(n=n||this.length)<0&&(n+=this.length),(t=t||0)<0&&(t+=this.length);var i=new r;if(nthis.length&&(n=this.length);for(var e=0,o=this.head;null!==o&&ethis.length&&(n=this.length);for(var e=this.length,o=this.tail;null!==o&&e>n;e--)o=o.prev;for(;null!==o&&e>t;e--,o=o.prev)i.push(o.value);return i},r.prototype.splice=function(t,n){t>this.length&&(t=this.length-1),t<0&&(t=this.length+t);for(var i=0,r=this.head;null!==r&&i>1)],n))<0?s=r+1:(u=r,a=!e);return a?s:~s}function p(t,n){return t>n?1:t=0}function m(t,n,i){var r=t.length;if(t[0]<=n)return 0;if(n<=t[r-1])return r-1;var e=void 0;if(i>0){for(e=1;e0?e-1:e:t[e-1]-n>>0,e=0;e0||i&&0===o)}))}function S(){return!0}function O(){return!1}function j(){}function E(t){var n,i,r,e=!1;return function(){var o=Array.prototype.slice.call(arguments);return e&&this===r&&x(o,i)||(e=!0,r=this,i=o,n=t.apply(this,arguments)),n}}function T(t){return function(){var n;try{n=t()}catch(t){return Promise.reject(t)}return n instanceof Promise?n:Promise.resolve(n)}()}var A="function"==typeof Object.assign?Object.assign:function(t,n){if(null==t)throw new TypeError("Cannot convert undefined or null to object");for(var i=Object(t),r=1,e=arguments.length;r0)},n.prototype.removeEventListener=function(t,n){var i=this.O&&this.O[t];if(i){var r=i.indexOf(n);-1!==r&&(this._&&t in this._?(i[r]=j,++this._[t]):(i.splice(r,1),0===i.length&&delete this.O[t]))}},n}(v),L="change",z="error",R="contextmenu",F="click",G="dblclick",D="dragenter",q="dragover",U="drop",B="keydown",X="keypress",V="load",W="resize",Y="touchmove",Z="wheel";function $(t,n,i,r,e){if(r&&r!==t&&(i=i.bind(r)),e){var o=i;i=function(){t.removeEventListener(n,i),o.apply(this,arguments)}}var s={target:t,type:n,listener:i};return t.addEventListener(n,i),s}function K(t,n,i,r){return $(t,n,i,r,!0)}function H(t){t&&t.target&&(t.target.removeEventListener(t.type,t.listener),P(t))}var J=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Q=function(t){function n(){var n=t.call(this)||this;return n.on=n.onInternal,n.once=n.onceInternal,n.un=n.unInternal,n.T=0,n}return J(n,t),n.prototype.changed=function(){++this.T,this.dispatchEvent(L)},n.prototype.getRevision=function(){return this.T},n.prototype.onInternal=function(t,n){if(Array.isArray(t)){for(var i=t.length,r=new Array(i),e=0;e0;)this.pop()},n.prototype.extend=function(t){for(var n=0,i=t.length;nt)throw new Error("Tile load sequence violation");this.state=t,this.changed()},n.prototype.load=function(){r()},n.prototype.getAlpha=function(t,n){if(!this.D)return 1;var i=this.q[t];if(i){if(-1===i)return 1}else i=n,this.q[t]=i;var r=n-i+1e3/60;return r>=this.D?1:yt(r/this.D)},n.prototype.inTransition=function(t){return!!this.D&&-1!==this.q[t]},n.prototype.endTransition=function(t){this.D&&(this.q[t]=-1)},n}(N),Mt=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),_t=function(t){function n(n){var i=this,r=ct;return(i=t.call(this,n.tileCoord,r,{transition:n.transition,interpolate:n.interpolate})||this).U=n.loader,i.B=null,i.V=null,i.W=n.size||[256,256],i}return Mt(n,t),n.prototype.getSize=function(){return this.W},n.prototype.getData=function(){return this.B},n.prototype.getError=function(){return this.V},n.prototype.load=function(){if(this.state===ct||this.state===dt){this.state=lt,this.changed();var t=this;this.U().then((function(n){t.B=n,t.state=vt,t.changed()})).catch((function(n){t.V=n,t.state=dt,t.changed()}))}},n}(xt);function St(t,n){if(!t)throw new h(n)}var Ot=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}();function jt(t){return"function"==typeof t?t:(Array.isArray(t)?n=t:(St("function"==typeof t.getZIndex,41),n=[t]),function(){return n});var n}var Et=function(t){function n(n){var i=t.call(this)||this;if(i.on,i.once,i.un,i.$=void 0,i.K="geometry",i.H=null,i.tt=void 0,i.nt=null,i.addChangeListener(i.K,i.it),n)if("function"==typeof n.getSimplifiedGeometry){var r=n;i.setGeometry(r)}else{var e=n;i.setProperties(e)}return i}return Ot(n,t),n.prototype.clone=function(){var t=new n(this.hasProperties()?this.getProperties():null);t.setGeometryName(this.getGeometryName());var i=this.getGeometry();i&&t.setGeometry(i.clone());var r=this.getStyle();return r&&t.setStyle(r),t},n.prototype.getGeometry=function(){return this.get(this.K)},n.prototype.getId=function(){return this.$},n.prototype.getGeometryName=function(){return this.K},n.prototype.getStyle=function(){return this.H},n.prototype.getStyleFunction=function(){return this.tt},n.prototype.rt=function(){this.changed()},n.prototype.it=function(){this.nt&&(H(this.nt),this.nt=null);var t=this.getGeometry();t&&(this.nt=$(t,L,this.rt,this)),this.changed()},n.prototype.setGeometry=function(t){this.set(this.K,t)},n.prototype.setStyle=function(t){this.H=t,this.tt=t?jt(t):void 0,this.changed()},n.prototype.setId=function(t){this.$=t,this.changed()},n.prototype.setGeometryName=function(t){this.removeChangeListener(this.K,this.it),this.K=t,this.addChangeListener(this.K,this.it),this.it()},n}(et),Tt="XY",At="XYZ",Pt="XYM",Ct="XYZM",kt={RADIANS:"radians",DEGREES:"degrees",FEET:"ft",METERS:"m",PIXELS:"pixels",TILE_PIXELS:"tile-pixels",USFEET:"us-ft"},It={9001:kt.METERS,9002:kt.FEET,9003:kt.USFEET,9101:kt.RADIANS,9102:kt.DEGREES};function Nt(t){return It[t]}var Lt={};Lt[kt.RADIANS]=6370997/(2*Math.PI),Lt[kt.DEGREES]=2*Math.PI*6370997/360,Lt[kt.FEET]=.3048,Lt[kt.METERS]=1,Lt[kt.USFEET]=1200/3937;var zt,Rt=kt,Ft="undefined"!=typeof navigator&&void 0!==navigator.userAgent?navigator.userAgent.toLowerCase():"",Gt=-1!==Ft.indexOf("firefox"),Dt=-1!==Ft.indexOf("safari")&&-1==Ft.indexOf("chrom"),qt=Dt&&!!(Ft.indexOf("version/15.4")>=0||Ft.match(/cpu (os|iphone os) 15_4 like mac os x/)),Ut=-1!==Ft.indexOf("webkit")&&-1==Ft.indexOf("edge"),Bt=-1!==Ft.indexOf("macintosh"),Xt="undefined"!=typeof devicePixelRatio?devicePixelRatio:1,Vt="undefined"!=typeof WorkerGlobalScope&&"undefined"!=typeof OffscreenCanvas&&self instanceof WorkerGlobalScope,Wt="undefined"!=typeof Image&&Image.prototype.decode,Yt=function(){var t=!1;try{var n=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("_",null,n),window.removeEventListener("_",null,n)}catch(t){}return t}(),Zt=new Array(6);function $t(){return[1,0,0,1,0,0]}function Kt(t){return Jt(t,1,0,0,1,0,0)}function Ht(t,n){var i=t[0],r=t[1],e=t[2],o=t[3],s=t[4],u=t[5],a=n[0],h=n[1],f=n[2],c=n[3],l=n[4],v=n[5];return t[0]=i*a+e*h,t[1]=r*a+o*h,t[2]=i*f+e*c,t[3]=r*f+o*c,t[4]=i*l+e*v+s,t[5]=r*l+o*v+u,t}function Jt(t,n,i,r,e,o,s){return t[0]=n,t[1]=i,t[2]=r,t[3]=e,t[4]=o,t[5]=s,t}function Qt(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t}function tn(t,n){var i=n[0],r=n[1];return n[0]=t[0]*i+t[2]*r+t[4],n[1]=t[1]*i+t[3]*r+t[5],n}function nn(t,n){var i=Math.cos(n),r=Math.sin(n);return Ht(t,Jt(Zt,i,r,-r,i,0,0))}function rn(t,n,i){return Ht(t,Jt(Zt,n,0,0,i,0,0))}function en(t,n,i){return Jt(t,n,0,0,i,0,0)}function on(t,n,i){return Ht(t,Jt(Zt,1,0,0,1,n,i))}function sn(t,n,i,r,e,o,s,u){var a=Math.sin(o),h=Math.cos(o);return t[0]=r*h,t[1]=e*a,t[2]=-r*a,t[3]=e*h,t[4]=s*r*h-u*r*a+n,t[5]=s*e*a+u*e*h+i,t}function un(t,n){var i=an(n);St(0!==i,32);var r=n[0],e=n[1],o=n[2],s=n[3],u=n[4],a=n[5];return t[0]=s/i,t[1]=-e/i,t[2]=-o/i,t[3]=r/i,t[4]=(o*a-s*u)/i,t[5]=-(r*a-e*u)/i,t}function an(t){return t[0]*t[3]-t[1]*t[2]}function hn(t){var n="matrix("+t.join(", ")+")";if(Vt)return n;var i=zt||(zt=document.createElement("div"));return i.style.transform=n,i.style.transform}var fn=0,cn=1,ln=2,vn=4,dn=8,pn=16;function yn(t){for(var n=Sn(),i=0,r=t.length;ie&&(a|=vn),uo&&(a|=ln),a===fn&&(a=cn),a}function Sn(){return[1/0,1/0,-1/0,-1/0]}function On(t,n,i,r,e){return e?(e[0]=t,e[1]=n,e[2]=i,e[3]=r,e):[t,n,i,r]}function jn(t){return On(1/0,1/0,-1/0,-1/0,t)}function En(t,n){var i=t[0],r=t[1];return On(i,r,i,r,n)}function Tn(t,n,i,r,e){return Nn(jn(e),t,n,i,r)}function An(t,n){return t[0]==n[0]&&t[2]==n[2]&&t[1]==n[1]&&t[3]==n[3]}function Pn(t,n,i){return Math.abs(t[0]-n[0])t[2]&&(t[2]=n[2]),n[1]t[3]&&(t[3]=n[3]),t}function kn(t,n){n[0]t[2]&&(t[2]=n[0]),n[1]t[3]&&(t[3]=n[1])}function In(t,n){for(var i=0,r=n.length;in[0]?r[0]=t[0]:r[0]=n[0],t[1]>n[1]?r[1]=t[1]:r[1]=n[1],t[2]=n[0]&&t[1]<=n[3]&&t[3]>=n[1]}function Hn(t){return t[2]=s&&p<=a),r||!(o&vn)||e&vn||(r=(y=v-(l-a)*d)>=u&&y<=h),r||!(o&dn)||e&dn||(r=(p=l-(v-u)/d)>=s&&p<=a),r||!(o&pn)||e&pn||(r=(y=v-(l-s)*d)>=u&&y<=h)}return r}function ni(t,n,i,r){var e=[];if(r>1)for(var o=t[2]-t[0],s=t[3]-t[1],u=0;u=i[2])){var e=$n(i),o=Math.floor((r[0]-i[0])/e)*e;t[0]-=o,t[2]-=o}return t}function ri(t,n){if(n.canWrapX()){var i=n.getExtent();if(!isFinite(t[0])||!isFinite(t[2]))return[[i[0],t[1],i[2],t[3]]];ii(t,n);var r=$n(i);if($n(t)>r)return[[i[0],t[1],i[2],t[3]]];if(t[0]i[2])return[[t[0],t[1],i[2],t[3]],[i[0],t[1],t[2]-r,t[3]]]}return[t]}var ei=function(){function t(t){this.et=t.code,this.ot=t.units,this.st=void 0!==t.extent?t.extent:null,this.ut=void 0!==t.worldExtent?t.worldExtent:null,this.ht=void 0!==t.axisOrientation?t.axisOrientation:"enu",this.ft=void 0!==t.global&&t.global,this.ct=!(!this.ft||!this.st),this.lt=t.getPointResolution,this.vt=null,this.dt=t.metersPerUnit}return t.prototype.canWrapX=function(){return this.ct},t.prototype.getCode=function(){return this.et},t.prototype.getExtent=function(){return this.st},t.prototype.getUnits=function(){return this.ot},t.prototype.getMetersPerUnit=function(){return this.dt||Lt[this.ot]},t.prototype.getWorldExtent=function(){return this.ut},t.prototype.getAxisOrientation=function(){return this.ht},t.prototype.isGlobal=function(){return this.ft},t.prototype.setGlobal=function(t){this.ft=t,this.ct=!(!t||!this.st)},t.prototype.getDefaultTileGrid=function(){return this.vt},t.prototype.setDefaultTileGrid=function(t){this.vt=t},t.prototype.setExtent=function(t){this.st=t,this.ct=!(!this.ft||!t)},t.prototype.setWorldExtent=function(t){this.ut=t},t.prototype.setGetPointResolution=function(t){this.lt=t},t.prototype.getPointResolutionFunc=function(){return this.lt},t}();function oi(t,n,i){return Math.min(Math.max(t,n),i)}var si="cosh"in Math?Math.cosh:function(t){var n=Math.exp(t);return(n+1/n)/2},ui="log2"in Math?Math.log2:function(t){return Math.log(t)*Math.LOG2E};function ai(t,n,i,r,e,o){var s=e-i,u=o-r;if(0!==s||0!==u){var a=((t-i)*s+(n-r)*u)/(s*s+u*u);a>1?(i=e,r=o):a>0&&(i+=s*a,r+=u*a)}return hi(t,n,i,r)}function hi(t,n,i,r){var e=i-t,o=r-n;return e*e+o*o}function fi(t){for(var n=t.length,i=0;ie&&(e=s,r=o)}if(0===e)return null;var u=t[r];t[r]=t[i],t[i]=u;for(var a=i+1;a=0;l--){c[l]=t[l][n]/t[l][l];for(var v=l-1;v>=0;v--)t[v][n]-=t[v][l]*c[l]}return c}function ci(t){return 180*t/Math.PI}function li(t){return t*Math.PI/180}function vi(t,n){var i=t%n;return i*n<0?i+n:i}function di(t,n,i){return t+i*(n-t)}function pi(t,n){var i=Math.pow(10,n);return Math.round(t*i)/i}function yi(t,n){return Math.round(pi(t,n))}function mi(t,n){return Math.floor(pi(t,n))}function wi(t,n){return Math.ceil(pi(t,n))}var gi=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),bi=6378137,xi=Math.PI*bi,Mi=[-xi,-xi,xi,xi],_i=[-180,-85,180,85],Si=bi*Math.log(Math.tan(Math.PI/2)),Oi=function(t){function n(n){return t.call(this,{code:n,units:Rt.METERS,extent:Mi,global:!0,worldExtent:_i,getPointResolution:function(t,n){return t/si(n[1]/bi)}})||this}return gi(n,t),n}(ei),ji=[new Oi("EPSG:3857"),new Oi("EPSG:102100"),new Oi("EPSG:102113"),new Oi("EPSG:900913"),new Oi("http://www.opengis.net/def/crs/EPSG/0/3857"),new Oi("http://www.opengis.net/gml/srs/epsg.xml#3857")];function Ei(t,n,i){var r=t.length,e=i>1?i:2,o=n;void 0===o&&(o=e>2?t.slice():new Array(r));for(var s=0;sSi?u=Si:u<-Si&&(u=-Si),o[s+1]=u}return o}function Ti(t,n,i){var r=t.length,e=i>1?i:2,o=n;void 0===o&&(o=e>2?t.slice():new Array(r));for(var s=0;sn?r:new Array(1+n-e).join("0")+r}function Xi(t,n){for(var i=(""+t).split("."),r=(""+n).split("."),e=0;es)return 1;if(s>o)return-1}return 0}function Vi(t,n){return t[0]+=+n[0],t[1]+=+n[1],t}function Wi(t,n){var i=n.getRadius(),r=n.getCenter(),e=r[0],o=r[1],s=t[0]-e,u=t[1]-o;0===s&&0===u&&(s=1);var a=Math.sqrt(s*s+u*u);return[e+i*s/a,o+i*u/a]}function Yi(t,n){var i,r,e=t[0],o=t[1],s=n[0],u=n[1],a=s[0],h=s[1],f=u[0],c=u[1],l=f-a,v=c-h,d=0===l&&0===v?0:(l*(e-a)+v*(o-h))/(l*l+v*v||0);return d<=0?(i=a,r=h):d>=1?(i=f,r=c):(i=a+d*l,r=h+d*v),[i,r]}function Zi(t,n,i){var r=vi(n+180,360)-180,e=Math.abs(3600*r),o=i||0,s=Math.pow(10,o),u=Math.floor(e/3600),a=Math.floor((e-3600*u)/60),h=e-3600*u-60*a;return(h=Math.ceil(h*s)/s)>=60&&(h=0,a+=1),a>=60&&(a=0,u+=1),u+"° "+Bi(a,2)+"′ "+Bi(h,2,o)+"″"+(0==r?"":" "+t.charAt(r<0?1:0))}function $i(t,n,i){return t?n.replace("{x}",t[0].toFixed(i)).replace("{y}",t[1].toFixed(i)):""}function Ki(t,n){for(var i=!0,r=t.length-1;r>=0;--r)if(t[r]!=n[r]){i=!1;break}return i}function Hi(t,n){var i=Math.cos(n),r=Math.sin(n),e=t[0]*i-t[1]*r,o=t[1]*i+t[0]*r;return t[0]=e,t[1]=o,t}function Ji(t,n){return t[0]*=n,t[1]*=n,t}function Qi(t,n){var i=t[0]-n[0],r=t[1]-n[1];return i*i+r*r}function tr(t,n){return Math.sqrt(Qi(t,n))}function nr(t,n){return Qi(t,Yi(t,n))}function ir(t,n){return $i(t,"{x}, {y}",n)}function rr(t,n){if(n.canWrapX()){var i=$n(n.getExtent()),r=er(t,n,i);r&&(t[0]-=r*i)}return t}function er(t,n,i){var r=n.getExtent(),e=0;if(n.canWrapX()&&(t[0]r[2])){var o=i||$n(r);e=Math.floor((t[0]-r[0])/o)}return e}var or=6371008.8;function sr(t,n,i){var r=i||or,e=li(t[1]),o=li(n[1]),s=(o-e)/2,u=li(n[0]-t[0])/2,a=Math.sin(s)*Math.sin(s)+Math.sin(u)*Math.sin(u)*Math.cos(e)*Math.cos(o);return 2*r*Math.atan2(Math.sqrt(a),Math.sqrt(1-a))}function ur(t,n){for(var i=0,r=0,e=t.length;r=h?n[u+f]:a[f];return s}}function Mr(t,n,i,r){var e=yr(t),o=yr(n);qi(e,o,xr(i)),qi(o,e,xr(r))}function _r(t,n){return cr(),Er(t,"EPSG:4326",void 0!==n?n:"EPSG:3857")}function Sr(t,n){if(t===n)return!0;var i=t.getUnits()===n.getUnits();return(t.getCode()===n.getCode()||Or(t,n)===lr)&&i}function Or(t,n){var i=Ui(t.getCode(),n.getCode());return i||(i=vr),i}function jr(t,n){return Or(yr(t),yr(n))}function Er(t,n,i){return jr(n,i)(t,void 0,t.length)}function Tr(t,n,i,r){return ni(t,jr(n,i),void 0,r)}var Ar=null;function Pr(t){Ar=yr(t)}function Cr(){return Ar}function kr(t,n){return Ar?Er(t,n,Ar):t}function Ir(t,n){return Ar?Er(t,Ar,n):(fr&&!Ki(t,[0,0])&&t[0]>=-180&&t[0]<=180&&t[1]>=-90&&t[1]<=90&&(fr=!1,console.warn("Call useGeographic() from ol/proj once to work with [longitude, latitude] coordinates.")),t)}function Nr(t,n){return Ar?Tr(t,n,Ar):t}function Lr(t,n){return Ar?Tr(t,Ar,n):t}function zr(t,n){if(!Ar)return t;var i=yr(n).getUnits(),r=Ar.getUnits();return i&&r?t*Lt[i]/Lt[r]:t}function Rr(t,n){if(!Ar)return t;var i=yr(n).getUnits(),r=Ar.getUnits();return i&&r?t*Lt[r]/Lt[i]:t}function Fr(t,n,i){return function(r){var e,o;if(t.canWrapX()){var s=t.getExtent(),u=$n(s);(o=er(r=r.slice(0),t,u))&&(r[0]=r[0]-o*u),r[0]=oi(r[0],s[0],s[2]),r[1]=oi(r[1],s[1],s[3]),e=i(r)}else e=i(r);return o&&n.canWrapX()&&(e[0]+=o*$n(n.getExtent())),e}}function Gr(){wr(ji),wr(Ni),gr(Ni,ji,Ei,Ti)}function Dr(t,n,i,r,e,o){for(var s=o||[],u=0,a=n;a1)u=i;else{if(l>0){for(var v=0;ve&&(e=h),o=u,s=a}return e}function Qr(t,n,i,r,e){for(var o=0,s=i.length;o0;){for(var c=h.pop(),l=h.pop(),v=0,d=t[l],p=t[l+1],y=t[c],m=t[c+1],w=l+r;wv&&(f=w,v=g)}v>e&&(a[(f-n)/r]=1,l+re&&(o[s++]=h,o[s++]=f,u=h,a=f);return h==u&&f==a||(o[s++]=h,o[s++]=f),s}function ce(t,n){return n*Math.round(t/n)}function le(t,n,i,r,e,o,s){if(n==i)return s;var u,a,h=ce(t[n],e),f=ce(t[n+1],e);n+=r,o[s++]=h,o[s++]=f;do{if(u=ce(t[n],e),a=ce(t[n+1],e),(n+=r)==i)return o[s++]=u,o[s++]=a,s}while(u==h&&a==f);for(;n0&&p>v)&&(d<0&&y0&&y>d)?(u=c,a=l):(o[s++]=u,o[s++]=a,h=u,f=a,u=c,a=l)}}return o[s++]=u,o[s++]=a,s}function ve(t,n,i,r,e,o,s,u){for(var a=0,h=i.length;ao&&(h-u)*(o-a)-(e-u)*(f-a)>0&&s++:f<=o&&(h-u)*(o-a)-(e-u)*(f-a)<0&&s--,u=h,a=f}return 0!==s}function Ee(t,n,i,r,e,o){if(0===i.length)return!1;if(!je(t,n,i[0],r,e,o))return!1;for(var s=1,u=i.length;sx&&Ee(t,n,i,r,h=(f+c)/2,d)&&(b=h,x=M),f=c}return isNaN(b)&&(b=e[o]),s?(s.push(b,d,x),s):[b,d,x]}function Pe(t,n,i,r,e){for(var o=[],s=0,u=i.length;s=e[0]&&o[2]<=e[2]||(o[1]>=e[1]&&o[3]<=e[3]||Ce(t,n,i,r,(function(t,n){return ti(e,t,n)})))))}function Ie(t,n,i,r,e){for(var o=0,s=i.length;o0}function Ge(t,n,i,r,e){for(var o=void 0!==e&&e,s=0,u=i.length;s0&&this.Zt[i+2]>t;)i-=3;var r=this.Zt[n+2]-this.Zt[i+2];if(r<1e3/60)return!1;var e=this.Zt[n]-this.Zt[i],o=this.Zt[n+1]-this.Zt[i+1];return this.$t=Math.atan2(o,e),this.Kt=Math.sqrt(e*e+o*o)/r,this.Kt>this.Wt},t.prototype.getDistance=function(){return(this.Wt-this.Kt)/this.Vt},t.prototype.getAngle=function(){return this.$t},t}(),No=/^#([a-f0-9]{3}|[a-f0-9]{4}(?:[a-f0-9]{2}){0,2})$/i,Lo=/^([a-z]*)$|^hsla?\(.*\)$/i;function zo(t){return"string"==typeof t?t:qo(t)}function Ro(t){var n=document.createElement("div");if(n.style.color=t,""!==n.style.color){document.body.appendChild(n);var i=getComputedStyle(n).color;return document.body.removeChild(n),i}return""}var Fo=function(){var t={},n=0;return function(i){var r;if(t.hasOwnProperty(i))r=t[i];else{if(n>=1024){var e=0;for(var o in t)0==(3&e++)&&(delete t[o],--n)}r=function(t){var n,i,r,e,o;Lo.exec(t)&&(t=Ro(t));if(No.exec(t)){var s=t.length-1,u=void 0;u=s<=4?1:2;var a=4===s||8===s;n=parseInt(t.substr(1+0*u,u),16),i=parseInt(t.substr(1+1*u,u),16),r=parseInt(t.substr(1+2*u,u),16),e=a?parseInt(t.substr(1+3*u,u),16):255,1==u&&(n=(n<<4)+n,i=(i<<4)+i,r=(r<<4)+r,a&&(e=(e<<4)+e)),o=[n,i,r,e/255]}else 0==t.indexOf("rgba(")?Do(o=t.slice(5,-1).split(",").map(Number)):0==t.indexOf("rgb(")?((o=t.slice(4,-1).split(",").map(Number)).push(1),Do(o)):St(!1,14);return o}(i),t[i]=r,++n}return r}}();function Go(t){return Array.isArray(t)?t:Fo(t)}function Do(t){return t[0]=oi(t[0]+.5|0,0,255),t[1]=oi(t[1]+.5|0,0,255),t[2]=oi(t[2]+.5|0,0,255),t[3]=oi(t[3],0,1),t}function qo(t){var n=t[0];n!=(0|n)&&(n=n+.5|0);var i=t[1];i!=(0|i)&&(i=i+.5|0);var r=t[2];return r!=(0|r)&&(r=r+.5|0),"rgba("+n+","+i+","+r+","+(void 0===t[3]?1:Math.round(100*t[3])/100)+")"}function Uo(t){return Lo.test(t)&&(t=Ro(t)),No.test(t)||0===t.indexOf("rgba(")||0===t.indexOf("rgb(")}var Bo=function(){function t(){this.Ht={},this.Jt=0,this.Qt=32}return t.prototype.clear=function(){this.Ht={},this.Jt=0},t.prototype.canExpireCache=function(){return this.Jt>this.Qt},t.prototype.expire=function(){if(this.canExpireCache()){var t=0;for(var n in this.Ht){var i=this.Ht[n];0!=(3&t++)||i.hasListener()||(delete this.Ht[n],--this.Jt)}}},t.prototype.get=function(t,n,i){var r=Xo(t,n,i);return r in this.Ht?this.Ht[r]:null},t.prototype.set=function(t,n,i,r){var e=Xo(t,n,i);this.Ht[e]=r,++this.Jt},t.prototype.setSize=function(t){this.Qt=t,this.expire()},t}();function Xo(t,n,i){return n+":"+t+":"+(i?zo(i):"null")}var Vo=Bo,Wo=new Bo,Yo="opacity",Zo="visible",$o="extent",Ko="zIndex",Ho="maxResolution",Jo="minResolution",Qo="maxZoom",ts="minZoom",ns="source",is="map",rs=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),es=function(t){function n(n){var i=t.call(this)||this;i.on,i.once,i.un,i.tn=n.background;var r=A({},n);return"object"==typeof n.properties&&(delete r.properties,A(r,n.properties)),r[Yo]=void 0!==n.opacity?n.opacity:1,St("number"==typeof r[Yo],64),r[Zo]=void 0===n.visible||n.visible,r[Ko]=n.zIndex,r[Ho]=void 0!==n.maxResolution?n.maxResolution:1/0,r[Jo]=void 0!==n.minResolution?n.minResolution:0,r[ts]=void 0!==n.minZoom?n.minZoom:-1/0,r[Qo]=void 0!==n.maxZoom?n.maxZoom:1/0,i.nn=void 0!==r.className?r.className:"ol-layer",delete r.className,i.setProperties(r),i.rn=null,i}return rs(n,t),n.prototype.getBackground=function(){return this.tn},n.prototype.getClassName=function(){return this.nn},n.prototype.getLayerState=function(t){var n=this.rn||{layer:this,managed:void 0===t||t},i=this.getZIndex();return n.opacity=oi(Math.round(100*this.getOpacity())/100,0,1),n.visible=this.getVisible(),n.extent=this.getExtent(),n.zIndex=void 0!==i||n.managed?i:1/0,n.maxResolution=this.getMaxResolution(),n.minResolution=Math.max(this.getMinResolution(),0),n.minZoom=this.getMinZoom(),n.maxZoom=this.getMaxZoom(),this.rn=n,n},n.prototype.getLayersArray=function(t){return r()},n.prototype.getLayerStatesArray=function(t){return r()},n.prototype.getExtent=function(){return this.get($o)},n.prototype.getMaxResolution=function(){return this.get(Ho)},n.prototype.getMinResolution=function(){return this.get(Jo)},n.prototype.getMinZoom=function(){return this.get(ts)},n.prototype.getMaxZoom=function(){return this.get(Qo)},n.prototype.getOpacity=function(){return this.get(Yo)},n.prototype.getSourceState=function(){return r()},n.prototype.getVisible=function(){return this.get(Zo)},n.prototype.getZIndex=function(){return this.get(Ko)},n.prototype.setBackground=function(t){this.tn=t,this.changed()},n.prototype.setExtent=function(t){this.set($o,t)},n.prototype.setMaxResolution=function(t){this.set(Ho,t)},n.prototype.setMinResolution=function(t){this.set(Jo,t)},n.prototype.setMaxZoom=function(t){this.set(Qo,t)},n.prototype.setMinZoom=function(t){this.set(ts,t)},n.prototype.setOpacity=function(t){St("number"==typeof t,64),this.set(Yo,t)},n.prototype.setVisible=function(t){this.set(Zo,t)},n.prototype.setZIndex=function(t){this.set(Ko,t)},n.prototype.disposeInternal=function(){this.rn&&(this.rn.layer=null,this.rn=null),t.prototype.disposeInternal.call(this)},n}(et),os="prerender",ss="postrender",us="precompose",as="postcompose",hs="rendercomplete",fs=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}();function cs(t,n){if(!t.visible)return!1;var i=n.resolution;if(i=t.maxResolution)return!1;var r=n.zoom;return r>t.minZoom&&r<=t.maxZoom}var ls=function(t){function n(n){var i=this,r=A({},n);delete r.source,(i=t.call(this,r)||this).on,i.once,i.un,i.en=null,i.sn=null,i.an=null,i.hn=null,i.rendered=!1,n.render&&(i.render=n.render),n.map&&i.setMap(n.map),i.addChangeListener(ns,i.fn);var e=n.source?n.source:null;return i.setSource(e),i}return fs(n,t),n.prototype.getLayersArray=function(t){var n=t||[];return n.push(this),n},n.prototype.getLayerStatesArray=function(t){var n=t||[];return n.push(this.getLayerState()),n},n.prototype.getSource=function(){return this.get(ns)||null},n.prototype.getRenderSource=function(){return this.getSource()},n.prototype.getSourceState=function(){var t=this.getSource();return t?t.getState():"undefined"},n.prototype.cn=function(){this.changed()},n.prototype.fn=function(){this.an&&(H(this.an),this.an=null);var t=this.getSource();t&&(this.an=$(t,L,this.cn,this)),this.changed()},n.prototype.getFeatures=function(t){return this.hn?this.hn.getFeatures(t):new Promise((function(t){return t([])}))},n.prototype.getData=function(t){return this.hn&&this.rendered?this.hn.getData(t):null},n.prototype.render=function(t,n){var i=this.getRenderer();if(i.prepareFrame(t))return this.rendered=!0,i.renderFrame(t,n)},n.prototype.unrender=function(){this.rendered=!1},n.prototype.setMapInternal=function(t){t||this.unrender(),this.set(is,t)},n.prototype.getMapInternal=function(){return this.get(is)},n.prototype.setMap=function(t){this.en&&(H(this.en),this.en=null),t||this.changed(),this.sn&&(H(this.sn),this.sn=null),t&&(this.en=$(t,us,(function(t){var n=t.frameState.layerStatesArray,i=this.getLayerState(!1);St(!n.some((function(t){return t.layer===i.layer})),67),n.push(i)}),this),this.sn=$(this,L,t.render,t),this.changed())},n.prototype.setSource=function(t){this.set(ns,t)},n.prototype.getRenderer=function(){return this.hn||(this.hn=this.createRenderer()),this.hn},n.prototype.hasRenderer=function(){return!!this.hn},n.prototype.createRenderer=function(){return null},n.prototype.disposeInternal=function(){this.hn&&(this.hn.dispose(),delete this.hn),this.setSource(null),t.prototype.disposeInternal.call(this)},n}(es),vs=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}();function ds(t,n){Wo.expire()}var ps=function(t){function n(n){var i=t.call(this)||this;return i.vn=n,i}return vs(n,t),n.prototype.dispatchRenderEvent=function(t,n){r()},n.prototype.calculateMatrices2D=function(t){var n=t.viewState,i=t.coordinateToPixelTransform,r=t.pixelToCoordinateTransform;sn(i,t.size[0]/2,t.size[1]/2,1/n.resolution,-1/n.resolution,-n.rotation,-n.center[0],-n.center[1]),un(r,i)},n.prototype.forEachFeatureAtCoordinate=function(t,n,i,r,e,o,s,u){var a,h=n.viewState;function f(t,n,i,r){return e.call(o,n,t?i:null,r)}var c=h.projection,l=rr(t.slice(),c),v=[[0,0]];if(c.canWrapX()&&r){var d=$n(c.getExtent());v.push([-d,0],[d,0])}for(var p=n.layerStatesArray,y=p.length,m=[],w=[],g=0;g=0;--b){var x=p[b],M=x.layer;if(M.hasRenderer()&&cs(x,h)&&s.call(u,M)){var _=M.getRenderer(),S=M.getSource();if(_&&S){var O=S.getWrapX()?l:t,j=f.bind(null,x.managed);w[0]=O[0]+v[g][0],w[1]=O[1]+v[g][1],a=_.forEachFeatureAtCoordinate(w,n,i,j,m)}if(a)return a}}if(0!==m.length){var E=1/m.length;return m.forEach((function(t,n){return t.distanceSq+=n*E})),m.sort((function(t,n){return t.distanceSq-n.distanceSq})),m.some((function(t){return a=t.callback(t.feature,t.layer,t.geometry)})),a}},n.prototype.forEachLayerAtPixel=function(t,n,i,e,o){return r()},n.prototype.hasFeatureAtCoordinate=function(t,n,i,r,e,o){return void 0!==this.forEachFeatureAtCoordinate(t,n,i,r,S,this,e,o)},n.prototype.getMap=function(){return this.vn},n.prototype.renderFrame=function(t){r()},n.prototype.scheduleExpireIconCache=function(t){Wo.canExpireCache()&&t.postRenderFunctions.push(ds)},n}(v),ys=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),ms=function(t){function n(n,i,r,e){var o=t.call(this,n)||this;return o.inversePixelTransform=i,o.frameState=r,o.context=e,o}return ys(n,t),n}(c),ws="ol-hidden",gs="ol-selectable",bs="ol-unselectable",xs="ol-unsupported",Ms="ol-control",_s="ol-collapsed",Ss=new RegExp(["^\\s*(?=(?:(?:[-a-z]+\\s*){0,2}(italic|oblique))?)","(?=(?:(?:[-a-z]+\\s*){0,2}(small-caps))?)","(?=(?:(?:[-a-z]+\\s*){0,2}(bold(?:er)?|lighter|[1-9]00 ))?)","(?:(?:normal|\\1|\\2|\\3)\\s*){0,3}((?:xx?-)?","(?:small|large)|medium|smaller|larger|[\\.\\d]+(?:\\%|in|[cem]m|ex|p[ctx]))","(?:\\s*\\/\\s*(normal|[\\.\\d]+(?:\\%|in|[cem]m|ex|p[ctx])?))","?\\s*([-,\\\"\\'\\sa-z]+?)\\s*$"].join(""),"i"),Os=["style","variant","weight","size","lineHeight","family"],js=function(t){var n=t.match(Ss);if(!n)return null;for(var i={lineHeight:"normal",size:"1.2em",style:"normal",weight:"normal",variant:"normal"},r=0,e=Os.length;r=0;--o)r[o].renderDeclutter(t);Po(this.pn,this.yn),this.dispatchRenderEvent(as,t),this.mn||(this.pn.style.display="",this.mn=!0),this.scheduleExpireIconCache(t)}else this.mn&&(this.pn.style.display="none",this.mn=!1)},n.prototype.forEachLayerAtPixel=function(t,n,i,r,e){for(var o=n.viewState,s=n.layerStatesArray,u=s.length-1;u>=0;--u){var a=s[u],h=a.layer;if(h.hasRenderer()&&cs(a,o)&&e(h)){var f=h.getRenderer().getDataAtPixel(t,n,i);if(f){var c=r(h,f);if(c)return c}}}},n}(ps),Js=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Qs=function(t){function n(n,i){var r=t.call(this,n)||this;return r.layer=i,r}return Js(n,t),n}(c),tu="layers",nu=function(t){function n(n){var i=this,r=n||{},e=A({},r);delete e.layers;var o=r.layers;return(i=t.call(this,e)||this).on,i.once,i.un,i.wn=[],i.gn={},i.addChangeListener(tu,i.bn),o?Array.isArray(o)?o=new ft(o.slice(),{unique:!0}):St("function"==typeof o.getArray,43):o=new ft(void 0,{unique:!0}),i.setLayers(o),i}return Js(n,t),n.prototype.xn=function(){this.changed()},n.prototype.bn=function(){this.wn.forEach(H),this.wn.length=0;var t=this.getLayers();for(var n in this.wn.push($(t,ot,this.Mn,this),$(t,st,this._n,this)),this.gn)this.gn[n].forEach(H);P(this.gn);for(var i=t.getArray(),r=0,e=i.length;rthis.In||Math.abs(t.clientY-this.Nn.clientY)>this.In},n.prototype.disposeInternal=function(){this.Dn&&(H(this.Dn),this.Dn=null),this.pn.removeEventListener(Y,this.Un),this.Rn&&(H(this.Rn),this.Rn=null),this.kn.forEach(H),this.kn.length=0,this.pn=null,t.prototype.disposeInternal.call(this)},n}(N),vu="postrender",du="movestart",pu="moveend",yu="loadstart",mu="loadend",wu="layergroup",gu="size",bu="target",xu="view",Mu=1/0,_u=function(){function t(t,n){this.Kn=t,this.Hn=n,this.Jn=[],this.Qn=[],this.ti={}}return t.prototype.clear=function(){this.Jn.length=0,this.Qn.length=0,P(this.ti)},t.prototype.dequeue=function(){var t=this.Jn,n=this.Qn,i=t[0];1==t.length?(t.length=0,n.length=0):(t[0]=t.pop(),n[0]=n.pop(),this.ni(0));var r=this.Hn(i);return delete this.ti[r],i},t.prototype.enqueue=function(t){St(!(this.Hn(t)in this.ti),31);var n=this.Kn(t);return n!=Mu&&(this.Jn.push(t),this.Qn.push(n),this.ti[this.Hn(t)]=!0,this.ii(0,this.Jn.length-1),!0)},t.prototype.getCount=function(){return this.Jn.length},t.prototype.ri=function(t){return 2*t+1},t.prototype.ei=function(t){return 2*t+2},t.prototype.oi=function(t){return t-1>>1},t.prototype.si=function(){var t;for(t=(this.Jn.length>>1)-1;t>=0;t--)this.ni(t)},t.prototype.isEmpty=function(){return 0===this.Jn.length},t.prototype.isKeyQueued=function(t){return t in this.ti},t.prototype.isQueued=function(t){return this.isKeyQueued(this.Hn(t))},t.prototype.ni=function(t){for(var n=this.Jn,i=this.Qn,r=n.length,e=n[t],o=i[t],s=t;t>1;){var u=this.ri(t),a=this.ei(t),h=at;){var s=this.oi(n);if(!(r[s]>o))break;i[n]=i[s],r[n]=r[s],n=s}i[n]=e,r[n]=o},t.prototype.reprioritize=function(){var t,n,i,r=this.Kn,e=this.Jn,o=this.Qn,s=0,u=e.length;for(n=0;n0;)r=(i=this.dequeue()[0]).getKey(),i.getState()!==ct||r in this.fi||(this.fi[r]=!0,++this.hi,++e,i.load())},n}(_u);function ju(t,n,i,r,e){if(!t||!(i in t.wantedTiles))return Mu;if(!t.wantedTiles[i][n.getKey()])return Mu;var o=t.viewState.center,s=r[0]-o[0],u=r[1]-o[1];return 65536*Math.log(e)+Math.sqrt(s*s+u*u)/e}var Eu=0,Tu=1,Au={CENTER:"center",RESOLUTION:"resolution",ROTATION:"rotation"},Pu=256;function Cu(t,n,i){return function(r,e,o,s,u){if(r){if(!e&&!n)return r;var a=n?0:o[0]*e,h=n?0:o[1]*e,f=u?u[0]:0,c=u?u[1]:0,l=t[0]+a/2+f,v=t[2]-a/2+f,d=t[1]+h/2+c,p=t[3]-h/2+c;l>v&&(v=l=(v+l)/2),d>p&&(p=d=(p+d)/2);var y=oi(r[0],l,v),m=oi(r[1],d,p);if(s&&i&&e){var w=30*e;y+=-w*Math.log(1+Math.max(0,l-r[0])/w)+w*Math.log(1+Math.max(0,r[0]-v)/w),m+=-w*Math.log(1+Math.max(0,d-r[1])/w)+w*Math.log(1+Math.max(0,r[1]-p)/w)}return[y,m]}}}function ku(t){return t}function Iu(t,n,i,r){var e=$n(n)/i[0],o=Vn(n)/i[1];return r?Math.min(t,Math.max(e,o)):Math.min(t,Math.min(e,o))}function Nu(t,n,i){var r=Math.min(t,n);return r*=Math.log(1+50*Math.max(0,t/n-1))/50+1,i&&(r=Math.max(r,i),r/=Math.log(1+50*Math.max(0,i/t-1))/50+1),oi(r,i/2,2*n)}function Lu(t,n,i,r){return function(e,o,s,u){if(void 0!==e){var a=t[0],h=t[t.length-1],f=i?Iu(a,i,s,r):a;if(u)return void 0===n||n?Nu(e,f,h):oi(e,h,f);var c=Math.min(f,e),l=Math.floor(m(t,c,o));return t[l]>f&&l1&&"function"==typeof arguments[i-1]&&(n=arguments[i-1],--i);for(var r=0;r0},n.prototype.getInteracting=function(){return this.ci[Tu]>0},n.prototype.cancelAnimations=function(){var t;this.setHint(Eu,-this.ci[Eu]);for(var n=0,i=this.li.length;n=0;--i){for(var r=this.li[i],e=!0,o=0,s=r.length;o0?a/u.duration:1;h>=1?(u.complete=!0,h=1):e=!1;var f=u.easing(h);if(u.sourceCenter){var c=u.sourceCenter[0],l=u.sourceCenter[1],v=u.targetCenter[0],d=u.targetCenter[1];this.bi=u.targetCenter;var p=c+f*(v-c),y=l+f*(d-l);this.mi=[p,y]}if(u.sourceResolution&&u.targetResolution){var m=1===f?u.targetResolution:u.sourceResolution+f*(u.targetResolution-u.sourceResolution);if(u.anchor){var w=this.Ni(this.getRotation()),g=this.Ci.resolution(m,0,w,!0);this.mi=this.calculateCenterZoom(g,u.anchor)}this.xi=u.targetResolution,this.wi=m,this.Li(!0)}if(void 0!==u.sourceRotation&&void 0!==u.targetRotation){var b=1===f?vi(u.targetRotation+Math.PI,2*Math.PI)-Math.PI:u.sourceRotation+f*(u.targetRotation-u.sourceRotation);if(u.anchor){var x=this.Ci.rotation(b,!0);this.mi=this.calculateCenterRotate(x,u.anchor)}this.Mi=u.targetRotation,this.gi=b}if(this.Li(!0),n=!0,!u.complete)break}}if(e){this.li[i]=null,this.setHint(Eu,-1),this.bi=null,this.xi=NaN,this.Mi=NaN;var M=r[0].callback;M&&Bu(M,!0)}}this.li=this.li.filter(Boolean),n&&void 0===this.vi&&(this.vi=requestAnimationFrame(this.Ii.bind(this)))}},n.prototype.calculateCenterRotate=function(t,n){var i,r=this.getCenterInternal();return void 0!==r&&(Hi(i=[r[0]-n[0],r[1]-n[1]],t-this.getRotation()),Vi(i,n)),i},n.prototype.calculateCenterZoom=function(t,n){var i,r=this.getCenterInternal(),e=this.getResolution();void 0!==r&&void 0!==e&&(i=[n[0]-t*(n[0]-r[0])/e,n[1]-t*(n[1]-r[1])/e]);return i},n.prototype.Ni=function(t){var n=this.yi;if(t){var i=n[0],r=n[1];return[Math.abs(i*Math.cos(t))+Math.abs(r*Math.sin(t)),Math.abs(i*Math.sin(t))+Math.abs(r*Math.cos(t))]}return n},n.prototype.setViewportSize=function(t){this.yi=Array.isArray(t)?t.slice():[100,100],this.getAnimating()||this.resolveConstraints(0)},n.prototype.getCenter=function(){var t=this.getCenterInternal();return t?kr(t,this.getProjection()):t},n.prototype.getCenterInternal=function(){return this.get(Au.CENTER)},n.prototype.getConstraints=function(){return this.Ci},n.prototype.getConstrainResolution=function(){return this.get("constrainResolution")},n.prototype.getHints=function(t){return void 0!==t?(t[0]=this.ci[0],t[1]=this.ci[1],t):this.ci.slice()},n.prototype.calculateExtent=function(t){return Nr(this.calculateExtentInternal(t),this.getProjection())},n.prototype.calculateExtentInternal=function(t){var n=t||this.zi(),i=this.getCenterInternal();St(i,1);var r=this.getResolution();St(void 0!==r,2);var e=this.getRotation();return St(void 0!==e,3),Bn(i,r,e,n)},n.prototype.getMaxResolution=function(){return this.Oi},n.prototype.getMinResolution=function(){return this.ji},n.prototype.getMaxZoom=function(){return this.getZoomForResolution(this.ji)},n.prototype.setMaxZoom=function(t){this.Si(this.ki({maxZoom:t}))},n.prototype.getMinZoom=function(){return this.getZoomForResolution(this.Oi)},n.prototype.setMinZoom=function(t){this.Si(this.ki({minZoom:t}))},n.prototype.setConstrainResolution=function(t){this.Si(this.ki({constrainResolution:t}))},n.prototype.getProjection=function(){return this.di},n.prototype.getResolution=function(){return this.get(Au.RESOLUTION)},n.prototype.getResolutions=function(){return this.Ti},n.prototype.getResolutionForExtent=function(t,n){return this.getResolutionForExtentInternal(Lr(t,this.getProjection()),n)},n.prototype.getResolutionForExtentInternal=function(t,n){var i=n||this.zi(),r=$n(t)/i[0],e=Vn(t)/i[1];return Math.max(r,e)},n.prototype.getResolutionForValueFunction=function(t){var n=t||2,i=this.getConstrainedResolution(this.Oi),r=this.ji,e=Math.log(i/r)/Math.log(n);return function(t){return i/Math.pow(n,t*e)}},n.prototype.getRotation=function(){return this.get(Au.ROTATION)},n.prototype.getValueForResolutionFunction=function(t){var n=Math.log(t||2),i=this.getConstrainedResolution(this.Oi),r=this.ji,e=Math.log(i/r)/n;return function(t){return Math.log(i/t)/n/e}},n.prototype.zi=function(t){var n=this.Ni(t),i=this.Ai;return i&&(n=[n[0]-i[1]-i[3],n[1]-i[0]-i[2]]),n},n.prototype.getState=function(){var t=this.getProjection(),n=this.getResolution(),i=this.getRotation(),r=this.getCenterInternal(),e=this.Ai;if(e){var o=this.zi();r=Zu(r,this.Ni(),[o[0]/2+e[3],o[1]/2+e[0]],n,i)}return{center:r.slice(0),projection:void 0!==t?t:null,resolution:n,nextCenter:this.bi,nextResolution:this.xi,nextRotation:this.Mi,rotation:i,zoom:this.getZoom()}},n.prototype.getZoom=function(){var t,n=this.getResolution();return void 0!==n&&(t=this.getZoomForResolution(n)),t},n.prototype.getZoomForResolution=function(t){var n,i,r=this.Pi||0;if(this.Ti){var e=m(this.Ti,t,1);r=e,n=this.Ti[e],i=e==this.Ti.length-1?2:n/this.Ti[e+1]}else n=this.Oi,i=this.Ei;return r+Math.log(n/t)/Math.log(i)},n.prototype.getResolutionForZoom=function(t){if(this.Ti){if(this.Ti.length<=1)return 0;var n=oi(Math.floor(t),0,this.Ti.length-2),i=this.Ti[n]/this.Ti[n+1];return this.Ti[n]/Math.pow(i,oi(t-n,0,1))}return this.Oi/Math.pow(this.Ei,t-this.Pi)},n.prototype.fit=function(t,n){var i;if(St(Array.isArray(t)||"function"==typeof t.getSimplifiedGeometry,24),Array.isArray(t))St(!Hn(t),25),i=Ze(r=Lr(t,this.getProjection()));else if("Circle"===t.getType()){var r;(i=Ze(r=Lr(t.getExtent(),this.getProjection()))).rotate(this.getRotation(),qn(r))}else{var e=Cr();i=e?t.clone().transform(e,this.getProjection()):t}this.fitInternal(i,n)},n.prototype.rotatedExtentForGeometry=function(t){for(var n=this.getRotation(),i=Math.cos(n),r=Math.sin(-n),e=t.getFlatCoordinates(),o=t.getStride(),s=1/0,u=1/0,a=-1/0,h=-1/0,f=0,c=e.length;f0&&t[1]>0}function Ju(t,n,i){return void 0===i&&(i=[0,0]),i[0]=t[0]*n+.5|0,i[1]=t[1]*n+.5|0,i}function Qu(t,n){return Array.isArray(t)?t:(void 0===n?n=[t,t]:(n[0]=t,n[1]=t),n)}var ta=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}();function na(t){t instanceof ls?t.setMapInternal(null):t instanceof nu&&t.getLayers().forEach(na)}function ia(t,n){if(t instanceof ls)t.setMapInternal(n);else if(t instanceof nu)for(var i=t.getLayers().getArray(),r=0,e=i.length;r=0;u--){var a=s[u];if(a.getMap()===this&&a.getActive()&&this.getTargetElement())if(!a.handleEvent(t)||t.propagationStopped)break}}},n.prototype.handlePostRender=function(){var t=this.Zi,n=this.hr;if(!n.isEmpty()){var i=this.Di,r=i;if(t){var e=t.viewHints;if(e[Eu]||e[Tu]){var o=Date.now()-t.time>8;i=o?0:8,r=o?0:2}}n.getTilesLoading()0;if(this.mn!=i&&(this.element.style.display=i?"":"none",this.mn=i),!x(n,this.Ir)){Ao(this._r);for(var r=0,e=n.length;r0&&n%(2*Math.PI)!=0?t.animate({rotation:0,duration:this.Fr,easing:mt}):t.setRotation(0))}},n.prototype.render=function(t){var n=t.frameState;if(n){var i=n.viewState.rotation;if(i!=this.Dr){var r="rotate("+i+"rad)";if(this.Gr){var e=this.element.classList.contains(ws);e||0!==i?e&&0!==i&&this.element.classList.remove(ws):this.element.classList.add(ws)}this.Pr.style.transform=r}this.Dr=i}},n}(oa),fa=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),ca=function(t){function n(n){var i=this,r=n||{};i=t.call(this,{element:document.createElement("div"),target:r.target})||this;var e=void 0!==r.className?r.className:"ol-zoom",o=void 0!==r.delta?r.delta:1,s=void 0!==r.zoomInClassName?r.zoomInClassName:e+"-in",u=void 0!==r.zoomOutClassName?r.zoomOutClassName:e+"-out",a=void 0!==r.zoomInLabel?r.zoomInLabel:"+",h=void 0!==r.zoomOutLabel?r.zoomOutLabel:"–",f=void 0!==r.zoomInTipLabel?r.zoomInTipLabel:"Zoom in",c=void 0!==r.zoomOutTipLabel?r.zoomOutTipLabel:"Zoom out",l=document.createElement("button");l.className=s,l.setAttribute("type","button"),l.title=f,l.appendChild("string"==typeof a?document.createTextNode(a):a),l.addEventListener(F,i.kr.bind(i,o),!1);var v=document.createElement("button");v.className=u,v.setAttribute("type","button"),v.title=c,v.appendChild("string"==typeof h?document.createTextNode(h):h),v.addEventListener(F,i.kr.bind(i,-o),!1);var d=e+" "+"ol-unselectable "+Ms,p=i.element;return p.className=d,p.appendChild(l),p.appendChild(v),i.Fr=void 0!==r.duration?r.duration:250,i}return fa(n,t),n.prototype.kr=function(t,n){n.preventDefault(),this.Ur(t)},n.prototype.Ur=function(t){var n=this.getMap().getView();if(n){var i=n.getZoom();if(void 0!==i){var r=n.getConstrainedZoom(i+t);this.Fr>0?(n.getAnimating()&&n.cancelAnimations(),n.animate({zoom:r,duration:this.Fr,easing:mt})):n.setZoom(r)}}},n}(oa);function la(t){var n=t||{},i=new ft;return(void 0===n.zoom||n.zoom)&&i.push(new ca(n.zoomOptions)),(void 0===n.rotate||n.rotate)&&i.push(new ha(n.rotateOptions)),(void 0===n.attribution||n.attribution)&&i.push(new ua(n.attributionOptions)),i}var va="active",da=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}();function pa(t,n,i){var r=t.getCenterInternal();if(r){var e=[r[0]+n[0],r[1]+n[1]];t.animateInternal({duration:void 0!==i?i:250,easing:gt,center:t.getConstrainedCenter(e)})}}function ya(t,n,i,r){var e=t.getZoom();if(void 0!==e){var o=t.getConstrainedZoom(e+n),s=t.getResolutionForZoom(o);t.getAnimating()&&t.cancelAnimations(),t.animate({resolution:s,anchor:i,duration:void 0!==r?r:250,easing:mt})}}var ma=function(t){function n(n){var i=t.call(this)||this;return i.on,i.once,i.un,n&&n.handleEvent&&(i.handleEvent=n.handleEvent),i.vn=null,i.setActive(!0),i}return da(n,t),n.prototype.getActive=function(){return this.get(va)},n.prototype.getMap=function(){return this.vn},n.prototype.handleEvent=function(t){return!0},n.prototype.setActive=function(t){this.set(va,t)},n.prototype.setMap=function(t){this.vn=t},n}(et),wa=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),ga=function(t){function n(n){var i=t.call(this)||this,r=n||{};return i.Br=r.delta?r.delta:1,i.Fr=void 0!==r.duration?r.duration:250,i}return wa(n,t),n.prototype.handleEvent=function(t){var n=!1;if(t.type==su.DBLCLICK){var i=t.originalEvent,r=t.map,e=t.coordinate,o=i.shiftKey?-this.Br:this.Br;ya(r.getView(),o,e,this.Fr),i.preventDefault(),n=!0}return!n},n}(ma),ba=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}();function xa(t){for(var n=t.length,i=0,r=0,e=0;e0}}else if(t.type==su.POINTERDOWN){var r=this.handleDownEvent(t);this.handlingDownUpSequence=r,n=this.stopDown(r)}else t.type==su.POINTERMOVE&&this.handleMoveEvent(t);return!n},n.prototype.handleMoveEvent=function(t){},n.prototype.handleUpEvent=function(t){return!1},n.prototype.stopDown=function(t){return t},n.prototype.Xr=function(t){t.activePointers&&(this.targetPointers=t.activePointers)},n}(ma);function _a(t){var n=arguments;return function(t){for(var i=!0,r=0,e=n.length;r0&&this.Zr(t)){var n=t.map.getView();return this.lastCentroid=null,n.getAnimating()&&n.cancelAnimations(),this.Vr&&this.Vr.begin(),this.$r=this.targetPointers.length>1,!0}return!1},n}(Ma),Ga=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Da=function(t){function n(n){var i=this,r=n||{};return(i=t.call(this,{stopDown:O})||this).Zr=r.condition?r.condition:Oa,i.Kr=void 0,i.Fr=void 0!==r.duration?r.duration:250,i}return Ga(n,t),n.prototype.handleDragEvent=function(t){if(La(t)){var n=t.map,i=n.getView();if(i.getConstraints().rotation!==Fu){var r=n.getSize(),e=t.pixel,o=Math.atan2(r[1]/2-e[1],e[0]-r[0]/2);if(void 0!==this.Kr){var s=o-this.Kr;i.adjustRotationInternal(-s)}this.Kr=o}}},n.prototype.handleUpEvent=function(t){return!La(t)||(t.map.getView().endInteraction(this.Fr),!1)},n.prototype.handleDownEvent=function(t){return!!La(t)&&(!(!Aa(t)||!this.Zr(t))&&(t.map.getView().beginInteraction(),this.Kr=void 0,!0))},n}(Ma),qa=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Ua=function(t){function n(n){var i=t.call(this)||this;return i.Hr=null,i.pn=document.createElement("div"),i.pn.style.position="absolute",i.pn.style.pointerEvents="auto",i.pn.className="ol-box "+n,i.vn=null,i.Jr=null,i.Qr=null,i}return qa(n,t),n.prototype.disposeInternal=function(){this.setMap(null)},n.prototype.te=function(){var t=this.Jr,n=this.Qr,i="px",r=this.pn.style;r.left=Math.min(t[0],n[0])+i,r.top=Math.min(t[1],n[1])+i,r.width=Math.abs(n[0]-t[0])+i,r.height=Math.abs(n[1]-t[1])+i},n.prototype.setMap=function(t){if(this.vn){this.vn.getOverlayContainer().removeChild(this.pn);var n=this.pn.style;n.left="inherit",n.top="inherit",n.width="inherit",n.height="inherit"}this.vn=t,this.vn&&this.vn.getOverlayContainer().appendChild(this.pn)},n.prototype.setPixels=function(t,n){this.Jr=t,this.Qr=n,this.createOrUpdateGeometry(),this.te()},n.prototype.createOrUpdateGeometry=function(){var t=this.Jr,n=this.Qr,i=[t,[t[0],n[1]],n,[n[0],t[1]]].map(this.vn.getCoordinateFromPixelInternal,this.vn);i[4]=i[0].slice(),this.Hr?this.Hr.setCoordinates([i]):this.Hr=new We([i])},n.prototype.getGeometry=function(){return this.Hr},n}(v),Ba=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Xa="boxstart",Va="boxdrag",Wa="boxend",Ya="boxcancel",Za=function(t){function n(n,i,r){var e=t.call(this,n)||this;return e.coordinate=i,e.mapBrowserEvent=r,e}return Ba(n,t),n}(c),$a=function(t){function n(n){var i=t.call(this)||this;i.on,i.once,i.un;var r=n||{};return i.ne=new Ua(r.className||"ol-dragbox"),i.ie=void 0!==r.minArea?r.minArea:64,r.onBoxEnd&&(i.onBoxEnd=r.onBoxEnd),i.Jr=null,i.Zr=r.condition?r.condition:Aa,i.re=r.boxEndCondition?r.boxEndCondition:i.defaultBoxEndCondition,i}return Ba(n,t),n.prototype.defaultBoxEndCondition=function(t,n,i){var r=i[0]-n[0],e=i[1]-n[1];return r*r+e*e>=this.ie},n.prototype.getGeometry=function(){return this.ne.getGeometry()},n.prototype.handleDragEvent=function(t){this.ne.setPixels(this.Jr,t.pixel),this.dispatchEvent(new Za(Va,t.coordinate,t))},n.prototype.handleUpEvent=function(t){this.ne.setMap(null);var n=this.re(t,this.Jr,t.pixel);return n&&this.onBoxEnd(t),this.dispatchEvent(new Za(n?Wa:Ya,t.coordinate,t)),!1},n.prototype.handleDownEvent=function(t){return!!this.Zr(t)&&(this.Jr=t.pixel,this.ne.setMap(t.map),this.ne.setPixels(this.Jr,this.Jr),this.dispatchEvent(new Za(Xa,t.coordinate,t)),!0)},n.prototype.onBoxEnd=function(t){},n}(Ma),Ka=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Ha=function(t){function n(n){var i=this,r=n||{},e=r.condition?r.condition:Ia;return(i=t.call(this,{condition:e,className:r.className||"ol-dragzoom",minArea:r.minArea})||this).Fr=void 0!==r.duration?r.duration:200,i.ee=void 0!==r.out&&r.out,i}return Ka(n,t),n.prototype.onBoxEnd=function(t){var n=this.getMap().getView(),i=this.getGeometry();if(this.ee){var r=n.rotatedExtentForGeometry(i),e=n.getResolutionForExtentInternal(r),o=n.getResolution()/e;(i=i.clone()).scale(o*o)}n.fitInternal(i,{duration:this.Fr,easing:mt})},n}($a),Ja=37,Qa=38,th=39,nh=40,ih=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),rh=function(t){function n(n){var i=t.call(this)||this,r=n||{};return i.oe=function(t){return ka(t)&&Na(t)},i.Zr=void 0!==r.condition?r.condition:i.oe,i.Fr=void 0!==r.duration?r.duration:100,i.se=void 0!==r.pixelDelta?r.pixelDelta:128,i}return ih(n,t),n.prototype.handleEvent=function(t){var n=!1;if(t.type==B){var i=t.originalEvent,r=i.keyCode;if(this.Zr(t)&&(r==nh||r==Ja||r==th||r==Qa)){var e=t.map.getView(),o=e.getResolution()*this.se,s=0,u=0;r==nh?u=-o:r==Ja?s=-o:r==th?s=o:u=o;var a=[s,u];Hi(a,e.getRotation()),pa(e,a,this.Fr),i.preventDefault(),n=!0}}return!n},n}(ma),eh=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),oh=function(t){function n(n){var i=t.call(this)||this,r=n||{};return i.Zr=r.condition?r.condition:Na,i.Br=r.delta?r.delta:1,i.Fr=void 0!==r.duration?r.duration:100,i}return eh(n,t),n.prototype.handleEvent=function(t){var n=!1;if(t.type==B||t.type==X){var i=t.originalEvent,r=i.charCode;if(this.Zr(t)&&(r=="+".charCodeAt(0)||r=="-".charCodeAt(0))){var e=t.map,o=r=="+".charCodeAt(0)?this.Br:-this.Br;ya(e.getView(),o,void 0,this.Fr),i.preventDefault(),n=!0}}return!n},n}(ma),sh=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),uh="trackpad",ah="wheel",hh=function(t){function n(n){var i=this,r=n||{};(i=t.call(this,r)||this).ue=0,i.ae=0,i.wt=void 0!==r.maxDelta?r.maxDelta:1,i.Fr=void 0!==r.duration?r.duration:250,i.he=void 0!==r.timeout?r.timeout:80,i.fe=void 0===r.useAnchor||r.useAnchor,i.ce=void 0!==r.constrainResolution&&r.constrainResolution;var e=r.condition?r.condition:Ta;return i.Zr=r.onFocusOnly?_a(Ea,e):e,i.le=null,i.ve=void 0,i.de,i.pe=void 0,i.ye=400,i.me,i.we=300,i}return sh(n,t),n.prototype.ge=function(){this.me=void 0;var t=this.getMap();t&&t.getView().endInteraction(void 0,this.ae?this.ae>0?1:-1:0,this.le)},n.prototype.handleEvent=function(t){if(!this.Zr(t))return!0;if(t.type!==Z)return!0;var n,i=t.map,r=t.originalEvent;if(r.preventDefault(),this.fe&&(this.le=t.coordinate),t.type==Z&&(n=r.deltaY,Gt&&r.deltaMode===WheelEvent.DOM_DELTA_PIXEL&&(n/=Xt),r.deltaMode===WheelEvent.DOM_DELTA_LINE&&(n*=40)),0===n)return!1;this.ae=n;var e=Date.now();void 0===this.ve&&(this.ve=e),(!this.pe||e-this.ve>this.ye)&&(this.pe=Math.abs(n)<4?uh:ah);var o=i.getView();if(this.pe===uh&&!o.getConstrainResolution()&&!this.ce)return this.me?clearTimeout(this.me):(o.getAnimating()&&o.cancelAnimations(),o.beginInteraction()),this.me=setTimeout(this.ge.bind(this),this.he),o.adjustZoom(-n/this.we,this.le),this.ve=e,!1;this.ue+=n;var s=Math.max(this.he-(e-this.ve),0);return clearTimeout(this.de),this.de=setTimeout(this.be.bind(this,i),s),!1},n.prototype.be=function(t){var n=t.getView();n.getAnimating()&&n.cancelAnimations();var i=-oi(this.ue,-this.wt*this.we,this.wt*this.we)/this.we;(n.getConstrainResolution()||this.ce)&&(i=i?i>0?1:-1:0),ya(n,i,this.le,this.Fr),this.pe=void 0,this.ue=0,this.le=null,this.ve=void 0,this.de=void 0},n.prototype.setMouseAnchor=function(t){this.fe=t,t||(this.le=null)},n}(ma),fh=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),ch=function(t){function n(n){var i=this,r=n||{},e=r;return e.stopDown||(e.stopDown=O),(i=t.call(this,e)||this).xe=null,i.Kr=void 0,i.Me=!1,i._e=0,i.Se=void 0!==r.threshold?r.threshold:.3,i.Fr=void 0!==r.duration?r.duration:250,i}return fh(n,t),n.prototype.handleDragEvent=function(t){var n=0,i=this.targetPointers[0],r=this.targetPointers[1],e=Math.atan2(r.clientY-i.clientY,r.clientX-i.clientX);if(void 0!==this.Kr){var o=e-this.Kr;this._e+=o,!this.Me&&Math.abs(this._e)>this.Se&&(this.Me=!0),n=o}this.Kr=e;var s=t.map,u=s.getView();if(u.getConstraints().rotation!==Fu){var a=s.getViewport().getBoundingClientRect(),h=xa(this.targetPointers);h[0]-=a.left,h[1]-=a.top,this.xe=s.getCoordinateFromPixelInternal(h),this.Me&&(s.render(),u.adjustRotationInternal(n,this.xe))}},n.prototype.handleUpEvent=function(t){return!(this.targetPointers.length<2)||(t.map.getView().endInteraction(this.Fr),!1)},n.prototype.handleDownEvent=function(t){if(this.targetPointers.length>=2){var n=t.map;return this.xe=null,this.Kr=void 0,this.Me=!1,this._e=0,this.handlingDownUpSequence||n.getView().beginInteraction(),!0}return!1},n}(Ma),lh=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),vh=function(t){function n(n){var i=this,r=n||{},e=r;return e.stopDown||(e.stopDown=O),(i=t.call(this,e)||this).xe=null,i.Fr=void 0!==r.duration?r.duration:400,i.Oe=void 0,i.je=1,i}return lh(n,t),n.prototype.handleDragEvent=function(t){var n=1,i=this.targetPointers[0],r=this.targetPointers[1],e=i.clientX-r.clientX,o=i.clientY-r.clientY,s=Math.sqrt(e*e+o*o);void 0!==this.Oe&&(n=this.Oe/s),this.Oe=s;var u=t.map,a=u.getView();1!=n&&(this.je=n);var h=u.getViewport().getBoundingClientRect(),f=xa(this.targetPointers);f[0]-=h.left,f[1]-=h.top,this.xe=u.getCoordinateFromPixelInternal(f),u.render(),a.adjustResolutionInternal(n,this.xe)},n.prototype.handleUpEvent=function(t){if(this.targetPointers.length<2){var n=t.map.getView(),i=this.je>1?1:-1;return n.endInteraction(this.Fr,i),!1}return!0},n.prototype.handleDownEvent=function(t){if(this.targetPointers.length>=2){var n=t.map;return this.xe=null,this.Oe=void 0,this.je=1,this.handlingDownUpSequence||n.getView().beginInteraction(),!0}return!1},n}(Ma);function dh(t){var n=t||{},i=new ft,r=new Io(-.005,.05,100);return(void 0===n.altShiftDragRotate||n.altShiftDragRotate)&&i.push(new Da),(void 0===n.doubleClickZoom||n.doubleClickZoom)&&i.push(new ga({delta:n.zoomDelta,duration:n.zoomDuration})),(void 0===n.dragPan||n.dragPan)&&i.push(new Fa({onFocusOnly:n.onFocusOnly,kinetic:r})),(void 0===n.pinchRotate||n.pinchRotate)&&i.push(new ch),(void 0===n.pinchZoom||n.pinchZoom)&&i.push(new vh({duration:n.zoomDuration})),(void 0===n.keyboard||n.keyboard)&&(i.push(new rh),i.push(new oh({delta:n.zoomDelta,duration:n.zoomDuration}))),(void 0===n.mouseWheelZoom||n.mouseWheelZoom)&&i.push(new hh({onFocusOnly:n.onFocusOnly,duration:n.zoomDuration})),(void 0===n.shiftDragZoom||n.shiftDragZoom)&&i.push(new Ha({duration:n.zoomDuration})),i}var ph=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),yh=function(t){function n(n){return(n=A({},n)).controls||(n.controls=la()),n.interactions||(n.interactions=dh({onFocusOnly:!0})),t.call(this,n)||this}return ph(n,t),n.prototype.createRenderer=function(){return new Hs(this)},n}(ra),mh=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),wh="element",gh="map",bh="offset",xh="position",Mh="positioning",_h=function(t){function n(n){var i=t.call(this)||this;i.on,i.once,i.un,i.options=n,i.id=n.id,i.insertFirst=void 0===n.insertFirst||n.insertFirst,i.stopEvent=void 0===n.stopEvent||n.stopEvent,i.element=document.createElement("div"),i.element.className=void 0!==n.className?n.className:"ol-overlay-container ol-selectable",i.element.style.position="absolute",i.element.style.pointerEvents="auto";var r=n.autoPan;return r&&"object"!=typeof r&&(r={animation:n.autoPanAnimation,margin:n.autoPanMargin}),i.autoPan=r||!1,i.rendered={jt:"",visible:!0},i.mapPostrenderListenerKey=null,i.addChangeListener(wh,i.handleElementChanged),i.addChangeListener(gh,i.handleMapChanged),i.addChangeListener(bh,i.handleOffsetChanged),i.addChangeListener(xh,i.handlePositionChanged),i.addChangeListener(Mh,i.handlePositioningChanged),void 0!==n.element&&i.setElement(n.element),i.setOffset(void 0!==n.offset?n.offset:[0,0]),i.setPositioning(n.positioning||"top-left"),void 0!==n.position&&i.setPosition(n.position),i}return mh(n,t),n.prototype.getElement=function(){return this.get(wh)},n.prototype.getId=function(){return this.id},n.prototype.getMap=function(){return this.get(gh)||null},n.prototype.getOffset=function(){return this.get(bh)},n.prototype.getPosition=function(){return this.get(xh)},n.prototype.getPositioning=function(){return this.get(Mh)},n.prototype.handleElementChanged=function(){Ao(this.element);var t=this.getElement();t&&this.element.appendChild(t)},n.prototype.handleMapChanged=function(){this.mapPostrenderListenerKey&&(To(this.element),H(this.mapPostrenderListenerKey),this.mapPostrenderListenerKey=null);var t=this.getMap();if(t){this.mapPostrenderListenerKey=$(t,vu,this.render,this),this.updatePixelPosition();var n=this.stopEvent?t.getOverlayContainerStopEvent():t.getOverlayContainer();this.insertFirst?n.insertBefore(this.element,n.childNodes[0]||null):n.appendChild(this.element),this.performAutoPan()}},n.prototype.render=function(){this.updatePixelPosition()},n.prototype.handleOffsetChanged=function(){this.updatePixelPosition()},n.prototype.handlePositionChanged=function(){this.updatePixelPosition(),this.performAutoPan()},n.prototype.handlePositioningChanged=function(){this.updatePixelPosition()},n.prototype.setElement=function(t){this.set(wh,t)},n.prototype.setMap=function(t){this.set(gh,t)},n.prototype.setOffset=function(t){this.set(bh,t)},n.prototype.setPosition=function(t){this.set(xh,t)},n.prototype.performAutoPan=function(){this.autoPan&&this.panIntoView(this.autoPan)},n.prototype.panIntoView=function(t){var n=this.getMap();if(n&&n.getTargetElement()&&this.get(xh)){var i=this.getRect(n.getTargetElement(),n.getSize()),r=this.getElement(),e=this.getRect(r,[Oo(r),jo(r)]),o=t||{},s=void 0===o.margin?20:o.margin;if(!xn(i,e)){var u=e[0]-i[0],a=i[2]-e[2],h=e[1]-i[1],f=i[3]-e[3],c=[0,0];if(u<0?c[0]=u-s:a<0&&(c[0]=Math.abs(a)+s),h<0?c[1]=h-s:f<0&&(c[1]=Math.abs(f)+s),0!==c[0]||0!==c[1]){var l=n.getView().getCenterInternal(),v=n.getPixelFromCoordinateInternal(l);if(!v)return;var d=[v[0]+c[0],v[1]+c[1]],p=o.animation||{};n.getView().animateInternal({center:n.getCoordinateFromPixelInternal(d),duration:p.duration,easing:p.easing})}}}},n.prototype.getRect=function(t,n){var i=t.getBoundingClientRect(),r=i.left+window.pageXOffset,e=i.top+window.pageYOffset;return[r,e,r+n[0],e+n[1]]},n.prototype.setPositioning=function(t){this.set(Mh,t)},n.prototype.setVisible=function(t){this.rendered.visible!==t&&(this.element.style.display=t?"":"none",this.rendered.visible=t)},n.prototype.updatePixelPosition=function(){var t=this.getMap(),n=this.getPosition();if(t&&t.isRendered()&&n){var i=t.getPixelFromCoordinate(n),r=t.getSize();this.updateRenderedPosition(i,r)}else this.setVisible(!1)},n.prototype.updateRenderedPosition=function(t,n){var i=this.element.style,r=this.getOffset(),e=this.getPositioning();this.setVisible(!0);var o=Math.round(t[0]+r[0])+"px",s=Math.round(t[1]+r[1])+"px",u="0%",a="0%";"bottom-right"==e||"center-right"==e||"top-right"==e?u="-100%":"bottom-center"!=e&&"center-center"!=e&&"top-center"!=e||(u="-50%"),"bottom-left"==e||"bottom-center"==e||"bottom-right"==e?a="-100%":"center-left"!=e&&"center-center"!=e&&"center-right"!=e||(a="-50%");var h="translate(".concat(u,", ").concat(a,") translate(").concat(o,", ").concat(s,")");this.rendered.jt!=h&&(this.rendered.jt=h,i.transform=h,i.msTransform=h)},n.prototype.getOptions=function(){return this.options},n}(et),Sh=function(){function t(t){this.highWaterMark=void 0!==t?t:2048,this.Ee=0,this.Te={},this.Ae=null,this.Pe=null}return t.prototype.canExpireCache=function(){return this.highWaterMark>0&&this.getCount()>this.highWaterMark},t.prototype.expireCache=function(t){for(;this.canExpireCache();)this.pop()},t.prototype.clear=function(){this.Ee=0,this.Te={},this.Ae=null,this.Pe=null},t.prototype.containsKey=function(t){return this.Te.hasOwnProperty(t)},t.prototype.forEach=function(t){for(var n=this.Ae;n;)t(n.Ce,n.ke,this),n=n.newer},t.prototype.get=function(t,n){var i=this.Te[t];return St(void 0!==i,15),i===this.Pe||(i===this.Ae?(this.Ae=this.Ae.newer,this.Ae.older=null):(i.newer.older=i.older,i.older.newer=i.newer),i.newer=null,i.older=this.Pe,this.Pe.newer=i,this.Pe=i),i.Ce},t.prototype.remove=function(t){var n=this.Te[t];return St(void 0!==n,15),n===this.Pe?(this.Pe=n.older,this.Pe&&(this.Pe.newer=null)):n===this.Ae?(this.Ae=n.newer,this.Ae&&(this.Ae.older=null)):(n.newer.older=n.older,n.older.newer=n.newer),delete this.Te[t],--this.Ee,n.Ce},t.prototype.getCount=function(){return this.Ee},t.prototype.getKeys=function(){var t,n=new Array(this.Ee),i=0;for(t=this.Pe;t;t=t.older)n[i++]=t.ke;return n},t.prototype.getValues=function(){var t,n=new Array(this.Ee),i=0;for(t=this.Pe;t;t=t.older)n[i++]=t.Ce;return n},t.prototype.peekLast=function(){return this.Ae.Ce},t.prototype.peekLastKey=function(){return this.Ae.ke},t.prototype.peekFirstKey=function(){return this.Pe.ke},t.prototype.peek=function(t){if(this.containsKey(t))return this.Te[t].Ce},t.prototype.pop=function(){var t=this.Ae;return delete this.Te[t.ke],t.newer&&(t.newer.older=null),this.Ae=t.newer,this.Ae||(this.Pe=null),--this.Ee,t.Ce},t.prototype.replace=function(t,n){this.get(t),this.Te[t].Ce=n},t.prototype.set=function(t,n){St(!(t in this.Te),16);var i={ke:t,newer:null,older:this.Pe,Ce:n};this.Pe?this.Pe.newer=i:this.Ae=i,this.Pe=i,this.Te[t]=i,++this.Ee},t.prototype.setSize=function(t){this.highWaterMark=t},t}();function Oh(t,n,i,r){return void 0!==r?(r[0]=t,r[1]=n,r[2]=i,r):[t,n,i]}function jh(t,n,i){return t+"/"+n+"/"+i}function Eh(t){return jh(t[0],t[1],t[2])}function Th(t){var n=t.substring(t.lastIndexOf("/")+1,t.length).split(",").map(Number);return jh(n[0],n[1],n[2])}function Ah(t){return t.split("/").map(Number)}function Ph(t){return(t[1]<i||i>n.getMaxZoom())return!1;var o=n.getFullTileRange(i);return!o||o.containsXY(r,e)}var kh=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Ih=function(t){function n(){return null!==t&&t.apply(this,arguments)||this}return kh(n,t),n.prototype.expireCache=function(t){for(;this.canExpireCache();){if(this.peekLast().getKey()in t)break;this.pop().release()}},n.prototype.pruneExceptNewestZ=function(){if(0!==this.getCount()){var t=Ah(this.peekFirstKey())[0];this.forEach(function(n){n.tileCoord[0]!==t&&(this.remove(Eh(n.tileCoord)),n.release())}.bind(this))}},n}(Sh),Nh=function(){function t(t,n,i,r){this.minX=t,this.maxX=n,this.minY=i,this.maxY=r}return t.prototype.contains=function(t){return this.containsXY(t[1],t[2])},t.prototype.containsTileRange=function(t){return this.minX<=t.minX&&t.maxX<=this.maxX&&this.minY<=t.minY&&t.maxY<=this.maxY},t.prototype.containsXY=function(t,n){return this.minX<=t&&t<=this.maxX&&this.minY<=n&&n<=this.maxY},t.prototype.equals=function(t){return this.minX==t.minX&&this.minY==t.minY&&this.maxX==t.maxX&&this.maxY==t.maxY},t.prototype.extend=function(t){t.minXthis.maxX&&(this.maxX=t.maxX),t.minYthis.maxY&&(this.maxY=t.maxY)},t.prototype.getHeight=function(){return this.maxY-this.minY+1},t.prototype.getSize=function(){return[this.getWidth(),this.getHeight()]},t.prototype.getWidth=function(){return this.maxX-this.minX+1},t.prototype.intersects=function(t){return this.minX<=t.maxX&&this.maxX>=t.minX&&this.minY<=t.maxY&&this.maxY>=t.minY},t}();function Lh(t,n,i,r,e){return void 0!==e?(e.minX=t,e.maxX=n,e.minY=i,e.maxY=r,e):new Nh(t,n,i,r)}var zh=Nh,Rh=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Fh=[],Gh=function(t){function n(n,i,r,e){var o=t.call(this,n,i,{transition:0})||this;return o.Ne={},o.executorGroups={},o.declutterExecutorGroups={},o.loadingSourceTiles=0,o.hitDetectionImageData={},o.Le={},o.sourceTiles=[],o.errorTileKeys={},o.wantedResolution,o.getSourceTiles=e.bind(void 0,o),o.wrappedTileCoord=r,o}return Rh(n,t),n.prototype.getContext=function(t){var n=o(t);return n in this.Ne||(this.Ne[n]=_o(1,1,Fh)),this.Ne[n]},n.prototype.hasContext=function(t){return o(t)in this.Ne},n.prototype.getImage=function(t){return this.hasContext(t)?this.getContext(t).canvas:null},n.prototype.getReplayState=function(t){var n=o(t);return n in this.Le||(this.Le[n]={dirty:!1,renderedRenderOrder:null,renderedResolution:NaN,renderedRevision:-1,renderedTileResolution:NaN,renderedTileRevision:-1,renderedTileZ:-1}),this.Le[n]},n.prototype.load=function(){this.getSourceTiles()},n.prototype.release=function(){for(var n in this.Ne){var i=this.Ne[n];So(i),Fh.push(i.canvas),delete this.Ne[n]}t.prototype.release.call(this)},n}(xt),Dh=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),qh=function(t){function n(n,i,r,e,o,s){var u=t.call(this,n,i,s)||this;return u.extent=null,u.ze=e,u.Re=null,u.U,u.projection=null,u.resolution,u.Xt=o,u.Fe=r,u.key=r,u}return Dh(n,t),n.prototype.getFormat=function(){return this.ze},n.prototype.getFeatures=function(){return this.Re},n.prototype.load=function(){this.state==ct&&(this.setState(lt),this.Xt(this,this.Fe),this.U&&this.U(this.extent,this.resolution,this.projection))},n.prototype.onLoad=function(t,n){this.setFeatures(t)},n.prototype.onError=function(){this.setState(dt)},n.prototype.setFeatures=function(t){this.Re=t,this.setState(vt)},n.prototype.setLoader=function(t){this.U=t},n}(xt);function Uh(t){return Array.isArray(t)?qo(t):t}var Bh=!1;function Xh(t,n,i,r,e,o,s){var u=new XMLHttpRequest;u.open("GET","function"==typeof t?t(i,r,e):t,!0),"arraybuffer"==n.getType()&&(u.responseType="arraybuffer"),u.withCredentials=Bh,u.onload=function(t){if(!u.status||u.status>=200&&u.status<300){var r=n.getType(),a=void 0;"json"==r||"text"==r?a=u.responseText:"xml"==r?(a=u.responseXML)||(a=(new DOMParser).parseFromString(u.responseText,"application/xml")):"arraybuffer"==r&&(a=u.response),a?o(n.readFeatures(a,{extent:i,featureProjection:e}),n.readProjection(a)):s()}else s()},u.onerror=s,u.send()}function Vh(t,n){return function(i,r,e,o,s){var u=this;Xh(t,n,i,r,e,(function(t,n){u.addFeatures(t),void 0!==o&&o(t)}),s||j)}}function Wh(t,n){return[[-1/0,-1/0,1/0,1/0]]}var Yh=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}();function Zh(t,n,i,r){var e=document.createElement("script"),s="olc_"+o(n);function u(){delete window[s],e.parentNode.removeChild(e)}e.async=!0,e.src=t+(-1==t.indexOf("?")?"?":"&")+(r||"callback")+"="+s;var a=setTimeout((function(){u(),i&&i()}),1e4);window[s]=function(t){clearTimeout(a),u(),n(t)},document.head.appendChild(e)}var $h,Kh=function(t){function n(n){var i=this,r="Unexpected response status: "+n.status;return(i=t.call(this,r)||this).name="ResponseError",i.response=n,i}return Yh(n,t),n}(Error),Hh=function(t){function n(n){var i=t.call(this,"Failed to issue request")||this;return i.name="ClientError",i.client=n,i}return Yh(n,t),n}(Error);function Jh(t){return new Promise((function(n,i){var r=new XMLHttpRequest;r.addEventListener("load",(function(t){var r=t.target;if(!r.status||r.status>=200&&r.status<300){var e=void 0;try{e=JSON.parse(r.responseText)}catch(t){var o="Error parsing response text as JSON: "+t.message;return void i(new Error(o))}n(e)}else i(new Kh(r))})),r.addEventListener("error",(function(t){i(new Hh(t.target))})),r.open("GET",t),r.setRequestHeader("Accept","application/json"),r.send()}))}function Qh(t,n){return n.indexOf("://")>=0?n:new URL(n,t).href}var tf=function(){function t(){}return t.prototype.drawCustom=function(t,n,i,r){},t.prototype.drawGeometry=function(t){},t.prototype.setStyle=function(t){},t.prototype.drawCircle=function(t,n){},t.prototype.drawFeature=function(t,n){},t.prototype.drawGeometryCollection=function(t,n){},t.prototype.drawLineString=function(t,n){},t.prototype.drawMultiLineString=function(t,n){},t.prototype.drawMultiPoint=function(t,n){},t.prototype.drawMultiPolygon=function(t,n){},t.prototype.drawPoint=function(t,n){},t.prototype.drawPolygon=function(t,n){},t.prototype.drawText=function(t,n){},t.prototype.setFillStrokeStyle=function(t,n){},t.prototype.setImageStyle=function(t,n){},t.prototype.setTextStyle=function(t,n){},t}(),nf=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),rf=function(t){function n(n,i,r,e,o,s,u){var a=t.call(this)||this;return a.Ne=n,a.kt=i,a.st=r,a.jt=e,a.Ge=o,a.De=s,a.qe=u,a.Ue=null,a.Be=null,a.Xe=null,a.Ve=null,a.We=null,a.Lt=null,a.Ye=0,a.Ze=0,a.$e=0,a.Ke=0,a.He=0,a.Je=0,a.Qe=!1,a.no=0,a.io=[0,0],a.ro=0,a.eo="",a.oo=0,a.so=0,a.uo=!1,a.ao=0,a.ho=[0,0],a.fo=null,a.co=null,a.lo=null,a.vo=[],a.do=[1,0,0,1,0,0],a}return nf(n,t),n.prototype.po=function(t,n,i,r){if(this.Lt){var e=Dr(t,n,i,r,this.jt,this.vo),o=this.Ne,s=this.do,u=o.globalAlpha;1!=this.Ke&&(o.globalAlpha=u*this.Ke);var a=this.no;this.Qe&&(a+=this.Ge);for(var h=0,f=e.length;h2||Math.abs(t[4*n+3]-191.25)>2}function mf(t,n,i,r){var e=Er(i,n,t),o=mr(n,r,i),s=n.getMetersPerUnit();void 0!==s&&(o*=s);var u=t.getMetersPerUnit();void 0!==u&&(o/=u);var a=t.getExtent();if(!a||bn(a,e)){var h=mr(t,o,e)/o;isFinite(h)&&h>0&&(o/=h)}return o}function wf(t,n,i,r){var e=qn(i),o=mf(t,n,e,r);return(!isFinite(o)||o<=0)&&Rn(i,(function(i){return o=mf(t,n,i,r),isFinite(o)&&o>0})),o}function gf(t,n,i,r,e,o,s,u,a,h,f,c){var l=_o(Math.round(i*t),Math.round(i*n),df);if(c||A(l,lf),0===a.length)return l.canvas;function v(t){return Math.round(t*i)/i}l.scale(i,i),l.globalCompositeOperation="lighter";var d=[1/0,1/0,-1/0,-1/0];a.forEach((function(t,n,i){Cn(d,t.extent)}));var p=$n(d),y=Vn(d),m=_o(Math.round(i*p/r),Math.round(i*y/r));c||A(m,lf);var w=i/r;a.forEach((function(t,n,i){var r=t.extent[0]-d[0],e=-(t.extent[3]-d[3]),o=$n(t.extent),s=Vn(t.extent);t.image.width>0&&t.image.height>0&&m.drawImage(t.image,h,h,t.image.width-2*h,t.image.height-2*h,r*w,e*w,o*w,s*w)}));var g=Yn(s);return u.getTriangles().forEach((function(t,n,e){var s=t.source,u=t.target,a=s[0][0],h=s[0][1],f=s[1][0],p=s[1][1],y=s[2][0],w=s[2][1],b=v((u[0][0]-g[0])/o),x=v(-(u[0][1]-g[1])/o),M=v((u[1][0]-g[0])/o),_=v(-(u[1][1]-g[1])/o),S=v((u[2][0]-g[0])/o),O=v(-(u[2][1]-g[1])/o),j=a,E=h;a=0,h=0;var T=fi([[f-=j,p-=E,0,0,M-b],[y-=j,w-=E,0,0,S-b],[0,0,f,p,_-x],[0,0,y,w,O-x]]);if(T){if(l.save(),l.beginPath(),function(){if(void 0===cf){var t=document.createElement("canvas").getContext("2d");t.globalCompositeOperation="lighter",t.fillStyle="rgba(210, 0, 0, 0.75)",pf(t,4,5,4,0),pf(t,4,5,0,5);var n=t.getImageData(0,0,3,3).data;cf=yf(n,0)||yf(n,4)||yf(n,8)}return cf}()||!c){l.moveTo(M,_);for(var A=b-M,P=x-_,C=0;C<4;C++)l.lineTo(M+v((C+1)*A/4),_+v(C*P/3)),3!=C&&l.lineTo(M+v((C+1)*A/4),_+v((C+1)*P/3));l.lineTo(S,O)}else l.moveTo(M,_),l.lineTo(b,x),l.lineTo(S,O);l.clip(),l.transform(T[0],T[2],T[1],T[3],b,x),l.translate(d[0]-j,d[3]-E),l.scale(r/i,-r/i),l.drawImage(m.canvas,0,0),l.restore()}})),f&&(l.save(),l.globalCompositeOperation="source-over",l.strokeStyle="black",l.lineWidth=1,u.getTriangles().forEach((function(t,n,i){var r=t.target,e=(r[0][0]-g[0])/o,s=-(r[0][1]-g[1])/o,u=(r[1][0]-g[0])/o,a=-(r[1][1]-g[1])/o,h=(r[2][0]-g[0])/o,f=-(r[2][1]-g[1])/o;l.beginPath(),l.moveTo(u,a),l.lineTo(e,s),l.lineTo(h,f),l.closePath(),l.stroke()})),l.restore()),l.canvas}var bf=[0,0,0],xf=function(){function t(t){var n;if(this.minZoom=void 0!==t.minZoom?t.minZoom:0,this.Ti=t.resolutions,St(_(this.Ti,(function(t,n){return n-t}),!0),17),!t.origins)for(var i=0,r=this.Ti.length-1;i=this.minZoom;){if(n(u,2===this.Ei?Lh(e=Math.floor(e/2),e,o=Math.floor(o/2),o,i):this.getTileRangeForExtentAndZ(s,u,i)))return!0;--u}return!1},t.prototype.getExtent=function(){return this.st},t.prototype.getMaxZoom=function(){return this.maxZoom},t.prototype.getMinZoom=function(){return this.minZoom},t.prototype.getOrigin=function(t){return this._o?this._o:this.So[t]},t.prototype.getResolution=function(t){return this.Ti[t]},t.prototype.getResolutions=function(){return this.Ti},t.prototype.getTileCoordChildTileRange=function(t,n,i){if(t[0]this.maxZoom||n0?r:Math.max(s/u[0],o/u[1]),h=e+1,f=new Array(h),c=0;c0))){var i=Uf(n.canvas).getExtension("WEBGL_lose_context");i&&i.loseContext(),delete Cc[t]}}(this.Yo),delete this.Io,delete this.qt},n.prototype.prepareDraw=function(t,n){var i=this.getGL(),r=this.getCanvas(),e=t.size,o=t.pixelRatio;r.width=e[0]*o,r.height=e[1]*o,r.style.width=e[0]+"px",r.style.height=e[1]+"px",i.useProgram(this.Ko);for(var s=this.rs.length-1;s>=0;s--)this.rs[s].init(t);i.bindTexture(i.TEXTURE_2D,null),i.clearColor(0,0,0,0),i.clear(i.COLOR_BUFFER_BIT),i.enable(i.BLEND),i.blendFunc(i.ONE,n?i.ZERO:i.ONE_MINUS_SRC_ALPHA),i.useProgram(this.Ko),this.applyFrameState(t),this.applyUniforms(t)},n.prototype.prepareDrawToRenderTarget=function(t,n,i){var r=this.getGL(),e=n.getSize();r.bindFramebuffer(r.FRAMEBUFFER,n.getFramebuffer()),r.viewport(0,0,e[0],e[1]),r.bindTexture(r.TEXTURE_2D,n.getTexture()),r.clearColor(0,0,0,0),r.clear(r.COLOR_BUFFER_BIT),r.enable(r.BLEND),r.blendFunc(r.ONE,i?r.ZERO:r.ONE_MINUS_SRC_ALPHA),r.useProgram(this.Ko),this.applyFrameState(t),this.applyUniforms(t)},n.prototype.drawElements=function(t,n){var i=this.getGL();this.getExtension("OES_element_index_uint");var r=i.UNSIGNED_INT,e=n-t,o=4*t;i.drawElements(i.TRIANGLES,e,r,o)},n.prototype.finalizeDraw=function(t,n,i){for(var r=0,e=this.rs.length;rthis.W[0]||n>=this.W[1])return Fc[0]=0,Fc[1]=0,Fc[2]=0,Fc[3]=0,Fc;this.readAll();var i=Math.floor(t)+(this.W[1]-Math.floor(n)-1)*this.W[0];return Fc[0]=this.B[4*i],Fc[1]=this.B[4*i+1],Fc[2]=this.B[4*i+2],Fc[3]=this.B[4*i+3],Fc},t.prototype.getTexture=function(){return this.ss},t.prototype.getFramebuffer=function(){return this.hs},t.prototype.cs=function(){var t=this.W,n=this.us.getGL();this.ss=this.us.createTexture(t,null,this.ss),n.bindFramebuffer(n.FRAMEBUFFER,this.hs),n.viewport(0,0,t[0],t[1]),n.framebufferTexture2D(n.FRAMEBUFFER,n.COLOR_ATTACHMENT0,n.TEXTURE_2D,this.ss,0),this.B=new Uint8Array(t[0]*t[1]*4)},t}(),Dc=!0,qc=function(){function t(t,n,i,r,e,o){this.ls=t,this.vs=n;var s={},u=jr(this.vs,this.ls);this.ds=function(t){var n=t[0]+"/"+t[1];return s[n]||(s[n]=u(t)),s[n]},this.ps=r,this.ys=e*e,this.ws=[],this.gs=!1,this.bs=this.ls.canWrapX()&&!!r&&!!this.ls.getExtent()&&$n(r)==$n(this.ls.getExtent()),this.xs=this.ls.getExtent()?$n(this.ls.getExtent()):null,this.Ms=this.vs.getExtent()?$n(this.vs.getExtent()):null;var a=Yn(i),h=Zn(i),f=Dn(i),c=Gn(i),l=this.ds(a),v=this.ds(h),d=this.ds(f),p=this.ds(c),y=10+(o?Math.max(0,Math.ceil(ui(Fn(i)/(o*o*256*256)))):0);if(this._s(a,h,f,c,l,v,d,p,y),this.gs){var m=1/0;this.ws.forEach((function(t,n,i){m=Math.min(m,t.source[0][0],t.source[1][0],t.source[2][0])})),this.ws.forEach(function(t){if(Math.max(t.source[0][0],t.source[1][0],t.source[2][0])-m>this.xs/2){var n=[[t.source[0][0],t.source[0][1]],[t.source[1][0],t.source[1][1]],[t.source[2][0],t.source[2][1]]];n[0][0]-m>this.xs/2&&(n[0][0]-=this.xs),n[1][0]-m>this.xs/2&&(n[1][0]-=this.xs),n[2][0]-m>this.xs/2&&(n[2][0]-=this.xs);var i=Math.min(n[0][0],n[1][0],n[2][0]);Math.max(n[0][0],n[1][0],n[2][0])-i.5&&f<1,v=!1;if(a>0){if(this.vs.isGlobal()&&this.Ms)v=$n(yn([t,n,i,r]))/this.Ms>.25||v;!l&&this.ls.isGlobal()&&f&&(v=f>.25||v)}if(!(!v&&this.ps&&isFinite(h[0])&&isFinite(h[1])&&isFinite(h[2])&&isFinite(h[3]))||Kn(h,this.ps)){var d=0;if(!(v||isFinite(e[0])&&isFinite(e[1])&&isFinite(o[0])&&isFinite(o[1])&&isFinite(s[0])&&isFinite(s[1])&&isFinite(u[0])&&isFinite(u[1])))if(a>0)v=!0;else if(1!=(d=(isFinite(e[0])&&isFinite(e[1])?0:8)+(isFinite(o[0])&&isFinite(o[1])?0:4)+(isFinite(s[0])&&isFinite(s[1])?0:2)+(isFinite(u[0])&&isFinite(u[1])?0:1))&&2!=d&&4!=d&&8!=d)return;if(a>0){if(!v){var p=[(t[0]+i[0])/2,(t[1]+i[1])/2],y=this.ds(p),m=void 0;if(l)m=(vi(e[0],c)+vi(s[0],c))/2-vi(y[0],c);else m=(e[0]+s[0])/2-y[0];var w=(e[1]+s[1])/2-y[1];v=m*m+w*w>this.ys}if(v){if(Math.abs(t[0]-i[0])<=Math.abs(t[1]-i[1])){var g=[(n[0]+i[0])/2,(n[1]+i[1])/2],b=this.ds(g),x=[(r[0]+t[0])/2,(r[1]+t[1])/2],M=this.ds(x);this._s(t,n,g,x,e,o,b,M,a-1),this._s(x,g,i,r,M,b,s,u,a-1)}else{var _=[(t[0]+n[0])/2,(t[1]+n[1])/2],S=this.ds(_),O=[(i[0]+r[0])/2,(i[1]+r[1])/2],j=this.ds(O);this._s(t,_,O,r,e,S,j,u,a-1),this._s(_,n,i,O,S,o,s,j,a-1)}return}}if(l){if(!this.bs)return;this.gs=!0}0==(11&d)&&this.Ss(t,i,r,e,s,u),0==(14&d)&&this.Ss(t,i,n,e,s,o),d&&(0==(13&d)&&this.Ss(n,r,t,o,u,e),0==(7&d)&&this.Ss(n,r,i,o,u,s))}},t.prototype.calculateSourceExtent=function(){var t=[1/0,1/0,-1/0,-1/0];return this.ws.forEach((function(n,i,r){var e=n.source;kn(t,e[0]),kn(t,e[1]),kn(t,e[2])})),t},t.prototype.getTriangles=function(){return this.ws},t}(),Uc=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Bc=function(t){function n(n,i,r,e,o,s,u,a,h,f,c,l){var v=t.call(this,o,ct,{interpolate:!!l})||this;v.Os=void 0!==c&&c,v.kt=u,v.js=a,v.qt=null,v.Es=i,v.Ts=e,v.As=s||o,v.Ps=[],v.Cs=null,v.ks=0;var d=e.getTileCoordExtent(v.As),p=v.Ts.getExtent(),y=v.Es.getExtent(),m=p?Wn(d,p):d;if(0===Fn(m))return v.state=pt,v;var w=n.getExtent();w&&(y=y?Wn(y,w):w);var g=e.getResolution(v.As[0]),b=wf(n,r,m,g);if(!isFinite(b)||b<=0)return v.state=pt,v;var x=void 0!==f?f:.5;if(v.Is=new qc(n,r,m,y,b*x,g),0===v.Is.getTriangles().length)return v.state=pt,v;v.ks=i.getZForResolution(b);var M=v.Is.calculateSourceExtent();if(y&&(n.canWrapX()?(M[1]=oi(M[1],y[1],y[3]),M[3]=oi(M[3],y[1],y[3])):M=Wn(M,y)),Fn(M)){for(var _=i.getTileRangeForExtentAndZ(M,v.ks),S=_.minX;S<=_.maxX;S++)for(var O=_.minY;O<=_.maxY;O++){var j=h(v.ks,S,O,u);j&&v.Ps.push(j)}0===v.Ps.length&&(v.state=pt)}else v.state=pt;return v}return Uc(n,t),n.prototype.getImage=function(){return this.qt},n.prototype.Ns=function(){var t=[];if(this.Ps.forEach(function(n,i,r){n&&n.getState()==vt&&t.push({extent:this.Es.getTileCoordExtent(n.tileCoord),image:n.getImage()})}.bind(this)),this.Ps.length=0,0===t.length)this.state=dt;else{var n=this.As[0],i=this.Ts.getTileSize(n),r="number"==typeof i?i:i[0],e="number"==typeof i?i:i[1],o=this.Ts.getResolution(n),s=this.Es.getResolution(this.ks),u=this.Ts.getTileCoordExtent(this.As);this.qt=gf(r,e,this.kt,s,this.Es.getExtent(),o,u,this.Is,t,this.js,this.Os,this.interpolate),this.state=vt}this.changed()},n.prototype.load=function(){if(this.state==ct){this.state=lt,this.changed();var t=0;this.Cs=[],this.Ps.forEach(function(n,i,r){var e=n.getState();if(e==ct||e==lt){t++;var o=$(n,L,(function(i){var r=n.getState();r!=vt&&r!=dt&&r!=pt||(H(o),0===--t&&(this.Ls(),this.Ns()))}),this);this.Cs.push(o)}}.bind(this)),0===t?setTimeout(this.Ns.bind(this),0):this.Ps.forEach((function(t,n,i){t.getState()==ct&&t.load()}))}},n.prototype.Ls=function(){this.Cs.forEach(H),this.Cs=null},n.prototype.release=function(){this.qt&&(So(this.qt.getContext("2d")),df.push(this.qt),this.qt=null),t.prototype.release.call(this)},n}(xt),Xc=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}();function Vc(t,n,i){var r=i?t.LINEAR:t.NEAREST;t.bindTexture(t.TEXTURE_2D,n),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,r),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,r)}function Wc(t,n,i,r,e,o){var s,u,a=t.getGL();i instanceof Float32Array?(s=a.FLOAT,t.getExtension("OES_texture_float"),u=null!==t.getExtension("OES_texture_float_linear")):(s=a.UNSIGNED_BYTE,u=!0);Vc(a,n,o&&u);var h,f=i.byteLength/r[1],c=1;switch(f%8==0?c=8:f%4==0?c=4:f%2==0&&(c=2),e){case 1:h=a.LUMINANCE;break;case 2:h=a.LUMINANCE_ALPHA;break;case 3:h=a.RGB;break;case 4:h=a.RGBA;break;default:throw new Error("Unsupported number of bands: ".concat(e))}var l=a.getParameter(a.UNPACK_ALIGNMENT);a.pixelStorei(a.UNPACK_ALIGNMENT,c),a.texImage2D(a.TEXTURE_2D,0,h,r[0],r[1],0,h,s,i),a.pixelStorei(a.UNPACK_ALIGNMENT,l)}var Yc=null;var Zc=function(t){function n(n){var i=t.call(this)||this;i.tile,i.textures=[],i.cr=i.cr.bind(i),i.zs=Qu(n.grid.getTileSize(n.tile.tileCoord[0])),i.js=n.gutter||0,i.bandCount=NaN,i.us=n.helper;var r=new mc(zf,Ff);return r.fromArray([0,1,1,1,1,0,0,0]),i.us.flushBufferData(r),i.coords=r,i.setTile(n.tile),i}return Xc(n,t),n.prototype.setTile=function(t){if(t!==this.tile)if(this.tile&&this.tile.removeEventListener(L,this.cr),this.tile=t,this.textures.length=0,this.loaded=t.getState()===vt,this.loaded)this.Rs();else{if(t instanceof ko){var n=t.getImage();n instanceof Image&&!n.crossOrigin&&(n.crossOrigin="anonymous")}t.addEventListener(L,this.cr)}},n.prototype.Rs=function(){var t=this.us,n=t.getGL(),i=this.tile;if(i instanceof ko||i instanceof Bc){var r=n.createTexture();return this.textures.push(r),this.bandCount=4,void function(t,n,i,r){Vc(t,n,r),t.texImage2D(t.TEXTURE_2D,0,t.RGBA,t.RGBA,t.UNSIGNED_BYTE,i)}(n,r,i.getImage(),i.interpolate)}var e=i.getSize(),o=[e[0]+2*this.js,e[1]+2*this.js],s=i.getData(),u=s instanceof Float32Array,a=o[0]*o[1],h=u?Float32Array:Uint8Array,f=h.BYTES_PER_ELEMENT,c=s.byteLength/o[1];this.bandCount=Math.floor(c/f/o[0]);var l=Math.ceil(this.bandCount/4);if(1===l){r=n.createTexture();return this.textures.push(r),void Wc(t,r,s,o,this.bandCount,i.interpolate)}for(var v=new Array(l),d=0;d=v;--d)for(var p=a.getTileRangeForExtentAndZ(n,d,this.Ys),y=a.getResolution(d),m=p.minX;m<=p.maxX;++m)for(var w=p.minY;w<=p.maxY;++w){var g=Oh(d,m,w,this.Zs),b=dl(u,g),x=void 0,M=void 0;if(l.containsKey(b)&&(M=(x=l.get(b)).tile),!x||x.tile.key!==u.getKey())if(M=u.getTile(d,m,w,t.pixelRatio,e.projection),x)if(this.iu(M))x.setTile(M);else{var _=M.getInterimTile();x.setTile(_)}else x=new Zc({tile:M,grid:a,helper:this.helper,gutter:h}),l.set(b,x);ll(r,x,d);var S=M.getKey();c[S]=!0,M.getState()===ct&&(t.tileQueue.isKeyQueued(S)||t.tileQueue.enqueue([M,f,a.getTileCoordCenter(g),y]))}},n.prototype.renderFrame=function(t){this.Zi=t,this.renderComplete=!0;var n=this.helper.getGL();this.preRender(n,t);var i=t.viewState,r=this.getLayer().getRenderSource(),e=r.getTileGridForProjection(i.projection),s=r.getGutterForProjection(i.projection),u=vl(t,t.extent),a=e.getZForResolution(i.resolution,r.zDirection),h={};if(t.nextExtent){var f=e.getZForResolution(i.nextResolution,r.zDirection),c=vl(t,t.nextExtent);this.enqueueTiles(t,c,f,h)}this.enqueueTiles(t,u,a,h);for(var l={},v=o(this),d=t.time,y=!1,m=h[a],w=0,g=m.length;w=x;--M){if(this.ru(e,b,M,h))break}}this.helper.useProgram(this.Ks),this.helper.prepareDraw(t,!y);for(var _=Object.keys(h).map(Number).sort(p),S=i.center[0],O=i.center[1],j=0,E=_.length;j0&&Wn(H=e.getTileCoordExtent(b),u,H),this.helper.setUniformFloatVec4(ul.RENDER_EXTENT,H),this.helper.setUniformFloatValue(ul.RESOLUTION,i.resolution),this.helper.setUniformFloatValue(ul.ZOOM,i.zoom),this.helper.drawElements(0,this.Qs.getSize())}}}this.helper.finalizeDraw(t,this.dispatchPreComposeEvent,this.dispatchPostComposeEvent);for(var J=this.helper.getCanvas(),Q=this.tu;Q.canExpireCache();){var tt;(tt=Q.pop()).dispose()}return t.postRenderFunctions.push((function(t,n){r.expireCache(n.viewState.projection,fl)})),this.postRender(n,t),J},n.prototype.getData=function(t){if(!this.helper.getGL())return null;var n=this.Zi;if(!n)return null;var i=this.getLayer(),r=tn(n.pixelToCoordinateTransform,t.slice()),e=n.viewState,o=i.getExtent();if(o&&!bn(Lr(o,e.projection),r))return null;var s,u,a,h=i.getSources(yn([r]),e.resolution);for(s=h.length-1;s>=0;--s)if("ready"===(u=h[s]).getState()){if(a=u.getTileGridForProjection(e.projection),u.getWrapX())break;var f=a.getExtent();if(!f||bn(f,r))break}if(s<0)return null;for(var c=this.tu,l=a.getZForResolution(e.resolution);l>=a.getMinZoom();--l){var v=a.getTileCoordForCoordAndZ(r,l),d=dl(u,v);if(c.containsKey(d)){var p=c.get(d);if(p.loaded){var y=a.getOrigin(l),m=Qu(a.getTileSize(l)),w=a.getResolution(l),g=(r[0]-y[0])/w-v[1]*m[0],b=(y[1]-r[1])/w-v[2]*m[1];return p.getPixelData(g,b)}}}return null},n.prototype.ru=function(t,n,i,r){var e=t.getTileRangeForTileCoordAndZ(n,i,this.Ys);if(!e)return!1;for(var o=!0,s=this.tu,u=this.getLayer().getRenderSource(),a=e.minX;a<=e.maxX;++a)for(var h=e.minY;h<=e.maxY;++h){var f=dl(u,[i,a,h]),c=!1;if(s.containsKey(f)){var l=s.get(f);l.loaded&&(ll(r,l,i),c=!0)}c||(o=!1)}return o},n.prototype.removeHelper=function(){if(this.helper){var n=this.tu;n.forEach((function(t){return t.dispose()})),n.clear()}t.prototype.removeHelper.call(this)},n.prototype.disposeInternal=function(){var n=this.helper;n&&(n.getGL().deleteProgram(this.Ks),delete this.Ks,n.deleteBuffer(this.Qs));t.prototype.disposeInternal.call(this),delete this.Qs,delete this.tu,delete this.Zi},n}(ol),yl=1,ml=2,wl=4,gl=8,bl=16,xl=31,Ml=0,_l={};function Sl(t){if("number"==typeof t)return yl;if("boolean"==typeof t)return gl;if("string"==typeof t)return Uo(t)?wl|ml:ml;if(!Array.isArray(t))throw new Error("Unhandled value type: ".concat(JSON.stringify(t)));var n=t;if(n.every((function(t){return"number"==typeof t})))return 3===n.length||4===n.length?wl|bl:bl;if("string"!=typeof n[0])throw new Error("Expected an expression operator but received: ".concat(JSON.stringify(n)));var i=_l[n[0]];if(void 0===i)throw new Error("Unrecognized expression operator: ".concat(JSON.stringify(n)));return i.getReturnType(n.slice(1))}function Ol(t){return ui(t)%1==0}function jl(t){var n=t.toString();return-1===n.indexOf(".")?n+".0":n}function El(t){if(t.length<2||t.length>4)throw new Error("`formatArray` can only output `vec2`, `vec3` or `vec4` arrays.");return"vec".concat(t.length,"(").concat(t.map(jl).join(", "),")")}function Tl(t){var n=Go(t).slice();return n.length<4&&n.push(1),El(n.map((function(t,n){return n<3?t/255:t})))}function Al(t,n){return void 0===t.stringLiteralsMap[n]&&(t.stringLiteralsMap[n]=Object.keys(t.stringLiteralsMap).length),t.stringLiteralsMap[n]}function Pl(t,n){return jl(Al(t,n))}function Cl(t,n,i){if(Array.isArray(n)&&"string"==typeof n[0]){var r=_l[n[0]];if(void 0===r)throw new Error("Unrecognized expression operator: ".concat(JSON.stringify(n)));return r.toGlsl(t,n.slice(1),i)}var e=Sl(n);if((e&yl)>0)return jl(n);if((e&gl)>0)return n.toString();if((e&ml)>0&&(void 0===i||i==ml))return Pl(t,n.toString());if((e&wl)>0&&(void 0===i||i==wl))return Tl(n);if((e&bl)>0)return El(n);throw new Error("Unexpected expression ".concat(n," (expected type ").concat(i,")"))}function kl(t){if(!(Sl(t)&yl))throw new Error("A numeric value was expected, got ".concat(JSON.stringify(t)," instead"))}function Il(t){for(var n=0;nn)throw new Error("At most ".concat(n," arguments were expected, got ").concat(t.length," instead"))}function Gl(t){if(t.length%2!=0)throw new Error("An even amount of arguments was expected, got ".concat(t," instead"))}function Dl(t,n){if(!Ol(n))throw new Error("Could not infer only one type from the following expression: ".concat(JSON.stringify(t)))}function ql(t){return"u_var_"+t}_l.get={getReturnType:function(t){return xl},toGlsl:function(t,n){zl(n,1),Nl(n[0]);var i=n[0].toString();return-1===t.attributes.indexOf(i)&&t.attributes.push(i),(t.inFragmentShader?"v_":"a_")+i}},_l.var={getReturnType:function(t){return xl},toGlsl:function(t,n){zl(n,1),Nl(n[0]);var i=n[0].toString();return-1===t.variables.indexOf(i)&&t.variables.push(i),ql(i)}};var Ul="u_paletteTextures";_l.palette={getReturnType:function(t){return wl},toGlsl:function(t,n){zl(n,2),kl(n[0]);var i=Cl(t,n[0]),r=n[1];if(!Array.isArray(r))throw new Error("The second argument of palette must be an array");for(var e=r.length,o=new Uint8Array(4*e),s=0;s"]={getReturnType:function(t){return gl},toGlsl:function(t,n){return zl(n,2),Il(n),"(".concat(Cl(t,n[0])," > ").concat(Cl(t,n[1]),")")}},_l[">="]={getReturnType:function(t){return gl},toGlsl:function(t,n){return zl(n,2),Il(n),"(".concat(Cl(t,n[0])," >= ").concat(Cl(t,n[1]),")")}},_l["<"]={getReturnType:function(t){return gl},toGlsl:function(t,n){return zl(n,2),Il(n),"(".concat(Cl(t,n[0])," < ").concat(Cl(t,n[1]),")")}},_l["<="]={getReturnType:function(t){return gl},toGlsl:function(t,n){return zl(n,2),Il(n),"(".concat(Cl(t,n[0])," <= ").concat(Cl(t,n[1]),")")}},_l["=="]=Xl("=="),_l["!="]=Xl("!="),_l["!"]={getReturnType:function(t){return gl},toGlsl:function(t,n){return zl(n,1),Ll(n[0]),"(!".concat(Cl(t,n[0]),")")}},_l.all=Vl("&&"),_l.any=Vl("||"),_l.between={getReturnType:function(t){return gl},toGlsl:function(t,n){zl(n,3),Il(n);var i=Cl(t,n[1]),r=Cl(t,n[2]),e=Cl(t,n[0]);return"(".concat(e," >= ").concat(i," && ").concat(e," <= ").concat(r,")")}},_l.array={getReturnType:function(t){return bl},toGlsl:function(t,n){Rl(n,2),Fl(n,4),Il(n);var i=n.map((function(n){return Cl(t,n,yl)}));return"vec".concat(n.length,"(").concat(i.join(", "),")")}},_l.color={getReturnType:function(t){return wl},toGlsl:function(t,n){Rl(n,3),Fl(n,4),Il(n);var i=n;3===n.length&&i.push(1);var r=n.map((function(n,i){return Cl(t,n,yl)+(i<3?" / 255.0":"")}));return"vec".concat(n.length,"(").concat(r.join(", "),")")}},_l.interpolate={getReturnType:function(t){for(var n=wl|yl,i=3;i=1;a-=2){var h=Cl(t,n[a]),f=Cl(t,n[a+1],e);u="(".concat(o," == ").concat(h," ? ").concat(f," : ").concat(u||s,")")}return u}},_l.case={getReturnType:function(t){for(var n=xl,i=1;i=0;o-=2){var a=Cl(t,n[o]),h=Cl(t,n[o+1],e);u="(".concat(a," ? ").concat(h," : ").concat(u||s,")")}return u}};var Wl=function(){function t(){this.uniforms=[],this.attributes=[],this.varyings=[],this.sizeExpression="vec2(1.0)",this.rotationExpression="0.0",this.offsetExpression="vec2(0.0)",this.colorExpression="vec4(1.0)",this.texCoordExpression="vec4(0.0, 0.0, 1.0, 1.0)",this.discardExpression="false",this.rotateWithView=!1}return t.prototype.addUniform=function(t){return this.uniforms.push(t),this},t.prototype.addAttribute=function(t){return this.attributes.push(t),this},t.prototype.addVarying=function(t,n,i){return this.varyings.push({name:t,type:n,expression:i}),this},t.prototype.setSizeExpression=function(t){return this.sizeExpression=t,this},t.prototype.setRotationExpression=function(t){return this.rotationExpression=t,this},t.prototype.setSymbolOffsetExpression=function(t){return this.offsetExpression=t,this},t.prototype.setColorExpression=function(t){return this.colorExpression=t,this},t.prototype.setTextureCoordinateExpression=function(t){return this.texCoordExpression=t,this},t.prototype.setFragmentDiscardExpression=function(t){return this.discardExpression=t,this},t.prototype.setSymbolRotateWithView=function(t){return this.rotateWithView=t,this},t.prototype.getSizeExpression=function(){return this.sizeExpression},t.prototype.getOffsetExpression=function(){return this.offsetExpression},t.prototype.getColorExpression=function(){return this.colorExpression},t.prototype.getTextureCoordinateExpression=function(){return this.texCoordExpression},t.prototype.getFragmentDiscardExpression=function(){return this.discardExpression},t.prototype.getSymbolVertexShader=function(t){var n=this.rotateWithView?"u_offsetScaleMatrix * u_offsetRotateMatrix":"u_offsetScaleMatrix",i=this.attributes,r=this.varyings;return t&&(i=i.concat("vec4 a_hitColor"),r=r.concat({name:"v_hitColor",type:"vec4",expression:"a_hitColor"})),"precision mediump float;\nuniform mat4 u_projectionMatrix;\nuniform mat4 u_offsetScaleMatrix;\nuniform mat4 u_offsetRotateMatrix;\nuniform float u_time;\nuniform float u_zoom;\nuniform float u_resolution;\n".concat(this.uniforms.map((function(t){return"uniform "+t+";"})).join("\n"),"\nattribute vec2 a_position;\nattribute float a_index;\n").concat(i.map((function(t){return"attribute "+t+";"})).join("\n"),"\nvarying vec2 v_texCoord;\nvarying vec2 v_quadCoord;\n").concat(r.map((function(t){return"varying "+t.type+" "+t.name+";"})).join("\n"),"\nvoid main(void) {\n mat4 offsetMatrix = ").concat(n,";\n vec2 halfSize = ").concat(this.sizeExpression," * 0.5;\n vec2 offset = ").concat(this.offsetExpression,";\n float angle = ").concat(this.rotationExpression,";\n float offsetX;\n float offsetY;\n if (a_index == 0.0) {\n offsetX = (offset.x - halfSize.x) * cos(angle) + (offset.y - halfSize.y) * sin(angle);\n offsetY = (offset.y - halfSize.y) * cos(angle) - (offset.x - halfSize.x) * sin(angle);\n } else if (a_index == 1.0) {\n offsetX = (offset.x + halfSize.x) * cos(angle) + (offset.y - halfSize.y) * sin(angle);\n offsetY = (offset.y - halfSize.y) * cos(angle) - (offset.x + halfSize.x) * sin(angle);\n } else if (a_index == 2.0) {\n offsetX = (offset.x + halfSize.x) * cos(angle) + (offset.y + halfSize.y) * sin(angle);\n offsetY = (offset.y + halfSize.y) * cos(angle) - (offset.x + halfSize.x) * sin(angle);\n } else {\n offsetX = (offset.x - halfSize.x) * cos(angle) + (offset.y + halfSize.y) * sin(angle);\n offsetY = (offset.y + halfSize.y) * cos(angle) - (offset.x - halfSize.x) * sin(angle);\n }\n vec4 offsets = offsetMatrix * vec4(offsetX, offsetY, 0.0, 0.0);\n gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;\n vec4 texCoord = ").concat(this.texCoordExpression,";\n float u = a_index == 0.0 || a_index == 3.0 ? texCoord.s : texCoord.p;\n float v = a_index == 2.0 || a_index == 3.0 ? texCoord.t : texCoord.q;\n v_texCoord = vec2(u, v);\n u = a_index == 0.0 || a_index == 3.0 ? 0.0 : 1.0;\n v = a_index == 2.0 || a_index == 3.0 ? 0.0 : 1.0;\n v_quadCoord = vec2(u, v);\n").concat(r.map((function(t){return" "+t.name+" = "+t.expression+";"})).join("\n"),"\n}")},t.prototype.getSymbolFragmentShader=function(t){var n=t?" if (gl_FragColor.a < 0.1) { discard; } gl_FragColor = v_hitColor;":"",i=this.varyings;return t&&(i=i.concat({name:"v_hitColor",type:"vec4",expression:"a_hitColor"})),"precision mediump float;\nuniform float u_time;\nuniform float u_zoom;\nuniform float u_resolution;\n".concat(this.uniforms.map((function(t){return"uniform "+t+";"})).join("\n"),"\nvarying vec2 v_texCoord;\nvarying vec2 v_quadCoord;\n").concat(i.map((function(t){return"varying "+t.type+" "+t.name+";"})).join("\n"),"\nvoid main(void) {\n if (").concat(this.discardExpression,") { discard; }\n gl_FragColor = ").concat(this.colorExpression,";\n gl_FragColor.rgb *= gl_FragColor.a;\n").concat(n,"\n}")},t}();function Yl(t){var n=t.symbol,i=void 0!==n.size?n.size:1,r=n.color||"white",e=n.textureCoord||[0,0,1,1],o=n.offset||[0,0],s=void 0!==n.opacity?n.opacity:1,u=void 0!==n.rotation?n.rotation:0,a={inFragmentShader:!1,variables:[],attributes:[],stringLiteralsMap:{},functions:{}},h=Cl(a,i,bl|yl),f=Cl(a,o,bl),c=Cl(a,e,bl),l=Cl(a,u,yl),v={inFragmentShader:!0,variables:a.variables,attributes:[],stringLiteralsMap:a.stringLiteralsMap,functions:{}},d=Cl(v,r,wl),p=Cl(v,s,yl),y="1.0",m="vec2(".concat(Cl(v,i,bl|yl),").x");switch(n.symbolType){case"square":case"image":break;case"circle":y="(1.0-smoothstep(1.-4./".concat(m,",1.,dot(v_quadCoord-.5,v_quadCoord-.5)*4.))");break;case"triangle":var w="(v_quadCoord*2.-1.)",g="(atan(".concat(w,".x,").concat(w,".y))");y="(1.0-smoothstep(.5-3./".concat(m,",.5,cos(floor(.5+").concat(g,"/2.094395102)*2.094395102-").concat(g,")*length(").concat(w,")))");break;default:throw new Error("Unexpected symbol type: "+n.symbolType)}var b=(new Wl).setSizeExpression("vec2(".concat(h,")")).setRotationExpression(l).setSymbolOffsetExpression(f).setTextureCoordinateExpression(c).setSymbolRotateWithView(!!n.rotateWithView).setColorExpression("vec4(".concat(d,".rgb, ").concat(d,".a * ").concat(p," * ").concat(y,")"));if(t.filter){var x=Cl(v,t.filter,gl);b.setFragmentDiscardExpression("!".concat(x))}var M={};if(v.variables.forEach((function(n){var i=ql(n);b.addUniform("float ".concat(i)),M[i]=function(){if(!t.variables||void 0===t.variables[n])throw new Error("The following variable is missing from the style: ".concat(n));var i=t.variables[n];return"string"==typeof i&&(i=Al(a,i)),void 0!==i?i:-9999999}})),"image"===n.symbolType&&n.src){var _=new Image;_.crossOrigin=void 0===n.crossOrigin?"anonymous":n.crossOrigin,_.src=n.src,b.addUniform("sampler2D u_texture").setColorExpression(b.getColorExpression()+" * texture2D(u_texture, v_texCoord)"),M.u_texture=_}return v.attributes.forEach((function(t){-1===a.attributes.indexOf(t)&&a.attributes.push(t),b.addVarying("v_".concat(t),"float","a_".concat(t))})),a.attributes.forEach((function(t){b.addAttribute("float a_".concat(t))})),{builder:b,attributes:a.attributes.map((function(t){return{name:t,callback:function(n,i){var r=i[t];return"string"==typeof r&&(r=Al(a,r)),void 0!==r?r:-9999999}}})),uniforms:M}}var Zl=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),$l=function(t){function n(n){var i=t.call(this,{extent:n.extent,origin:n.origin,origins:n.origins,resolutions:n.resolutions,tileSize:n.tileSize,tileSizes:n.tileSizes,sizes:n.sizes})||this;return i.eu=n.matrixIds,i}return Zl(n,t),n.prototype.getMatrixId=function(t){return this.eu[t]},n.prototype.getMatrixIds=function(){return this.eu},n}(xf),Kl=$l;function Hl(t,n,i){var r=[],e=[],o=[],s=[],u=[],a=void 0!==i?i:[],h=yr(t.SupportedCRS),f=h.getMetersPerUnit(),c="ne"==h.getAxisOrientation().substr(0,2);return t.TileMatrix.sort((function(t,n){return n.ScaleDenominator-t.ScaleDenominator})),t.TileMatrix.forEach((function(n){if(!(a.length>0)||b(a,(function(i){return n.Identifier==i.TileMatrix||-1===n.Identifier.indexOf(":")&&t.Identifier+":"+n.Identifier===i.TileMatrix}))){e.push(n.Identifier);var i=28e-5*n.ScaleDenominator/f,h=n.TileWidth,l=n.TileHeight;c?o.push([n.TopLeftCorner[1],n.TopLeftCorner[0]]):o.push(n.TopLeftCorner),r.push(i),s.push(h==l?h:[h,l]),u.push([n.MatrixWidth,n.MatrixHeight])}})),new $l({extent:n,origins:o,resolutions:r,matrixIds:e,tileSizes:s,sizes:u})}var Jl=function(){function t(t){this.ou=t.opacity,this.su=t.rotateWithView,this.Dr=t.rotation,this.uu=t.scale,this.au=Qu(t.scale),this.hu=t.displacement,this.fu=t.declutterMode}return t.prototype.clone=function(){var n=this.getScale();return new t({opacity:this.getOpacity(),scale:Array.isArray(n)?n.slice():n,rotation:this.getRotation(),rotateWithView:this.getRotateWithView(),displacement:this.getDisplacement().slice(),declutterMode:this.getDeclutterMode()})},t.prototype.getOpacity=function(){return this.ou},t.prototype.getRotateWithView=function(){return this.su},t.prototype.getRotation=function(){return this.Dr},t.prototype.getScale=function(){return this.uu},t.prototype.getScaleArray=function(){return this.au},t.prototype.getDisplacement=function(){return this.hu},t.prototype.getDeclutterMode=function(){return this.fu},t.prototype.getAnchor=function(){return r()},t.prototype.getImage=function(t){return r()},t.prototype.getHitDetectionImage=function(){return r()},t.prototype.getPixelRatio=function(t){return 1},t.prototype.getImageState=function(){return r()},t.prototype.getImageSize=function(){return r()},t.prototype.getOrigin=function(){return r()},t.prototype.getSize=function(){return r()},t.prototype.setDisplacement=function(t){this.hu=t},t.prototype.setOpacity=function(t){this.ou=t},t.prototype.setRotateWithView=function(t){this.su=t},t.prototype.setRotation=function(t){this.Dr=t},t.prototype.setScale=function(t){this.uu=t,this.au=Qu(t)},t.prototype.listenImageChange=function(t){r()},t.prototype.load=function(){r()},t.prototype.unlistenImageChange=function(t){r()},t}(),Ql=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),tv=function(t){function n(n){var i=this,r=void 0!==n.rotateWithView&&n.rotateWithView;return(i=t.call(this,{opacity:1,rotateWithView:r,rotation:void 0!==n.rotation?n.rotation:0,scale:void 0!==n.scale?n.scale:1,displacement:void 0!==n.displacement?n.displacement:[0,0],declutterMode:n.declutterMode})||this).qt=void 0,i.cu=null,i.lu=void 0!==n.fill?n.fill:null,i._o=[0,0],i.Zt=n.points,i.vu=void 0!==n.radius?n.radius:n.radius1,i.du=n.radius2,i.$t=void 0!==n.angle?n.angle:0,i.pu=void 0!==n.stroke?n.stroke:null,i.W=null,i.yu=null,i.render(),i}return Ql(n,t),n.prototype.clone=function(){var t=this.getScale(),i=new n({fill:this.getFill()?this.getFill().clone():void 0,points:this.getPoints(),radius:this.getRadius(),radius2:this.getRadius2(),angle:this.getAngle(),stroke:this.getStroke()?this.getStroke().clone():void 0,rotation:this.getRotation(),rotateWithView:this.getRotateWithView(),scale:Array.isArray(t)?t.slice():t,displacement:this.getDisplacement().slice(),declutterMode:this.getDeclutterMode()});return i.setOpacity(this.getOpacity()),i},n.prototype.getAnchor=function(){var t=this.W;if(!t)return null;var n=this.getDisplacement();return[t[0]/2-n[0],t[1]/2+n[1]]},n.prototype.getAngle=function(){return this.$t},n.prototype.getFill=function(){return this.lu},n.prototype.setFill=function(t){this.lu=t,this.render()},n.prototype.getHitDetectionImage=function(){return this.cu||this.mu(this.yu),this.cu},n.prototype.getImage=function(t){var n=this.qt[t];if(!n){var i=this.yu,r=_o(i.size*t,i.size*t);this.wu(i,r,t),n=r.canvas,this.qt[t]=n}return n},n.prototype.getPixelRatio=function(t){return t},n.prototype.getImageSize=function(){return this.W},n.prototype.getImageState=function(){return po},n.prototype.getOrigin=function(){return this._o},n.prototype.getPoints=function(){return this.Zt},n.prototype.getRadius=function(){return this.vu},n.prototype.getRadius2=function(){return this.du},n.prototype.getSize=function(){return this.W},n.prototype.getStroke=function(){return this.pu},n.prototype.setStroke=function(t){this.pu=t,this.render()},n.prototype.listenImageChange=function(t){},n.prototype.load=function(){},n.prototype.unlistenImageChange=function(t){},n.prototype.gu=function(t,n,i){if(0===n||this.Zt===1/0||"bevel"!==t&&"miter"!==t)return n;var r=this.vu,e=void 0===this.du?r:this.du;if(r0,6);var c=void 0!==r.src?lo:po;return i.Mu=void 0!==r.color?Go(r.color):null,i.Nu=vv(h,f,void 0!==i.Iu?i.Iu:null,i.Bt,c,i.Mu),i.Lu=void 0!==r.offset?r.offset:[0,0],i.zu=void 0!==r.offsetOrigin?r.offsetOrigin:av,i._o=null,i.W=void 0!==r.size?r.size:null,i}return pv(n,t),n.prototype.clone=function(){var t=this.getScale();return new n({anchor:this.xe.slice(),anchorOrigin:this.Pu,anchorXUnits:this.Cu,anchorYUnits:this.ku,color:this.Mu&&this.Mu.slice?this.Mu.slice():this.Mu||void 0,crossOrigin:this.Bt,imgSize:this.Iu,offset:this.Lu.slice(),offsetOrigin:this.zu,opacity:this.getOpacity(),rotateWithView:this.getRotateWithView(),rotation:this.getRotation(),scale:Array.isArray(t)?t.slice():t,size:null!==this.W?this.W.slice():void 0,src:this.getSrc(),displacement:this.getDisplacement().slice(),declutterMode:this.getDeclutterMode()})},n.prototype.getAnchor=function(){var t=this.Au;if(!t){t=this.xe;var n=this.getSize();if(this.Cu==ev||this.ku==ev){if(!n)return null;t=this.xe.slice(),this.Cu==ev&&(t[0]*=n[0]),this.ku==ev&&(t[1]*=n[1])}if(this.Pu!=av){if(!n)return null;t===this.xe&&(t=this.xe.slice()),this.Pu!=hv&&this.Pu!=uv||(t[0]=-t[0]+n[0]),this.Pu!=sv&&this.Pu!=uv||(t[1]=-t[1]+n[1])}this.Au=t}var i=this.getDisplacement();return[t[0]-i[0],t[1]+i[1]]},n.prototype.setAnchor=function(t){this.xe=t,this.Au=null},n.prototype.getColor=function(){return this.Mu},n.prototype.getImage=function(t){return this.Nu.getImage(t)},n.prototype.getPixelRatio=function(t){return this.Nu.getPixelRatio(t)},n.prototype.getImageSize=function(){return this.Nu.getSize()},n.prototype.getImageState=function(){return this.Nu.getImageState()},n.prototype.getHitDetectionImage=function(){return this.Nu.getHitDetectionImage()},n.prototype.getOrigin=function(){if(this._o)return this._o;var t=this.Lu;if(this.zu!=av){var n=this.getSize(),i=this.Nu.getSize();if(!n||!i)return null;t=t.slice(),this.zu!=hv&&this.zu!=uv||(t[0]=i[0]-n[0]-t[0]),this.zu!=sv&&this.zu!=uv||(t[1]=i[1]-n[1]-t[1])}return this._o=t,this._o},n.prototype.getSrc=function(){return this.Nu.getSrc()},n.prototype.getSize=function(){return this.W?this.W:this.Nu.getSize()},n.prototype.listenImageChange=function(t){this.Nu.addEventListener(L,t)},n.prototype.load=function(){this.Nu.load()},n.prototype.unlistenImageChange=function(t){this.Nu.removeEventListener(L,t)},n}(Jl),mv=function(){function t(t){var n=t||{};this.Mu=void 0!==n.color?n.color:null,this.Ru=n.lineCap,this.Fu=void 0!==n.lineDash?n.lineDash:null,this.Gu=n.lineDashOffset,this.Du=n.lineJoin,this.qu=n.miterLimit,this.Uu=n.width}return t.prototype.clone=function(){var n=this.getColor();return new t({color:Array.isArray(n)?n.slice():n||void 0,lineCap:this.getLineCap(),lineDash:this.getLineDash()?this.getLineDash().slice():void 0,lineDashOffset:this.getLineDashOffset(),lineJoin:this.getLineJoin(),miterLimit:this.getMiterLimit(),width:this.getWidth()})},t.prototype.getColor=function(){return this.Mu},t.prototype.getLineCap=function(){return this.Ru},t.prototype.getLineDash=function(){return this.Fu},t.prototype.getLineDashOffset=function(){return this.Gu},t.prototype.getLineJoin=function(){return this.Du},t.prototype.getMiterLimit=function(){return this.qu},t.prototype.getWidth=function(){return this.Uu},t.prototype.setColor=function(t){this.Mu=t},t.prototype.setLineCap=function(t){this.Ru=t},t.prototype.setLineDash=function(t){this.Fu=t},t.prototype.setLineDashOffset=function(t){this.Gu=t},t.prototype.setLineJoin=function(t){this.Du=t},t.prototype.setMiterLimit=function(t){this.qu=t},t.prototype.setWidth=function(t){this.Uu=t},t}(),wv=function(){function t(t){var n=t||{};this.Hr=null,this.Bu=_v,void 0!==n.geometry&&this.setGeometry(n.geometry),this.lu=void 0!==n.fill?n.fill:null,this.Lt=void 0!==n.image?n.image:null,this.hn=void 0!==n.renderer?n.renderer:null,this.Xu=void 0!==n.hitDetectionRenderer?n.hitDetectionRenderer:null,this.pu=void 0!==n.stroke?n.stroke:null,this.eo=void 0!==n.text?n.text:null,this.Vu=n.zIndex}return t.prototype.clone=function(){var n=this.getGeometry();return n&&"object"==typeof n&&(n=n.clone()),new t({geometry:n,fill:this.getFill()?this.getFill().clone():void 0,image:this.getImage()?this.getImage().clone():void 0,renderer:this.getRenderer(),stroke:this.getStroke()?this.getStroke().clone():void 0,text:this.getText()?this.getText().clone():void 0,zIndex:this.getZIndex()})},t.prototype.getRenderer=function(){return this.hn},t.prototype.setRenderer=function(t){this.hn=t},t.prototype.setHitDetectionRenderer=function(t){this.Xu=t},t.prototype.getHitDetectionRenderer=function(){return this.Xu},t.prototype.getGeometry=function(){return this.Hr},t.prototype.getGeometryFunction=function(){return this.Bu},t.prototype.getFill=function(){return this.lu},t.prototype.setFill=function(t){this.lu=t},t.prototype.getImage=function(){return this.Lt},t.prototype.setImage=function(t){this.Lt=t},t.prototype.getStroke=function(){return this.pu},t.prototype.setStroke=function(t){this.pu=t},t.prototype.getText=function(){return this.eo},t.prototype.setText=function(t){this.eo=t},t.prototype.getZIndex=function(){return this.Vu},t.prototype.setGeometry=function(t){"function"==typeof t?this.Bu=t:"string"==typeof t?this.Bu=function(n){return n.get(t)}:t?void 0!==t&&(this.Bu=function(){return t}):this.Bu=_v,this.Hr=t},t.prototype.setZIndex=function(t){this.Vu=t},t}();function gv(t){var n;if("function"==typeof t)n=t;else{var i;if(Array.isArray(t))i=t;else St("function"==typeof t.getZIndex,41),i=[t];n=function(){return i}}return n}var bv=null;function xv(t,n){if(!bv){var i=new rv({color:"rgba(255,255,255,0.4)"}),r=new mv({color:"#3399CC",width:1.25});bv=[new wv({image:new iv({fill:i,stroke:r,radius:5}),fill:i,stroke:r})]}return bv}function Mv(){var t={},n=[255,255,255,1],i=[0,153,255,1];return t.Polygon=[new wv({fill:new rv({color:[255,255,255,.5]})})],t.MultiPolygon=t.Polygon,t.LineString=[new wv({stroke:new mv({color:n,width:5})}),new wv({stroke:new mv({color:i,width:3})})],t.MultiLineString=t.LineString,t.Circle=t.Polygon.concat(t.LineString),t.Point=[new wv({image:new iv({radius:6,fill:new rv({color:i}),stroke:new mv({color:n,width:1.5})}),zIndex:1/0})],t.MultiPoint=t.Point,t.GeometryCollection=t.Polygon.concat(t.LineString,t.Point),t}function _v(t){return t.getGeometry()}var Sv=wv,Ov="point",jv="line",Ev=function(){function t(t){var n=t||{};this.Wu=n.font,this.Dr=n.rotation,this.su=n.rotateWithView,this.uu=n.scale,this.au=Qu(void 0!==n.scale?n.scale:1),this.eo=n.text,this.Yu=n.textAlign,this.Zu=n.justify,this.$u=n.textBaseline,this.lu=void 0!==n.fill?n.fill:new rv({color:"#333"}),this.Ku=void 0!==n.maxAngle?n.maxAngle:Math.PI/4,this.Hu=void 0!==n.placement?n.placement:Ov,this.Ju=!!n.overflow,this.pu=void 0!==n.stroke?n.stroke:null,this.Qu=void 0!==n.offsetX?n.offsetX:0,this.ta=void 0!==n.offsetY?n.offsetY:0,this.na=n.backgroundFill?n.backgroundFill:null,this.ia=n.backgroundStroke?n.backgroundStroke:null,this.Ai=void 0===n.padding?null:n.padding}return t.prototype.clone=function(){var n=this.getScale();return new t({font:this.getFont(),placement:this.getPlacement(),maxAngle:this.getMaxAngle(),overflow:this.getOverflow(),rotation:this.getRotation(),rotateWithView:this.getRotateWithView(),scale:Array.isArray(n)?n.slice():n,text:this.getText(),textAlign:this.getTextAlign(),justify:this.getJustify(),textBaseline:this.getTextBaseline(),fill:this.getFill()?this.getFill().clone():void 0,stroke:this.getStroke()?this.getStroke().clone():void 0,offsetX:this.getOffsetX(),offsetY:this.getOffsetY(),backgroundFill:this.getBackgroundFill()?this.getBackgroundFill().clone():void 0,backgroundStroke:this.getBackgroundStroke()?this.getBackgroundStroke().clone():void 0,padding:this.getPadding()||void 0})},t.prototype.getOverflow=function(){return this.Ju},t.prototype.getFont=function(){return this.Wu},t.prototype.getMaxAngle=function(){return this.Ku},t.prototype.getPlacement=function(){return this.Hu},t.prototype.getOffsetX=function(){return this.Qu},t.prototype.getOffsetY=function(){return this.ta},t.prototype.getFill=function(){return this.lu},t.prototype.getRotateWithView=function(){return this.su},t.prototype.getRotation=function(){return this.Dr},t.prototype.getScale=function(){return this.uu},t.prototype.getScaleArray=function(){return this.au},t.prototype.getStroke=function(){return this.pu},t.prototype.getText=function(){return this.eo},t.prototype.getTextAlign=function(){return this.Yu},t.prototype.getJustify=function(){return this.Zu},t.prototype.getTextBaseline=function(){return this.$u},t.prototype.getBackgroundFill=function(){return this.na},t.prototype.getBackgroundStroke=function(){return this.ia},t.prototype.getPadding=function(){return this.Ai},t.prototype.setOverflow=function(t){this.Ju=t},t.prototype.setFont=function(t){this.Wu=t},t.prototype.setMaxAngle=function(t){this.Ku=t},t.prototype.setOffsetX=function(t){this.Qu=t},t.prototype.setOffsetY=function(t){this.ta=t},t.prototype.setPlacement=function(t){this.Hu=t},t.prototype.setRotateWithView=function(t){this.su=t},t.prototype.setFill=function(t){this.lu=t},t.prototype.setRotation=function(t){this.Dr=t},t.prototype.setScale=function(t){this.uu=t,this.au=Qu(void 0!==t?t:1)},t.prototype.setStroke=function(t){this.pu=t},t.prototype.setText=function(t){this.eo=t},t.prototype.setTextAlign=function(t){this.Yu=t},t.prototype.setJustify=function(t){this.Zu=t},t.prototype.setTextBaseline=function(t){this.$u=t},t.prototype.setBackgroundFill=function(t){this.na=t},t.prototype.setBackgroundStroke=function(t){this.ia=t},t.prototype.setPadding=function(t){this.Ai=t},t}(),Tv=function(){function t(t){this.ra,this.ea,this.oa,this.sa=void 0===t||t,this.ua=0}return t.prototype.insertItem=function(t){var n={prev:void 0,next:void 0,data:t},i=this.oa;if(i){var r=i.next;n.prev=i,n.next=r,i.next=n,r&&(r.prev=n),i===this.ea&&(this.ea=n)}else this.ra=n,this.ea=n,this.sa&&(n.next=n,n.prev=n);this.oa=n,this.ua++},t.prototype.removeItem=function(){var t=this.oa;if(t){var n=t.next,i=t.prev;n&&(n.prev=i),i&&(i.next=n),this.oa=n||i,this.ra===this.ea?(this.oa=void 0,this.ra=void 0,this.ea=void 0):this.ra===t?this.ra=this.oa:this.ea===t&&(this.ea=i?this.oa.prev:this.oa),this.ua--}},t.prototype.firstItem=function(){if(this.oa=this.ra,this.oa)return this.oa.data},t.prototype.lastItem=function(){if(this.oa=this.ea,this.oa)return this.oa.data},t.prototype.nextItem=function(){if(this.oa&&this.oa.next)return this.oa=this.oa.next,this.oa.data},t.prototype.getNextItem=function(){if(this.oa&&this.oa.next)return this.oa.next.data},t.prototype.prevItem=function(){if(this.oa&&this.oa.prev)return this.oa=this.oa.prev,this.oa.data},t.prototype.getPrevItem=function(){if(this.oa&&this.oa.prev)return this.oa.prev.data},t.prototype.getCurrItem=function(){if(this.oa)return this.oa.data},t.prototype.setFirstItem=function(){this.sa&&this.oa&&(this.ra=this.oa,this.ea=this.oa.prev)},t.prototype.concat=function(t){if(t.oa){if(this.oa){var n=this.oa.next;this.oa.next=t.ra,t.ra.prev=this.oa,n.prev=t.ea,t.ea.next=n,this.ua+=t.ua}else this.oa=t.oa,this.ra=t.ra,this.ea=t.ea,this.ua=t.ua;t.oa=void 0,t.ra=void 0,t.ea=void 0,t.ua=0}},t.prototype.getLength=function(){return this.ua},t}(),Av=i(72),Pv=function(){function t(t){this.aa=new Av(t),this.ha={}}return t.prototype.insert=function(t,n){var i={minX:t[0],minY:t[1],maxX:t[2],maxY:t[3],value:n};this.aa.insert(i),this.ha[o(n)]=i},t.prototype.load=function(t,n){for(var i=new Array(n.length),r=0,e=n.length;ri.highWaterMark&&(i.highWaterMark=t)},n.prototype.useTile=function(t,n,i,r){},n}(zv),Gv=function(t){function n(n,i){var r=t.call(this,n)||this;return r.tile=i,r}return Rv(n,t),n}(c),Dv=Fv,qv=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Uv=function(t){function n(i){var r=t.call(this,{attributions:i.attributions,cacheSize:i.cacheSize,opaque:i.opaque,projection:i.projection,state:i.state,tileGrid:i.tileGrid,tilePixelRatio:i.tilePixelRatio,wrapX:i.wrapX,transition:i.transition,interpolate:i.interpolate,key:i.key,attributionsCollapsible:i.attributionsCollapsible,zDirection:i.zDirection})||this;return r.wa=r.tileUrlFunction===n.prototype.tileUrlFunction,r.tileLoadFunction=i.tileLoadFunction,i.tileUrlFunction&&(r.tileUrlFunction=i.tileUrlFunction),r.urls=null,i.urls?r.setUrls(i.urls):i.url&&r.setUrl(i.url),r.ga={},r}return qv(n,t),n.prototype.getTileLoadFunction=function(){return this.tileLoadFunction},n.prototype.getTileUrlFunction=function(){return Object.getPrototypeOf(this).tileUrlFunction===this.tileUrlFunction?this.tileUrlFunction.bind(this):this.tileUrlFunction},n.prototype.getUrls=function(){return this.urls},n.prototype.handleTileChange=function(t){var n,i=t.target,r=o(i),e=i.getState();e==lt?(this.ga[r]=!0,n=Cv):r in this.ga&&(delete this.ga[r],n=e==dt?Iv:e==vt?kv:void 0),null!=n&&this.dispatchEvent(new Gv(n,i))},n.prototype.setTileLoadFunction=function(t){this.tileCache.clear(),this.tileLoadFunction=t,this.changed()},n.prototype.setTileUrlFunction=function(t,n){this.tileUrlFunction=t,this.tileCache.pruneExceptNewestZ(),void 0!==n?this.setKey(n):this.changed()},n.prototype.setUrl=function(t){var n=If(t);this.urls=n,this.setUrls(n)},n.prototype.setUrls=function(t){this.urls=t;var n=t.join("\n");this.wa?this.setTileUrlFunction(Pf(t,this.tileGrid),n):this.setKey(n)},n.prototype.tileUrlFunction=function(t,n,i){},n.prototype.useTile=function(t,n,i){var r=jh(t,n,i);this.tileCache.containsKey(r)&&this.tileCache.get(r)},n}(Dv),Bv=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}();function Xv(t,n){t.getImage().src=n}var Vv=function(t){function n(n){var i=this,r=void 0===n.imageSmoothing||n.imageSmoothing;return void 0!==n.interpolate&&(r=n.interpolate),(i=t.call(this,{attributions:n.attributions,cacheSize:n.cacheSize,opaque:n.opaque,projection:n.projection,state:n.state,tileGrid:n.tileGrid,tileLoadFunction:n.tileLoadFunction?n.tileLoadFunction:Xv,tilePixelRatio:n.tilePixelRatio,tileUrlFunction:n.tileUrlFunction,url:n.url,urls:n.urls,wrapX:n.wrapX,transition:n.transition,interpolate:r,key:n.key,attributionsCollapsible:n.attributionsCollapsible,zDirection:n.zDirection})||this).crossOrigin=void 0!==n.crossOrigin?n.crossOrigin:null,i.tileClass=void 0!==n.tileClass?n.tileClass:ko,i.tileCacheForProjection={},i.tileGridForProjection={},i.ba=n.reprojectionErrorThreshold,i.xa=!1,i}return Bv(n,t),n.prototype.canExpireCache=function(){if(this.tileCache.canExpireCache())return!0;for(var t in this.tileCacheForProjection)if(this.tileCacheForProjection[t].canExpireCache())return!0;return!1},n.prototype.expireCache=function(t,n){var i=this.getTileCacheForProjection(t);for(var r in this.tileCache.expireCache(this.tileCache==i?n:{}),this.tileCacheForProjection){var e=this.tileCacheForProjection[r];e.expireCache(e==i?n:{})}},n.prototype.getGutterForProjection=function(t){return this.getProjection()&&t&&!Sr(this.getProjection(),t)?0:this.getGutter()},n.prototype.getGutter=function(){return 0},n.prototype.getKey=function(){var n=t.prototype.getKey.call(this);return this.getInterpolate()||(n+=":disable-interpolation"),n},n.prototype.getOpaque=function(n){return!(this.getProjection()&&n&&!Sr(this.getProjection(),n))&&t.prototype.getOpaque.call(this,n)},n.prototype.getTileGridForProjection=function(t){var n=this.getProjection();if(!this.tileGrid||n&&!Sr(n,t)){var i=o(t);return i in this.tileGridForProjection||(this.tileGridForProjection[i]=Mf(t)),this.tileGridForProjection[i]}return this.tileGrid},n.prototype.getTileCacheForProjection=function(t){var n=this.getProjection();if(!n||Sr(n,t))return this.tileCache;var i=o(t);return i in this.tileCacheForProjection||(this.tileCacheForProjection[i]=new Ih(this.tileCache.highWaterMark)),this.tileCacheForProjection[i]},n.prototype.Ma=function(t,n,i,r,e,o){var s=[t,n,i],u=this.getTileCoordForTileUrlFunction(s,e),a=u?this.tileUrlFunction(u,r,e):void 0,h=new this.tileClass(s,void 0!==a?ct:pt,void 0!==a?a:"",this.crossOrigin,this.tileLoadFunction,this.tileOptions);return h.key=o,h.addEventListener(L,this.handleTileChange.bind(this)),h},n.prototype.getTile=function(t,n,i,r,e){var o=this.getProjection();if(o&&e&&!Sr(o,e)){var s=this.getTileCacheForProjection(e),u=[t,n,i],a=void 0,h=Eh(u);s.containsKey(h)&&(a=s.get(h));var f=this.getKey();if(a&&a.key==f)return a;var c=this.getTileGridForProjection(o),l=this.getTileGridForProjection(e),v=this.getTileCoordForTileUrlFunction(u,e),d=new Bc(o,c,e,l,u,v,this.getTilePixelRatio(r),this.getGutter(),function(t,n,i,r){return this.getTileInternal(t,n,i,r,o)}.bind(this),this.ba,this.xa,this.getInterpolate());return d.key=f,a?(d.interimTile=a,d.refreshInterimChain(),s.replace(h,d)):s.set(h,d),d}return this.getTileInternal(t,n,i,r,o||e)},n.prototype.getTileInternal=function(t,n,i,r,e){var o=null,s=jh(t,n,i),u=this.getKey();if(this.tileCache.containsKey(s)){if((o=this.tileCache.get(s)).key!=u){var a=o;o=this.Ma(t,n,i,r,e,u),a.getState()==ct?o.interimTile=a.interimTile:o.interimTile=a,o.refreshInterimChain(),this.tileCache.replace(s,o)}}else o=this.Ma(t,n,i,r,e,u),this.tileCache.set(s,o);return o},n.prototype.setRenderReprojectionEdges=function(t){if(this.xa!=t){for(var n in this.xa=t,this.tileCacheForProjection)this.tileCacheForProjection[n].clear();this.changed()}},n.prototype.setTileGridForProjection=function(t,n){var i=yr(t);if(i){var r=o(i);r in this.tileGridForProjection||(this.tileGridForProjection[r]=n)}},n}(Uv),Wv=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}();function Yv(t){var n,i,r=t[0],e=new Array(r),o=1<>=1;return e.join("")}var Zv=function(t){function n(n){var i=this,r=void 0!==n.hidpi&&n.hidpi,e=void 0===n.imageSmoothing||n.imageSmoothing;return void 0!==n.interpolate&&(e=n.interpolate),(i=t.call(this,{cacheSize:n.cacheSize,crossOrigin:"anonymous",interpolate:e,opaque:!0,projection:yr("EPSG:3857"),reprojectionErrorThreshold:n.reprojectionErrorThreshold,state:"loading",tileLoadFunction:n.tileLoadFunction,tilePixelRatio:r?2:1,wrapX:void 0===n.wrapX||n.wrapX,transition:n.transition,zDirection:n.zDirection})||this)._a=r,i.Sa=void 0!==n.culture?n.culture:"en-us",i.Oa=void 0!==n.maxZoom?n.maxZoom:-1,i.ja=n.key,i.Ea=n.imagerySet,Zh("https://dev.virtualearth.net/REST/v1/Imagery/Metadata/"+i.Ea+"?uriScheme=https&include=ImageryProviders&key="+i.ja+"&c="+i.Sa,i.handleImageryMetadataResponse.bind(i),void 0,"jsonp"),i}return Wv(n,t),n.prototype.getApiKey=function(){return this.ja},n.prototype.getImagerySet=function(){return this.Ea},n.prototype.handleImageryMetadataResponse=function(t){if(200==t.statusCode&&"OK"==t.statusDescription&&"ValidCredentials"==t.authenticationResultCode&&1==t.resourceSets.length&&1==t.resourceSets[0].resources.length){var n=t.resourceSets[0].resources[0],i=-1==this.Oa?n.zoomMax:this.Oa,r=Tf(this.getProjection()),e=this._a?2:1,o=n.imageWidth==n.imageHeight?n.imageWidth/e:[n.imageWidth/e,n.imageHeight/e],s=Of({extent:r,minZoom:n.zoomMin,maxZoom:i,tileSize:o});this.tileGrid=s;var u=this.Sa,a=this._a;if(this.tileUrlFunction=Cf(n.imageUrlSubdomains.map((function(t){var i=[0,0,0],r=n.imageUrl.replace("{subdomain}",t).replace("{culture}",u);return function(t,n,e){if(t){Oh(t[0],t[1],t[2],i);var o=r;return a&&(o+="&dpi=d1&device=mobile"),o.replace("{quadkey}",Yv(i))}}}))),n.imageryProviders){var h=Or(yr("EPSG:4326"),this.getProjection());this.setAttributions(function(t){var i=[],r=t.viewState,e=this.getTileGrid(),o=e.getZForResolution(r.resolution,this.zDirection),s=e.getTileCoordForCoordAndZ(r.center,o)[0];return n.imageryProviders.map((function(n){for(var r=!1,e=n.coverageAreas,o=0,u=e.length;o=a.zoomMin&&s<=a.zoomMax){var f=a.bbox;if(Kn(ni([f[1],f[0],f[3],f[2]],h),t.extent)){r=!0;break}}}r&&i.push(n.attribution)})),i.push('Terms of Use'),i}.bind(this))}this.setState("ready")}else this.setState("error")},n}(Vv),$v=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Kv=function(t){function n(n){var i=this,r=n||{},e=void 0===r.imageSmoothing||r.imageSmoothing;void 0!==r.interpolate&&(e=r.interpolate);var o=void 0!==r.projection?r.projection:"EPSG:3857",s=void 0!==r.tileGrid?r.tileGrid:Of({extent:Tf(o),maxResolution:r.maxResolution,maxZoom:r.maxZoom,minZoom:r.minZoom,tileSize:r.tileSize});return(i=t.call(this,{attributions:r.attributions,cacheSize:r.cacheSize,crossOrigin:r.crossOrigin,interpolate:e,opaque:r.opaque,projection:o,reprojectionErrorThreshold:r.reprojectionErrorThreshold,tileGrid:s,tileLoadFunction:r.tileLoadFunction,tilePixelRatio:r.tilePixelRatio,tileUrlFunction:r.tileUrlFunction,url:r.url,urls:r.urls,wrapX:void 0===r.wrapX||r.wrapX,transition:r.transition,attributionsCollapsible:r.attributionsCollapsible,zDirection:r.zDirection})||this).js=void 0!==r.gutter?r.gutter:0,i}return $v(n,t),n.prototype.getGutter=function(){return this.js},n}(Vv),Hv=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Jv=function(t){function n(n){var i=t.call(this,{attributions:n.attributions,cacheSize:n.cacheSize,crossOrigin:n.crossOrigin,maxZoom:void 0!==n.maxZoom?n.maxZoom:18,minZoom:n.minZoom,projection:n.projection,transition:n.transition,wrapX:n.wrapX,zDirection:n.zDirection})||this;return i.Ta=n.account,i.Aa=n.map||"",i.Pa=n.config||{},i.Ca={},i.ka(),i}return Hv(n,t),n.prototype.getConfig=function(){return this.Pa},n.prototype.updateConfig=function(t){A(this.Pa,t),this.ka()},n.prototype.setConfig=function(t){this.Pa=t||{},this.ka()},n.prototype.ka=function(){var t=JSON.stringify(this.Pa);if(this.Ca[t])this.Ia(this.Ca[t]);else{var n="https://"+this.Ta+".carto.com/api/v1/map";this.Aa&&(n+="/named/"+this.Aa);var i=new XMLHttpRequest;i.addEventListener("load",this.Na.bind(this,t)),i.addEventListener("error",this.La.bind(this)),i.open("POST",n),i.setRequestHeader("Content-type","application/json"),i.send(JSON.stringify(this.Pa))}},n.prototype.Na=function(t,n){var i=n.target;if(!i.status||i.status>=200&&i.status<300){var r=void 0;try{r=JSON.parse(i.responseText)}catch(t){return void this.setState("error")}this.Ia(r),this.Ca[t]=r,this.setState("ready")}else this.setState("error")},n.prototype.La=function(t){this.setState("error")},n.prototype.Ia=function(t){var n="https://"+t.cdn_url.https+"/"+this.Ta+"/api/v1/map/"+t.layergroupid+"/{z}/{x}/{y}.png";this.setUrl(n)},n}(Kv),Qv="addfeature",td="changefeature",nd="clear",id="removefeature",rd="featuresloadstart",ed="featuresloadend",od="featuresloaderror",sd=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),ud=function(t){function n(n,i,r){var e=t.call(this,n)||this;return e.feature=i,e.features=r,e}return sd(n,t),n}(c),ad=function(t){function n(n){var i=this,r=n||{};(i=t.call(this,{attributions:r.attributions,interpolate:!0,projection:void 0,state:"ready",wrapX:void 0===r.wrapX||r.wrapX})||this).on,i.once,i.un,i.U=j,i.ze=r.format,i.za=void 0===r.overlaps||r.overlaps,i.Fe=r.url,void 0!==r.loader?i.U=r.loader:void 0!==i.Fe&&(St(i.ze,7),i.U=Vh(i.Fe,i.ze)),i.Ra=void 0!==r.strategy?r.strategy:Wh;var e,o,s=void 0===r.useSpatialIndex||r.useSpatialIndex;return i.Fa=s?new Pv:null,i.Ga=new Pv,i.Da=0,i.qa={},i.Ua={},i.Ba={},i.Xa={},i.Va=null,Array.isArray(r.features)?o=r.features:r.features&&(o=(e=r.features).getArray()),s||void 0!==e||(e=new ft(o)),void 0!==o&&i.addFeaturesInternal(o),void 0!==e&&i.Wa(e),i}return sd(n,t),n.prototype.addFeature=function(t){this.addFeatureInternal(t),this.changed()},n.prototype.addFeatureInternal=function(t){var n=o(t);if(this.Ya(n,t)){this.Za(n,t);var i=t.getGeometry();if(i){var r=i.getExtent();this.Fa&&this.Fa.insert(r,t)}else this.qa[n]=t;this.dispatchEvent(new ud(Qv,t))}else this.Va&&this.Va.remove(t)},n.prototype.Za=function(t,n){this.Xa[t]=[$(n,L,this.$a,this),$(n,l,this.$a,this)]},n.prototype.Ya=function(t,n){var i=!0,r=n.getId();return void 0!==r&&(r.toString()in this.Ua?i=!1:this.Ua[r.toString()]=n),i&&(St(!(t in this.Ba),30),this.Ba[t]=n),i},n.prototype.addFeatures=function(t){this.addFeaturesInternal(t),this.changed()},n.prototype.addFeaturesInternal=function(t){for(var n=[],i=[],r=[],e=0,s=t.length;e0},n.prototype.refresh=function(){this.clear(!0),this.Ga.clear(),t.prototype.refresh.call(this)},n.prototype.removeLoadedExtent=function(t){var n,i=this.Ga;i.forEachInExtent(t,(function(i){if(An(i.extent,t))return n=i,!0})),n&&i.remove(n)},n.prototype.removeFeature=function(t){if(t){var n=o(t);n in this.qa?delete this.qa[n]:this.Fa&&this.Fa.remove(t),this.removeFeatureInternal(t)&&this.changed()}},n.prototype.removeFeatureInternal=function(t){var n=o(t),i=this.Xa[n];if(i){i.forEach(H),delete this.Xa[n];var r=t.getId();return void 0!==r&&delete this.Ua[r.toString()],delete this.Ba[n],this.dispatchEvent(new ud(id,t)),t}},n.prototype.Ka=function(t){var n=!1;for(var i in this.Ua)if(this.Ua[i]===t){delete this.Ua[i],n=!0;break}return n},n.prototype.setLoader=function(t){this.U=t},n.prototype.setUrl=function(t){St(this.ze,7),this.Fe=t,this.setLoader(Vh(t,this.ze))},n}(zv),hd=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),fd=function(t){function n(n){var i=t.call(this,{attributions:n.attributions,wrapX:n.wrapX})||this;return i.resolution=void 0,i.distance=void 0!==n.distance?n.distance:20,i.minDistance=n.minDistance||0,i.interpolationRatio=0,i.features=[],i.geometryFunction=n.geometryFunction||function(t){var n=t.getGeometry();return St("Point"==n.getType(),10),n},i.Ha=n.createCluster,i.source=null,i.Ja=i.refresh.bind(i),i.updateDistance(i.distance,i.minDistance),i.setSource(n.source||null),i}return hd(n,t),n.prototype.clear=function(n){this.features.length=0,t.prototype.clear.call(this,n)},n.prototype.getDistance=function(){return this.distance},n.prototype.getSource=function(){return this.source},n.prototype.loadFeatures=function(t,n,i){this.source.loadFeatures(t,n,i),n!==this.resolution&&(this.resolution=n,this.refresh())},n.prototype.setDistance=function(t){this.updateDistance(t,this.minDistance)},n.prototype.setMinDistance=function(t){this.updateDistance(this.distance,t)},n.prototype.getMinDistance=function(){return this.minDistance},n.prototype.setSource=function(t){this.source&&this.source.removeEventListener(L,this.Ja),this.source=t,t&&t.addEventListener(L,this.Ja),this.refresh()},n.prototype.refresh=function(){this.clear(),this.cluster(),this.addFeatures(this.features)},n.prototype.updateDistance=function(t,n){var i=0===t?0:Math.min(n,t)/t,r=t!==this.distance||this.interpolationRatio!==i;this.distance=t,this.minDistance=n,this.interpolationRatio=i,r&&this.refresh()},n.prototype.cluster=function(){if(void 0!==this.resolution&&this.source)for(var t=[1/0,1/0,-1/0,-1/0],n=this.distance*this.resolution,i=this.source.getFeatures(),r={},e=0,s=i.length;e=0;--r){var e=this.geometryFunction(t[r]);e?Vi(i,e.getCoordinates()):t.splice(r,1)}Ji(i,1/t.length);var o=qn(n),s=this.interpolationRatio,u=new Se([i[0]*(1-s)+o[0]*s,i[1]*(1-s)+o[1]*s]);return this.Ha?this.Ha(u,t):new Et({geometry:u,features:t})},n}(ad),cd=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),ld=function(t){function n(n){var i=this,r=void 0===n.projection?"EPSG:3857":n.projection,e=n.tileGrid;if(void 0===e&&r&&(e=Of({extent:Tf(r),maxResolution:n.maxResolution,maxZoom:n.maxZoom,minZoom:n.minZoom,tileSize:n.tileSize})),(i=t.call(this,{cacheSize:.1,attributions:n.attributions,attributionsCollapsible:n.attributionsCollapsible,projection:r,tileGrid:e,opaque:n.opaque,state:n.state,tilePixelRatio:n.tilePixelRatio,wrapX:n.wrapX,transition:n.transition,interpolate:n.interpolate})||this).js=void 0!==n.gutter?n.gutter:0,i.jo=n.tileSize?Qu(n.tileSize):null,!i.jo&&n.tilePixelRatio&&e){var o=Qu(e.getTileSize(0));i.jo=[o[0]*n.tilePixelRatio,o[1]*n.tilePixelRatio]}return i.Oo=null,i.ga={},i.U=n.loader,i.cr=i.cr.bind(i),i.bandCount=void 0===n.bandCount?4:n.bandCount,i}return cd(n,t),n.prototype.setTileSizes=function(t){this.Oo=t},n.prototype.getTileSize=function(t){if(this.Oo)return this.Oo[t];if(this.jo)return this.jo;var n=this.getTileGrid();return n?Qu(n.getTileSize(t)):[256,256]},n.prototype.getGutterForProjection=function(t){return this.js},n.prototype.setLoader=function(t){this.U=t},n.prototype.getTile=function(t,n,i,r,e){var o=this.getTileSize(t),s=jh(t,n,i);if(this.tileCache.containsKey(s))return this.tileCache.get(s);var u=this.U;var a=A({tileCoord:[t,n,i],loader:function(){return T((function(){return u(t,n,i)}))},size:o},this.tileOptions),h=new _t(a);return h.key=this.getKey(),h.addEventListener(L,this.cr),this.tileCache.set(s,h),h},n.prototype.cr=function(t){var n,i=t.target,r=o(i),e=i.getState();e==lt?(this.ga[r]=!0,n=Cv):r in this.ga&&(delete this.ga[r],n=e==dt?Iv:e==vt?kv:void 0),n&&this.dispatchEvent(new Gv(n,i))},n}(Dv);const vd=new ArrayBuffer(4),dd=new Float32Array(vd),pd=new Uint32Array(vd),yd=new Uint32Array(512),md=new Uint32Array(512);for(let t=0;t<256;++t){const n=t-127;n<-27?(yd[t]=0,yd[256|t]=32768,md[t]=24,md[256|t]=24):n<-14?(yd[t]=1024>>-n-14,yd[256|t]=1024>>-n-14|32768,md[t]=-n-1,md[256|t]=-n-1):n<=15?(yd[t]=n+15<<10,yd[256|t]=n+15<<10|32768,md[t]=13,md[256|t]=13):n<128?(yd[t]=31744,yd[256|t]=64512,md[t]=24,md[256|t]=24):(yd[t]=31744,yd[256|t]=64512,md[t]=13,md[256|t]=13)}const wd=new Uint32Array(2048),gd=new Uint32Array(64),bd=new Uint32Array(64);wd[0]=0;for(let t=1;t<1024;++t){let n=t<<13,i=0;for(;0==(8388608&n);)i-=8388608,n<<=1;n&=-8388609,i+=947912704,wd[t]=n|i}for(let t=1024;t<2048;++t)wd[t]=939524096+(t-1024<<13);gd[0]=0;for(let t=1;t<31;++t)gd[t]=t<<23;gd[31]=1199570944,gd[32]=2147483648;for(let t=33;t<63;++t)gd[t]=2147483648+(t-32<<23);gd[63]=3347054592,bd[0]=0;for(let t=1;t<64;++t)bd[t]=32===t?0:1024;function xd(t){const n=t>>10;return pd[0]=wd[bd[n]+(1023&t)]+gd[n],dd[0]}const Md=Reflect.getPrototypeOf(Uint8Array).prototype,_d=Reflect.getOwnPropertyDescriptor(Md,Symbol.toStringTag).get;function Sd(t){return void 0!==_d.call(t)}const Od=Object.prototype.toString;function jd(t){return!!ArrayBuffer.isView(t)&&(!Sd(t)&&"[object DataView]"===Od.call(t))}function Ed(t,n){if(!jd(t))throw new TypeError("First argument to getFloat16 function must be a DataView");for(var i=arguments.length,r=new Array(i>2?i-2:0),e=2;eCd.set(t,n)))}async function Id(t){const n=Cd.get(t.Compression);if(!n)throw new Error(`Unknown compression method identifier: ${t.Compression}`);return new(await n())(t)}function Nd(t,n,i){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:1;return new(Object.getPrototypeOf(t).constructor)(n*i*r)}function Ld(t,n,i,r,e){const o=n/r,s=i/e;return t.map((t=>{const u=Nd(t,r,e);for(let a=0;a{const u=Nd(t,r,e);for(let a=0;ai.e(226).then(i.bind(i,966)).then((t=>t.default)))),kd(5,(()=>i.e(611).then(i.bind(i,611)).then((t=>t.default)))),kd(6,(()=>{throw new Error("old style JPEG compression is not supported.")})),kd(7,(()=>i.e(382).then(i.bind(i,382)).then((t=>t.default)))),kd([8,32946],(()=>Promise.all([i.e(247),i.e(356)]).then(i.bind(i,356)).then((t=>t.default)))),kd(32773,(()=>i.e(395).then(i.bind(i,395)).then((t=>t.default)))),kd(34887,(()=>Promise.all([i.e(247),i.e(54)]).then(i.bind(i,54)).then((t=>t.default)))),kd(50001,(()=>i.e(629).then(i.bind(i,629)).then((t=>t.default))));var Ud=class{constructor(t,n,i,r,e,o){this.fileDirectory=t,this.geoKeys=n,this.dataView=i,this.littleEndian=r,this.tiles=e?{}:null,this.isTiled=!t.StripOffsets;const s=t.PlanarConfiguration;if(this.planarConfiguration=void 0===s?1:s,1!==this.planarConfiguration&&2!==this.planarConfiguration)throw new Error("Invalid planar configuration.");this.source=o}getFileDirectory(){return this.fileDirectory}getGeoKeys(){return this.geoKeys}getWidth(){return this.fileDirectory.ImageWidth}getHeight(){return this.fileDirectory.ImageLength}getSamplesPerPixel(){return void 0!==this.fileDirectory.SamplesPerPixel?this.fileDirectory.SamplesPerPixel:1}getTileWidth(){return this.isTiled?this.fileDirectory.TileWidth:this.getWidth()}getTileHeight(){return this.isTiled?this.fileDirectory.TileLength:void 0!==this.fileDirectory.RowsPerStrip?Math.min(this.fileDirectory.RowsPerStrip,this.getHeight()):this.getHeight()}getBlockWidth(){return this.getTileWidth()}getBlockHeight(t){return this.isTiled||(t+1)*this.getTileHeight()<=this.getHeight()?this.getTileHeight():this.getHeight()-t*this.getTileHeight()}getBytesPerPixel(){let t=0;for(let n=0;n=this.fileDirectory.BitsPerSample.length)throw new RangeError(`Sample index ${t} is out of range.`);return Math.ceil(this.fileDirectory.BitsPerSample[t]/8)}getReaderForSample(t){const n=this.fileDirectory.SampleFormat?this.fileDirectory.SampleFormat[t]:1,i=this.fileDirectory.BitsPerSample[t];switch(n){case 1:if(i<=8)return DataView.prototype.getUint8;if(i<=16)return DataView.prototype.getUint16;if(i<=32)return DataView.prototype.getUint32;break;case 2:if(i<=8)return DataView.prototype.getInt8;if(i<=16)return DataView.prototype.getInt16;if(i<=32)return DataView.prototype.getInt32;break;case 3:switch(i){case 16:return function(t,n){return Ed(this,t,n)};case 32:return DataView.prototype.getFloat32;case 64:return DataView.prototype.getFloat64}}throw Error("Unsupported data format/bitsPerSample")}getSampleFormat(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;return this.fileDirectory.SampleFormat?this.fileDirectory.SampleFormat[t]:1}getBitsPerSample(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;return this.fileDirectory.BitsPerSample[t]}getArrayForSample(t,n){return qd(this.getSampleFormat(t),this.getBitsPerSample(t),n)}async getTileOrStrip(t,n,i,r,e){const o=Math.ceil(this.getWidth()/this.getTileWidth()),s=Math.ceil(this.getHeight()/this.getTileHeight());let u;const{tiles:a}=this;let h,f;1===this.planarConfiguration?u=n*o+t:2===this.planarConfiguration&&(u=i*o*s+n*o+t),this.isTiled?(h=this.fileDirectory.TileOffsets[u],f=this.fileDirectory.TileByteCounts[u]):(h=this.fileDirectory.StripOffsets[u],f=this.fileDirectory.StripByteCounts[u]);const c=(await this.source.fetch([{offset:h,length:f}],e))[0];let l;return null!==a&&a[u]?l=a[u]:(l=(async()=>{let t=await r.decode(this.fileDirectory,c);const i=this.getSampleFormat(),e=this.getBitsPerSample();return function(t,n){return(1!==t&&2!==t||!(n<=32)||n%8!=0)&&(3!==t||16!==n&&32!==n&&64!==n)}(i,e)&&(t=function(t,n,i,r,e,o,s){const u=new DataView(t),a=2===i?1:r,h=qd(n,e,2===i?s*o:s*o*r),f=parseInt("1".repeat(e),2);if(1===n){let t;t=1===i?r*e:e;let n=o*t;0!=(7&n)&&(n=n+7&-8);for(let t=0;t>8-e-v&f;else if(v+e<=16)h[c]=u.getUint16(l)>>16-e-v&f;else if(v+e<=24){const t=u.getUint16(l)<<8|u.getUint8(l+2);h[c]=t>>24-e-v&f}else h[c]=u.getUint32(l)>>32-e-v&f}}}}return h.buffer}(t,i,this.planarConfiguration,this.getSamplesPerPixel(),e,this.getTileWidth(),this.getBlockHeight(n))),t})(),null!==a&&(a[u]=l)),{x:t,y:n,sample:i,data:await l}}async _readRaster(t,n,i,r,e,o,s,u,a){const h=this.getTileWidth(),f=this.getTileHeight(),c=this.getWidth(),l=this.getHeight(),v=Math.max(Math.floor(t[0]/h),0),d=Math.min(Math.ceil(t[2]/h),Math.ceil(c/h)),p=Math.max(Math.floor(t[1]/f),0),y=Math.min(Math.ceil(t[3]/f),Math.ceil(l/f)),m=t[2]-t[0];let w=this.getBytesPerPixel();const g=[],b=[];for(let t=0;t{const o=e.data,s=new DataView(o),u=this.getBlockHeight(e.y),a=e.y*f,d=e.x*h,p=a+u,y=(e.x+1)*h,x=b[v],_=Math.min(u,u-(p-t[3]),l-a),S=Math.min(h,h-(y-t[2]),c-d);for(let e=Math.max(0,t[1]-a);e<_;++e)for(let o=Math.max(0,t[0]-d);o6&&void 0!==arguments[6]?arguments[6]:"nearest";switch(s.toLowerCase()){case"nearest":return Fd(t,n,i,r,e,o);case"bilinear":case"linear":return Gd(t,n,i,r,e,o);default:throw new Error(`Unsupported resampling method: '${s}'`)}}(i,t[2]-t[0],t[3]-t[1],o,s,n.length,u):function(t,n,i,r,e){let o=arguments.length>5&&void 0!==arguments[5]?arguments[5]:"nearest";switch(o.toLowerCase()){case"nearest":return Ld(t,n,i,r,e);case"bilinear":case"linear":return Rd(t,n,i,r,e);default:throw new Error(`Unsupported resampling method: '${o}'`)}}(i,t[2]-t[0],t[3]-t[1],o,s,u),e.width=o,e.height=s,e}return i.width=o||t[2]-t[0],i.height=s||t[3]-t[1],i}async readRasters(){let{window:t,samples:n=[],interleave:i,pool:r=null,width:e,height:o,resampleMethod:s,fillValue:u,signal:a}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const h=t||[0,0,this.getWidth(),this.getHeight()];if(h[0]>h[2]||h[1]>h[3])throw new Error("Invalid subsets");const f=(h[2]-h[0])*(h[3]-h[1]),c=this.getSamplesPerPixel();if(n&&n.length){for(let t=0;t=c)return Promise.reject(new RangeError(`Invalid sample index '${n[t]}'.`))}else for(let t=0;t0&&void 0!==arguments[0]?arguments[0]:{};const a=t||[0,0,this.getWidth(),this.getHeight()];if(a[0]>a[2]||a[1]>a[3])throw new Error("Invalid subsets");const h=this.fileDirectory.PhotometricInterpretation;if(h===Pd.Ie.RGB){let a=[0,1,2];if(this.fileDirectory.ExtraSamples!==Pd.pd.Unspecified&&s){a=[];for(let t=0;t>24)/500+u,h=u-(t[n+2]<<24>>24)/200;a=.95047*(a*a*a>.008856?a*a*a:(a-16/116)/7.787),u=1*(u*u*u>.008856?u*u*u:(u-16/116)/7.787),h=1.08883*(h*h*h>.008856?h*h*h:(h-16/116)/7.787),e=3.2406*a+-1.5372*u+-.4986*h,o=-.9689*a+1.8758*u+.0415*h,s=.0557*a+-.204*u+1.057*h,e=e>.0031308?1.055*e**(1/2.4)-.055:12.92*e,o=o>.0031308?1.055*o**(1/2.4)-.055:12.92*o,s=s>.0031308?1.055*s**(1/2.4)-.055:12.92*s,r[i]=255*Math.max(0,Math.min(1,e)),r[i+1]=255*Math.max(0,Math.min(1,o)),r[i+2]=255*Math.max(0,Math.min(1,s))}return r}(v);break;default:throw new Error("Unsupported photometric interpretation.")}if(!n){const t=new Uint8Array(p.length/3),n=new Uint8Array(p.length/3),i=new Uint8Array(p.length/3);for(let r=0,e=0;r0&&void 0!==arguments[0]?arguments[0]:null;const n={};if(!this.fileDirectory.GDAL_METADATA)return null;const i=this.fileDirectory.GDAL_METADATA;let r=Ad(i,"Item");r=null===t?r.filter((t=>void 0===Td(t,"sample"))):r.filter((n=>Number(Td(n,"sample"))===t));for(let t=0;t0&&void 0!==arguments[0]?arguments[0]:null;const n=this.fileDirectory.ModelPixelScale,i=this.fileDirectory.ModelTransformation;if(n)return[n[0],-n[1],n[2]];if(i)return[i[0],i[5],i[10]];if(t){const[n,i,r]=t.getResolution();return[n*t.getWidth()/this.getWidth(),i*t.getHeight()/this.getHeight(),r*t.getWidth()/this.getWidth()]}throw new Error("The image does not have an affine transformation.")}pixelIsArea(){return 1===this.geoKeys.GTRasterTypeGeoKey}getBoundingBox(){const t=this.getOrigin(),n=this.getResolution(),i=t[0],r=t[1],e=i+n[0]*this.getWidth(),o=r+n[1]*this.getHeight();return[Math.min(i,e),Math.min(r,o),Math.max(i,e),Math.max(r,o)]}};class Bd{constructor(t){this._dataView=new DataView(t)}get buffer(){return this._dataView.buffer}getUint64(t,n){const i=this.getUint32(t,n),r=this.getUint32(t+4,n);let e;if(n){if(e=i+2**32*r,!Number.isSafeInteger(e))throw new Error(`${e} exceeds MAX_SAFE_INTEGER. Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues`);return e}if(e=2**32*i+r,!Number.isSafeInteger(e))throw new Error(`${e} exceeds MAX_SAFE_INTEGER. Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues`);return e}getInt64(t,n){let i=0;const r=(128&this._dataView.getUint8(t+(n?7:0)))>0;let e=!0;for(let o=0;o<8;o++){let s=this._dataView.getUint8(t+(n?o:7-o));r&&(e?0!==s&&(s=255&~(s-1),e=!1):s=255&~s),i+=s*256**o}return r&&(i=-i),i}getUint8(t,n){return this._dataView.getUint8(t,n)}getInt8(t,n){return this._dataView.getInt8(t,n)}getUint16(t,n){return this._dataView.getUint16(t,n)}getInt16(t,n){return this._dataView.getInt16(t,n)}getUint32(t,n){return this._dataView.getUint32(t,n)}getInt32(t,n){return this._dataView.getInt32(t,n)}getFloat16(t,n){return Ed(this._dataView,t,n)}getFloat32(t,n){return this._dataView.getFloat32(t,n)}getFloat64(t,n){return this._dataView.getFloat64(t,n)}}class Xd{constructor(t,n,i,r){this._dataView=new DataView(t),this._sliceOffset=n,this._littleEndian=i,this._bigTiff=r}get sliceOffset(){return this._sliceOffset}get sliceTop(){return this._sliceOffset+this.buffer.byteLength}get littleEndian(){return this._littleEndian}get bigTiff(){return this._bigTiff}get buffer(){return this._dataView.buffer}covers(t,n){return this.sliceOffset<=t&&this.sliceTop>=t+n}readUint8(t){return this._dataView.getUint8(t-this._sliceOffset,this._littleEndian)}readInt8(t){return this._dataView.getInt8(t-this._sliceOffset,this._littleEndian)}readUint16(t){return this._dataView.getUint16(t-this._sliceOffset,this._littleEndian)}readInt16(t){return this._dataView.getInt16(t-this._sliceOffset,this._littleEndian)}readUint32(t){return this._dataView.getUint32(t-this._sliceOffset,this._littleEndian)}readInt32(t){return this._dataView.getInt32(t-this._sliceOffset,this._littleEndian)}readFloat32(t){return this._dataView.getFloat32(t-this._sliceOffset,this._littleEndian)}readFloat64(t){return this._dataView.getFloat64(t-this._sliceOffset,this._littleEndian)}readUint64(t){const n=this.readUint32(t),i=this.readUint32(t+4);let r;if(this._littleEndian){if(r=n+2**32*i,!Number.isSafeInteger(r))throw new Error(`${r} exceeds MAX_SAFE_INTEGER. Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues`);return r}if(r=2**32*n+i,!Number.isSafeInteger(r))throw new Error(`${r} exceeds MAX_SAFE_INTEGER. Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues`);return r}readInt64(t){let n=0;const i=(128&this._dataView.getUint8(t+(this._littleEndian?7:0)))>0;let r=!0;for(let e=0;e<8;e++){let o=this._dataView.getUint8(t+(this._littleEndian?e:7-e));i&&(r?0!==o&&(o=255&~(o-1),r=!1):o=255&~o),n+=o*256**e}return i&&(n=-n),n}readOffset(t){return this._bigTiff?this.readUint64(t):this.readUint32(t)}}const Vd="\r\n\r\n";function Wd(t){if(void 0!==Object.fromEntries)return Object.fromEntries(t);const n={};for(const[i,r]of t)n[i.toLowerCase()]=r;return n}function Yd(t){return Wd(t.split("\r\n").map((t=>{const n=t.split(":").map((t=>t.trim()));return n[0]=n[0].toLowerCase(),n})))}function Zd(t){let n,i,r;return t&&([,n,i,r]=t.match(/bytes (\d+)-(\d+)\/(\d+)/),n=parseInt(n,10),i=parseInt(i,10),r=parseInt(r,10)),{start:n,end:i,total:r}}class $d{async fetch(t){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0;return Promise.all(t.map((t=>this.fetchSlice(t,n))))}async fetchSlice(t){throw new Error(`fetching of slice ${t} not possible, not implemented`)}get fileSize(){return null}async close(){}}var Kd=i(875);function Hd(t,n){const i=Array.isArray(t)?t:Array.from(t),r=Array.isArray(n)?n:Array.from(n);return i.map(((t,n)=>[t,r[n]]))}class Jd extends Error{constructor(t){super(t),Error.captureStackTrace&&Error.captureStackTrace(this,Jd),this.name="AbortError"}}class Qd extends Error{constructor(t,n){super(n),this.errors=t,this.message=n,this.name="AggregateError"}}const tp=Qd;class np{constructor(t,n){let i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null;this.offset=t,this.length=n,this.data=i}get top(){return this.offset+this.length}}class ip{constructor(t,n,i){this.offset=t,this.length=n,this.blockIds=i}}class rp extends $d{constructor(t){let{blockSize:n=65536,cacheSize:i=100}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};super(),this.source=t,this.blockSize=n,this.blockCache=new Kd({max:i}),this.blockRequests=new Map,this.blockIdsToFetch=new Set}get fileSize(){return this.source.fileSize}async fetch(t,n){const i=new Map,r=new Map,e=new Set;for(const{offset:n,length:o}of t){let t=n+o;const{fileSize:s}=this;null!==s&&(t=Math.min(t,s));for(let o=Math.floor(n/this.blockSize)*this.blockSize;osetTimeout(n,t)))}(),this.fetchBlocks(n);for(const t of e){const n=this.blockRequests.get(t),e=this.blockCache.get(t);if(n)r.set(t,n);else{if(!e)throw new Error(`Block ${t} is not in the block requests`);i.set(t,e)}}let o=await Promise.allSettled(Array.from(r.values()));if(o.some((t=>"rejected"===t.status))){const t=new Set;for(const[i,e]of Hd(r.keys(),o)){const{rejected:r,reason:o}=e;r&&"AbortError"===o.name&&o.signal!==n&&(this.blockIdsToFetch.add(i),t.add(i))}if(this.blockIdsToFetch.length>0){this.fetchBlocks(n);for(const n of t){const t=this.blockRequests.get(n);if(!t)throw new Error(`Block ${n} is not in the block requests`);r.set(n,t)}o=await Promise.allSettled(Array.from(r.values()))}}if(o.some((t=>"rejected"===t.status))){if(n&&n.aborted)throw new Jd("Request was aborted");throw new tp(o.filter((t=>"rejected"===t.status)).map((t=>t.reason)),"Request failed")}const s=o.map((t=>t.value)),u=new Map(Hd(Array.from(r.keys()),s));for(const[t,n]of i)u.set(t,n);return this.readSliceData(t,u)}fetchBlocks(t){if(this.blockIdsToFetch.size>0){const n=this.groupBlocks(this.blockIdsToFetch),i=this.source.fetch(n,t);for(let r=0;r{try{const t=(await i)[r],e=n*this.blockSize,o=e-t.offset,s=Math.min(o+this.blockSize,t.data.byteLength),u=t.data.slice(o,s),a=new np(e,u.byteLength,u);return this.blockCache.set(n,a),a}catch(n){throw"AbortError"===n.name&&(n.signal=t),n}finally{this.blockRequests.delete(n)}})();this.blockRequests.set(n,e)}}this.blockIdsToFetch.clear()}}groupBlocks(t){const n=Array.from(t).sort(((t,n)=>t-n));if(0===n.length)return[];let i=[],r=null;const e=[];for(const t of n)null===r||r+1===t?(i.push(t),r=t):(e.push(new ip(i[0]*this.blockSize,i.length*this.blockSize,i)),i=[t],r=t);return e.push(new ip(i[0]*this.blockSize,i.length*this.blockSize,i)),e}readSliceData(t,n){return t.map((t=>{const i=t.offset+t.length,r=Math.floor(t.offset/this.blockSize),e=Math.floor((t.offset+t.length)/this.blockSize),o=new ArrayBuffer(t.length),s=new Uint8Array(o);for(let o=r;o<=e;++o){const r=n.get(o),e=r.offset-t.offset,u=r.top-i;let a,h=0,f=0;e<0?h=-e:e>0&&(f=e),a=u<0?r.length-h:i-r.offset-h;const c=new Uint8Array(r.data,h,a);s.set(c,f)}return o}))}}class ep{get ok(){return this.status>=200&&this.status<=299}get status(){throw new Error("not implemented")}getHeader(t){throw new Error("not implemented")}async getData(){throw new Error("not implemented")}}class op{constructor(t){this.url=t}async request(){let{headers:t,credentials:n,signal:i}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};throw new Error("request is not implemented")}}class sp extends ep{constructor(t){super(),this.response=t}get status(){return this.response.status}getHeader(t){return this.response.headers.get(t)}async getData(){return this.response.arrayBuffer?await this.response.arrayBuffer():(await this.response.buffer()).buffer}}class up extends op{constructor(t,n){super(t),this.credentials=n}async request(){let{headers:t,credentials:n,signal:i}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const r=await fetch(this.url,{headers:t,credentials:n,signal:i});return new sp(r)}}class ap extends ep{constructor(t,n){super(),this.xhr=t,this.data=n}get status(){return this.xhr.status}getHeader(t){return this.xhr.getResponseHeader(t)}async getData(){return this.data}}class hp extends op{constructRequest(t,n){return new Promise(((i,r)=>{const e=new XMLHttpRequest;e.open("GET",this.url),e.responseType="arraybuffer";for(const[n,i]of Object.entries(t))e.setRequestHeader(n,i);e.onload=()=>{const t=e.response;i(new ap(e,t))},e.onerror=r,e.onabort=()=>r(new Jd("Request aborted")),e.send(),n&&(n.aborted&&e.abort(),n.addEventListener("abort",(()=>e.abort())))}))}async request(){let{headers:t,signal:n}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return await this.constructRequest(t,n)}}var fp=i(752),cp=i(640),lp=i(630);class vp extends ep{constructor(t,n){super(),this.response=t,this.dataPromise=n}get status(){return this.response.statusCode}getHeader(t){return this.response.headers[t]}async getData(){return await this.dataPromise}}class dp extends op{constructor(t){super(t),this.parsedUrl=lp.parse(this.url),this.httpApi="http:"===this.parsedUrl.protocol?fp:cp}constructRequest(t,n){return new Promise(((i,r)=>{const e=this.httpApi.get({...this.parsedUrl,headers:t},(t=>{const n=new Promise((n=>{const i=[];t.on("data",(t=>{i.push(t)})),t.on("end",(()=>{const t=Buffer.concat(i).buffer;n(t)})),t.on("error",r)}));i(new vp(t,n))}));e.on("error",r),n&&(n.aborted&&e.destroy(new Jd("Request aborted")),n.addEventListener("abort",(()=>e.destroy(new Jd("Request aborted")))))}))}async request(){let{headers:t,signal:n}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return await this.constructRequest(t,n)}}class pp extends $d{constructor(t,n,i,r){super(),this.client=t,this.headers=n,this.maxRanges=i,this.allowFullFile=r,this._fileSize=null}async fetch(t,n){return this.maxRanges>=t.length?this.fetchSlices(t,n):(this.maxRanges>0&&t.length,Promise.all(t.map((t=>this.fetchSlice(t,n)))))}async fetchSlices(t,n){const i=await this.client.request({headers:{...this.headers,Range:`bytes=${t.map((t=>{let{offset:n,length:i}=t;return`${n}-${n+i}`})).join(",")}`},signal:n});if(i.ok){if(206===i.status){const{type:r,params:e}=function(t){const[n,...i]=t.split(";").map((t=>t.trim()));return{type:n,params:Wd(i.map((t=>t.split("="))))}}(i.getHeader("content-type"));if("multipart/byteranges"===r){const t=function(t,n){let i=null;const r=new TextDecoder("ascii"),e=[],o=`--${n}`,s=`${o}--`;for(let n=0;n<10;++n)r.decode(new Uint8Array(t,n,o.length))===o&&(i=n);if(null===i)throw new Error("Could not find initial boundary");for(;i1){const i=await Promise.all(t.slice(1).map((t=>this.fetchSlice(t,n))));return h.concat(i)}return h}{if(!this.allowFullFile)throw new Error("Server responded with full file");const t=await i.getData();return this._fileSize=t.byteLength,[{data:t,offset:0,length:t.byteLength}]}}throw new Error("Error fetching data.")}async fetchSlice(t,n){const{offset:i,length:r}=t,e=await this.client.request({headers:{...this.headers,Range:`bytes=${i}-${i+r}`},signal:n});if(e.ok){if(206===e.status){const t=await e.getData(),{total:n}=Zd(e.getHeader("content-range"));return this._fileSize=n||null,{data:t,offset:i,length:r}}{if(!this.allowFullFile)throw new Error("Server responded with full file");const t=await e.getData();return this._fileSize=t.byteLength,{data:t,offset:0,length:t.byteLength}}}throw new Error("Error fetching data.")}get fileSize(){return this._fileSize}}function yp(t,n){let{blockSize:i,cacheSize:r}=n;return null===i?t:new rp(t,i,r)}function mp(t){let{headers:n={},credentials:i,maxRanges:r=0,allowFullFile:e=!1,...o}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const s=new up(t,i),u=new pp(s,n,r,e);return yp(u,o)}function wp(t){let{headers:n={},maxRanges:i=0,allowFullFile:r=!1,...e}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const o=new hp(t),s=new pp(o,n,i,r);return yp(s,e)}function gp(t){let{headers:n={},maxRanges:i=0,allowFullFile:r=!1,...e}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const o=new dp(t),s=new pp(o,n,i,r);return yp(s,e)}function bp(t){let{forceXHR:n=!1,...i}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return"function"!=typeof fetch||n?"undefined"!=typeof XMLHttpRequest?wp(t,i):gp(t,i):mp(t,i)}class xp extends $d{constructor(t){super(),this.file=t}async fetchSlice(t,n){return new Promise(((i,r)=>{const e=this.file.slice(t.offset,t.offset+t.length),o=new FileReader;o.onload=t=>i(t.target.result),o.onerror=r,o.onabort=r,o.readAsArrayBuffer(e),n&&n.addEventListener("abort",(()=>o.abort()))}))}}function Mp(t){switch(t){case Pd.sf.BYTE:case Pd.sf.ASCII:case Pd.sf.SBYTE:case Pd.sf.UNDEFINED:return 1;case Pd.sf.SHORT:case Pd.sf.SSHORT:return 2;case Pd.sf.LONG:case Pd.sf.SLONG:case Pd.sf.FLOAT:case Pd.sf.IFD:return 4;case Pd.sf.RATIONAL:case Pd.sf.SRATIONAL:case Pd.sf.DOUBLE:case Pd.sf.LONG8:case Pd.sf.SLONG8:case Pd.sf.IFD8:return 8;default:throw new RangeError(`Invalid field type: ${t}`)}}function _p(t,n,i,r){let e=null,o=null;const s=Mp(n);switch(n){case Pd.sf.BYTE:case Pd.sf.ASCII:case Pd.sf.UNDEFINED:e=new Uint8Array(i),o=t.readUint8;break;case Pd.sf.SBYTE:e=new Int8Array(i),o=t.readInt8;break;case Pd.sf.SHORT:e=new Uint16Array(i),o=t.readUint16;break;case Pd.sf.SSHORT:e=new Int16Array(i),o=t.readInt16;break;case Pd.sf.LONG:case Pd.sf.IFD:e=new Uint32Array(i),o=t.readUint32;break;case Pd.sf.SLONG:e=new Int32Array(i),o=t.readInt32;break;case Pd.sf.LONG8:case Pd.sf.IFD8:e=new Array(i),o=t.readUint64;break;case Pd.sf.SLONG8:e=new Array(i),o=t.readInt64;break;case Pd.sf.RATIONAL:e=new Uint32Array(2*i),o=t.readUint32;break;case Pd.sf.SRATIONAL:e=new Int32Array(2*i),o=t.readInt32;break;case Pd.sf.FLOAT:e=new Float32Array(i),o=t.readFloat32;break;case Pd.sf.DOUBLE:e=new Float64Array(i),o=t.readFloat64;break;default:throw new RangeError(`Invalid field type: ${n}`)}if(n!==Pd.sf.RATIONAL&&n!==Pd.sf.SRATIONAL)for(let n=0;n0&&void 0!==arguments[0]?arguments[0]:{};const{window:n,width:i,height:r}=t;let{resX:e,resY:o,bbox:s}=t;const u=await this.getImage();let a=u;const h=await this.getImageCount(),f=u.getBoundingBox();if(n&&s)throw new Error('Both "bbox" and "window" passed.');if(i||r){if(n){const[t,i]=u.getOrigin(),[r,e]=u.getResolution();s=[t+n[0]*r,i+n[1]*e,t+n[2]*r,i+n[3]*e]}const t=s||f;if(i){if(e)throw new Error("Both width and resX passed");e=(t[2]-t[0])/i}if(r){if(o)throw new Error("Both width and resY passed");o=(t[3]-t[1])/r}}if(e||o){const t=[];for(let n=0;nt.getWidth()-n.getWidth()));for(let n=0;nr||o&&o>s)break}}let c=n;if(s){const[t,n]=u.getOrigin(),[i,r]=a.getResolution(u);c=[Math.round((s[0]-t)/i),Math.round((s[1]-n)/r),Math.round((s[2]-t)/i),Math.round((s[3]-n)/r)],c=[Math.min(c[0],c[2]),Math.min(c[1],c[3]),Math.max(c[0],c[2]),Math.max(c[1],c[3])]}return a.readRasters({...t,window:c})}}class Ep extends jp{constructor(t,n,i,r){let e=arguments.length>4&&void 0!==arguments[4]?arguments[4]:{};super(),this.source=t,this.littleEndian=n,this.bigTiff=i,this.firstIFDOffset=r,this.cache=e.cache||!1,this.ifdRequests=[],this.ghostValues=null}async getSlice(t,n){const i=this.bigTiff?4048:1024;return new Xd((await this.source.fetch([{offset:t,length:void 0!==n?n:i}]))[0],t,this.littleEndian,this.bigTiff)}async parseFileDirectoryAt(t){const n=this.bigTiff?20:12,i=this.bigTiff?8:2;let r=await this.getSlice(t);const e=this.bigTiff?r.readUint64(t):r.readUint16(t),o=e*n+(this.bigTiff?16:6);r.covers(t,o)||(r=await this.getSlice(t,o));const s={};let u=t+(this.bigTiff?8:2);for(let t=0;t{const n=await this.ifdRequests[t-1];if(0===n.nextIFDByteOffset)throw new Op(t);return this.parseFileDirectoryAt(n.nextIFDByteOffset)})(),this.ifdRequests[t]}async getImage(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;const n=await this.requestIFD(t);return new Ud(n.fileDirectory,n.geoKeyDirectory,this.dataView,this.littleEndian,this.cache,this.source)}async getImageCount(){let t=0,n=!0;for(;n;)try{await this.requestIFD(t),++t}catch(t){if(!(t instanceof Op))throw t;n=!1}return t}async getGhostValues(){const t=this.bigTiff?16:8;if(this.ghostValues)return this.ghostValues;const n="GDAL_STRUCTURAL_METADATA_SIZE=",i=n.length+100;let r=await this.getSlice(t,i);if(n===_p(r,Pd.sf.ASCII,n.length,t)){const n=_p(r,Pd.sf.ASCII,i,t).split("\n")[0],e=Number(n.split("=")[1].split(" ")[0])+n.length;e>i&&(r=await this.getSlice(t,e));const o=_p(r,Pd.sf.ASCII,e,t);this.ghostValues={},o.split("\n").filter((t=>t.length>0)).map((t=>t.split("="))).forEach((t=>{let[n,i]=t;this.ghostValues[n]=i}))}return this.ghostValues}static async fromSource(t,n,i){const r=(await t.fetch([{offset:0,length:1024}],i))[0],e=new Bd(r),o=e.getUint16(0,0);let s;if(18761===o)s=!0;else{if(19789!==o)throw new TypeError("Invalid byte order value.");s=!1}const u=e.getUint16(2,s);let a;if(42===u)a=!1;else{if(43!==u)throw new TypeError("Invalid magic number.");a=!0;if(8!==e.getUint16(4,s))throw new Error("Unsupported offset byte-size.")}const h=a?e.getUint64(8,s):e.getUint32(4,s);return new Ep(t,s,a,h,n)}close(){return"function"==typeof this.source.close&&this.source.close()}}class Tp extends jp{constructor(t,n){super(),this.mainFile=t,this.overviewFiles=n,this.imageFiles=[t].concat(n),this.fileDirectoriesPerFile=null,this.fileDirectoriesPerFileParsing=null,this.imageCount=null}async parseFileDirectoriesPerFile(){const t=[this.mainFile.parseFileDirectoryAt(this.mainFile.firstIFDOffset)].concat(this.overviewFiles.map((t=>t.parseFileDirectoryAt(t.firstIFDOffset))));return this.fileDirectoriesPerFile=await Promise.all(t),this.fileDirectoriesPerFile}async getImage(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;await this.getImageCount(),await this.parseFileDirectoriesPerFile();let n=0,i=0;for(let r=0;rt.getImageCount())));return this.imageCounts=await Promise.all(t),this.imageCount=this.imageCounts.reduce(((t,n)=>t+n),0),this.imageCount}}async function Ap(t,n){return Ep.fromSource(new xp(t),n)}const Pp="undefined"!=typeof navigator&&navigator.hardwareConcurrency||2;var Cp,kp=class{constructor(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Pp,n=arguments.length>1?arguments[1]:void 0;this.workers=null,this._awaitingDecoder=null,this.size=t,this.messageId=0,t&&(this._awaitingDecoder=n?Promise.resolve(n):new Promise((t=>{i.e(231).then(i.bind(i,231)).then((n=>{t(n.create)}))})),this._awaitingDecoder.then((n=>{this._awaitingDecoder=null,this.workers=[];for(let i=0;ii.decode(t,n))):new Promise((i=>{const r=this.workers.find((t=>t.idle))||this.workers[Math.floor(Math.random()*this.size)];r.idle=!1;const e=this.messageId++,o=t=>{t.data.id===e&&(r.idle=!0,i(t.data.decoded),r.worker.removeEventListener("message",o))};r.worker.addEventListener("message",o),r.worker.postMessage({fileDirectory:t,buffer:n,id:e},[n])}))}destroy(){this.workers&&(this.workers.forEach((t=>{t.worker.terminate()})),this.workers=null)}},Ip=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Np="STATISTICS_MAXIMUM",Lp="STATISTICS_MINIMUM";function zp(t){try{return t.getBoundingBox()}catch(i){var n=t.fileDirectory;return[0,0,n.ImageWidth,n.ImageLength]}}function Rp(t){try{return t.getOrigin().slice(0,2)}catch(n){return[0,t.fileDirectory.ImageLength]}}function Fp(t,n){try{return t.getResolution(n)}catch(i){return[n.fileDirectory.ImageWidth/t.fileDirectory.ImageWidth,n.fileDirectory.ImageHeight/t.fileDirectory.ImageHeight]}}function Gp(t){var n=t.geoKeys;if(!n)return null;if(n.ProjectedCSTypeGeoKey){if(!(r=yr(i="EPSG:"+n.ProjectedCSTypeGeoKey)))(e=Nt(n.ProjLinearUnitsGeoKey))&&(r=new ei({code:i,units:e}));return r}if(n.GeographicTypeGeoKey){var i,r,e;if(!(r=yr(i="EPSG:"+n.GeographicTypeGeoKey)))(e=Nt(n.GeogAngularUnitsGeoKey))&&(r=new ei({code:i,units:e}));return r}return null}function Dp(t){return t.getImageCount().then((function(n){for(var i=new Array(n),r=0;r1&&void 0!==arguments[1]?arguments[1]:[],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=arguments.length>3?arguments[3]:void 0;const e=await Ep.fromSource(bp(t,i),r),o=await Promise.all(n.map((t=>Ep.fromSource(bp(t,i)))));return new Tp(e,o)}(t.url,t.overviews,n):async function(t){let n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=arguments.length>2?arguments[2]:void 0;return Ep.fromSource(bp(t,n),i)}(t.url,n)).then(Dp)}function Up(t,n,i,r,e){if(Array.isArray(t)){var o=t.length;if(!Array.isArray(n)||o!=n.length){var s=new Error(r);throw e(s),s}for(var u=0;ui*t)throw new Error(r)}function Bp(t){return t instanceof Int8Array?-128:t instanceof Int16Array?-32768:t instanceof Int32Array?-2147483648:t instanceof Float32Array?12e-39:0}function Xp(t){return t instanceof Int8Array?127:t instanceof Uint8Array||t instanceof Uint8ClampedArray?255:t instanceof Int16Array?32767:t instanceof Uint16Array?65535:t instanceof Int32Array?2147483647:t instanceof Uint32Array?4294967295:t instanceof Float32Array?34e37:255}var Vp=function(t){function n(n){var i=t.call(this,{state:"loading",tileGrid:null,projection:null,opaque:n.opaque,transition:n.transition,interpolate:!1!==n.interpolate,wrapX:n.wrapX})||this;i.Qa=n.sources;var r=i.Qa.length;i.th=n.sourceOptions,i.nh=new Array(r),i.ih=new Array(r),i.rh,i.eh,i.oh,i.sh=!1!==n.normalize,i.uh=!1,i.V=null,i.ah=n.convertToRGB?"readRGB":"readRasters",i.setKey(i.Qa.map((function(t){return t.url})).join(","));for(var e=i,o=new Array(r),s=0;sw.length&&(h=o.length-w.length);var T=o[o.length-1]/w[w.length-1];l.ih[f]=T;var A=w.map((function(t){return t*T}));E="Resolution mismatch for source ".concat(f,", got [").concat(A,"] but expected [").concat(o,"]");Up(o.slice(h,o.length),A,.02,E,l.viewRejector)}else o=w,l.ih[f]=1;r?Up(r.slice(h,r.length),m,.01,"Tile size mismatch for source ".concat(f),l.viewRejector):r=m,e?Up(e.slice(h,e.length),y,0,"Tile size mismatch for source ".concat(f),l.viewRejector):e=y,l.nh[f]=c.reverse()},l=this,v=0;v=0;--d){var w=Gp(m[d]);if(w){this.projection=w;break}}}this.rh=s,this.eh=u,this.oh=a;t:for(v=0;vl||h>l;)f.push([Math.ceil(a/l),Math.ceil(h/l)]),l+=l;break;case $p:for(var v=a,d=h;v>l||d>l;)f.push([Math.ceil(v/l),Math.ceil(d/l)]),v>>=1,d>>=1;break;default:St(!1,53)}f.push([1,1]),f.reverse();for(var p=[u],y=[0],m=1,w=f.length;m1,r=i&&t.imageInfo.profile[1].supports?t.imageInfo.profile[1].supports:[],e=i&&t.imageInfo.profile[1].formats?t.imageInfo.profile[1].formats:[],o=i&&t.imageInfo.profile[1].qualities?t.imageInfo.profile[1].qualities:[];return{url:t.imageInfo["@id"].replace(/\/?(?:info\.json)?$/g,""),sizes:void 0===t.imageInfo.sizes?void 0:t.imageInfo.sizes.map((function(t){return[t.width,t.height]})),tileSize:void 0===t.imageInfo.tiles?void 0:[t.imageInfo.tiles.map((function(t){return t.width}))[0],t.imageInfo.tiles.map((function(t){return void 0===t.height?t.width:t.height}))[0]],resolutions:void 0===t.imageInfo.tiles?void 0:t.imageInfo.tiles.map((function(t){return t.scaleFactors}))[0],supports:Jp(Jp([],n.supports,!0),r,!0),formats:Jp(Jp([],n.formats,!0),e,!0),qualities:Jp(Jp([],n.qualities,!0),o,!0)}},sy[ny]=function(t){var n=t.getComplianceLevelSupportedFeatures(),i=void 0===t.imageInfo.extraFormats?n.formats:Jp(Jp([],n.formats,!0),t.imageInfo.extraFormats,!0),r=void 0!==t.imageInfo.preferredFormats&&Array.isArray(t.imageInfo.preferredFormats)&&t.imageInfo.preferredFormats.length>0?t.imageInfo.preferredFormats.filter((function(t){return y(["jpg","png","gif"],t)})).reduce((function(t,n){return void 0===t&&y(i,n)?n:t}),void 0):void 0;return{url:t.imageInfo.id,sizes:void 0===t.imageInfo.sizes?void 0:t.imageInfo.sizes.map((function(t){return[t.width,t.height]})),tileSize:void 0===t.imageInfo.tiles?void 0:[t.imageInfo.tiles.map((function(t){return t.width}))[0],t.imageInfo.tiles.map((function(t){return t.height}))[0]],resolutions:void 0===t.imageInfo.tiles?void 0:t.imageInfo.tiles.map((function(t){return t.scaleFactors}))[0],supports:void 0===t.imageInfo.extraFeatures?n.supports:Jp(Jp([],n.supports,!0),t.imageInfo.extraFeatures,!0),formats:i,qualities:void 0===t.imageInfo.extraQualities?n.qualities:Jp(Jp([],n.qualities,!0),t.imageInfo.extraQualities,!0),preferredFormat:r}};var uy=function(){function t(t){this.setImageInfo(t)}return t.prototype.setImageInfo=function(t){this.imageInfo="string"==typeof t?JSON.parse(t):t},t.prototype.getImageApiVersion=function(){if(void 0!==this.imageInfo){var t=this.imageInfo["@context"]||"ol-no-context";"string"==typeof t&&(t=[t]);for(var n=0;n0&&"string"==typeof this.imageInfo.profile[0]&&ey.test(this.imageInfo.profile[0]))return this.imageInfo.profile[0]}},t.prototype.getComplianceLevelFromProfile=function(t){var n=this.getComplianceLevelEntryFromProfile(t);if(void 0!==n){var i=n.match(/level[0-2](?:\.json)?$/g);return Array.isArray(i)?i[0].replace(".json",""):void 0}},t.prototype.getComplianceLevelSupportedFeatures=function(){if(void 0!==this.imageInfo){var t=this.getImageApiVersion(),n=this.getComplianceLevelFromProfile(t);return void 0===n?iy.none.none:iy[t][n]}},t.prototype.getTileSourceOptions=function(t){var n=t||{},i=this.getImageApiVersion();if(void 0!==i){var r=void 0===i?void 0:sy[i](this);if(void 0!==r)return{url:r.url,version:i,size:[this.imageInfo.width,this.imageInfo.height],sizes:r.sizes,format:void 0!==n.format&&y(r.formats,n.format)?n.format:void 0!==r.preferredFormat?r.preferredFormat:"jpg",supports:r.supports,quality:n.quality&&y(r.qualities,n.quality)?n.quality:y(r.qualities,"native")?"native":"default",resolutions:Array.isArray(r.resolutions)?r.resolutions.sort((function(t,n){return n-t})):void 0,tileSize:r.tileSize}}},t}(),ay=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}();function hy(t){return t.toLocaleString("en",{maximumFractionDigits:10})}var fy=function(t){function n(n){var i=this,r=n||{},e=void 0===r.imageSmoothing||r.imageSmoothing;void 0!==r.interpolate&&(e=r.interpolate);var o=r.url||"";o+=o.lastIndexOf("/")===o.length-1||""===o?"":"/";var s=r.version||ty,u=r.sizes||[],a=r.size;St(null!=a&&Array.isArray(a)&&2==a.length&&!isNaN(a[0])&&a[0]>0&&!isNaN(a[1])&&a[1]>0,60);var h,f,c,l=a[0],v=a[1],d=r.tileSize,p=r.tilePixelRatio||1,m=r.format||"jpg",w=r.quality||(r.version==Qp?"native":"default"),g=r.resolutions||[],b=r.supports||[],x=r.extent||[0,-v,l,0],M=null!=u&&Array.isArray(u)&&u.length>0,_=void 0!==d&&("number"==typeof d&&Number.isInteger(d)&&d>0||Array.isArray(d)&&d.length>0),S=null!=b&&Array.isArray(b)&&(y(b,"regionByPx")||y(b,"regionByPct"))&&(y(b,"sizeByWh")||y(b,"sizeByH")||y(b,"sizeByW")||y(b,"sizeByPct"));if(g.sort((function(t,n){return n-t})),_||S)if(null!=d&&("number"==typeof d&&Number.isInteger(d)&&d>0?(h=d,f=d):Array.isArray(d)&&d.length>0&&((1==d.length||null==d[1]&&Number.isInteger(d[0]))&&(h=d[0],f=d[0]),2==d.length&&(Number.isInteger(d[0])&&Number.isInteger(d[1])?(h=d[0],f=d[1]):null==d[0]&&Number.isInteger(d[1])&&(h=d[1],f=d[1])))),void 0!==h&&void 0!==f||(h=Pu,f=Pu),0==g.length)for(var O=c=Math.max(Math.ceil(Math.log(l/h)/Math.LN2),Math.ceil(Math.log(v/f)/Math.LN2));O>=0;O--)g.push(Math.pow(2,O));else{var j=Math.max.apply(Math,g);c=Math.round(Math.log(j)/Math.LN2)}else if(h=l,f=v,g=[],M){u.sort((function(t,n){return t[0]-n[0]})),c=-1;var E=[];for(O=0;O0&&g[g.length-1]==T?E.push(O):(g.push(T),c++)}if(E.length>0)for(O=0;Oc)){var d=t[1],p=t[2],x=g[a];if(!(void 0===d||void 0===p||void 0===x||d<0||Math.ceil(l/x/h)<=d||p<0||Math.ceil(v/x/f)<=p)){if(S||_){var O=d*h*x,j=p*f*x,E=h*x,T=f*x,A=h,P=f;if(O+E>l&&(E=l-O),j+T>v&&(T=v-j),O+h*x>l&&(A=Math.floor((l-O+x-1)/x)),j+f*x>v&&(P=Math.floor((v-j+x-1)/x)),0==O&&E==l&&0==j&&T==v)r="full";else if(!S||y(b,"regionByPx"))r=O+","+j+","+E+","+T;else if(y(b,"regionByPct")){r="pct:"+hy(O/l*100)+","+hy(j/v*100)+","+hy(E/l*100)+","+hy(T/v*100)}s!=ny||S&&!y(b,"sizeByWh")?!S||y(b,"sizeByW")?e=A+",":y(b,"sizeByH")?e=","+P:y(b,"sizeByWh")?e=A+","+P:y(b,"sizeByPct")&&(e="pct:"+hy(100/x)):e=A+","+P}else if(r="full",M){var C=u[a][0],k=u[a][1];e=s==ny?C==l&&k==v?"max":C+","+k:C==l?"full":C+","}else e=s==ny?"max":"full";return o+r+"/"+e+"/0/"+w+"."+m}}},transition:r.transition})||this).zDirection=r.zDirection,i}return ay(n,t),n}(Vv),cy=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),ly=function(t){function n(n,i,r,e,o,s,u){var a=this,h=n.getExtent(),f=i.getExtent(),c=f?Wn(r,f):r,l=mf(n,i,qn(c),e),v=new qc(n,i,c,h,.5*l,e),d=s(v.calculateSourceExtent(),l,o),p=d?lo:mo,y=d?d.getPixelRatio():1;return(a=t.call(this,r,e,y,p)||this).vs=i,a.ps=h,a.Is=v,a.wi=e,a.dh=r,a.ph=d,a.yh=y,a.da=u,a.qt=null,a.mh=null,a}return cy(n,t),n.prototype.disposeInternal=function(){this.state==vo&&this.wh(),t.prototype.disposeInternal.call(this)},n.prototype.getImage=function(){return this.qt},n.prototype.getProjection=function(){return this.vs},n.prototype.Ns=function(){var t=this.ph.getState();if(t==po){var n=$n(this.dh)/this.wi,i=Vn(this.dh)/this.wi;this.qt=gf(n,i,this.yh,this.ph.getResolution(),this.ps,this.wi,this.dh,this.Is,[{extent:this.ph.getExtent(),image:this.ph.getImage()}],0,void 0,this.da)}this.state=t,this.changed()},n.prototype.load=function(){if(this.state==lo){this.state=vo,this.changed();var t=this.ph.getState();t==po||t==yo?this.Ns():(this.mh=$(this.ph,L,(function(t){var n=this.ph.getState();n!=po&&n!=yo||(this.wh(),this.Ns())}),this),this.ph.load())}},n.prototype.wh=function(){H(this.mh),this.mh=null},n}(co),vy=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),dy="imageloadstart",py="imageloadend",yy="imageloaderror",my=function(t){function n(n,i){var r=t.call(this,n)||this;return r.image=i,r}return vy(n,t),n}(c);function wy(t,n){t.getImage().src=n}var gy=function(t){function n(n){var i=this,r=void 0===n.imageSmoothing||n.imageSmoothing;return void 0!==n.interpolate&&(r=n.interpolate),(i=t.call(this,{attributions:n.attributions,projection:n.projection,state:n.state,interpolate:r})||this).on,i.once,i.un,i.Ti=void 0!==n.resolutions?n.resolutions:null,i.gh=null,i.bh=0,i}return vy(n,t),n.prototype.getResolutions=function(){return this.Ti},n.prototype.findNearestResolution=function(t){if(this.Ti){var n=m(this.Ti,t,0);t=this.Ti[n]}return t},n.prototype.getImage=function(t,n,i,r){var e=this.getProjection();if(e&&r&&!Sr(e,r)){if(this.gh){if(this.bh==this.getRevision()&&Sr(this.gh.getProjection(),r)&&this.gh.getResolution()==n&&An(this.gh.getExtent(),t))return this.gh;this.gh.dispose(),this.gh=null}return this.gh=new ly(e,r,t,n,i,function(t,n,i){return this.getImageInternal(t,n,i,e)}.bind(this),this.getInterpolate()),this.bh=this.getRevision(),this.gh}return e&&(r=e),this.getImageInternal(t,n,i,r)},n.prototype.getImageInternal=function(t,n,i,e){return r()},n.prototype.handleImageChange=function(t){var n,i=t.target;switch(i.getState()){case vo:this.loading=!0,n=dy;break;case po:this.loading=!1,n=py;break;case yo:this.loading=!1,n=yy;break;default:return}this.hasListener(n)&&this.dispatchEvent(new my(n,i))},n}(zv),by=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),xy=function(t){function n(n){var i=this,r=n||{},e=void 0===r.imageSmoothing||r.imageSmoothing;return void 0!==r.interpolate&&(e=r.interpolate),(i=t.call(this,{attributions:r.attributions,interpolate:e,projection:r.projection,resolutions:r.resolutions})||this).Bt=void 0!==r.crossOrigin?r.crossOrigin:null,i._a=void 0===r.hidpi||r.hidpi,i.Fe=r.url,i.Rt=void 0!==r.imageLoadFunction?r.imageLoadFunction:wy,i.xh=r.params||{},i.Lt=null,i.Mh=[0,0],i._h=0,i.Sh=void 0!==r.ratio?r.ratio:1.5,i}return by(n,t),n.prototype.getParams=function(){return this.xh},n.prototype.getImageInternal=function(t,n,i,r){if(void 0===this.Fe)return null;n=this.findNearestResolution(n),i=this._a?i:1;var e=this.Lt;if(e&&this._h==this.getRevision()&&e.getResolution()==n&&e.getPixelRatio()==i&&xn(e.getExtent(),t))return e;var o={F:"image",FORMAT:"PNG32",TRANSPARENT:!0};A(o,this.xh);var s=((t=t.slice())[0]+t[2])/2,u=(t[1]+t[3])/2;if(1!=this.Sh){var a=this.Sh*$n(t)/2,h=this.Sh*Vn(t)/2;t[0]=s-a,t[1]=u-h,t[2]=s+a,t[3]=u+h}var f=n/i,c=Math.ceil($n(t)/f),l=Math.ceil(Vn(t)/f);t[0]=s-f*c/2,t[2]=s+f*c/2,t[1]=u-f*l/2,t[3]=u+f*l/2,this.Mh[0]=c,this.Mh[1]=l;var v=this.Oh(t,this.Mh,i,r,o);return this.Lt=new bo(t,n,i,v,this.Bt,this.Rt),this._h=this.getRevision(),this.Lt.addEventListener(L,this.handleImageChange.bind(this)),this.Lt},n.prototype.getImageLoadFunction=function(){return this.Rt},n.prototype.Oh=function(t,n,i,r,e){var o=r.getCode().split(/:(?=\d+$)/).pop();e.SIZE=n[0]+","+n[1],e.BBOX=t.join(","),e.BBOXSR=o,e.IMAGESR=o,e.DPI=Math.round(90*i);var s=this.Fe,u=s.replace(/MapServer\/?$/,"MapServer/export").replace(/ImageServer\/?$/,"ImageServer/exportImage");return u==s&&St(!1,50),Nf(u,e)},n.prototype.getUrl=function(){return this.Fe},n.prototype.setImageLoadFunction=function(t){this.Lt=null,this.Rt=t,this.changed()},n.prototype.setUrl=function(t){t!=this.Fe&&(this.Fe=t,this.Lt=null,this.changed())},n.prototype.updateParams=function(t){A(this.xh,t),this.Lt=null,this.changed()},n}(gy),My=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),_y=function(t){function n(n){var i=this,r=n||{},e=void 0===r.imageSmoothing||r.imageSmoothing;return void 0!==r.interpolate&&(e=r.interpolate),(i=t.call(this,{attributions:r.attributions,interpolate:e,projection:r.projection,resolutions:r.resolutions,state:r.state})||this).jh=r.canvasFunction,i.qt=null,i._h=0,i.Sh=void 0!==r.ratio?r.ratio:1.5,i}return My(n,t),n.prototype.getImageInternal=function(t,n,i,r){n=this.findNearestResolution(n);var e=this.qt;if(e&&this._h==this.getRevision()&&e.getResolution()==n&&e.getPixelRatio()==i&&xn(e.getExtent(),t))return e;Qn(t=t.slice(),this.Sh);var o=[$n(t)/n*i,Vn(t)/n*i],s=this.jh.call(this,t,n,i,o,r);return s&&(e=new Mo(t,n,i,s)),this.qt=e,this._h=this.getRevision(),e},n}(gy),Sy=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}();var Oy=function(t){function n(n){var i=this,r=void 0===n.imageSmoothing||n.imageSmoothing;return void 0!==n.interpolate&&(r=n.interpolate),(i=t.call(this,{interpolate:r,projection:n.projection,resolutions:n.resolutions})||this).Bt=void 0!==n.crossOrigin?n.crossOrigin:null,i.Eh=void 0!==n.displayDpi?n.displayDpi:96,i.xh=n.params||{},i.Fe=n.url,i.Rt=void 0!==n.imageLoadFunction?n.imageLoadFunction:wy,i._a=void 0===n.hidpi||n.hidpi,i.dt=void 0!==n.metersPerUnit?n.metersPerUnit:1,i.Sh=void 0!==n.ratio?n.ratio:1,i.Th=void 0!==n.useOverlay&&n.useOverlay,i.Lt=null,i._h=0,i}return Sy(n,t),n.prototype.getParams=function(){return this.xh},n.prototype.getImageInternal=function(t,n,i,r){n=this.findNearestResolution(n),i=this._a?i:1;var e=this.Lt;if(e&&this._h==this.getRevision()&&e.getResolution()==n&&e.getPixelRatio()==i&&xn(e.getExtent(),t))return e;1!=this.Sh&&Qn(t=t.slice(),this.Sh);var o=[$n(t)/n*i,Vn(t)/n*i];if(void 0!==this.Fe){var s=this.getUrl(this.Fe,this.xh,t,o,r);(e=new bo(t,n,i,s,this.Bt,this.Rt)).addEventListener(L,this.handleImageChange.bind(this))}else e=null;return this.Lt=e,this._h=this.getRevision(),e},n.prototype.getImageLoadFunction=function(){return this.Rt},n.prototype.updateParams=function(t){A(this.xh,t),this.changed()},n.prototype.getUrl=function(t,n,i,r,e){var o=function(t,n,i,r){var e=$n(t),o=Vn(t),s=n[0],u=n[1],a=.0254/r;return u*e>s*o?e*i/(s*a):o*i/(u*a)}(i,r,this.dt,this.Eh),s=qn(i),u={OPERATION:this.Th?"GETDYNAMICMAPOVERLAYIMAGE":"GETMAPIMAGE",VERSION:"2.0.0",LOCALE:"en",CLIENTAGENT:"ol/source/ImageMapGuide source",CLIP:"1",SETDISPLAYDPI:this.Eh,SETDISPLAYWIDTH:Math.round(r[0]),SETDISPLAYHEIGHT:Math.round(r[1]),SETVIEWSCALE:o,SETVIEWCENTERX:s[0],SETVIEWCENTERY:s[1]};return A(u,n),Nf(t,u)},n.prototype.setImageLoadFunction=function(t){this.Lt=null,this.Rt=t,this.changed()},n}(gy),jy=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Ey=function(t){function n(n){var i=this,r=void 0!==n.crossOrigin?n.crossOrigin:null,e=void 0!==n.imageLoadFunction?n.imageLoadFunction:wy,o=void 0===n.imageSmoothing||n.imageSmoothing;return void 0!==n.interpolate&&(o=n.interpolate),(i=t.call(this,{attributions:n.attributions,interpolate:o,projection:yr(n.projection)})||this).Fe=n.url,i.Ah=n.imageExtent,i.Lt=new bo(i.Ah,void 0,1,i.Fe,r,e),i.Mh=n.imageSize?n.imageSize:null,i.Lt.addEventListener(L,i.handleImageChange.bind(i)),i}return jy(n,t),n.prototype.getImageExtent=function(){return this.Ah},n.prototype.getImageInternal=function(t,n,i,r){return Kn(t,this.Lt.getExtent())?this.Lt:null},n.prototype.getUrl=function(){return this.Fe},n.prototype.handleImageChange=function(n){if(this.Lt.getState()==po){var i=this.Lt.getExtent(),r=this.Lt.getImage(),e=void 0,o=void 0;this.Mh?(e=this.Mh[0],o=this.Mh[1]):(e=r.width,o=r.height);var s=$n(i),u=Vn(i),a=s/e,h=u/o,f=e,c=o;if(a>h?f=Math.round(s/h):c=Math.round(u/a),f!==e||c!==o){var l=_o(f,c);this.getInterpolate()||A(l,lf);var v=l.canvas;l.drawImage(r,0,0,e,o,0,0,v.width,v.height),this.Lt.setImage(v)}}t.prototype.handleImageChange.call(this,n)},n}(gy),Ty="1.3.0",Ay=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Py=[101,101],Cy=function(t){function n(n){var i=this,r=n||{},e=void 0===r.imageSmoothing||r.imageSmoothing;return void 0!==r.interpolate&&(e=r.interpolate),(i=t.call(this,{attributions:r.attributions,interpolate:e,projection:r.projection,resolutions:r.resolutions})||this).Bt=void 0!==r.crossOrigin?r.crossOrigin:null,i.Fe=r.url,i.Rt=void 0!==r.imageLoadFunction?r.imageLoadFunction:wy,i.xh=r.params||{},i.Ph=!0,i.Ch(),i.kh=r.serverType,i._a=void 0===r.hidpi||r.hidpi,i.Lt=null,i.Mh=[0,0],i._h=0,i.Sh=void 0!==r.ratio?r.ratio:1.5,i}return Ay(n,t),n.prototype.getFeatureInfoUrl=function(t,n,i,r){if(void 0!==this.Fe){var e=yr(i),o=this.getProjection();o&&o!==e&&(n=mf(o,e,t,n),t=Er(t,e,o));var s=Bn(t,n,0,Py),u={SERVICE:"WMS",VERSION:Ty,REQUEST:"GetFeatureInfo",FORMAT:"image/png",TRANSPARENT:!0,QUERY_LAYERS:this.xh.LAYERS};A(u,this.xh,r);var a=mi((t[0]-s[0])/n,4),h=mi((s[3]-t[1])/n,4);return u[this.Ph?"I":"X"]=a,u[this.Ph?"J":"Y"]=h,this.Oh(s,Py,1,o||e,u)}},n.prototype.getLegendUrl=function(t,n){if(void 0!==this.Fe){var i={SERVICE:"WMS",VERSION:Ty,REQUEST:"GetLegendGraphic",FORMAT:"image/png"};if(void 0===n||void 0===n.LAYER){var r=this.xh.LAYERS;if(!(!Array.isArray(r)||1===r.length))return;i.LAYER=r}if(void 0!==t){var e=this.getProjection()?this.getProjection().getMetersPerUnit():1;i.SCALE=t*e/28e-5}return A(i,n),Nf(this.Fe,i)}},n.prototype.getParams=function(){return this.xh},n.prototype.getImageInternal=function(t,n,i,r){if(void 0===this.Fe)return null;n=this.findNearestResolution(n),1==i||this._a&&void 0!==this.kh||(i=1);var e=n/i,o=qn(t),s=Bn(o,e,0,[wi($n(t)/e,4),wi(Vn(t)/e,4)]),u=Bn(o,e,0,[wi(this.Sh*$n(t)/e,4),wi(this.Sh*Vn(t)/e,4)]),a=this.Lt;if(a&&this._h==this.getRevision()&&a.getResolution()==n&&a.getPixelRatio()==i&&xn(a.getExtent(),s))return a;var h={SERVICE:"WMS",VERSION:Ty,REQUEST:"GetMap",FORMAT:"image/png",TRANSPARENT:!0};A(h,this.xh),this.Mh[0]=yi($n(u)/e,4),this.Mh[1]=yi(Vn(u)/e,4);var f=this.Oh(u,this.Mh,i,r,h);return this.Lt=new bo(u,n,i,f,this.Bt,this.Rt),this._h=this.getRevision(),this.Lt.addEventListener(L,this.handleImageChange.bind(this)),this.Lt},n.prototype.getImageLoadFunction=function(){return this.Rt},n.prototype.Oh=function(t,n,i,r,e){if(St(void 0!==this.Fe,9),e[this.Ph?"CRS":"SRS"]=r.getCode(),"STYLES"in this.xh||(e.STYLES=""),1!=i)switch(this.kh){case"geoserver":var o=90*i+.5|0;"FORMAT_OPTIONS"in e?e.FORMAT_OPTIONS+=";dpi:"+o:e.FORMAT_OPTIONS="dpi:"+o;break;case"mapserver":e.MAP_RESOLUTION=90*i;break;case"carmentaserver":case"qgis":e.DPI=90*i;break;default:St(!1,8)}e.WIDTH=n[0],e.HEIGHT=n[1];var s,u=r.getAxisOrientation();return s=this.Ph&&"ne"==u.substr(0,2)?[t[1],t[0],t[3],t[2]]:t,e.BBOX=s.join(","),Nf(this.Fe,e)},n.prototype.getUrl=function(){return this.Fe},n.prototype.setImageLoadFunction=function(t){this.Lt=null,this.Rt=t,this.changed()},n.prototype.setUrl=function(t){t!=this.Fe&&(this.Fe=t,this.Lt=null,this.changed())},n.prototype.updateParams=function(t){A(this.xh,t),this.Ch(),this.Lt=null,this.changed()},n.prototype.Ch=function(){var t=this.xh.VERSION||Ty;this.Ph=Xi(t,"1.3")>=0},n}(gy),ky={"image/png":!0,"image/jpeg":!0,"image/gif":!0,"image/webp":!0},Iy={"application/vnd.mapbox-vector-tile":!0,"application/geo+json":!0};function Ny(t,n){for(var i,r,e=0;el.maxTileCol||h.tileRowl.maxTileRow)return}A(h,T);var v=i.replace(/\{(\w+?)\}/g,(function(t,n){return h[n]}));return Qh(P,v)}}}}function Ry(t){return Jh(t.url).then((function(n){return function(t,n){var i,r=n.tileMatrixSetLimits;if("map"===n.dataType)i=Ny(n.links,t.mediaType);else{if("vector"!==n.dataType)throw new Error('Expected tileset data type to be "map" or "vector"');i=Ly(n.links,t.mediaType,t.supportedMediaTypes)}if(n.tileMatrixSet)return zy(t,n.tileMatrixSet,i,r);var e=n.links.find((function(t){return"http://www.opengis.net/def/rel/ogc/1.0/tiling-scheme"===t.rel}));if(!e)throw new Error("Expected http://www.opengis.net/def/rel/ogc/1.0/tiling-scheme link or tileMatrixSet");var o=e.href;return Jh(Qh(t.url,o)).then((function(n){return zy(t,n,i,r)}))}(t,n)}))}var Fy=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Gy=function(t){function n(n){var i=this,r=void 0===n.imageSmoothing||n.imageSmoothing;return void 0!==n.interpolate&&(r=n.interpolate),i=t.call(this,{attributions:n.attributions,cacheSize:n.cacheSize,crossOrigin:n.crossOrigin,interpolate:r,projection:n.projection,reprojectionErrorThreshold:n.reprojectionErrorThreshold,state:"loading",tileLoadFunction:n.tileLoadFunction,wrapX:void 0===n.wrapX||n.wrapX,transition:n.transition})||this,Ry({url:n.url,projection:i.getProjection(),mediaType:n.mediaType,context:n.context||null}).then(i.Ih.bind(i)).catch(i.Nh.bind(i)),i}return Fy(n,t),n.prototype.Ih=function(t){this.tileGrid=t.grid,this.setTileUrlFunction(t.urlFunction,t.urlTemplate),this.setState("ready")},n.prototype.Nh=function(t){console.error(t),this.setState("error")},n}(Vv),Dy=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),qy=function(t){function n(n){var i=this,r=n.projection||"EPSG:3857",e=n.extent||Tf(r),o=n.tileGrid||Of({extent:e,maxResolution:n.maxResolution,maxZoom:void 0!==n.maxZoom?n.maxZoom:22,minZoom:n.minZoom,tileSize:n.tileSize||512});return(i=t.call(this,{attributions:n.attributions,attributionsCollapsible:n.attributionsCollapsible,cacheSize:n.cacheSize,interpolate:!0,opaque:!1,projection:r,state:n.state,tileGrid:o,tileLoadFunction:n.tileLoadFunction?n.tileLoadFunction:Uy,tileUrlFunction:n.tileUrlFunction,url:n.url,urls:n.urls,wrapX:void 0===n.wrapX||n.wrapX,transition:n.transition,zDirection:void 0===n.zDirection?1:n.zDirection})||this).ze=n.format?n.format:null,i.sourceTileCache=new Ih(i.tileCache.highWaterMark),i.za=null==n.overlaps||n.overlaps,i.tileClass=n.tileClass?n.tileClass:qh,i.Lh={},i}return Dy(n,t),n.prototype.getFeaturesInExtent=function(t){var n=[],i=this.tileCache;if(0===i.getCount())return n;var r=Ah(i.peekFirstKey())[0],e=this.tileGrid;return i.forEach((function(i){if(i.tileCoord[0]===r&&i.getState()===vt)for(var o=i.getSourceTiles(),s=0,u=o.length;s=s.width)return null;var h=Vn(o),f=Math.floor(s.height*((o[3]-r[1])/h));return f<0||f>=s.height?null:this.getImageData(s,a,f)},n.prototype.renderFrame=function(t,n){var i=this.Lt,r=i.getExtent(),e=i.getResolution(),o=i.getPixelRatio(),s=t.layerStatesArray[t.layerIndex],u=t.pixelRatio,a=t.viewState,h=a.center,f=u*e/(a.resolution*o),c=t.extent,l=a.resolution,v=a.rotation,d=Math.round($n(c)/l*u),p=Math.round(Vn(c)/l*u);sn(this.pixelTransform,t.size[0]/2,t.size[1]/2,1/u,1/u,v,-d/2,-p/2),un(this.inversePixelTransform,this.pixelTransform);var y=hn(this.pixelTransform);this.useContainer(n,y,this.getBackground(t));var m=this.context,w=m.canvas;w.width!=d||w.height!=p?(w.width=d,w.height=p):this.containerReused||m.clearRect(0,0,d,p);var g=!1,b=!0;if(s.extent){var x=Lr(s.extent,a.projection);(g=(b=Kn(x,t.extent))&&!xn(x,t.extent))&&this.clipUnrotated(m,t,x)}var M=i.getImage(),_=sn(this.tempTransform,d/2,p/2,f,f,0,o*(r[0]-h[0])/e,o*(h[1]-r[3])/e);this.renderedResolution=e*u/o;var S=M.width*_[0],O=M.height*_[3];if(this.getLayer().getSource().getInterpolate()||A(m,lf),this.preRender(m,t),b&&S>=.5&&O>=.5){var j=_[4],E=_[5],T=s.opacity,P=void 0;1!==T&&(P=m.globalAlpha,m.globalAlpha=T),m.drawImage(M,0,0,+M.width,+M.height,j,E,S,O),1!==T&&(m.globalAlpha=P)}return this.postRender(m,t),g&&m.restore(),A(m,vf),y!==w.style.transform&&(w.style.transform=y),this.container},n}(tm),rm=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),em=function(t){function n(n){return t.call(this,n)||this}return rm(n,t),n.prototype.createRenderer=function(){return new im(this)},n.prototype.getData=function(n){return t.prototype.getData.call(this,n)},n}($y),om="preload",sm="useInterimTilesOnError",um=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),am=function(t){function n(n){var i=this,r=n||{},e=A({},r);return delete e.preload,delete e.useInterimTilesOnError,(i=t.call(this,e)||this).on,i.once,i.un,i.setPreload(void 0!==r.preload?r.preload:0),i.setUseInterimTilesOnError(void 0===r.useInterimTilesOnError||r.useInterimTilesOnError),i}return um(n,t),n.prototype.getPreload=function(){return this.get(om)},n.prototype.setPreload=function(t){this.set(om,t)},n.prototype.getUseInterimTilesOnError=function(){return this.get(sm)},n.prototype.setUseInterimTilesOnError=function(t){this.set(sm,t)},n.prototype.getData=function(n){return t.prototype.getData.call(this,n)},n}(ls),hm=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),fm=function(t){function n(n){var i=t.call(this,n)||this;return i.extentChanged=!0,i.zh=null,i.renderedPixelRatio,i.renderedProjection=null,i.renderedRevision,i.renderedTiles=[],i.Rh=!1,i.tmpExtent=[1/0,1/0,-1/0,-1/0],i.Fh=new zh(0,0,0,0),i}return hm(n,t),n.prototype.isDrawableTile=function(t){var n=this.getLayer(),i=t.getState(),r=n.getUseInterimTilesOnError();return i==vt||i==pt||i==dt&&!r},n.prototype.getTile=function(t,n,i,r){var e=r.pixelRatio,o=r.viewState.projection,s=this.getLayer(),u=s.getSource().getTile(t,n,i,e,o);return u.getState()==dt&&(s.getUseInterimTilesOnError()?s.getPreload()>0&&(this.Rh=!0):u.setState(vt)),this.isDrawableTile(u)||(u=u.getInterimTile()),u},n.prototype.getData=function(t){var n=this.frameState;if(!n)return null;var i=this.getLayer(),r=tn(n.pixelToCoordinateTransform,t.slice()),e=i.getExtent();if(e&&!bn(e,r))return null;for(var o=n.pixelRatio,s=n.viewState.projection,u=n.viewState,a=i.getRenderSource(),h=a.getTileGridForProjection(u.projection),f=a.getTilePixelRatio(n.pixelRatio),c=h.getZForResolution(u.resolution);c>=h.getMinZoom();--c){var l=h.getTileCoordForCoordAndZ(r,c),v=a.getTile(c,l[1],l[2],o,s);if(!(v instanceof ko||v instanceof Bc))return null;if(v.getState()===vt){var d=h.getOrigin(c),p=Qu(h.getTileSize(c)),y=h.getResolution(c),m=Math.floor(f*((r[0]-d[0])/y-l[1]*p[0])),w=Math.floor(f*((d[1]-r[1])/y-l[2]*p[1])),g=Math.round(f*a.getGutterForProjection(u.projection));return this.getImageData(v.getImage(),m+g,w+g)}}return null},n.prototype.loadedTileCallback=function(n,i,r){return!!this.isDrawableTile(r)&&t.prototype.loadedTileCallback.call(this,n,i,r)},n.prototype.prepareFrame=function(t){return!!this.getLayer().getSource()},n.prototype.renderFrame=function(t,n){var i=t.layerStatesArray[t.layerIndex],r=t.viewState,e=r.projection,s=r.resolution,u=r.center,a=r.rotation,h=t.pixelRatio,f=this.getLayer(),c=f.getSource(),l=c.getRevision(),v=c.getTileGridForProjection(e),d=v.getZForResolution(s,c.zDirection),y=v.getResolution(d),m=t.extent,w=t.viewState.resolution,g=c.getTilePixelRatio(h),b=Math.round($n(m)/w*h),x=Math.round(Vn(m)/w*h),M=i.extent&&Lr(i.extent,e);M&&(m=Wn(m,Lr(i.extent,e)));var _=y*b/2/g,S=y*x/2/g,O=[u[0]-_,u[1]-S,u[0]+_,u[1]+S],j=v.getTileRangeForExtentAndZ(m,d),E={};E[d]={};var T=this.createLoadedTileFinder(c,e,E),P=this.tmpExtent,C=this.Fh;this.Rh=!1;for(var k=a?Xn(r.center,w,a,t.size):void 0,I=j.minX;I<=j.maxX;++I)for(var N=j.minY;N<=j.maxY;++N)if(!a||v.tileCoordIntersectsViewport([d,I,N],k)){var L=this.getTile(d,I,N,t);if(this.isDrawableTile(L)){var z=o(this);if(L.getState()==vt)E[d][L.tileCoord.toString()]=L,(ot=L.inTransition(z))&&1!==i.opacity&&(L.endTransition(z),ot=!1),this.Rh||!ot&&-1!==this.renderedTiles.indexOf(L)||(this.Rh=!0);if(1===L.getAlpha(z,t.time))continue}var R=v.getTileCoordChildTileRange(L.tileCoord,C,P),F=!1;R&&(F=T(d+1,R)),F||v.forEachTileCoordParentTileRange(L.tileCoord,T,C,P)}var G=y/s*h/g;sn(this.pixelTransform,t.size[0]/2,t.size[1]/2,1/h,1/h,a,-b/2,-x/2);var D=hn(this.pixelTransform);this.useContainer(n,D,this.getBackground(t));var q=this.context,U=q.canvas;un(this.inversePixelTransform,this.pixelTransform),sn(this.tempTransform,b/2,x/2,G,G,0,-b/2,-x/2),U.width!=b||U.height!=x?(U.width=b,U.height=x):this.containerReused||q.clearRect(0,0,b,x),M&&this.clipUnrotated(q,t,M),c.getInterpolate()||A(q,lf),this.preRender(q,t),this.renderedTiles.length=0;var B,X,V,W=Object.keys(E).map(Number);W.sort(p),1!==i.opacity||this.containerReused&&!c.getOpaque(t.viewState.projection)?(B=[],X=[]):W=W.reverse();for(var Y=W.length-1;Y>=0;--Y){var Z=W[Y],$=c.getTilePixelSize(Z,h,e),K=v.getResolution(Z)/y,H=$[0]*K*G,J=$[1]*K*G,Q=v.getTileCoordForCoordAndZ(Yn(O),Z),tt=v.getTileCoordExtent(Q),nt=tn(this.tempTransform,[g*(tt[0]-O[0])/y,g*(O[3]-tt[3])/y]),it=g*c.getGutterForProjection(e),rt=E[Z];for(var et in rt){var ot,st=(L=rt[et]).tileCoord,ut=Q[1]-st[1],at=Math.round(nt[0]-(ut-1)*H),ht=Q[2]-st[2],ft=Math.round(nt[1]-(ht-1)*J),ct=at-(I=Math.round(nt[0]-ut*H)),lt=ft-(N=Math.round(nt[1]-ht*J)),dt=d===Z,pt=!1;if(!(ot=dt&&1!==L.getAlpha(o(this),t.time)))if(B){V=[I,N,I+ct,N,I+ct,N+lt,I,N+lt];for(var yt=0,mt=B.length;ytthis._maxQueueLength;)this._queue.shift().callback(null,null)},n.prototype._dispatch=function(){if(!this._running&&0!==this._queue.length){var t=this._queue.shift();this._job=t;var n=t.inputs[0].width,i=t.inputs[0].height,r=t.inputs.map((function(t){return t.data.buffer})),e=this._workers.length;if(this._running=e,1!==e)for(var o=t.inputs[0].data.length,s=4*Math.ceil(o/4/e),u=0;uStamen Design, under CC BY 3.0.',Wy],Cm={terrain:{extension:"jpg",opaque:!0},"terrain-background":{extension:"jpg",opaque:!0},"terrain-labels":{extension:"png",opaque:!1},"terrain-lines":{extension:"png",opaque:!1},"toner-background":{extension:"png",opaque:!0},toner:{extension:"png",opaque:!0},"toner-hybrid":{extension:"png",opaque:!1},"toner-labels":{extension:"png",opaque:!1},"toner-lines":{extension:"png",opaque:!1},"toner-lite":{extension:"png",opaque:!0},watercolor:{extension:"jpg",opaque:!0}},km={terrain:{minZoom:0,maxZoom:18},toner:{minZoom:0,maxZoom:20},watercolor:{minZoom:0,maxZoom:18}},Im=function(t){function n(n){var i=void 0===n.imageSmoothing||n.imageSmoothing;void 0!==n.interpolate&&(i=n.interpolate);var r=n.layer.indexOf("-"),e=-1==r?n.layer:n.layer.slice(0,r),o=km[e],s=Cm[n.layer],u=void 0!==n.url?n.url:"https://stamen-tiles-{a-d}.a.ssl.fastly.net/"+n.layer+"/{z}/{x}/{y}."+s.extension;return t.call(this,{attributions:Pm,cacheSize:n.cacheSize,crossOrigin:"anonymous",interpolate:i,maxZoom:null!=n.maxZoom?n.maxZoom:o.maxZoom,minZoom:null!=n.minZoom?n.minZoom:o.minZoom,opaque:s.opaque,reprojectionErrorThreshold:n.reprojectionErrorThreshold,tileLoadFunction:n.tileLoadFunction,transition:n.transition,url:u,wrapX:n.wrapX,zDirection:n.zDirection})||this}return Am(n,t),n}(Kv),Nm=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Lm=function(t){function n(n){var i=this,r=n||{},e=void 0===r.imageSmoothing||r.imageSmoothing;return void 0!==r.interpolate&&(e=r.interpolate),(i=t.call(this,{attributions:r.attributions,cacheSize:r.cacheSize,crossOrigin:r.crossOrigin,interpolate:e,projection:r.projection,reprojectionErrorThreshold:r.reprojectionErrorThreshold,tileGrid:r.tileGrid,tileLoadFunction:r.tileLoadFunction,url:r.url,urls:r.urls,wrapX:void 0===r.wrapX||r.wrapX,transition:r.transition,zDirection:r.zDirection})||this).xh=r.params||{},i._a=void 0===r.hidpi||r.hidpi,i.Ao=[1/0,1/0,-1/0,-1/0],i.setKey(i.$h()),i}return Nm(n,t),n.prototype.$h=function(){var t=0,n=[];for(var i in this.xh)n[t++]=i+"-"+this.xh[i];return n.join("/")},n.prototype.getParams=function(){return this.xh},n.prototype.Oh=function(t,n,i,r,e,o){var s=this.urls;if(s){var u,a=e.getCode().split(/:(?=\d+$)/).pop();if(o.SIZE=n[0]+","+n[1],o.BBOX=i.join(","),o.BBOXSR=a,o.IMAGESR=a,o.DPI=Math.round(o.DPI?o.DPI*r:90*r),1==s.length)u=s[0];else u=s[vi(Ph(t),s.length)];return Nf(u.replace(/MapServer\/?$/,"MapServer/export").replace(/ImageServer\/?$/,"ImageServer/exportImage"),o)}},n.prototype.getTilePixelRatio=function(t){return this._a?t:1},n.prototype.updateParams=function(t){A(this.xh,t),this.setKey(this.$h())},n.prototype.tileUrlFunction=function(t,n,i){var r=this.getTileGrid();if(r||(r=this.getTileGridForProjection(i)),!(r.getResolutions().length<=t[0])){1==n||this._a||(n=1);var e=r.getTileCoordExtent(t,this.Ao),o=Qu(r.getTileSize(t[0]),this.tmpSize);1!=n&&(o=Ju(o,n,this.tmpSize));var s={F:"image",FORMAT:"PNG32",TRANSPARENT:!0};return A(s,this.xh),this.Oh(t,o,e,n,i,s)}},n}(Vv),zm=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Rm=function(t){function n(n){var i=this,r=n||{};return i=t.call(this,{opaque:!1,projection:r.projection,tileGrid:r.tileGrid,wrapX:void 0===r.wrapX||r.wrapX,zDirection:r.zDirection,url:r.template||"z:{z} x:{x} y:{y}",tileLoadFunction:function(t,n){var r=t.getTileCoord()[0],e=Qu(i.tileGrid.getTileSize(r)),o=_o(e[0],e[1]);o.strokeStyle="grey",o.strokeRect(.5,.5,e[0]+.5,e[1]+.5),o.fillStyle="grey",o.strokeStyle="white",o.textAlign="center",o.textBaseline="middle",o.font="24px sans-serif",o.lineWidth=4,o.strokeText(n,e[0]/2,e[1]/2,e[0]),o.fillText(n,e[0]/2,e[1]/2,e[0]),t.setImage(o.canvas)}})||this}return zm(n,t),n}(Kv),Fm=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Gm=function(t){function n(n){var i=this,r=void 0===n.imageSmoothing||n.imageSmoothing;if(void 0!==n.interpolate&&(r=n.interpolate),(i=t.call(this,{attributions:n.attributions,cacheSize:n.cacheSize,crossOrigin:n.crossOrigin,interpolate:r,projection:yr("EPSG:3857"),reprojectionErrorThreshold:n.reprojectionErrorThreshold,state:"loading",tileLoadFunction:n.tileLoadFunction,wrapX:void 0===n.wrapX||n.wrapX,transition:n.transition,zDirection:n.zDirection})||this).Kh=null,i.jo=n.tileSize,n.url)if(n.jsonp)Zh(n.url,i.handleTileJSONResponse.bind(i),i.handleTileJSONError.bind(i));else{var e=new XMLHttpRequest;e.addEventListener("load",i.Hh.bind(i)),e.addEventListener("error",i.Jh.bind(i)),e.open("GET",n.url),e.send()}else n.tileJSON?i.handleTileJSONResponse(n.tileJSON):St(!1,51);return i}return Fm(n,t),n.prototype.Hh=function(t){var n=t.target;if(!n.status||n.status>=200&&n.status<300){var i=void 0;try{i=JSON.parse(n.responseText)}catch(t){return void this.handleTileJSONError()}this.handleTileJSONResponse(i)}else this.handleTileJSONError()},n.prototype.Jh=function(t){this.handleTileJSONError()},n.prototype.getTileJSON=function(){return this.Kh},n.prototype.handleTileJSONResponse=function(t){var n,i=yr("EPSG:4326"),r=this.getProjection();if(void 0!==t.bounds){var e=Or(i,r);n=ni(t.bounds,e)}var o=Tf(r),s=t.minzoom||0,u=Of({extent:o,maxZoom:t.maxzoom||22,minZoom:s,tileSize:this.jo});if(this.tileGrid=u,this.tileUrlFunction=Pf(t.tiles,u),void 0!==t.attribution&&!this.getAttributions()){var a=void 0!==n?n:o;this.setAttributions((function(n){return Kn(a,n.extent)?[t.attribution]:null}))}this.Kh=t,this.setState("ready")},n.prototype.handleTileJSONError=function(){this.setState("error")},n}(Vv),Dm=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),qm=function(t){function n(n){var i=this,r=n||{},e=void 0===r.imageSmoothing||r.imageSmoothing;void 0!==r.interpolate&&(e=r.interpolate);var o=r.params||{},s=!("TRANSPARENT"in o)||o.TRANSPARENT;return(i=t.call(this,{attributions:r.attributions,attributionsCollapsible:r.attributionsCollapsible,cacheSize:r.cacheSize,crossOrigin:r.crossOrigin,interpolate:e,opaque:!s,projection:r.projection,reprojectionErrorThreshold:r.reprojectionErrorThreshold,tileClass:r.tileClass,tileGrid:r.tileGrid,tileLoadFunction:r.tileLoadFunction,url:r.url,urls:r.urls,wrapX:void 0===r.wrapX||r.wrapX,transition:r.transition,zDirection:r.zDirection})||this).js=void 0!==r.gutter?r.gutter:0,i.xh=o,i.Ph=!0,i.kh=r.serverType,i._a=void 0===r.hidpi||r.hidpi,i.Ao=[1/0,1/0,-1/0,-1/0],i.Ch(),i.setKey(i.$h()),i}return Dm(n,t),n.prototype.getFeatureInfoUrl=function(t,n,i,r){var e=yr(i),o=this.getProjection(),s=this.getTileGrid();s||(s=this.getTileGridForProjection(e));var u=s.getZForResolution(n,this.zDirection),a=s.getTileCoordForCoordAndZ(t,u);if(!(s.getResolutions().length<=a[0])){var h=s.getResolution(a[0]),f=s.getTileCoordExtent(a,this.Ao),c=Qu(s.getTileSize(a[0]),this.tmpSize),l=this.js;0!==l&&(c=Ku(c,l,this.tmpSize),f=mn(f,h*l,f)),o&&o!==e&&(h=mf(o,e,t,h),f=Tr(f,e,o),t=Er(t,e,o));var v={SERVICE:"WMS",VERSION:Ty,REQUEST:"GetFeatureInfo",FORMAT:"image/png",TRANSPARENT:!0,QUERY_LAYERS:this.xh.LAYERS};A(v,this.xh,r);var d=Math.floor((t[0]-f[0])/h),p=Math.floor((f[3]-t[1])/h);return v[this.Ph?"I":"X"]=d,v[this.Ph?"J":"Y"]=p,this.Oh(a,c,f,1,o||e,v)}},n.prototype.getLegendUrl=function(t,n){if(void 0!==this.urls[0]){var i={SERVICE:"WMS",VERSION:Ty,REQUEST:"GetLegendGraphic",FORMAT:"image/png"};if(void 0===n||void 0===n.LAYER){var r=this.xh.LAYERS;if(!(!Array.isArray(r)||1===r.length))return;i.LAYER=r}if(void 0!==t){var e=this.getProjection()?this.getProjection().getMetersPerUnit():1;i.SCALE=t*e/28e-5}return A(i,n),Nf(this.urls[0],i)}},n.prototype.getGutter=function(){return this.js},n.prototype.getParams=function(){return this.xh},n.prototype.Oh=function(t,n,i,r,e,o){var s=this.urls;if(s){if(o.WIDTH=n[0],o.HEIGHT=n[1],o[this.Ph?"CRS":"SRS"]=e.getCode(),"STYLES"in this.xh||(o.STYLES=""),1!=r)switch(this.kh){case"geoserver":var u=90*r+.5|0;"FORMAT_OPTIONS"in o?o.FORMAT_OPTIONS+=";dpi:"+u:o.FORMAT_OPTIONS="dpi:"+u;break;case"mapserver":o.MAP_RESOLUTION=90*r;break;case"carmentaserver":case"qgis":o.DPI=90*r;break;default:St(!1,52)}var a,h=e.getAxisOrientation(),f=i;if(this.Ph&&"ne"==h.substr(0,2)){var c=void 0;c=i[0],f[0]=i[1],f[1]=c,c=i[2],f[2]=i[3],f[3]=c}if(o.BBOX=f.join(","),1==s.length)a=s[0];else a=s[vi(Ph(t),s.length)];return Nf(a,o)}},n.prototype.getTilePixelRatio=function(t){return this._a&&void 0!==this.kh?t:1},n.prototype.$h=function(){var t=0,n=[];for(var i in this.xh)n[t++]=i+"-"+this.xh[i];return n.join("/")},n.prototype.updateParams=function(t){A(this.xh,t),this.Ch(),this.setKey(this.$h())},n.prototype.Ch=function(){var t=this.xh.VERSION||Ty;this.Ph=Xi(t,"1.3")>=0},n.prototype.tileUrlFunction=function(t,n,i){var r=this.getTileGrid();if(r||(r=this.getTileGridForProjection(i)),!(r.getResolutions().length<=t[0])){1==n||this._a&&void 0!==this.kh||(n=1);var e=r.getResolution(t[0]),o=r.getTileCoordExtent(t,this.Ao),s=Qu(r.getTileSize(t[0]),this.tmpSize),u=this.js;0!==u&&(s=Ku(s,u,this.tmpSize),o=mn(o,e*u,o)),1!=n&&(s=Ju(s,n,this.tmpSize));var a={SERVICE:"WMS",VERSION:Ty,REQUEST:"GetMap",FORMAT:"image/png",TRANSPARENT:!0};return A(a,this.xh),this.Oh(t,s,o,n,i,a)}},n}(Vv),Um=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Bm=function(t){function n(n,i,r,e,o,s){var u=t.call(this,n,i)||this;return u.Nt=r,u.st=e,u.Qh=o,u.tf=null,u.nf=null,u.B=null,u.if=s,u}return Um(n,t),n.prototype.getImage=function(){return null},n.prototype.getData=function(t){if(!this.tf||!this.nf)return null;var n=(t[0]-this.st[0])/(this.st[2]-this.st[0]),i=(t[1]-this.st[1])/(this.st[3]-this.st[1]),r=this.tf[Math.floor((1-i)*this.tf.length)];if("string"!=typeof r)return null;var e=r.charCodeAt(Math.floor(n*r.length));e>=93&&e--,e>=35&&e--;var o=null;if((e-=32)in this.nf){var s=this.nf[e];o=this.B&&s in this.B?this.B[s]:s}return o},n.prototype.forDataAtCoordinate=function(t,n,i){this.state==pt&&!0===i?(this.state=ct,K(this,L,(function(i){n(this.getData(t))}),this),this.rf()):!0===i?setTimeout(function(){n(this.getData(t))}.bind(this),0):n(this.getData(t))},n.prototype.getKey=function(){return this.Nt},n.prototype.Nh=function(){this.state=dt,this.changed()},n.prototype.Ut=function(t){this.tf=t.grid,this.nf=t.keys,this.B=t.data,this.state=vt,this.changed()},n.prototype.rf=function(){if(this.state==ct)if(this.state=lt,this.if)Zh(this.Nt,this.Ut.bind(this),this.Nh.bind(this));else{var t=new XMLHttpRequest;t.addEventListener("load",this.Hh.bind(this)),t.addEventListener("error",this.Jh.bind(this)),t.open("GET",this.Nt),t.send()}},n.prototype.Hh=function(t){var n=t.target;if(!n.status||n.status>=200&&n.status<300){var i=void 0;try{i=JSON.parse(n.responseText)}catch(t){return void this.Nh()}this.Ut(i)}else this.Nh()},n.prototype.Jh=function(t){this.Nh()},n.prototype.load=function(){this.Qh?this.rf():this.setState(pt)},n}(xt),Xm=function(t){function n(n){var i=t.call(this,{projection:yr("EPSG:3857"),state:"loading",zDirection:n.zDirection})||this;if(i.Qh=void 0===n.preemptive||n.preemptive,i.ef=kf,i.uf=void 0,i.if=n.jsonp||!1,n.url)if(i.if)Zh(n.url,i.handleTileJSONResponse.bind(i),i.handleTileJSONError.bind(i));else{var r=new XMLHttpRequest;r.addEventListener("load",i.Hh.bind(i)),r.addEventListener("error",i.Jh.bind(i)),r.open("GET",n.url),r.send()}else n.tileJSON?i.handleTileJSONResponse(n.tileJSON):St(!1,51);return i}return Um(n,t),n.prototype.Hh=function(t){var n=t.target;if(!n.status||n.status>=200&&n.status<300){var i=void 0;try{i=JSON.parse(n.responseText)}catch(t){return void this.handleTileJSONError()}this.handleTileJSONResponse(i)}else this.handleTileJSONError()},n.prototype.Jh=function(t){this.handleTileJSONError()},n.prototype.getTemplate=function(){return this.uf},n.prototype.forDataAtCoordinateAndResolution=function(t,n,i,r){if(this.tileGrid){var e=this.tileGrid.getZForResolution(n,this.zDirection),o=this.tileGrid.getTileCoordForCoordAndZ(t,e);this.getTile(o[0],o[1],o[2],1,this.getProjection()).forDataAtCoordinate(t,i,r)}else!0===r?setTimeout((function(){i(null)}),0):i(null)},n.prototype.handleTileJSONError=function(){this.setState("error")},n.prototype.handleTileJSONResponse=function(t){var n,i=yr("EPSG:4326"),r=this.getProjection();if(void 0!==t.bounds){var e=Or(i,r);n=ni(t.bounds,e)}var o=Tf(r),s=t.minzoom||0,u=Of({extent:o,maxZoom:t.maxzoom||22,minZoom:s});this.tileGrid=u,this.uf=t.template;var a=t.grids;if(a){if(this.ef=Pf(a,u),void 0!==t.attribution){var h=void 0!==n?n:o;this.setAttributions((function(n){return Kn(h,n.extent)?[t.attribution]:null}))}this.setState("ready")}else this.setState("error")},n.prototype.getTile=function(t,n,i,r,e){var o=jh(t,n,i);if(this.tileCache.containsKey(o))return this.tileCache.get(o);var s=[t,n,i],u=this.getTileCoordForTileUrlFunction(s,e),a=this.ef(u,r,e),h=new Bm(s,void 0!==a?ct:pt,void 0!==a?a:"",this.tileGrid.getTileCoordExtent(s),this.Qh,this.if);return this.tileCache.set(o,h),h},n.prototype.useTile=function(t,n,i){var r=jh(t,n,i);this.tileCache.containsKey(r)&&this.tileCache.get(r)},n}(Dv),Vm=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Wm=function(t){function n(n){var i=this,r=void 0===n.imageSmoothing||n.imageSmoothing;void 0!==n.interpolate&&(r=n.interpolate);var e=void 0!==n.requestEncoding?n.requestEncoding:"KVP",o=n.tileGrid,s=n.urls;return void 0===s&&void 0!==n.url&&(s=If(n.url)),(i=t.call(this,{attributions:n.attributions,attributionsCollapsible:n.attributionsCollapsible,cacheSize:n.cacheSize,crossOrigin:n.crossOrigin,interpolate:r,projection:n.projection,reprojectionErrorThreshold:n.reprojectionErrorThreshold,tileClass:n.tileClass,tileGrid:o,tileLoadFunction:n.tileLoadFunction,tilePixelRatio:n.tilePixelRatio,urls:s,wrapX:void 0!==n.wrapX&&n.wrapX,transition:n.transition,zDirection:n.zDirection})||this).af=void 0!==n.version?n.version:"1.0.0",i.ze=void 0!==n.format?n.format:"image/jpeg",i.hf=void 0!==n.dimensions?n.dimensions:{},i.Ds=n.layer,i.ff=n.matrixSet,i.H=n.style,i.cf=e,i.setKey(i.lf()),s&&s.length>0&&(i.tileUrlFunction=Cf(s.map(i.createFromWMTSTemplate.bind(i)))),i}return Vm(n,t),n.prototype.setUrls=function(t){this.urls=t;var n=t.join("\n");this.setTileUrlFunction(Cf(t.map(this.createFromWMTSTemplate.bind(this))),n)},n.prototype.getDimensions=function(){return this.hf},n.prototype.getFormat=function(){return this.ze},n.prototype.getLayer=function(){return this.Ds},n.prototype.getMatrixSet=function(){return this.ff},n.prototype.getRequestEncoding=function(){return this.cf},n.prototype.getStyle=function(){return this.H},n.prototype.getVersion=function(){return this.af},n.prototype.lf=function(){var t=0,n=[];for(var i in this.hf)n[t++]=i+"-"+this.hf[i];return n.join("/")},n.prototype.updateDimensions=function(t){A(this.hf,t),this.setKey(this.lf())},n.prototype.createFromWMTSTemplate=function(t){var n=this.cf,i={layer:this.Ds,style:this.H,tilematrixset:this.ff};"KVP"==n&&A(i,{Service:"WMTS",Request:"GetTile",Version:this.af,Format:this.ze}),t="KVP"==n?Nf(t,i):t.replace(/\{(\w+?)\}/g,(function(t,n){return n.toLowerCase()in i?i[n.toLowerCase()]:t}));var r=this.tileGrid,e=this.hf;return function(i,o,s){if(i){var u={TileMatrix:r.getMatrixId(i[0]),TileCol:i[1],TileRow:i[2]};A(u,e);var a=t;return a="KVP"==n?Nf(a,u):a.replace(/\{(\w+?)\}/g,(function(t,n){return u[n]}))}}},n}(Vv);var Ym=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Zm="renderOrder",$m=function(t){function n(n){var i=this,r=n||{},e=A({},r);return delete e.style,delete e.renderBuffer,delete e.updateWhileAnimating,delete e.updateWhileInteracting,(i=t.call(this,e)||this).vf=void 0!==r.declutter&&r.declutter,i.df=void 0!==r.renderBuffer?r.renderBuffer:100,i.H=null,i.tt=void 0,i.setStyle(r.style),i.pf=void 0!==r.updateWhileAnimating&&r.updateWhileAnimating,i.yf=void 0!==r.updateWhileInteracting&&r.updateWhileInteracting,i}return Ym(n,t),n.prototype.getDeclutter=function(){return this.vf},n.prototype.getFeatures=function(n){return t.prototype.getFeatures.call(this,n)},n.prototype.getRenderBuffer=function(){return this.df},n.prototype.getRenderOrder=function(){return this.get(Zm)},n.prototype.getStyle=function(){return this.H},n.prototype.getStyleFunction=function(){return this.tt},n.prototype.getUpdateWhileAnimating=function(){return this.pf},n.prototype.getUpdateWhileInteracting=function(){return this.yf},n.prototype.renderDeclutter=function(t){t.declutterTree||(t.declutterTree=new Av(9)),this.getRenderer().renderDeclutter(t)},n.prototype.setRenderOrder=function(t){this.set(Zm,t)},n.prototype.setStyle=function(t){this.H=void 0!==t?t:xv,this.tt=null===t?void 0:gv(this.H),this.changed()},n}(ls);var Km=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Hm=function(t){function n(n,i){var r=this,e=i.uniforms||{},s=[1,0,0,1,0,0];e[Sc]=s,(r=t.call(this,n,{uniforms:e,postProcesses:i.postProcesses})||this).ready=!1,r.mf=-1,r.wf=new mc(zf,Gf),r.gf=new mc(zf,Gf),r.bf=new mc(Rf,Gf),r.Hs=i.vertexShader,r.Js=i.fragmentShader,r.Ks,r.xf=!(!i.hitFragmentShader||!i.hitVertexShader),r.Mf=i.hitVertexShader,r._f=i.hitFragmentShader,r.Sf;var u=i.attributes?i.attributes.map((function(t){return{name:"a_"+t.name,size:1,type:Pc.FLOAT}})):[];r.attributes=[{name:"a_position",size:2,type:Pc.FLOAT},{name:"a_index",size:1,type:Pc.FLOAT}].concat(u),r.hitDetectionAttributes=[{name:"a_position",size:2,type:Pc.FLOAT},{name:"a_index",size:1,type:Pc.FLOAT},{name:"a_hitColor",size:4,type:Pc.FLOAT},{name:"a_featureUid",size:1,type:Pc.FLOAT}].concat(u),r.customAttributes=i.attributes?i.attributes:[],r.$i=[1/0,1/0,-1/0,-1/0],r.Of=s,r.jf=[1,0,0,1,0,0],r.Ef=[1,0,0,1,0,0],r.Tf=new Float32Array(0),r.Af=new Float32Array(0),r.Pf,r.Cf=0,r.kf=function(){var t='const e="function"==typeof Object.assign?Object.assign:function(e,n){if(null==e)throw new TypeError("Cannot convert undefined or null to object");const t=Object(e);for(let e=1,n=arguments.length;e=0||n.match(/cpu (os|iphone os) 15_4 like mac os x/)),-1!==n.indexOf("webkit")&&n.indexOf("edge"),n.indexOf("macintosh"),"undefined"!=typeof WorkerGlobalScope&&"undefined"!=typeof OffscreenCanvas&&(self,WorkerGlobalScope),function(){let e=!1;try{const n=Object.defineProperty({},"passive",{get:function(){e=!0}});window.addEventListener("_",null,n),window.removeEventListener("_",null,n)}catch(e){}}(),new Array(6);const t="GENERATE_BUFFERS",o=[],r={vertexPosition:0,indexPosition:0};function i(e,n,t,o,r){e[n+0]=t,e[n+1]=o,e[n+2]=r}function s(e,n,t,s,f,c){const l=3+f,a=e[n+0],u=e[n+1],d=o;d.length=f;for(let t=0;t{const o=n.data;if(o.type===t){const n=3,t=2,r=o.customAttributesCount,i=t+r,c=new Float32Array(o.renderInstructions),l=c.length/i,a=4*l*(r+n),u=new Uint32Array(6*l),d=new Float32Array(a);let g;for(let e=0;ec&&(this.instructions.push([rw.CUSTOM,c,o,t,i,pe]),this.hitDetectionInstructions.push([rw.CUSTOM,c,o,t,r||i,pe]));break;case"Point":e=t.getFlatCoordinates(),this.coordinates.push(e[0],e[1]),o=this.coordinates.length,this.instructions.push([rw.CUSTOM,c,o,t,i]),this.hitDetectionInstructions.push([rw.CUSTOM,c,o,t,r||i])}this.endGeometry(n)},n.prototype.beginGeometry=function(t,n){this.qf=[rw.BEGIN_GEOMETRY,n,0,t],this.instructions.push(this.qf),this.Uf=[rw.BEGIN_GEOMETRY,n,0,t],this.hitDetectionInstructions.push(this.Uf)},n.prototype.finish=function(){return{instructions:this.instructions,hitDetectionInstructions:this.hitDetectionInstructions,coordinates:this.coordinates}},n.prototype.reverseHitDetectionInstructions=function(){var t,n=this.hitDetectionInstructions;n.reverse();var i,r,e=n.length,o=-1;for(t=0;tthis.maxLineWidth&&(this.maxLineWidth=i.lineWidth,this.Bf=null)}else i.strokeStyle=void 0,i.lineCap=void 0,i.lineDash=null,i.lineDashOffset=void 0,i.lineJoin=void 0,i.lineWidth=void 0,i.miterLimit=void 0},n.prototype.createFill=function(t){var n=t.fillStyle,i=[rw.SET_FILL_STYLE,n];return"string"!=typeof n&&i.push(!0),i},n.prototype.applyStroke=function(t){this.instructions.push(this.createStroke(t))},n.prototype.createStroke=function(t){return[rw.SET_STROKE_STYLE,t.strokeStyle,t.lineWidth*this.pixelRatio,t.lineCap,t.lineJoin,t.miterLimit,this.applyPixelRatio(t.lineDash),t.lineDashOffset*this.pixelRatio]},n.prototype.updateFillStyle=function(t,n){var i=t.fillStyle;"string"==typeof i&&t.currentFillStyle==i||(void 0!==i&&this.instructions.push(n.call(this,t)),t.currentFillStyle=i)},n.prototype.updateStrokeStyle=function(t,n){var i=t.strokeStyle,r=t.lineCap,e=t.lineDash,o=t.lineDashOffset,s=t.lineJoin,u=t.lineWidth,a=t.miterLimit;(t.currentStrokeStyle!=i||t.currentLineCap!=r||e!=t.currentLineDash&&!x(t.currentLineDash,e)||t.currentLineDashOffset!=o||t.currentLineJoin!=s||t.currentLineWidth!=u||t.currentMiterLimit!=a)&&(void 0!==i&&n.call(this,t),t.currentStrokeStyle=i,t.currentLineCap=r,t.currentLineDash=e,t.currentLineDashOffset=o,t.currentLineJoin=s,t.currentLineWidth=u,t.currentMiterLimit=a)},n.prototype.endGeometry=function(t){this.qf[2]=this.instructions.length,this.qf=null,this.Uf[2]=this.hitDetectionInstructions.length,this.Uf=null;var n=[rw.END_GEOMETRY,t];this.instructions.push(n),this.hitDetectionInstructions.push(n)},n.prototype.getBufferedMaxExtent=function(){if(!this.Bf&&(this.Bf=wn(this.maxExtent),this.maxLineWidth>0)){var t=this.resolution*(this.maxLineWidth+1)/2;mn(this.Bf,t,this.Bf)}return this.Bf},n}(tf),sw=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),uw=function(t){function n(n,i,r,e){var o=t.call(this,n,i,r,e)||this;return o._u=null,o.Lt=null,o.Wf=void 0,o.Yf=void 0,o.Zf=void 0,o.$f=void 0,o.ou=void 0,o.Kf=void 0,o.Hf=void 0,o.su=void 0,o.Dr=void 0,o.uu=void 0,o.Uu=void 0,o.fu=void 0,o.Jf=void 0,o}return sw(n,t),n.prototype.drawPoint=function(t,n){if(this.Lt){this.beginGeometry(t,n);var i=t.getFlatCoordinates(),r=t.getStride(),e=this.coordinates.length,o=this.appendFlatPointCoordinates(i,r);this.instructions.push([rw.DRAW_IMAGE,e,o,this.Lt,this.Yf*this.Wf,this.Zf*this.Wf,Math.ceil(this.$f*this.Wf),this.ou,this.Kf*this.Wf,this.Hf*this.Wf,this.su,this.Dr,[this.uu[0]*this.pixelRatio/this.Wf,this.uu[1]*this.pixelRatio/this.Wf],Math.ceil(this.Uu*this.Wf),this.fu,this.Jf]),this.hitDetectionInstructions.push([rw.DRAW_IMAGE,e,o,this._u,this.Yf,this.Zf,this.$f,this.ou,this.Kf,this.Hf,this.su,this.Dr,this.uu,this.Uu,this.fu,this.Jf]),this.endGeometry(n)}},n.prototype.drawMultiPoint=function(t,n){if(this.Lt){this.beginGeometry(t,n);var i=t.getFlatCoordinates(),r=t.getStride(),e=this.coordinates.length,o=this.appendFlatPointCoordinates(i,r);this.instructions.push([rw.DRAW_IMAGE,e,o,this.Lt,this.Yf*this.Wf,this.Zf*this.Wf,Math.ceil(this.$f*this.Wf),this.ou,this.Kf*this.Wf,this.Hf*this.Wf,this.su,this.Dr,[this.uu[0]*this.pixelRatio/this.Wf,this.uu[1]*this.pixelRatio/this.Wf],Math.ceil(this.Uu*this.Wf),this.fu,this.Jf]),this.hitDetectionInstructions.push([rw.DRAW_IMAGE,e,o,this._u,this.Yf,this.Zf,this.$f,this.ou,this.Kf,this.Hf,this.su,this.Dr,this.uu,this.Uu,this.fu,this.Jf]),this.endGeometry(n)}},n.prototype.finish=function(){return this.reverseHitDetectionInstructions(),this.Yf=void 0,this.Zf=void 0,this._u=null,this.Lt=null,this.Wf=void 0,this.$f=void 0,this.uu=void 0,this.ou=void 0,this.Kf=void 0,this.Hf=void 0,this.su=void 0,this.Dr=void 0,this.Uu=void 0,t.prototype.finish.call(this)},n.prototype.setImageStyle=function(t,n){var i=t.getAnchor(),r=t.getSize(),e=t.getOrigin();this.Wf=t.getPixelRatio(this.pixelRatio),this.Yf=i[0],this.Zf=i[1],this._u=t.getHitDetectionImage(),this.Lt=t.getImage(this.pixelRatio),this.$f=r[1],this.ou=t.getOpacity(),this.Kf=e[0],this.Hf=e[1],this.su=t.getRotateWithView(),this.Dr=t.getRotation(),this.uu=t.getScaleArray(),this.Uu=r[0],this.fu=t.getDeclutterMode(),this.Jf=n},n}(ow),aw=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),hw=function(t){function n(n,i,r,e){return t.call(this,n,i,r,e)||this}return aw(n,t),n.prototype.Qf=function(t,n,i,r){var e=this.coordinates.length,o=this.appendFlatLineCoordinates(t,n,i,r,!1,!1),s=[rw.MOVE_TO_LINE_TO,e,o];return this.instructions.push(s),this.hitDetectionInstructions.push(s),i},n.prototype.drawLineString=function(t,n){var i=this.state,r=i.strokeStyle,e=i.lineWidth;if(void 0!==r&&void 0!==e){this.updateStrokeStyle(i,this.applyStroke),this.beginGeometry(t,n),this.hitDetectionInstructions.push([rw.SET_STROKE_STYLE,i.strokeStyle,i.lineWidth,i.lineCap,i.lineJoin,i.miterLimit,Ps,0],nw);var o=t.getFlatCoordinates(),s=t.getStride();this.Qf(o,0,o.length,s),this.hitDetectionInstructions.push(tw),this.endGeometry(n)}},n.prototype.drawMultiLineString=function(t,n){var i=this.state,r=i.strokeStyle,e=i.lineWidth;if(void 0!==r&&void 0!==e){this.updateStrokeStyle(i,this.applyStroke),this.beginGeometry(t,n),this.hitDetectionInstructions.push([rw.SET_STROKE_STYLE,i.strokeStyle,i.lineWidth,i.lineCap,i.lineJoin,i.miterLimit,i.lineDash,i.lineDashOffset],nw);for(var o=t.getEnds(),s=t.getFlatCoordinates(),u=t.getStride(),a=0,h=0,f=o.length;ht&&(m>y&&(y=m,d=w,p=o),m=0,w=o-e)),s=u,f=l,c=v),a=g,h=b}return(m+=u)>y?[w,o]:[d,p]}var vw=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),dw={left:0,end:0,center:.5,right:1,start:1,top:0,middle:.5,hanging:.2,alphabetic:.8,ideographic:.8,bottom:1},pw=function(t){function n(n,i,r,e){var o=t.call(this,n,i,r,e)||this;return o.rc=null,o.eo="",o.oo=0,o.so=0,o.uo=void 0,o.ao=0,o.fo=null,o.fillStates={},o.co=null,o.strokeStates={},o.lo={},o.textStates={},o.ec="",o.oc="",o.sc="",o.Jf=void 0,o}return vw(n,t),n.prototype.finish=function(){var n=t.prototype.finish.call(this);return n.textStates=this.textStates,n.fillStates=this.fillStates,n.strokeStates=this.strokeStates,n},n.prototype.drawText=function(t,n){var i=this.fo,r=this.co,e=this.lo;if(""!==this.eo&&e&&(i||r)){var o=this.coordinates,s=o.length,u=t.getType(),a=null,h=t.getStride();if(e.placement!==jv||"LineString"!=u&&"MultiLineString"!=u&&"Polygon"!=u&&"MultiPolygon"!=u){var f=e.overflow?null:[];switch(u){case"Point":case"MultiPoint":a=t.getFlatCoordinates();break;case"LineString":a=t.getFlatMidpoint();break;case"Circle":a=t.getCenter();break;case"MultiLineString":a=t.getFlatMidpoints(),h=2;break;case"Polygon":a=t.getFlatInteriorPoint(),e.overflow||f.push(a[2]/this.resolution),h=3;break;case"MultiPolygon":var c=t.getFlatInteriorPoints();a=[];for(M=0,_=c.length;M<_;M+=3)e.overflow||f.push(c[M+2]/this.resolution),a.push(c[M],c[M+1]);if(0===a.length)return;h=2}if((P=this.appendFlatPointCoordinates(a,h))===s)return;if(f&&(P-s)/2!=a.length/h){var l=s/2;f=f.filter((function(t,n){var i=o[2*(l+n)]===a[n*h]&&o[2*(l+n)+1]===a[n*h+1];return i||--l,i}))}this.uc(),(e.backgroundFill||e.backgroundStroke)&&(this.setFillStrokeStyle(e.backgroundFill,e.backgroundStroke),e.backgroundFill&&(this.updateFillStyle(this.state,this.createFill),this.hitDetectionInstructions.push(this.createFill(this.state))),e.backgroundStroke&&(this.updateStrokeStyle(this.state,this.applyStroke),this.hitDetectionInstructions.push(this.createStroke(this.state)))),this.beginGeometry(t,n);var v=e.padding;if(v!=zs&&(e.scale[0]<0||e.scale[1]<0)){var d=e.padding[0],p=e.padding[1],y=e.padding[2],m=e.padding[3];e.scale[0]<0&&(p=-p,m=-m),e.scale[1]<0&&(d=-d,y=-y),v=[d,p,y,m]}var w=this.pixelRatio;this.instructions.push([rw.DRAW_IMAGE,s,P,null,NaN,NaN,NaN,1,0,0,this.uo,this.ao,[1,1],NaN,void 0,this.Jf,v==zs?zs:v.map((function(t){return t*w})),!!e.backgroundFill,!!e.backgroundStroke,this.eo,this.ec,this.sc,this.oc,this.oo,this.so,f]);var g=1/w;this.hitDetectionInstructions.push([rw.DRAW_IMAGE,s,P,null,NaN,NaN,NaN,1,0,0,this.uo,this.ao,[g,g],NaN,void 0,this.Jf,v,!!e.backgroundFill,!!e.backgroundStroke,this.eo,this.ec,this.sc,this.oc,this.oo,this.so,f]),this.endGeometry(n)}else{if(!Kn(this.getBufferedMaxExtent(),t.getExtent()))return;var b=void 0;if(a=t.getFlatCoordinates(),"LineString"==u)b=[a.length];else if("MultiLineString"==u)b=t.getEnds();else if("Polygon"==u)b=t.getEnds().slice(0,1);else if("MultiPolygon"==u){var x=t.getEndss();b=[];for(var M=0,_=x.length;M<_;++M)b.push(x[M][0])}this.beginGeometry(t,n);for(var S=e.textAlign,O=0,j=void 0,E=0,T=b.length;ET[2]}else O=b>j;var A,P=Math.PI,C=[],k=M+r===n;if(y=0,m=_,l=t[n=M],v=t[n+1],k){w(),A=Math.atan2(v-p,l-d),O&&(A+=A>0?-P:P);var I=(j+b)/2,N=(E+x)/2;return C[0]=[I,N,(S-o)/2,A,e],C}for(var L=0,z=(e=e.replace(/\n/g," ")).length;L0?-P:P),void 0!==A){var F=R-A;if(F+=F>P?-2*P:F<-P?2*P:0,Math.abs(F)>s)return null}A=R;for(var G=L,D=0;L0&&t.push("\n",""),t.push(n,""),t}var Aw=function(){function t(t,n,i,r){this.overlaps=i,this.pixelRatio=n,this.resolution=t,this.vc,this.instructions=r.instructions,this.coordinates=r.coordinates,this.dc={},this.yc=[1,0,0,1,0,0],this.hitDetectionInstructions=r.hitDetectionInstructions,this.vo=null,this.Ge=0,this.fillStates=r.fillStates||{},this.strokeStates=r.strokeStates||{},this.textStates=r.textStates||{},this.mc={},this.rc={}}return t.prototype.createLabel=function(t,n,i,r){var e=t+n+i+r;if(this.rc[e])return this.rc[e];var o=r?this.strokeStates[r]:null,s=i?this.fillStates[i]:null,u=this.textStates[n],a=this.pixelRatio,h=[u.scale[0]*a,u.scale[1]*a],f=Array.isArray(t),c=u.justify?dw[u.justify]:Ew(Array.isArray(t)?t[0]:t,u.textAlign||Ns),l=r&&o.lineWidth?o.lineWidth:0,v=f?t:t.split("\n").reduce(Tw,[]),d=Zs(u,v),p=d.width,y=d.height,m=d.widths,w=d.heights,g=d.lineWidths,b=p+l,x=[],M=(b+2)*h[0],_=(y+l)*h[1],S={width:M<0?Math.floor(M):Math.ceil(M),height:_<0?Math.floor(_):Math.ceil(_),contextInstructions:x};(1==h[0]&&1==h[1]||x.push("scale",h),r)&&(x.push("strokeStyle",o.strokeStyle),x.push("lineWidth",l),x.push("lineCap",o.lineCap),x.push("lineJoin",o.lineJoin),x.push("miterLimit",o.miterLimit),(Vt?OffscreenCanvasRenderingContext2D:CanvasRenderingContext2D).prototype.setLineDash&&(x.push("setLineDash",[o.lineDash]),x.push("lineDashOffset",o.lineDashOffset)));i&&x.push("fillStyle",s.fillStyle),x.push("textBaseline","middle"),x.push("textAlign","center");for(var O,j=.5-c,E=c*b+j*l,T=[],A=[],P=0,C=0,k=0,I=0,N=0,L=v.length;Nt?t-a:e,b=o+h>n?n-h:o,x=v[3]+g*c[0]+v[1],M=v[0]+b*c[1]+v[2],_=m-v[3],S=w-v[0];return(d||0!==f)&&(xw[0]=_,Sw[0]=_,xw[1]=S,Mw[1]=S,Mw[0]=_+x,_w[0]=Mw[0],_w[1]=S+M,Sw[1]=_w[1]),0!==f?(tn(y=sn([1,0,0,1,0,0],i,r,1,1,f,-i,-r),xw),tn(y,Mw),tn(y,_w),tn(y,Sw),On(Math.min(xw[0],Mw[0],_w[0],Sw[0]),Math.min(xw[1],Mw[1],_w[1],Sw[1]),Math.max(xw[0],Mw[0],_w[0],Sw[0]),Math.max(xw[1],Mw[1],_w[1],Sw[1]),bw)):On(Math.min(_,_+x),Math.min(S,S+M),Math.max(_,_+x),Math.max(S,S+M),bw),l&&(m=Math.round(m),w=Math.round(w)),{drawImageX:m,drawImageY:w,drawImageW:g,drawImageH:b,originX:a,originY:h,declutterBox:{minX:bw[0],minY:bw[1],maxX:bw[2],maxY:bw[3],value:p},canvasTransform:y,scale:c}},t.prototype.xc=function(t,n,i,r,e,o,s){var u=!(!o&&!s),a=r.declutterBox,h=t.canvas,f=s?s[2]*r.scale[0]/2:0;return a.minX-f<=h.width/n&&a.maxX+f>=0&&a.minY-f<=h.height/n&&a.maxY+f>=0&&(u&&this.wc(t,xw,Mw,_w,Sw,o,s),$s(t,r.canvasTransform,e,i,r.originX,r.originY,r.drawImageW,r.drawImageH,r.drawImageX,r.drawImageY,r.scale)),!0},t.prototype.lu=function(t){if(this.vc){var n=tn(this.yc,[0,0]),i=512*this.pixelRatio;t.save(),t.translate(n[0]%i,n[1]%i),t.rotate(this.Ge)}t.fill(),this.vc&&t.restore()},t.prototype.gc=function(t,n){t.strokeStyle=n[1],t.lineWidth=n[2],t.lineCap=n[3],t.lineJoin=n[4],t.miterLimit=n[5],t.setLineDash&&(t.lineDashOffset=n[7],t.setLineDash(n[6]))},t.prototype.Mc=function(t,n,i,r){var e=this.textStates[n],o=this.createLabel(t,n,r,i),s=this.strokeStates[i],u=this.pixelRatio,a=Ew(Array.isArray(t)?t[0]:t,e.textAlign||Ns),h=dw[e.textBaseline||Ls],f=s&&s.lineWidth?s.lineWidth:0;return{label:o,anchorX:a*(o.width/u-2*e.scale[0])+2*(.5-a)*f,anchorY:h*o.height/u+2*(.5-h)*f}},t.prototype._c=function(t,n,i,r,e,o,s,u){var a;this.vo&&x(i,this.yc)?a=this.vo:(this.vo||(this.vo=[]),a=Dr(this.coordinates,0,this.coordinates.length,2,i,this.vo),Qt(this.yc,i));for(var h,f,c,l,v,d,p,y,m,w,g,b,M,_,S,O,j=0,E=r.length,T=0,A=0,P=0,C=null,k=null,I=this.dc,N=this.Ge,L=Math.round(1e12*Math.atan2(-i[1],i[0]))/1e12,z={context:t,pixelRatio:this.pixelRatio,resolution:this.resolution,rotation:N},R=this.instructions!=r||this.overlaps?0:200;jR&&(this.lu(t),A=0),P>R&&(t.stroke(),P=0),A||P||(t.beginPath(),l=NaN,v=NaN),++j;break;case rw.CIRCLE:var G=a[T=F[1]],D=a[T+1],q=a[T+2]-G,U=a[T+3]-D,B=Math.sqrt(q*q+U*U);t.moveTo(G+B,D),t.arc(G,D,B,0,2*Math.PI,!0),++j;break;case rw.CLOSE_PATH:t.closePath(),++j;break;case rw.CUSTOM:T=F[1],h=F[2];var X=F[3],V=F[4],W=6==F.length?F[5]:void 0;z.geometry=X,z.feature=M,j in I||(I[j]=[]);var Y=I[j];W?W(a,T,h,2,Y):(Y[0]=a[T],Y[1]=a[T+1],Y.length=2),V(Y,z),++j;break;case rw.DRAW_IMAGE:T=F[1],h=F[2],y=F[3],f=F[4],c=F[5];var Z=F[6],$=F[7],K=F[8],H=F[9],J=F[10],Q=F[11],tt=F[12],nt=F[13],it=F[14],rt=F[15];if(!y&&F.length>=20){m=F[19],w=F[20],g=F[21],b=F[22];var et=this.Mc(m,w,g,b);y=et.label,F[3]=y;var ot=F[23];f=(et.anchorX-ot)*this.pixelRatio,F[4]=f;var st=F[24];c=(et.anchorY-st)*this.pixelRatio,F[5]=c,Z=y.height,F[6]=Z,nt=y.width,F[13]=nt}var ut=void 0;F.length>25&&(ut=F[25]);var at=void 0,ht=void 0,ft=void 0;F.length>17?(at=F[16],ht=F[17],ft=F[18]):(at=zs,ht=!1,ft=!1),J&&L?Q+=N:J||L||(Q-=N);for(var ct=0;T0){if(!o||"Image"!==c&&"Text"!==c||-1!==o.indexOf(t)){var h=(l[u]-3)/4,v=r-h%s,d=r-(h/s|0),p=e(t,n,v*v+d*d);if(p)return p}f.clearRect(0,0,s,s);break}}var d,y,m,w,g,b=Object.keys(this.Sc).map(Number);for(b.sort(p),d=b.length-1;d>=0;--d){var x=b[d].toString();for(m=this.Sc[x],y=Pw.length-1;y>=0;--y)if(void 0!==(w=m[c=Pw[y]])&&(g=w.executeHitDetection(f,u,i,v,h)))return g}},t.prototype.getClipCoords=function(t){var n=this.fc;if(!n)return null;var i=n[0],r=n[1],e=n[2],o=n[3],s=[i,r,i,o,e,o,e,r];return Dr(s,0,8,2,t,s),s},t.prototype.isEmpty=function(){return k(this.Sc)},t.prototype.execute=function(t,n,i,r,e,o,s){var u=Object.keys(this.Sc).map(Number);u.sort(p),this.fc&&(t.save(),this.clip(t,i));var a,h,f,c,l,v,d=o||Pw;for(s&&u.reverse(),a=0,h=u.length;ai)break;var u=r[s];u||(u=[],r[s]=u),u.push(4*((t+e)*n+(t+o))+3),e>0&&u.push(4*((t-e)*n+(t+o))+3),o>0&&(u.push(4*((t+e)*n+(t-o))+3),e>0&&u.push(4*((t-e)*n+(t-o))+3))}for(var a=[],h=(e=0,r.length);ev[2];)m=p*++y,h.push(this.getRenderTransform(r,e,o,Lw,f,c,m).slice()),d-=p}this.Cc=zw(i,h,this.kc,a.getStyleFunction(),u,e,o)}n(Rw(t,this.kc,this.Cc))}.bind(this))},n.prototype.forEachFeatureAtCoordinate=function(t,n,i,r,e){var s=this;if(this.Gc){var u,a=n.viewState.resolution,h=n.viewState.rotation,f=this.getLayer(),c={},l=function(t,n,i){var s=o(t),u=c[s];if(u){if(!0!==u&&ig[0]&&_[2]>g[2]&&w.push([_[0]-b,_[1],_[2]-b,_[3]])}if(this.ready&&this.Ic==f&&this._h==l&&this.Fc==d&&xn(this.Nc,y))return x(this.zh,m)||(this.Cc=null,this.zh=m),this.zc=p,this.replayGroupChanged=!1,!0;this.Gc=null;var S,O=new mw(uf(f,c),y,f,c);this.getLayer().getDeclutter()&&(S=new mw(uf(f,c),y,f,c));var j,E=Cr();if(E){for(var T=0,A=w.length;T0)n([]);else{var m=Yn(c.getTileCoordExtent(r.wrappedTileCoord)),w=[(l[0]-m[0])/f,(m[1]-l[1])/f],g=r.getSourceTiles().reduce((function(t,n){return t.concat(n.getFeatures())}),[]),b=r.hitDetectionImageData[s];if(!b&&!this.Pc){var x=Qu(c.getTileSize(c.getZForResolution(f,u.zDirection))),M=this.Lc;b=zw(x,[this.getRenderTransform(c.getTileCoordCenter(r.wrappedTileCoord),f,0,Lw,x[0]*Lw,x[1]*Lw,0)],g,e.getStyleFunction(),c.getTileCoordExtent(r.wrappedTileCoord),r.getReplayState(e).renderedResolution,M),r.hitDetectionImageData[s]=b}n(Rw(w,g,b))}}.bind(this))},n.prototype.handleFontsChanged=function(){var t=this.getLayer();t.getVisible()&&void 0!==this.Yc&&t.changed()},n.prototype.Ac=function(t){this.renderIfReadyAndVisible()},n.prototype.renderDeclutter=function(t){var n=this.context,i=n.globalAlpha;n.globalAlpha=this.getLayer().getOpacity();for(var r=t.viewHints,e=!(r[Eu]||r[Tu]),s=this.renderedTiles,u=0,a=s.length;u=0;--c)f[c].execute(this.context,1,this.getTileRenderTransform(h,t),t.viewState.rotation,e,void 0,t.declutterTree)}n.globalAlpha=i},n.prototype.getTileRenderTransform=function(t,n){var i=n.pixelRatio,r=n.viewState,e=r.center,o=r.resolution,s=r.rotation,u=n.size,a=Math.round(u[0]*i),h=Math.round(u[1]*i),f=this.getLayer().getSource().getTileGridForProjection(n.viewState.projection),c=t.tileCoord,l=f.getTileCoordExtent(t.wrappedTileCoord),v=f.getTileCoordExtent(c,this.tmpExtent)[0]-l[0];return Ht(rn(this.inversePixelTransform.slice(),1/i,1/i),this.getRenderTransform(e,o,s,i,a,h,v))},n.prototype.renderFrame=function(n,i){var r=n.viewHints,e=!(r[Eu]||r[Tu]);t.prototype.renderFrame.call(this,n,i),this.Wc=n.pixelToCoordinateTransform.slice(),this.Lc=n.viewState.rotation;var s=this.getLayer(),u=s.getRenderMode(),a=this.context,h=a.globalAlpha;a.globalAlpha=s.getOpacity();for(var f=Yw[u],c=n.viewState,l=c.rotation,v=s.getSource(),d=v.getTileGridForProjection(c.projection).getZForResolution(c.resolution,v.zDirection),p=this.renderedTiles,y=[],m=[],w=!0,g=p.length-1;g>=0;--g){var b=p[g];w=w&&!b.getReplayState(s).dirty;var x=b.executorGroups[o(s)].filter((function(t){return t.hasExecutors(f)}));if(0!==x.length){var M=this.getTileRenderTransform(b,n),_=b.tileCoord[0],S=!1,O=x[0].getClipCoords(M);if(O){for(var j=0,E=y.length;j1?s:2,x=o||new Array(b);for(p=0;p>1;e1?new sg(i,Tt,e):new We(i,Tt,r);default:throw new Error("Invalid geometry type:"+n)}}ag.prototype.getEndss=ag.prototype.getEnds,ag.prototype.getFlatCoordinates=ag.prototype.getOrientedFlatCoordinates;var fg=ag;var cg=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),lg=function(t){function n(n){return t.call(this,n)||this}return cg(n,t),n.prototype.createRenderer=function(){return new Gw(this)},n}($m);function vg(t,n,i){for(var r,e,o,s,u,a,h=[],f=t(0),c=t(1),l=n(f),v=n(c),d=[c,f],p=[v,l],y=[1,0],m={},w=1e5;--w>0&&y.length>0;)o=y.pop(),f=d.pop(),l=p.pop(),(a=o.toString())in m||(h.push(l[0],l[1]),m[a]=!0),s=y.pop(),c=d.pop(),v=p.pop(),ai((e=n(r=t(u=(o+s)/2)))[0],e[1],l[0],l[1],v[0],v[1])this.Dl.length;)u=new Et,this.Dl.push(u);var h=r.getFeaturesCollection();h.clear();var f,c,l=0;for(f=0,c=this.wl.length;fMath.PI/2);for(var d=ff(t),p=h;p<=f;++p){var y=this.wl.length+this.gl.length,m=void 0,w=void 0,g=void 0,b=void 0;if(this.Tl)for(w=0,g=this.Tl.length;w=u?(t[0]=s[0],t[2]=s[2]):o=!0);var a=[oi(n[0],this.dl,this.ll),oi(n[1],this.pl,this.vl)],h=this.Ml(a);isNaN(h[1])&&(h[1]=Math.abs(this.al)>=Math.abs(this.fl)?this.al:this.fl);var f,c,l,v,d=oi(h[0],this.cl,this.hl),p=oi(h[1],this.fl,this.al),y=this.ml,m=t;o||(m=[oi(t[0],this.dl,this.ll),oi(t[1],this.pl,this.vl),oi(t[2],this.dl,this.ll),oi(t[3],this.pl,this.vl)]);var w=ni(m,this.Ml,void 0,8),g=w[3],b=w[2],x=w[1],M=w[0];if(o||(bn(m,this.Sl)&&(M=this.cl,x=this.fl),bn(m,this.Ol)&&(b=this.hl,x=this.fl),bn(m,this.jl)&&(M=this.cl,g=this.al),bn(m,this.El)&&(b=this.hl,g=this.al),g=oi(g,p,this.al),b=oi(b,d,this.hl),x=oi(x,this.fl,p),M=oi(M,this.cl,d)),v=oi(d=Math.floor(d/e)*e,this.cl,this.hl),c=this.Vl(v,x,g,r,t,0),f=0,o)for(;(v-=e)>=M&&f++r[o]&&(e=o,o=1);var s=Math.max(n[1],r[e]),u=Math.min(n[3],r[o]),a=oi(n[1]+Math.abs(n[1]-n[3])*this.kl,s,u),h=[r[e-1]+(r[o-1]-r[e-1])*(a-r[e])/(r[o]-r[e]),a],f=this.Tl[i].geom;return f.setCoordinates(h),f},n.prototype.getMeridians=function(){return this.wl},n.prototype.Zl=function(t,n,i,r,e){var o=pg(t,n,i,this.di,r),s=this.gl[e];return s?(s.setFlatCoordinates(Tt,o),s.changed()):s=new ng(o,Tt),s},n.prototype.Kl=function(t,n,i){var r=t.getFlatCoordinates(),e=0,o=r.length-2;r[e]>r[o]&&(e=o,o=0);var s=Math.max(n[0],r[e]),u=Math.min(n[2],r[o]),a=oi(n[0]+Math.abs(n[0]-n[2])*this.Il,s,u),h=[a,r[e+1]+(r[o+1]-r[e+1])*(a-r[e])/(r[o]-r[e])],f=this.Al[i].geom;return f.setCoordinates(h),f},n.prototype.getParallels=function(){return this.gl},n.prototype.Bl=function(t){var n=yr("EPSG:4326"),i=t.getWorldExtent();this.al=i[3],this.hl=i[2],this.fl=i[1],this.cl=i[0];var r=jr(t,n);if(this.cl=Math.abs(this.fl)?this.al:this.fl),this.di=t},n}(lg),bg=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),xg="blur",Mg="gradient",_g="radius",Sg=["#00f","#0ff","#0f0","#ff0","#f00"];var Og=function(t){function n(n){var i=this,r=n||{},e=A({},r);delete e.gradient,delete e.radius,delete e.blur,delete e.weight,(i=t.call(this,e)||this).Jl=null,i.addChangeListener(Mg,i.Ql),i.setGradient(r.gradient?r.gradient:Sg),i.setBlur(void 0!==r.blur?r.blur:15),i.setRadius(void 0!==r.radius?r.radius:8);var o=r.weight?r.weight:"weight";return i.tv="string"==typeof o?function(t){return t.get(o)}:o,i.setRenderOrder(null),i}return bg(n,t),n.prototype.getBlur=function(){return this.get(xg)},n.prototype.getGradient=function(){return this.get(Mg)},n.prototype.getRadius=function(){return this.get(_g)},n.prototype.Ql=function(){this.Jl=function(t){for(var n=1,i=256,r=_o(n,i),e=r.createLinearGradient(0,0,n,i),o=1/(t.length-1),s=0,u=t.length;s>3)?i.readString():2===t?i.readFloat():3===t?i.readDouble():4===t?i.readVarint64():5===t?i.readVarint():6===t?i.readSVarint():7===t?i.readBoolean():null;n.values.push(r)}}function Ig(t,n,i){if(1==t)n.id=i.readVarint();else if(2==t)for(var r=i.readVarint()+i.pos;i.pos>3}s--,1===o||2===o?(u+=t.readSVarint(),a+=t.readSVarint(),1===o&&h>f&&(r.push(h),f=h),i.push(u,a),h+=2):7===o?h>f&&(i.push(i[f],i[f+1]),h+=2):St(!1,59)}h>f&&(r.push(h),f=h)},n.prototype.ov=function(t,n,i){var r,e=n.type;if(0===e)return null;var o,s=n.properties;this.rv?(o=s[this.rv],delete s[this.rv]):o=n.id,s[this.iv]=n.layer.name;var u=[],a=[];this.ev(t,n,u,a);var h=function(t,n){var i;1===t?i=1===n?"Point":"MultiPoint":2===t?i=1===n?"LineString":"MultiLineString":3===t&&(i="Polygon");return i}(e,a.length);if(this.nv===fg)(r=new this.nv(h,u,a,s,o)).transform(i.dataProjection);else{var f=void 0;if("Polygon"==h){var c=Be(u,a);f=c.length>1?new sg(u,Tt,c):new We(u,Tt,a)}else f="Point"===h?new Se(u,Tt):"LineString"===h?new ng(u,Tt):"MultiPoint"===h?new Kw(u,Tt):"MultiLineString"===h?new rg(u,Tt,a):null;r=new(0,this.nv),this.K&&r.setGeometryName(this.K);var l=Eg(f,!1,i);r.setGeometry(l),void 0!==o&&r.setId(o),r.setProperties(s,!0)}return r},n.prototype.getType=function(){return"arraybuffer"},n.prototype.readFeatures=function(t,n){var i=this.Uh,r=this.adaptOptions(n),e=yr(r.dataProjection);e.setWorldExtent(r.extent),r.dataProjection=e;var o=new Ag(t),s=o.readFields(Cg,{}),u=[];for(var a in s)if(!i||-1!=i.indexOf(a)){var h=s[a],f=h?[0,0,h.extent,h.extent]:null;e.setExtent(f);for(var c=0,l=h.length;c255?255:t}function Hg(t){return t<0?0:t>1?1:t}function Jg(t){return"%"===t[t.length-1]?Kg(parseFloat(t)/100*255):Kg(parseInt(t))}function Qg(t){return"%"===t[t.length-1]?Hg(parseFloat(t)/100):Hg(parseFloat(t))}function tb(t,n,i){return i<0?i+=1:i>1&&(i-=1),6*i<1?t+(n-t)*i*6:2*i<1?n:3*i<2?t+(n-t)*(2/3-i)*6:t}try{Yg={}.parseCSSColor=function(t){var n,i=t.replace(/ /g,"").toLowerCase();if(i in $g)return $g[i].slice();if("#"===i[0])return 4===i.length?(n=parseInt(i.substr(1),16))>=0&&n<=4095?[(3840&n)>>4|(3840&n)>>8,240&n|(240&n)>>4,15&n|(15&n)<<4,1]:null:7===i.length&&(n=parseInt(i.substr(1),16))>=0&&n<=16777215?[(16711680&n)>>16,(65280&n)>>8,255&n,1]:null;var r=i.indexOf("("),e=i.indexOf(")");if(-1!==r&&e+1===i.length){var o=i.substr(0,r),s=i.substr(r+1,e-(r+1)).split(","),u=1;switch(o){case"rgba":if(4!==s.length)return null;u=Qg(s.pop());case"rgb":return 3!==s.length?null:[Jg(s[0]),Jg(s[1]),Jg(s[2]),u];case"hsla":if(4!==s.length)return null;u=Qg(s.pop());case"hsl":if(3!==s.length)return null;var a=(parseFloat(s[0])%360+360)%360/360,h=Qg(s[1]),f=Qg(s[2]),c=f<=.5?f*(h+1):f+h-f*h,l=2*f-c;return[Kg(255*tb(l,c,a+1/3)),Kg(255*tb(l,c,a)),Kg(255*tb(l,c,a-1/3)),u];default:return null}}return null}}catch(t){}var nb=function(t,n,i,r){void 0===r&&(r=1),this.r=t,this.g=n,this.b=i,this.a=r};function ib(t){return"object"==typeof t?["literal",t]:t}function rb(t,n){var i=t.stops;if(!i)return function(t,n){var i=["get",t.property];if(void 0===t.default)return"string"===n.type?["string",i]:i;if("enum"===n.type)return["match",i,Object.keys(n.values),i,t.default];var r=["color"===n.type?"to-color":n.type,i,ib(t.default)];return"array"===n.type&&r.splice(1,0,n.value,n.length||null),r}(t,n);var r=i&&"object"==typeof i[0][0],e=r||void 0!==t.property,o=r||!e;return i=i.map((function(t){return!e&&n.tokens&&"string"==typeof t[1]?[t[0],fb(t[1])]:[t[0],ib(t[1])]})),r?function(t,n,i){for(var r={},e={},o=[],s=0;s3&&n===t[t.length-2]||(r&&2===t.length||t.push(n),t.push(i))}function hb(t,n){return t.type?t.type:n.expression.interpolated?"exponential":"interval"}function fb(t){for(var n=["concat"],i=/{([^{}]+)}/g,r=0,e=i.exec(t);null!==e;e=i.exec(t)){var o=t.slice(r,i.lastIndex-e[0].length);r=i.lastIndex,o.length>0&&n.push(o),n.push(["get",e[1]])}if(1===n.length)return t;if(r":"value"===t.itemType.kind?"array":"array<"+n+">"}return t.kind}var Ob=[vb,db,pb,yb,mb,xb,wb,_b(gb),Mb];function jb(t,n){if("error"===n.kind)return null;if("array"===t.kind){if("array"===n.kind&&(0===n.N&&"value"===n.itemType.kind||!jb(t.itemType,n.itemType))&&("number"!=typeof t.N||t.N===n.N))return null}else{if(t.kind===n.kind)return null;if("value"===t.kind)for(var i=0,r=Ob;i=0&&t<=255&&"number"==typeof n&&n>=0&&n<=255&&"number"==typeof i&&i>=0&&i<=255?void 0===r||"number"==typeof r&&r>=0&&r<=1?null:"Invalid rgba value ["+[t,n,i,r].join(", ")+"]: 'a' must be between 0 and 1.":"Invalid rgba value ["+("number"==typeof r?[t,n,i,r]:[t,n,i]).join(", ")+"]: 'r', 'g', and 'b' must be between 0 and 255."}function Nb(t){if(null===t)return!0;if("string"==typeof t)return!0;if("boolean"==typeof t)return!0;if("number"==typeof t)return!0;if(t instanceof nb)return!0;if(t instanceof Ab)return!0;if(t instanceof Cb)return!0;if(t instanceof kb)return!0;if(Array.isArray(t)){for(var n=0,i=t;n2){var u=t[1];if("string"!=typeof u||!(u in Gb)||"object"===u)return n.error('The item type argument of "array" must be one of string, number, boolean',1);o=Gb[u],r++}else o=gb;if(t.length>3){if(null!==t[2]&&("number"!=typeof t[2]||t[2]<0||t[2]!==Math.floor(t[2])))return n.error('The length argument to "array" must be a positive integer literal',2);s=t[2],r++}i=_b(o,s)}else i=Gb[e];for(var a=[];r1)&&n.push(r)}}return n.concat(this.args.map((function(t){return t.serialize()})))};var qb=function(t){this.type=xb,this.sections=t};qb.parse=function(t,n){if(t.length<2)return n.error("Expected at least one argument.");var i=t[1];if(!Array.isArray(i)&&"object"==typeof i)return n.error("First argument must be an image or text section.");for(var r=[],e=!1,o=1;o<=t.length-1;++o){var s=t[o];if(e&&"object"==typeof s&&!Array.isArray(s)){e=!1;var u=null;if(s["font-scale"]&&!(u=n.parse(s["font-scale"],1,db)))return null;var a=null;if(s["text-font"]&&!(a=n.parse(s["text-font"],1,_b(pb))))return null;var h=null;if(s["text-color"]&&!(h=n.parse(s["text-color"],1,mb)))return null;var f=r[r.length-1];f.scale=u,f.font=a,f.textColor=h}else{var c=n.parse(t[o],1,gb);if(!c)return null;var l=c.type.kind;if("string"!==l&&"value"!==l&&"null"!==l&&"resolvedImage"!==l)return n.error("Formatted text type must be 'string', 'value', 'image' or 'null'.");e=!0,r.push({content:c,scale:null,font:null,textColor:null})}}return new qb(r)},qb.prototype.evaluate=function(t){return new Cb(this.sections.map((function(n){var i=n.content.evaluate(t);return Lb(i)===Mb?new Pb("",i,null,null,null):new Pb(zb(i),null,n.scale?n.scale.evaluate(t):null,n.font?n.font.evaluate(t).join(","):null,n.textColor?n.textColor.evaluate(t):null)})))},qb.prototype.eachChild=function(t){for(var n=0,i=this.sections;n-1),i},Ub.prototype.eachChild=function(t){t(this.input)},Ub.prototype.outputDefined=function(){return!1},Ub.prototype.serialize=function(){return["image",this.input.serialize()]};var Bb={"to-boolean":yb,"to-color":mb,"to-number":db,"to-string":pb},Xb=function(t,n){this.type=t,this.args=n};Xb.parse=function(t,n){if(t.length<2)return n.error("Expected at least one argument.");var i=t[0];if(("to-boolean"===i||"to-string"===i)&&2!==t.length)return n.error("Expected one argument.");for(var r=Bb[i],e=[],o=1;o4?"Invalid rbga value "+JSON.stringify(n)+": expected an array containing either three or four numeric values.":Ib(n[0],n[1],n[2],n[3])))return new nb(n[0]/255,n[1]/255,n[2]/255,n[3])}throw new Fb(i||"Could not parse color from value '"+("string"==typeof n?n:String(JSON.stringify(n)))+"'")}if("number"===this.type.kind){for(var s=null,u=0,a=this.args;u=n[2])&&(!(t[1]<=n[1])&&!(t[3]>=n[3])))}function Jb(t,n){var i,r=(180+t[0])/360,e=(i=t[1],(180-180/Math.PI*Math.log(Math.tan(Math.PI/4+i*Math.PI/360)))/360),o=Math.pow(2,n.z);return[Math.round(r*o*$b),Math.round(e*o*$b)]}function Qb(t,n,i){var r=t[0]-n[0],e=t[1]-n[1],o=t[0]-i[0],s=t[1]-i[1];return r*s-o*e==0&&r*o<=0&&e*s<=0}function tx(t,n,i){return n[1]>t[1]!=i[1]>t[1]&&t[0]<(i[0]-n[0])*(t[1]-n[1])/(i[1]-n[1])+n[0]}function nx(t,n){for(var i=!1,r=0,e=n.length;r0&&c<0||f<0&&c>0}function ex(t,n,i){for(var r=0,e=i;ri[2]){var e=.5*r,o=t[0]-i[0]>e?-r:i[0]-t[0]>e?r:0;0===o&&(o=t[0]-i[2]>e?-r:i[2]-t[0]>e?r:0),t[0]+=o}Kb(n,t)}function fx(t,n,i,r){var e=Math.pow(2,r.z)*$b,o=[r.x*$b,r.y*$b],s=[];if(!t)return s;for(var u=0,a=t;u=0)return!1;var i=!0;return t.eachChild((function(t){i&&!px(t,n)&&(i=!1)})),i}lx.parse=function(t,n){if(2!==t.length)return n.error("'within' expression requires exactly one argument, but found "+(t.length-1)+" instead.");if(Nb(t[1])){var i=t[1];if("FeatureCollection"===i.type)for(var r=0;rn))throw new Fb("Input is not a number.");s=u-1}return 0}mx.prototype.parse=function(t,n,i,r,e){return void 0===e&&(e={}),n?this.concat(n,i,r)._parse(t,e):this._parse(t,e)},mx.prototype._parse=function(t,n){function i(t,n,i){return"assert"===i?new Db(n,[t]):"coerce"===i?new Xb(n,[t]):t}if(null!==t&&"string"!=typeof t&&"boolean"!=typeof t&&"number"!=typeof t||(t=["literal",t]),Array.isArray(t)){if(0===t.length)return this.error('Expected an array with at least one element. If you wanted a literal array, use ["literal", []].');var r=t[0];if("string"!=typeof r)return this.error("Expression name must be a string, but found "+typeof r+' instead. If you wanted a literal array, use ["literal", [...]].',0),null;var e=this.registry[r];if(e){var o=e.parse(t,this);if(!o)return null;if(this.expectedType){var s=this.expectedType,u=o.type;if("string"!==s.kind&&"number"!==s.kind&&"boolean"!==s.kind&&"object"!==s.kind&&"array"!==s.kind||"value"!==u.kind)if("color"!==s.kind&&"formatted"!==s.kind&&"resolvedImage"!==s.kind||"value"!==u.kind&&"string"!==u.kind){if(this.checkSubtype(s,u))return null}else o=i(o,s,n.typeAnnotation||"coerce");else o=i(o,s,n.typeAnnotation||"assert")}if(!(o instanceof Rb)&&"resolvedImage"!==o.type.kind&&wx(o)){var a=new Wb;try{o=new Rb(o.type,o.evaluate(a))}catch(t){return this.error(t.message),null}}return o}return this.error('Unknown expression "'+r+'". If you wanted a literal array, use ["literal", [...]].',0)}return void 0===t?this.error("'undefined' value invalid. Use null instead."):"object"==typeof t?this.error('Bare objects invalid. Use ["literal", {...}] instead.'):this.error("Expected an array, but found "+typeof t+" instead.")},mx.prototype.concat=function(t,n,i){var r="number"==typeof t?this.path.concat(t):this.path,e=i?this.scope.concat(i):this.scope;return new mx(this.registry,r,n||null,e,this.errors)},mx.prototype.error=function(t){for(var n=[],i=arguments.length-1;i-- >0;)n[i]=arguments[i+1];var r=""+this.key+n.map((function(t){return"["+t+"]"})).join("");this.errors.push(new cb(r,t))},mx.prototype.checkSubtype=function(t,n){var i=jb(t,n);return i&&this.error(i),i};var bx=function(t,n,i){this.type=t,this.input=n,this.labels=[],this.outputs=[];for(var r=0,e=i;r=s)return n.error('Input/output pairs for "step" expressions must be arranged with input values in strictly ascending order.',a);var f=n.parse(u,h,e);if(!f)return null;e=e||f.type,r.push([s,f])}return new bx(e,i,r)},bx.prototype.evaluate=function(t){var n=this.labels,i=this.outputs;if(1===n.length)return i[0].evaluate(t);var r=this.input.evaluate(t);if(r<=n[0])return i[0].evaluate(t);var e=n.length;return r>=n[e-1]?i[e-1].evaluate(t):i[gx(n,r)].evaluate(t)},bx.prototype.eachChild=function(t){t(this.input);for(var n=0,i=this.outputs;n0&&t.push(this.labels[n]),t.push(this.outputs[n].serialize());return t};var xx=Mx;function Mx(t,n,i,r){this.cx=3*t,this.bx=3*(i-t)-this.cx,this.ax=1-this.cx-this.bx,this.cy=3*n,this.by=3*(r-n)-this.cy,this.ay=1-this.cy-this.by,this.p1x=t,this.p1y=r,this.p2x=i,this.p2y=r}function _x(t,n,i){return t*(1-i)+n*i}Mx.prototype.sampleCurveX=function(t){return((this.ax*t+this.bx)*t+this.cx)*t},Mx.prototype.sampleCurveY=function(t){return((this.ay*t+this.by)*t+this.cy)*t},Mx.prototype.sampleCurveDerivativeX=function(t){return(3*this.ax*t+2*this.bx)*t+this.cx},Mx.prototype.solveCurveX=function(t,n){var i,r,e,o,s;for(void 0===n&&(n=1e-6),e=t,s=0;s<8;s++){if(o=this.sampleCurveX(e)-t,Math.abs(o)(r=1))return r;for(;io?i=e:r=e,e=.5*(r-i)+i}return e},Mx.prototype.solve=function(t,n){return this.sampleCurveY(this.solveCurveX(t,n))};var Sx=Object.freeze({__proto__:null,number:_x,color:function(t,n,i){return new nb(_x(t.r,n.r,i),_x(t.g,n.g,i),_x(t.b,n.b,i),_x(t.a,n.a,i))},array:function(t,n,i){return t.map((function(t,r){return _x(t,n[r],i)}))}}),Ox=.95047,jx=1.08883,Ex=4/29,Tx=6/29,Ax=3*Tx*Tx,Px=Math.PI/180,Cx=180/Math.PI;function kx(t){return t>.008856451679035631?Math.pow(t,1/3):t/Ax+Ex}function Ix(t){return t>Tx?t*t*t:Ax*(t-Ex)}function Nx(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function Lx(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function zx(t){var n=Lx(t.r),i=Lx(t.g),r=Lx(t.b),e=kx((.4124564*n+.3575761*i+.1804375*r)/Ox),o=kx((.2126729*n+.7151522*i+.072175*r)/1);return{l:116*o-16,a:500*(e-o),b:200*(o-kx((.0193339*n+.119192*i+.9503041*r)/jx)),alpha:t.a}}function Rx(t){var n=(t.l+16)/116,i=isNaN(t.a)?n:n+t.a/500,r=isNaN(t.b)?n:n-t.b/200;return n=1*Ix(n),i=Ox*Ix(i),r=jx*Ix(r),new nb(Nx(3.2404542*i-1.5371385*n-.4985314*r),Nx(-.969266*i+1.8760108*n+.041556*r),Nx(.0556434*i-.2040259*n+1.0572252*r),t.alpha)}function Fx(t,n,i){var r=n-t;return t+i*(r>180||r<-180?r-360*Math.round(r/360):r)}var Gx={forward:zx,reverse:Rx,interpolate:function(t,n,i){return{l:_x(t.l,n.l,i),a:_x(t.a,n.a,i),b:_x(t.b,n.b,i),alpha:_x(t.alpha,n.alpha,i)}}},Dx={forward:function(t){var n=zx(t),i=n.l,r=n.a,e=n.b,o=Math.atan2(e,r)*Cx;return{h:o<0?o+360:o,c:Math.sqrt(r*r+e*e),l:i,alpha:t.a}},reverse:function(t){var n=t.h*Px,i=t.c;return Rx({l:t.l,a:Math.cos(n)*i,b:Math.sin(n)*i,alpha:t.alpha})},interpolate:function(t,n,i){return{h:Fx(t.h,n.h,i),c:_x(t.c,n.c,i),l:_x(t.l,n.l,i),alpha:_x(t.alpha,n.alpha,i)}}},qx=function(t,n,i,r,e){this.type=t,this.operator=n,this.interpolation=i,this.input=r,this.labels=[],this.outputs=[];for(var o=0,s=e;o1})))return n.error("Cubic bezier interpolation requires four numeric arguments with values between 0 and 1.",1);r={name:"cubic-bezier",controlPoints:u}}if(t.length-1<4)return n.error("Expected at least 4 arguments, but found only "+(t.length-1)+".");if((t.length-1)%2!=0)return n.error("Expected an even number of arguments.");if(!(e=n.parse(e,2,db)))return null;var a=[],h=null;"interpolate-hcl"===i||"interpolate-lab"===i?h=mb:n.expectedType&&"value"!==n.expectedType.kind&&(h=n.expectedType);for(var f=0;f=c)return n.error('Input/output pairs for "interpolate" expressions must be arranged with input values in strictly ascending order.',v);var p=n.parse(l,d,h);if(!p)return null;h=h||p.type,a.push([c,p])}return"number"===h.kind||"color"===h.kind||"array"===h.kind&&"number"===h.itemType.kind&&"number"==typeof h.N?new qx(h,i,r,e,a):n.error("Type "+Sb(h)+" is not interpolatable.")},qx.prototype.evaluate=function(t){var n=this.labels,i=this.outputs;if(1===n.length)return i[0].evaluate(t);var r=this.input.evaluate(t);if(r<=n[0])return i[0].evaluate(t);var e=n.length;if(r>=n[e-1])return i[e-1].evaluate(t);var o=gx(n,r),s=n[o],u=n[o+1],a=qx.interpolationFactor(this.interpolation,r,s,u),h=i[o].evaluate(t),f=i[o+1].evaluate(t);return"interpolate"===this.operator?Sx[this.type.kind.toLowerCase()](h,f,a):"interpolate-hcl"===this.operator?Dx.reverse(Dx.interpolate(Dx.forward(h),Dx.forward(f),a)):Gx.reverse(Gx.interpolate(Gx.forward(h),Gx.forward(f),a))},qx.prototype.eachChild=function(t){t(this.input);for(var n=0,i=this.outputs;n=i.length)throw new Fb("Array index out of bounds: "+n+" > "+(i.length-1)+".");if(n!==Math.floor(n))throw new Fb("Array index must be an integer, but found "+n+" instead.");return i[n]},Vx.prototype.eachChild=function(t){t(this.index),t(this.input)},Vx.prototype.outputDefined=function(){return!1},Vx.prototype.serialize=function(){return["at",this.index.serialize(),this.input.serialize()]};var Wx=function(t,n){this.type=yb,this.needle=t,this.haystack=n};Wx.parse=function(t,n){if(3!==t.length)return n.error("Expected 2 arguments, but found "+(t.length-1)+" instead.");var i=n.parse(t[1],1,gb),r=n.parse(t[2],2,gb);return i&&r?Eb(i.type,[yb,pb,db,vb,gb])?new Wx(i,r):n.error("Expected first argument to be of type boolean, string, number or null, but found "+Sb(i.type)+" instead"):null},Wx.prototype.evaluate=function(t){var n=this.needle.evaluate(t),i=this.haystack.evaluate(t);if(null==i)return!1;if(!Tb(n,["boolean","string","number","null"]))throw new Fb("Expected first argument to be of type boolean, string, number or null, but found "+Sb(Lb(n))+" instead.");if(!Tb(i,["string","array"]))throw new Fb("Expected second argument to be of type array or string, but found "+Sb(Lb(i))+" instead.");return i.indexOf(n)>=0},Wx.prototype.eachChild=function(t){t(this.needle),t(this.haystack)},Wx.prototype.outputDefined=function(){return!0},Wx.prototype.serialize=function(){return["in",this.needle.serialize(),this.haystack.serialize()]};var Yx=function(t,n,i){this.type=db,this.needle=t,this.haystack=n,this.fromIndex=i};Yx.parse=function(t,n){if(t.length<=2||t.length>=5)return n.error("Expected 3 or 4 arguments, but found "+(t.length-1)+" instead.");var i=n.parse(t[1],1,gb),r=n.parse(t[2],2,gb);if(!i||!r)return null;if(!Eb(i.type,[yb,pb,db,vb,gb]))return n.error("Expected first argument to be of type boolean, string, number or null, but found "+Sb(i.type)+" instead");if(4===t.length){var e=n.parse(t[3],3,db);return e?new Yx(i,r,e):null}return new Yx(i,r)},Yx.prototype.evaluate=function(t){var n=this.needle.evaluate(t),i=this.haystack.evaluate(t);if(!Tb(n,["boolean","string","number","null"]))throw new Fb("Expected first argument to be of type boolean, string, number or null, but found "+Sb(Lb(n))+" instead.");if(!Tb(i,["string","array"]))throw new Fb("Expected second argument to be of type array or string, but found "+Sb(Lb(i))+" instead.");if(this.fromIndex){var r=this.fromIndex.evaluate(t);return i.indexOf(n,r)}return i.indexOf(n)},Yx.prototype.eachChild=function(t){t(this.needle),t(this.haystack),this.fromIndex&&t(this.fromIndex)},Yx.prototype.outputDefined=function(){return!1},Yx.prototype.serialize=function(){if(null!=this.fromIndex&&void 0!==this.fromIndex){var t=this.fromIndex.serialize();return["index-of",this.needle.serialize(),this.haystack.serialize(),t]}return["index-of",this.needle.serialize(),this.haystack.serialize()]};var Zx=function(t,n,i,r,e,o){this.inputType=t,this.type=n,this.input=i,this.cases=r,this.outputs=e,this.otherwise=o};Zx.parse=function(t,n){if(t.length<5)return n.error("Expected at least 4 arguments, but found only "+(t.length-1)+".");if(t.length%2!=1)return n.error("Expected an even number of arguments.");var i,r;n.expectedType&&"value"!==n.expectedType.kind&&(r=n.expectedType);for(var e={},o=[],s=2;sNumber.MAX_SAFE_INTEGER)return h.error("Branch labels must be integers no larger than "+Number.MAX_SAFE_INTEGER+".");if("number"==typeof l&&Math.floor(l)!==l)return h.error("Numeric branch labels must be integer values.");if(i){if(h.checkSubtype(i,Lb(l)))return null}else i=Lb(l);if(void 0!==e[String(l)])return h.error("Branch labels must be unique.");e[String(l)]=o.length}var v=n.parse(a,s,r);if(!v)return null;r=r||v.type,o.push(v)}var d=n.parse(t[1],1,gb);if(!d)return null;var p=n.parse(t[t.length-1],t.length-1,r);return p?"value"!==d.type.kind&&n.concat(1).checkSubtype(i,d.type)?null:new Zx(i,r,d,e,o,p):null},Zx.prototype.evaluate=function(t){var n=this.input.evaluate(t);return(Lb(n)===this.inputType&&this.outputs[this.cases[n]]||this.otherwise).evaluate(t)},Zx.prototype.eachChild=function(t){t(this.input),this.outputs.forEach(t),t(this.otherwise)},Zx.prototype.outputDefined=function(){return this.outputs.every((function(t){return t.outputDefined()}))&&this.otherwise.outputDefined()},Zx.prototype.serialize=function(){for(var t=this,n=["match",this.input.serialize()],i=[],r={},e=0,o=Object.keys(this.cases).sort();e=5)return n.error("Expected 3 or 4 arguments, but found "+(t.length-1)+" instead.");var i=n.parse(t[1],1,gb),r=n.parse(t[2],2,db);if(!i||!r)return null;if(!Eb(i.type,[_b(gb),pb,gb]))return n.error("Expected first argument to be of type array or string, but found "+Sb(i.type)+" instead");if(4===t.length){var e=n.parse(t[3],3,db);return e?new Kx(i.type,i,r,e):null}return new Kx(i.type,i,r)},Kx.prototype.evaluate=function(t){var n=this.input.evaluate(t),i=this.beginIndex.evaluate(t);if(!Tb(n,["string","array"]))throw new Fb("Expected first argument to be of type array or string, but found "+Sb(Lb(n))+" instead.");if(this.endIndex){var r=this.endIndex.evaluate(t);return n.slice(i,r)}return n.slice(i)},Kx.prototype.eachChild=function(t){t(this.input),t(this.beginIndex),this.endIndex&&t(this.endIndex)},Kx.prototype.outputDefined=function(){return!1},Kx.prototype.serialize=function(){if(null!=this.endIndex&&void 0!==this.endIndex){var t=this.endIndex.serialize();return["slice",this.input.serialize(),this.beginIndex.serialize(),t]}return["slice",this.input.serialize(),this.beginIndex.serialize()]};var tM=Qx("==",(function(t,n,i){return n===i}),Jx),nM=Qx("!=",(function(t,n,i){return n!==i}),(function(t,n,i,r){return!Jx(0,n,i,r)})),iM=Qx("<",(function(t,n,i){return n",(function(t,n,i){return n>i}),(function(t,n,i,r){return r.compare(n,i)>0})),eM=Qx("<=",(function(t,n,i){return n<=i}),(function(t,n,i,r){return r.compare(n,i)<=0})),oM=Qx(">=",(function(t,n,i){return n>=i}),(function(t,n,i,r){return r.compare(n,i)>=0})),sM=function(t,n,i,r,e){this.type=pb,this.number=t,this.locale=n,this.currency=i,this.minFractionDigits=r,this.maxFractionDigits=e};sM.parse=function(t,n){if(3!==t.length)return n.error("Expected two arguments.");var i=n.parse(t[1],1,db);if(!i)return null;var r=t[2];if("object"!=typeof r||Array.isArray(r))return n.error("NumberFormat options argument must be an object.");var e=null;if(r.locale&&!(e=n.parse(r.locale,1,pb)))return null;var o=null;if(r.currency&&!(o=n.parse(r.currency,1,pb)))return null;var s=null;if(r["min-fraction-digits"]&&!(s=n.parse(r["min-fraction-digits"],1,db)))return null;var u=null;return r["max-fraction-digits"]&&!(u=n.parse(r["max-fraction-digits"],1,db))?null:new sM(i,e,o,s,u)},sM.prototype.evaluate=function(t){return new Intl.NumberFormat(this.locale?this.locale.evaluate(t):[],{style:this.currency?"currency":"decimal",currency:this.currency?this.currency.evaluate(t):void 0,minimumFractionDigits:this.minFractionDigits?this.minFractionDigits.evaluate(t):void 0,maximumFractionDigits:this.maxFractionDigits?this.maxFractionDigits.evaluate(t):void 0}).format(this.number.evaluate(t))},sM.prototype.eachChild=function(t){t(this.number),this.locale&&t(this.locale),this.currency&&t(this.currency),this.minFractionDigits&&t(this.minFractionDigits),this.maxFractionDigits&&t(this.maxFractionDigits)},sM.prototype.outputDefined=function(){return!1},sM.prototype.serialize=function(){var t={};return this.locale&&(t.locale=this.locale.serialize()),this.currency&&(t.currency=this.currency.serialize()),this.minFractionDigits&&(t["min-fraction-digits"]=this.minFractionDigits.serialize()),this.maxFractionDigits&&(t["max-fraction-digits"]=this.maxFractionDigits.serialize()),["number-format",this.number.serialize(),t]};var uM=function(t){this.type=db,this.input=t};uM.parse=function(t,n){if(2!==t.length)return n.error("Expected 1 argument, but found "+(t.length-1)+" instead.");var i=n.parse(t[1],1);return i?"array"!==i.type.kind&&"string"!==i.type.kind&&"value"!==i.type.kind?n.error("Expected argument of type string or array, but found "+Sb(i.type)+" instead."):new uM(i):null},uM.prototype.evaluate=function(t){var n=this.input.evaluate(t);if("string"==typeof n)return n.length;if(Array.isArray(n))return n.length;throw new Fb("Expected value to be of type string or array, but found "+Sb(Lb(n))+" instead.")},uM.prototype.eachChild=function(t){t(this.input)},uM.prototype.outputDefined=function(){return!1},uM.prototype.serialize=function(){var t=["length"];return this.eachChild((function(n){t.push(n.serialize())})),t};var aM={"==":tM,"!=":nM,">":rM,"<":iM,">=":oM,"<=":eM,array:Db,at:Vx,boolean:Db,case:$x,coalesce:Bx,collator:Zb,format:qb,image:Ub,in:Wx,"index-of":Yx,interpolate:qx,"interpolate-hcl":qx,"interpolate-lab":qx,length:uM,let:Xx,literal:Rb,match:Zx,number:Db,"number-format":sM,object:Db,slice:Kx,step:bx,string:Db,"to-boolean":Xb,"to-color":Xb,"to-number":Xb,"to-string":Xb,var:yx,within:lx};function hM(t,n){var i=n[0],r=n[1],e=n[2],o=n[3];i=i.evaluate(t),r=r.evaluate(t),e=e.evaluate(t);var s=o?o.evaluate(t):1,u=Ib(i,r,e,s);if(u)throw new Fb(u);return new nb(i/255*s,r/255*s,e/255*s,s)}function fM(t,n){return t in n}function cM(t,n){var i=n[t];return void 0===i?null:i}function lM(t){return{type:t}}function vM(t){return{result:"success",value:t}}function dM(t){return{result:"error",value:t}}function pM(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}Yb.register(aM,{error:[{kind:"error"},[pb],function(t,n){var i=n[0];throw new Fb(i.evaluate(t))}],typeof:[pb,[gb],function(t,n){return Sb(Lb(n[0].evaluate(t)))}],"to-rgba":[_b(db,4),[mb],function(t,n){return n[0].evaluate(t).toArray()}],rgb:[mb,[db,db,db],hM],rgba:[mb,[db,db,db,db],hM],has:{type:yb,overloads:[[[pb],function(t,n){return fM(n[0].evaluate(t),t.properties())}],[[pb,wb],function(t,n){var i=n[0],r=n[1];return fM(i.evaluate(t),r.evaluate(t))}]]},get:{type:gb,overloads:[[[pb],function(t,n){return cM(n[0].evaluate(t),t.properties())}],[[pb,wb],function(t,n){var i=n[0],r=n[1];return cM(i.evaluate(t),r.evaluate(t))}]]},"feature-state":[gb,[pb],function(t,n){return cM(n[0].evaluate(t),t.featureState||{})}],properties:[wb,[],function(t){return t.properties()}],"geometry-type":[pb,[],function(t){return t.geometryType()}],id:[gb,[],function(t){return t.id()}],zoom:[db,[],function(t){return t.globals.zoom}],pitch:[db,[],function(t){return t.globals.pitch||0}],"distance-from-center":[db,[],function(t){return t.distanceFromCenter()}],"heatmap-density":[db,[],function(t){return t.globals.heatmapDensity||0}],"line-progress":[db,[],function(t){return t.globals.lineProgress||0}],"sky-radial-progress":[db,[],function(t){return t.globals.skyRadialProgress||0}],accumulated:[gb,[],function(t){return void 0===t.globals.accumulated?null:t.globals.accumulated}],"+":[db,lM(db),function(t,n){for(var i=0,r=0,e=n;r":[yb,[pb,gb],function(t,n){var i=n[0],r=n[1],e=t.properties()[i.value],o=r.value;return typeof e==typeof o&&e>o}],"filter-id->":[yb,[gb],function(t,n){var i=n[0],r=t.id(),e=i.value;return typeof r==typeof e&&r>e}],"filter-<=":[yb,[pb,gb],function(t,n){var i=n[0],r=n[1],e=t.properties()[i.value],o=r.value;return typeof e==typeof o&&e<=o}],"filter-id-<=":[yb,[gb],function(t,n){var i=n[0],r=t.id(),e=i.value;return typeof r==typeof e&&r<=e}],"filter->=":[yb,[pb,gb],function(t,n){var i=n[0],r=n[1],e=t.properties()[i.value],o=r.value;return typeof e==typeof o&&e>=o}],"filter-id->=":[yb,[gb],function(t,n){var i=n[0],r=t.id(),e=i.value;return typeof r==typeof e&&r>=e}],"filter-has":[yb,[gb],function(t,n){return n[0].value in t.properties()}],"filter-has-id":[yb,[],function(t){return null!==t.id()&&void 0!==t.id()}],"filter-type-in":[yb,[_b(pb)],function(t,n){return n[0].value.indexOf(t.geometryType())>=0}],"filter-id-in":[yb,[_b(gb)],function(t,n){return n[0].value.indexOf(t.id())>=0}],"filter-in-small":[yb,[pb,_b(gb)],function(t,n){var i=n[0];return n[1].value.indexOf(t.properties()[i.value])>=0}],"filter-in-large":[yb,[pb,_b(gb)],function(t,n){var i=n[0],r=n[1];return function(t,n,i,r){for(;i<=r;){var e=i+r>>1;if(n[e]===t)return!0;n[e]>t?r=e-1:i=e+1}return!1}(t.properties()[i.value],r.value,0,r.value.length-1)}],all:{type:yb,overloads:[[[yb,yb],function(t,n){var i=n[0],r=n[1];return i.evaluate(t)&&r.evaluate(t)}],[lM(yb),function(t,n){for(var i=0,r=n;i-1}(n))return dM([new cb("","zoom expressions not supported")]);var o=xM(i);if(!o&&!e)return dM([new cb("",'"zoom" expression may only be used as input to a top-level "step" or "interpolate" expression.')]);if(o instanceof cb)return dM([o]);if(o instanceof qx&&!function(t){return!!t.expression&&t.expression.interpolated}(n))return dM([new cb("",'"interpolate" expressions cannot be used with this property')]);if(!o)return vM(new wM(r?"constant":"source",t.value));var s=o instanceof qx?o.interpolation:void 0;return vM(new gM(r?"camera":"composite",t.value,o.labels,s))}function xM(t){var n=null;if(t instanceof Xx)n=xM(t.result);else if(t instanceof Bx)for(var i=0,r=t.args;i":{},">=":{},"<":{},"<=":{},in:{},"!in":{},all:{},any:{},none:{},has:{},"!has":{},within:{}}},geometry_type:{type:"enum",values:{Point:{},LineString:{},Polygon:{}}},function:{expression:{type:"expression"},stops:{type:"array",value:"function_stop"},base:{type:"number",default:1,minimum:0},property:{type:"string",default:"$zoom"},type:{type:"enum",values:{identity:{},exponential:{},interval:{},categorical:{}},default:"exponential"},colorSpace:{type:"enum",values:{rgb:{},lab:{},hcl:{}},default:"rgb"},default:{type:"*",required:!1}},function_stop:{type:"array",minimum:0,maximum:24,value:["number","color"],length:2},expression:{type:"array",value:"*",minimum:1},expression_name:{type:"enum",values:{let:{group:"Variable binding"},var:{group:"Variable binding"},literal:{group:"Types"},array:{group:"Types"},at:{group:"Lookup"},in:{group:"Lookup"},"index-of":{group:"Lookup"},slice:{group:"Lookup"},case:{group:"Decision"},match:{group:"Decision"},coalesce:{group:"Decision"},step:{group:"Ramps, scales, curves"},interpolate:{group:"Ramps, scales, curves"},"interpolate-hcl":{group:"Ramps, scales, curves"},"interpolate-lab":{group:"Ramps, scales, curves"},ln2:{group:"Math"},pi:{group:"Math"},e:{group:"Math"},typeof:{group:"Types"},string:{group:"Types"},number:{group:"Types"},boolean:{group:"Types"},object:{group:"Types"},collator:{group:"Types"},format:{group:"Types"},image:{group:"Types"},"number-format":{group:"Types"},"to-string":{group:"Types"},"to-number":{group:"Types"},"to-boolean":{group:"Types"},"to-rgba":{group:"Color"},"to-color":{group:"Types"},rgb:{group:"Color"},rgba:{group:"Color"},get:{group:"Lookup"},has:{group:"Lookup"},length:{group:"Lookup"},properties:{group:"Feature data"},"feature-state":{group:"Feature data"},"geometry-type":{group:"Feature data"},id:{group:"Feature data"},zoom:{group:"Camera"},pitch:{group:"Camera"},"distance-from-center":{group:"Camera"},"heatmap-density":{group:"Heatmap"},"line-progress":{group:"Feature data"},"sky-radial-progress":{group:"sky"},accumulated:{group:"Feature data"},"+":{group:"Math"},"*":{group:"Math"},"-":{group:"Math"},"/":{group:"Math"},"%":{group:"Math"},"^":{group:"Math"},sqrt:{group:"Math"},log10:{group:"Math"},ln:{group:"Math"},log2:{group:"Math"},sin:{group:"Math"},cos:{group:"Math"},tan:{group:"Math"},asin:{group:"Math"},acos:{group:"Math"},atan:{group:"Math"},min:{group:"Math"},max:{group:"Math"},round:{group:"Math"},abs:{group:"Math"},ceil:{group:"Math"},floor:{group:"Math"},distance:{group:"Math"},"==":{group:"Decision"},"!=":{group:"Decision"},">":{group:"Decision"},"<":{group:"Decision"},">=":{group:"Decision"},"<=":{group:"Decision"},all:{group:"Decision"},any:{group:"Decision"},"!":{group:"Decision"},within:{group:"Decision"},"is-supported-script":{group:"String"},upcase:{group:"String"},downcase:{group:"String"},concat:{group:"String"},"resolved-locale":{group:"String"}}},fog:{range:{type:"array",default:[.5,10],minimum:-20,maximum:20,length:2,value:"number","property-type":"data-constant",transition:!0,expression:{interpolated:!0,parameters:["zoom"]}},color:{type:"color","property-type":"data-constant",default:"#ffffff",expression:{interpolated:!0,parameters:["zoom"]},transition:!0},"horizon-blend":{type:"number","property-type":"data-constant",default:.1,minimum:0,maximum:1,expression:{interpolated:!0,parameters:["zoom"]},transition:!0}},light:{anchor:{type:"enum",default:"viewport",values:{map:{},viewport:{}},"property-type":"data-constant",transition:!1,expression:{interpolated:!1,parameters:["zoom"]}},position:{type:"array",default:[1.15,210,30],length:3,value:"number","property-type":"data-constant",transition:!0,expression:{interpolated:!0,parameters:["zoom"]}},color:{type:"color","property-type":"data-constant",default:"#ffffff",expression:{interpolated:!0,parameters:["zoom"]},transition:!0},intensity:{type:"number","property-type":"data-constant",default:.5,minimum:0,maximum:1,expression:{interpolated:!0,parameters:["zoom"]},transition:!0}},projection:{name:{type:"enum",values:{albers:{},equalEarth:{},equirectangular:{},lambertConformalConic:{},mercator:{},naturalEarth:{},winkelTripel:{}},default:"mercator",required:!0},center:{type:"array",length:2,value:"number","property-type":"data-constant",transition:!1,requires:[{name:["albers","lambertConformalConic"]}]},parallels:{type:"array",length:2,value:"number","property-type":"data-constant",transition:!1,requires:[{name:["albers","lambertConformalConic"]}]}},terrain:{source:{type:"string",required:!0},exaggeration:{type:"number","property-type":"data-constant",default:1,minimum:0,maximum:1e3,expression:{interpolated:!0,parameters:["zoom"]},transition:!0}},paint:["paint_fill","paint_line","paint_circle","paint_heatmap","paint_fill-extrusion","paint_symbol","paint_raster","paint_hillshade","paint_background","paint_sky"],paint_fill:{"fill-antialias":{type:"boolean",default:!0,expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"fill-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-color":{type:"color",default:"#000000",transition:!0,requires:[{"!":"fill-pattern"}],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-outline-color":{type:"color",transition:!0,requires:[{"!":"fill-pattern"},{"fill-antialias":!0}],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"fill-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["fill-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"fill-pattern":{type:"resolvedImage",transition:!0,expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"cross-faded-data-driven"}},"paint_fill-extrusion":{"fill-extrusion-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"fill-extrusion-color":{type:"color",default:"#000000",transition:!0,requires:[{"!":"fill-extrusion-pattern"}],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-extrusion-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"fill-extrusion-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["fill-extrusion-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"fill-extrusion-pattern":{type:"resolvedImage",transition:!0,expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"cross-faded-data-driven"},"fill-extrusion-height":{type:"number",default:0,minimum:0,units:"meters",transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-extrusion-base":{type:"number",default:0,minimum:0,units:"meters",transition:!0,requires:["fill-extrusion-height"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"fill-extrusion-vertical-gradient":{type:"boolean",default:!0,transition:!1,expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"}},paint_line:{"line-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-color":{type:"color",default:"#000000",transition:!0,requires:[{"!":"line-pattern"}],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"line-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["line-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"line-width":{type:"number",default:1,minimum:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-gap-width":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-offset":{type:"number",default:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-blur":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"line-dasharray":{type:"array",value:"number",minimum:0,transition:!0,units:"line widths",requires:[{"!":"line-pattern"}],expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"cross-faded-data-driven"},"line-pattern":{type:"resolvedImage",transition:!0,expression:{interpolated:!1,parameters:["zoom","feature"]},"property-type":"cross-faded-data-driven"},"line-gradient":{type:"color",transition:!1,requires:[{"!":"line-pattern"},{source:"geojson",has:{lineMetrics:!0}}],expression:{interpolated:!0,parameters:["line-progress"]},"property-type":"color-ramp"}},paint_circle:{"circle-radius":{type:"number",default:5,minimum:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-color":{type:"color",default:"#000000",transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-blur":{type:"number",default:0,transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"circle-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["circle-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"circle-pitch-scale":{type:"enum",values:{map:{},viewport:{}},default:"map",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"circle-pitch-alignment":{type:"enum",values:{map:{},viewport:{}},default:"viewport",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"circle-stroke-width":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-stroke-color":{type:"color",default:"#000000",transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"circle-stroke-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"}},paint_heatmap:{"heatmap-radius":{type:"number",default:30,minimum:1,transition:!0,units:"pixels",expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"heatmap-weight":{type:"number",default:1,minimum:0,transition:!1,expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"heatmap-intensity":{type:"number",default:1,minimum:0,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"heatmap-color":{type:"color",default:["interpolate",["linear"],["heatmap-density"],0,"rgba(0, 0, 255, 0)",.1,"royalblue",.3,"cyan",.5,"lime",.7,"yellow",1,"red"],transition:!1,expression:{interpolated:!0,parameters:["heatmap-density"]},"property-type":"color-ramp"},"heatmap-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"}},paint_symbol:{"icon-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-color":{type:"color",default:"#000000",transition:!0,requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-halo-color":{type:"color",default:"rgba(0, 0, 0, 0)",transition:!0,requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-halo-width":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-halo-blur":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"icon-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",requires:["icon-image"],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"icon-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["icon-image","icon-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"text-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-color":{type:"color",default:"#000000",transition:!0,overridable:!0,requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-halo-color":{type:"color",default:"rgba(0, 0, 0, 0)",transition:!0,requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-halo-width":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-halo-blur":{type:"number",default:0,minimum:0,transition:!0,units:"pixels",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom","feature","feature-state"]},"property-type":"data-driven"},"text-translate":{type:"array",value:"number",length:2,default:[0,0],transition:!0,units:"pixels",requires:["text-field"],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"text-translate-anchor":{type:"enum",values:{map:{},viewport:{}},default:"map",requires:["text-field","text-translate"],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"}},paint_raster:{"raster-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-hue-rotate":{type:"number",default:0,period:360,transition:!0,units:"degrees",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-brightness-min":{type:"number",default:0,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-brightness-max":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-saturation":{type:"number",default:0,minimum:-1,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-contrast":{type:"number",default:0,minimum:-1,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"raster-resampling":{type:"enum",values:{linear:{},nearest:{}},default:"linear",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"raster-fade-duration":{type:"number",default:300,minimum:0,transition:!1,units:"milliseconds",expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"}},paint_hillshade:{"hillshade-illumination-direction":{type:"number",default:335,minimum:0,maximum:359,transition:!1,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-illumination-anchor":{type:"enum",values:{map:{},viewport:{}},default:"viewport",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-exaggeration":{type:"number",default:.5,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-shadow-color":{type:"color",default:"#000000",transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-highlight-color":{type:"color",default:"#FFFFFF",transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"hillshade-accent-color":{type:"color",default:"#000000",transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"}},paint_background:{"background-color":{type:"color",default:"#000000",transition:!0,requires:[{"!":"background-pattern"}],expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"},"background-pattern":{type:"resolvedImage",transition:!0,expression:{interpolated:!1,parameters:["zoom"]},"property-type":"cross-faded"},"background-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"}},paint_sky:{"sky-type":{type:"enum",values:{gradient:{},atmosphere:{}},default:"atmosphere",expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"sky-atmosphere-sun":{type:"array",value:"number",length:2,units:"degrees",minimum:[0,0],maximum:[360,180],transition:!1,requires:[{"sky-type":"atmosphere"}],expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"sky-atmosphere-sun-intensity":{type:"number",requires:[{"sky-type":"atmosphere"}],default:10,minimum:0,maximum:100,transition:!1,"property-type":"data-constant"},"sky-gradient-center":{type:"array",requires:[{"sky-type":"gradient"}],value:"number",default:[0,0],length:2,units:"degrees",minimum:[0,0],maximum:[360,180],transition:!1,expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"sky-gradient-radius":{type:"number",requires:[{"sky-type":"gradient"}],default:90,minimum:0,maximum:180,transition:!1,expression:{interpolated:!1,parameters:["zoom"]},"property-type":"data-constant"},"sky-gradient":{type:"color",default:["interpolate",["linear"],["sky-radial-progress"],.8,"#87ceeb",1,"white"],transition:!1,requires:[{"sky-type":"gradient"}],expression:{interpolated:!0,parameters:["sky-radial-progress"]},"property-type":"color-ramp"},"sky-atmosphere-halo-color":{type:"color",default:"white",transition:!1,requires:[{"sky-type":"atmosphere"}],"property-type":"data-constant"},"sky-atmosphere-color":{type:"color",default:"white",transition:!1,requires:[{"sky-type":"atmosphere"}],"property-type":"data-constant"},"sky-opacity":{type:"number",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:["zoom"]},"property-type":"data-constant"}},transition:{duration:{type:"number",default:300,minimum:0,units:"milliseconds"},delay:{type:"number",default:0,minimum:0,units:"milliseconds"}},"property-type":{"data-driven":{type:"property-type"},"cross-faded":{type:"property-type"},"cross-faded-data-driven":{type:"property-type"},"color-ramp":{type:"property-type"},"data-constant":{type:"property-type"},constant:{type:"property-type"}},promoteId:{"*":{type:"string"}}};function SM(t){if(!0===t||!1===t)return!0;if(!Array.isArray(t)||0===t.length)return!1;switch(t[0]){case"has":return t.length>=2&&"$id"!==t[1]&&"$type"!==t[1];case"in":return t.length>=3&&("string"!=typeof t[1]||Array.isArray(t[2]));case"!in":case"!has":case"none":return!1;case"==":case"!=":case">":case">=":case"<":case"<=":return 3!==t.length||Array.isArray(t[1])||Array.isArray(t[2]);case"any":case"all":for(var n=0,i=t.slice(1);n",">=","<","<=","to-boolean"]);function PM(t,n){return tn?1:0}function CM(t){if(!Array.isArray(t))return!1;if("within"===t[0])return!0;for(var n=1;n"===i||"<="===i||">="===i?IM(t[1],t[2],i):"any"===i?(n=t.slice(1),["any"].concat(n.map(kM))):"all"===i?["all"].concat(t.slice(1).map(kM)):"none"===i?["all"].concat(t.slice(1).map(kM).map(zM)):"in"===i?NM(t[1],t.slice(2)):"!in"===i?zM(NM(t[1],t.slice(2))):"has"===i?LM(t[1]):"!has"===i?zM(LM(t[1])):"within"!==i||t}function IM(t,n,i){switch(t){case"$type":return["filter-type-"+i,n];case"$id":return["filter-id-"+i,n];default:return["filter-"+i,t,n]}}function NM(t,n){if(0===n.length)return!1;switch(t){case"$type":return["filter-type-in",["literal",n]];case"$id":return["filter-id-in",["literal",n]];default:return n.length>200&&!n.some((function(t){return typeof t!=typeof n[0]}))?["filter-in-large",t,["literal",n.sort(PM)]]:["filter-in-small",t,["literal",n]]}}function LM(t){switch(t){case"$type":return!0;case"$id":return["filter-has-id"];default:return["filter-has",t]}}function zM(t){return["!",t]}var RM=["type","source","source-layer","minzoom","maxzoom","filter","layout"];function FM(t,n){var i={};for(var r in t)"ref"!==r&&(i[r]=t[r]);return RM.forEach((function(t){t in n&&(i[t]=n[t])})),i}var GM={thin:100,hairline:100,"ultra-light":100,"extra-light":100,light:200,book:300,regular:400,normal:400,plain:400,roman:400,standard:400,medium:500,"semi-bold":600,"demi-bold":600,bold:700,heavy:800,black:800,"extra-bold":800,"ultra-black":900,"extra-black":900,"ultra-bold":900,"heavy-black":900,fat:900,poster:900},DM=" ",qM=/(italic|oblique)$/i,UM={},BM=function(t,n,i){var r=UM[t];if(!r){Array.isArray(t)||(t=[t]);for(var e=400,o="normal",s=[],u=0,a=t.length;u1?h[h.length-2].toLowerCase():"";if(f==c||f==c.replace("-","")||l+"-"+f==c){e=GM[c],h.pop(),l&&c.startsWith(l)&&h.pop();break}}"number"==typeof f&&(e=f);var v=h.join(DM).replace("Klokantech Noto Sans","Noto Sans");-1!==v.indexOf(DM)&&(v='"'+v+'"'),s.push(v)}r=UM[t]=[o,e,s]}return r[0]+DM+r[1]+DM+n+"px"+(i?"/"+i:"")+DM+r[2]},XM="https://api.mapbox.com";function VM(t){var n="mapbox://";return 0!==t.indexOf(n)?"":t.slice(n.length)}function WM(t,n){var i=VM(t);if(!i)return decodeURI(new URL(t,location.href).href);var r="styles/";if(0!==i.indexOf(r))throw new Error("unexpected style url: "+t);var e=i.slice(r.length);return XM+"/styles/v1/"+e+"?&access_token="+n}function YM(t,n,i,r){var e=new URL(t,r),o=VM(t);return o?"https://{a-d}.tiles.mapbox.com/v4/"+o+"/{z}/{x}/{y}.vector.pbf?access_token="+n:n?(e.searchParams.set(i,n),decodeURI(e.href)):decodeURI(e.href)}function ZM(t){return t*Math.PI/180}var $M=function(){for(var t=[],n=78271.51696402048;t.length<=24;n/=2)t.push(n);return t}();function KM(t,n){if("undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&"undefined"!=typeof OffscreenCanvas)return new OffscreenCanvas(t,n);var i=document.createElement("canvas");return i.width=t,i.height=n,i}var HM={};function JM(t,n,i){if(void 0===i&&(i={}),n in HM)return HM[n];var r=i.transformRequest&&i.transformRequest(n,t)||new Request(n);r.headers.get("Accept")||r.headers.set("Accept","application/json");var e=fetch(r).then((function(t){return delete HM[n],t.ok?t.json():Promise.reject(new Error("Error fetching source "+n))})).catch((function(t){return delete HM[n],Promise.reject(new Error("Error fetching source "+n))}));return HM[n]=e,e}function QM(t,n){if("string"!=typeof t)return Promise.resolve(t);if(!t.trim().startsWith("{"))return JM("Style",t=WM(t,n.accessToken),n);try{var i=JSON.parse(t);return Promise.resolve(i)}catch(t){return Promise.reject(t)}}var t_={};function n_(t,n,i){void 0===i&&(i={});var r=[n,JSON.stringify(t)].toString(),e=t_[r];if(!e||i.transformRequest){var o=t.url;if(o){var s=YM(o,i.accessToken,i.accessTokenParam||"access_token",n||location.href);e=o.startsWith("mapbox://")?Promise.resolve(A({},t,{url:void 0,tiles:s})):JM("Source",s,i).then((function(t){for(var n=0,r=t.tiles.length;n=.05){for(var i="",r=t.split("\n"),e=r_.slice(0,Math.round(n/.1)),o=0,s=r.length;o0&&(i+="\n"),i+=r[o].split("").join(e);return i}return t}function o_(){return i_||(i_=KM(1,1).getContext("2d")),i_}function s_(t,n){return o_().measureText(t).width+(t.length-1)*n}var u_={};function a_(t,n,i,r){if(-1!==t.indexOf("\n")){for(var e=t.split("\n"),o=[],s=0,u=e.length;s1){var c=o_();c.font=n;for(var l=c.measureText("M").width*i,v="",d=[],p=0,y=f.length;p1;++g){var x=d[g];if(s_(x,r)<.35*l){var M=g>0?s_(d[g-1],r):1/0,_=g.7*l&&s_(E,r)<.6*l){var T=j.split(" "),A=T.pop();s_(A,r)<.2*l&&(d[S]=T.join(" "),d[S+1]=A+" "+E),O-=1}}h=d.join("\n")}else h=t;h=e_(h,r),u_[a]=h}return h}var h_,f_=/font-family: ?([^;]*);/,c_=/("|')/g;function l_(t){if(!h_){h_={};for(var n=document.styleSheets,i=0,r=n.length;i0&&"string"==typeof a[0]&&a[0]in aM);if(!l&&pM(f)&&(f=rb(f,c),l=!0),l){var v=function(t,n){var i=bM(t,n);if("error"===i.result)throw new Error(i.value.map((function(t){return t.key+": "+t.message})).join(", "));return i.value}(f,c);h[i]=v.evaluate.bind(v)}else"color"==c.type&&(f=nb.parse(f)),h[i]=function(){return f}}return b_.zoom=r,h[i](b_,e,s)}function M_(t,n,i,r){return x_(t,"layout","icon-allow-overlap",n,i,r)?x_(t,"layout","icon-ignore-placement",n,i,r)?"none":"obstacle":"declutter"}function __(t,n,i,r,e){return e||console.warn("No filterCache provided to evaluateFilter()"),t in e||(e[t]=OM(n).filter),b_.zoom=r,e[t](b_,i)}var S_=!1;function O_(t,n){if(t){if(!S_&&(0===t.a||0===n))return;var i=t.a;return n=void 0===n?1:n,0===i?"transparent":"rgba("+Math.round(255*t.r/i)+","+Math.round(255*t.g/i)+","+Math.round(255*t.b/i)+","+i*n+")"}return t}var j_=/^([^]*)\{(.*)\}([^]*)$/;function E_(t,n){var i;do{if(i=t.match(j_)){var r=n[i[2]]||"";t=i[1]+r+i[3]}}while(i);return t}var T_=!1;function A_(t,n,i,r,e,o,s){if(void 0===r&&(r=$M),void 0===e&&(e=void 0),void 0===o&&(o=void 0),void 0===s&&(s=void 0),"string"==typeof n&&(n=JSON.parse(n)),8!=n.version)throw new Error("glStyle version 8 required.");var u,a;if(o)if("undefined"!=typeof Image){var h=new Image;h.crossOrigin="anonymous",h.onload=function(){u=h,a=[h.width,h.height],t.changed(),h.onload=null},h.src=o}else if("undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope){var f=self;f.postMessage({action:"loadImage",src:o}),f.addEventListener("message",(function(t){"imageLoaded"===t.data.action&&t.data.src===o&&(u=t.data.image,a=[u.width,u.height])}))}for(var c,l=function(t){t=t.slice();for(var n=Object.create(null),i=0;i=S.maxzoom)){var C=S.filter;if(!C||__(O,C,d,f,w)){c=S;var k=void 0,I=void 0,N=void 0,L=void 0,z=void 0,R=void 0,F=_.index;if(3==l&&("fill"==S.type||"fill-extrusion"==S.type))if(I=x_(S,"paint",S.type+"-opacity",f,d,m,g),S.type+"-pattern"in P){var G=x_(S,"paint",S.type+"-pattern",f,d,m,g);if(G){var D="string"==typeof G?E_(G,o):G.toString();if(u&&e&&e[D]){++b,(R=A[b])&&R.getFill()&&!R.getStroke()&&!R.getText()||(R=new Sv({fill:new rv}),A[b]=R),N=R.getFill(),R.setZIndex(F);var q=D+"."+I,U=y[q];if(!U){var B=e[D],X=KM(B.width,B.height),V=X.getContext("2d");V.globalAlpha=I,V.drawImage(u,B.x,B.y,B.width,B.height,0,0,B.width,B.height),U=V.createPattern(X,"repeat"),y[q]=U}N.setColor(U)}}}else k=O_(x_(S,"paint",S.type+"-color",f,d,m,g),I),S.type+"-outline-color"in P&&(z=O_(x_(S,"paint",S.type+"-outline-color",f,d,m,g),I)),z||(z=k),(k||z)&&(++b,(!(R=A[b])||k&&!R.getFill()||!k&&R.getFill()||z&&!R.getStroke()||!z&&R.getStroke()||R.getText())&&(R=new Sv({fill:k?new rv:void 0,stroke:z?new mv:void 0}),A[b]=R),k&&(N=R.getFill()).setColor(k),z&&((L=R.getStroke()).setColor(z),L.setWidth(.5)),R.setZIndex(F));if(1!=l&&"line"==S.type){k=!("line-pattern"in P)&&"line-color"in P?O_(x_(S,"paint","line-color",f,d,m,g),x_(S,"paint","line-opacity",f,d,m,g)):void 0;var W=x_(S,"paint","line-width",f,d,m,g);k&&W>0&&(++b,(R=A[b])&&R.getStroke()&&!R.getFill()&&!R.getText()||(R=new Sv({stroke:new mv}),A[b]=R),(L=R.getStroke()).setLineCap(x_(S,"layout","line-cap",f,d,m,g)),L.setLineJoin(x_(S,"layout","line-join",f,d,m,g)),L.setMiterLimit(x_(S,"layout","line-miter-limit",f,d,m,g)),L.setColor(k),L.setWidth(W),L.setLineDash(P["line-dasharray"]?x_(S,"paint","line-dasharray",f,d,m,g).map((function(t){return t*W})):null),R.setZIndex(F))}var Y=!1,Z=null,$=0,K=void 0,H=void 0,J=void 0;if((1==l||2==l)&&"icon-image"in j){var Q=x_(S,"layout","icon-image",f,d,m,g);if(Q){K="string"==typeof Q?E_(Q,o):Q.toString();var tt=void 0;if(u&&e&&e[K]){var nt=x_(S,"layout","icon-rotation-alignment",f,d,m,g);if(2==l){var it=n.getGeometry();if(it.getFlatMidpoint||it.getFlatMidpoints){var rt=it.getExtent();if(Math.sqrt(Math.max(Math.pow((rt[2]-rt[0])/i,2),Math.pow((rt[3]-rt[1])/i,2)))>150){var et="MultiLineString"===it.getType()?it.getFlatMidpoints():it.getFlatMidpoint();if(y_||(y_=new fg("Point",p_=[NaN,NaN],[],{},null)),tt=y_,p_[0]=et[0],p_[1]=et[1],"line"===x_(S,"layout","symbol-placement",f,d,m,g)&&"map"===nt)for(var ot=it.getStride(),st=it.getFlatCoordinates(),ut=0,at=st.length-ot;ut=vt&&et[0]<=pt&&et[1]>=dt&&et[1]<=yt){$=Math.atan2(ft-lt,ct-ht);break}}}}}if(2!==l||tt){var mt=x_(S,"layout","icon-size",f,d,m,g),wt=void 0!==P["icon-color"]?x_(S,"paint","icon-color",f,d,m,g):null;if(!wt||0!==wt.a){var gt=K+"."+mt;if(null!==wt&&(gt+="."+wt),!(H=p[gt])){var bt=e[K],xt=M_(S,f,d,m);H=new yv({color:wt?[255*wt.r,255*wt.g,255*wt.b,wt.a]:void 0,img:u,imgSize:a,size:[bt.width,bt.height],offset:[bt.x,bt.y],rotateWithView:"map"===nt,scale:mt/bt.pixelRatio,displacement:"icon-offset"in j?x_(S,"layout","icon-offset",f,d,m,g).map((function(t){return-t*bt.pixelRatio})):void 0,declutterMode:xt}),p[gt]=H}}H&&(++b,(R=A[b])&&R.getImage()&&!R.getFill()&&!R.getStroke()||(R=new Sv,A[b]=R),R.setGeometry(tt),H.setRotation($+ZM(x_(S,"layout","icon-rotate",f,d,m,g))),H.setOpacity(x_(S,"paint","icon-opacity",f,d,m,g)),H.setAnchor(w_[x_(S,"layout","icon-anchor",f,d,m,g)]),R.setImage(H),Z=R.getText(),R.setText(void 0),R.setZIndex(F),Y=!0,J=!1)}else J=!0}}}if(1==l&&"circle"===S.type){++b,(R=A[b])&&R.getImage()&&!R.getFill()&&!R.getStroke()||(R=new Sv,A[b]=R);var Mt="circle-radius"in P?x_(S,"paint","circle-radius",f,d,m,g):5,_t=O_(x_(S,"paint","circle-stroke-color",f,d,m,g),x_(S,"paint","circle-stroke-opacity",f,d,m,g)),St=O_(x_(S,"paint","circle-color",f,d,m,g),x_(S,"paint","circle-opacity",f,d,m,g)),Ot=x_(S,"paint","circle-stroke-width",f,d,m,g),jt=Mt+"."+_t+"."+St+"."+Ot;(H=p[jt])||(H=new iv({radius:Mt,stroke:_t&&Ot>0?new mv({width:Ot,color:_t}):void 0,fill:St?new rv({color:St}):void 0,declutterMode:"none"}),p[jt]=H),R.setImage(H),Z=R.getText(),R.setText(void 0),R.setGeometry(void 0),R.setZIndex(F),Y=!0}var Et=void 0,Tt=void 0,At=void 0,Pt=void 0,Ct=void 0,kt=void 0;if("text-field"in j){Pt=Math.round(x_(S,"layout","text-size",f,d,m,g));var It=x_(S,"layout","text-font",f,d,m,g);At=x_(S,"layout","text-line-height",f,d,m,g),(Tt=BM(s?s(It):It,Pt,At)).includes("sans-serif")||(Tt+=",sans-serif"),Ct=x_(S,"layout","text-letter-spacing",f,d,m,g),kt=x_(S,"layout","text-max-width",f,d,m,g);var Nt=x_(S,"layout","text-field",f,d,m,g);Et="object"==typeof Nt&&Nt.sections?1===Nt.sections.length?Nt.toString():Nt.sections.reduce((function(t,n,i){var r=n.fontStack?n.fontStack.split(","):It,e=BM(s?s(r):r,Pt*(n.scale||1),At),o=n.text;if("\n"===o)return t.push("\n",""),t;if(2!=l){for(var u=0,a=(o=a_(o,e,kt,Ct).split("\n")).length;u0&&t.push("\n",""),t.push(o[u],e);return t}t.push(e_(o,Ct),e)}),[]):E_(Nt,o).trim(),I=x_(S,"paint","text-opacity",f,d,m,g)}if(Et&&I&&!J){Y||(++b,(R=A[b])&&R.getText()&&!R.getFill()&&!R.getStroke()||(R=new Sv,A[b]=R),R.setImage(void 0),R.setGeometry(void 0)),R.getText()||R.setText(Z||new Ev({padding:[2,2,2,2]})),Z=R.getText();var Lt=j["text-transform"];"uppercase"==Lt?Et=Array.isArray(Et)?Et.map((function(t,n){return n%2?t:t.toUpperCase()})):Et.toUpperCase():"lowercase"==Lt&&(Et=Array.isArray(Et)?Et.map((function(t,n){return n%2?t:t.toLowerCase()})):Et.toLowerCase());var zt=Array.isArray(Et)?Et:2==l?e_(Et,Ct):a_(Et,Tt,kt,Ct);Z.setText(zt),Z.setFont(Tt),Z.setRotation(ZM(x_(S,"layout","text-rotate",f,d,m,g)));var Rt=x_(S,"layout","text-anchor",f,d,m,g),Ft=Y||1==l?"point":x_(S,"layout","symbol-placement",f,d,m,g);Z.setPlacement(Ft),Z.setOverflow("point"===Ft);var Gt=x_(S,"paint","text-halo-width",f,d,m,g),Dt=x_(S,"layout","text-offset",f,d,m,g),qt=x_(S,"paint","text-translate",f,d,m,g),Ut=0,Bt=0;if("point"==Ft){var Xt="center";-1!==Rt.indexOf("left")?(Xt="left",Bt=Gt):-1!==Rt.indexOf("right")&&(Xt="right",Bt=-Gt),Z.setTextAlign(Xt);var Vt=x_(S,"layout","text-rotation-alignment",f,d,m,g);Z.setRotateWithView("map"==Vt)}else Z.setMaxAngle(ZM(x_(S,"layout","text-max-angle",f,d,m,g))*Et.length/zt.length),Z.setTextAlign(),Z.setRotateWithView(!1);var Wt="middle";0==Rt.indexOf("bottom")?(Wt="bottom",Ut=-Gt-.5*(At-1)*Pt):0==Rt.indexOf("top")&&(Wt="top",Ut=Gt+.5*(At-1)*Pt),Z.setTextBaseline(Wt),Z.setOffsetX(Dt[0]*Pt+Bt+qt[0]),Z.setOffsetY(Dt[1]*Pt+Ut+qt[1]),T.setColor(O_(x_(S,"paint","text-color",f,d,m,g),I)),Z.setFill(T);var Yt=O_(x_(S,"paint","text-halo-color",f,d,m,g),I);if(Yt){E.setColor(Yt),Gt*=2;var Zt=.5*Pt;E.setWidth(Gt<=Zt?Gt:Zt),Z.setStroke(E)}else Z.setStroke(void 0);var $t=x_(S,"layout","text-padding",f,d,m,g),Kt=Z.getPadding();$t!==Kt[0]&&(Kt[0]=$t,Kt[1]=$t,Kt[2]=$t,Kt[3]=$t),R.setZIndex(F)}}}}return b>-1?(A.length=b+1,T_&&("function"==typeof n.set?n.set("mapbox-layer",c):n.getProperties()["mapbox-layer"]=c),A):void 0}};return t.setStyle(P),t.set("mapbox-source",c),t.set("mapbox-layers",d),t.set("mapbox-featurestate",{}),P}function P_(t,n){n.accessToken||(n=A({},n),new URL(t).searchParams.forEach((function(t,i){n.accessToken=t,n.accessTokenParam=i})));return n}function C_(t,n,i,r,e){var o,s,u;return void 0===i&&(i=""),void 0===r&&(r={}),void 0===e&&(e=void 0),"string"==typeof r?(o=r,u={}):(o=r.styleUrl,u=r),e||(e=u.resolutions),o||"string"!=typeof n||n.trim().startsWith("{")||(o=n),o&&(o=o.startsWith("data:")?location.href:WM(o,u.accessToken),u=P_(o,u)),new Promise((function(r,a){QM(n,u).then((function(n){if(8!=n.version)return a(new Error("glStyle version 8 required."));if(!(t instanceof lg||t instanceof Rg))return a(new Error("Can only apply to VectorLayer or VectorTileLayer"));var h,f,c,l=t instanceof Rg?"vector":"geojson";if(i?s=Array.isArray(i)?n.layers.find((function(t){return t.id===i[0]})).source:i:(s=Object.keys(n.sources).find((function(t){return n.sources[t].type===l})),i=s),!s)return a(new Error("No "+l+" source found in the glStyle."));function v(){if(t instanceof Rg)return z_(n.sources[s],o,u).then((function(n){var i=t.getSource();if(i?n!==i&&(i.setTileUrlFunction(n.getTileUrlFunction()),i.ze||(i.ze=n.ze),i.getAttributions()||i.setAttributions(n.getAttributions()),i.getTileLoadFunction()===Uy&&i.setTileLoadFunction(n.getTileLoadFunction()),Sr(i.getProjection(),n.getProjection())&&(i.tileGrid=n.getTileGrid())):t.setSource(n),!isFinite(t.getMaxResolution())&&!isFinite(t.getMinZoom())){var r=t.getSource().getTileGrid();t.setMaxResolution(r.getResolution(r.getMinZoom()))}}));var i=n.sources[s],r=t.getSource();r&&r.get("mapbox-source")===i||(r=F_(i,o,u));var e=t.getSource();return e?r!==e&&(e.getAttributions()||e.setAttributions(r.getAttributions()),e.ze||(e.ze=r.getFormat()),e.Fe=r.getUrl()):t.setSource(r),Promise.resolve()}function d(){c||n.sprite&&!h?c?(t.setStyle(c),v().then(r).catch(a)):a(new Error("Something went wrong trying to apply style.")):(c=A_(t,n,i,e,h,f,d_),t.getStyle()?v().then(r).catch(a):a(new Error("Nothing to show for source ["+s+"]")))}if(n.sprite){var p=new URL(function(t,n,i){var r=VM(t);if(!r)return decodeURI(new URL(t,i).href);var e="sprites/";if(0!==r.indexOf(e))throw new Error("unexpected sprites url: "+t);var o=r.slice(e.length);return XM+"/styles/v1/"+o+"/sprite?access_token="+n}(n.sprite,u.accessToken,o||location.href)),y=.5==(window.devicePixelRatio>=1.5?.5:1)?"@2x":"",m=p.origin+p.pathname+y+".json"+p.search;new Promise((function(t,n){JM("Sprite",m,u).then(t).catch((function(i){JM("Sprite",m=p.origin+p.pathname+".json"+p.search,u).then(t).catch(n)}))})).then((function(t){void 0===t&&a(new Error("No sprites found.")),h=t,f=p.origin+p.pathname+y+".png"+p.search,d()})).catch((function(t){a(new Error("Sprites cannot be loaded: "+m+": "+t.message))}))}else d()})).catch(a)}))}var k_={};function I_(t,n){var i={id:n.id,type:n.type},r={};function e(e){var o=n.layout||{},s=n.paint||{};i.paint=s;var u,a,h="function"==typeof t.getSource?t.getSource().getTileGrid().getZForResolution(e):t.getView().getZoom(),f="function"==typeof t.getTargetElement?t.getTargetElement():void 0;if(void 0!==s["background-color"]&&(u=x_(i,"paint","background-color",h,k_,r),f&&(f.style.background=nb.parse(u).toString())),void 0!==s["background-opacity"]&&(a=x_(i,"paint","background-opacity",h,k_,r),f&&(f.style.opacity=a)),"none"!=o.visibility)return O_(u,a);f&&(f.style.backgroundColor="",f.style.opacity="")}if("function"==typeof t.getTargetElement)t.getTargetElement()&&e(),t.on(["change:resolution","change:target"],e);else{if("function"!=typeof t.setBackground)throw new Error("Unable to apply background.");t.setBackground(e)}}function N_(t,n){n.layers.some((function(n){if("background"===n.type)return I_(t,n),!0}))}function L_(t){var n=t.bounds;if(n){var i=_r([n[0],n[1]]),r=_r([n[2],n[3]]);return[i[0],i[1],r[0],r[1]]}}function z_(t,n,i){return new Promise((function(r,e){n_(t,n,i).then((function(t){var n=new Gm({tileJSON:t}),i=n.getTileJSON(),e=n.getTileGrid(),o=L_(i),s=i.minzoom||0,u=i.maxzoom||22,a={attributions:n.getAttributions(),format:new Lg,tileGrid:new xf({origin:e.getOrigin(0),extent:o||e.getExtent(),minZoom:s,resolutions:$M.slice(0,u+1),tileSize:512})};Array.isArray(i.tiles)?a.urls=i.tiles:a.url=i.tiles,t.olSourceOptions&&Object.assign(a,t.olSourceOptions),r(new qy(a))})).catch(e)}))}var R_=new Zg;function F_(t,n,i){var r=t.data,e={};if("string"==typeof r){var o=YM(r,i.accessToken,i.accessTokenParam||"access_token",n||location.href);if(i.transformRequest){var s=i.transformRequest(o,"GeoJSON");s instanceof Request&&(o=encodeURI(s.url))}e.url=o}else e.features=R_.readFeatures(r,{featureProjection:Cr()||"EPSG:3857"});var u=new ad(A({attributions:t.attribution,format:R_},e));return u.set("mapbox-source",t),u}var G_=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),D_=function(t){function n(n){var i=t.call(this,z)||this;return i.error=n,i}return G_(n,t),n}(c),q_=function(t){function n(n){var i=this,r=!("declutter"in n)||n.declutter,e=new qy({state:"loading",format:new Lg});i=t.call(this,{source:e,background:n.background,declutter:r,className:n.className,opacity:n.opacity,visible:n.visible,zIndex:n.zIndex,minResolution:n.minResolution,maxResolution:n.maxResolution,minZoom:n.minZoom,maxZoom:n.maxZoom,renderOrder:n.renderOrder,renderBuffer:n.renderBuffer,renderMode:n.renderMode,map:n.map,updateWhileAnimating:n.updateWhileAnimating,updateWhileInteracting:n.updateWhileInteracting,preload:n.preload,useInterimTilesOnError:n.useInterimTilesOnError,properties:n.properties})||this,n.accessToken&&(i.accessToken=n.accessToken);var o=n.styleUrl;return C_(i,o,n.layers||n.source,{accessToken:i.accessToken}).then((function(){e.setState("ready")})).catch((function(t){i.dispatchEvent(new D_(t)),i.getSource().setState("error")})),void 0===i.getBackground()&&function(t,n,i){void 0===i&&(i={}),"object"==typeof n?(N_(t,n),Promise.resolve()):QM(n,i).then((function(n){N_(t,n)}))}(i,n.styleUrl,{accessToken:i.accessToken}),i}return G_(n,t),n}(Rg),U_=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),B_=function(t){function n(n){var i=this,r=n||{},e=A({},r);return delete e.imageRatio,(i=t.call(this,e)||this).lv=void 0!==r.imageRatio?r.imageRatio:1,i}return U_(n,t),n.prototype.getImageRatio=function(){return this.lv},n.prototype.createRenderer=function(){return new qw(this)},n}($m),X_=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),V_=function(t){function n(n){var i=this,r=A({},n);return(i=t.call(this,r)||this).vv=Yl(n.style),i.dv=n.style.variables||{},i.pv=!!n.disableHitDetection,i}return X_(n,t),n.prototype.createRenderer=function(){return new Hm(this,{vertexShader:this.vv.builder.getSymbolVertexShader(),fragmentShader:this.vv.builder.getSymbolFragmentShader(),hitVertexShader:!this.pv&&this.vv.builder.getSymbolVertexShader(!0),hitFragmentShader:!this.pv&&this.vv.builder.getSymbolFragmentShader(!0),uniforms:this.vv.uniforms,attributes:this.vv.attributes})},n.prototype.updateStyleVariables=function(t){A(this.dv,t),this.changed()},n}(ls),W_=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}();function Y_(t,n){var i="\n attribute vec2 ".concat(al.TEXTURE_COORD,";\n uniform mat4 ").concat(ul.TILE_TRANSFORM,";\n uniform float ").concat(ul.TEXTURE_PIXEL_WIDTH,";\n uniform float ").concat(ul.TEXTURE_PIXEL_HEIGHT,";\n uniform float ").concat(ul.TEXTURE_RESOLUTION,";\n uniform float ").concat(ul.TEXTURE_ORIGIN_X,";\n uniform float ").concat(ul.TEXTURE_ORIGIN_Y,";\n uniform float ").concat(ul.DEPTH,";\n\n varying vec2 v_textureCoord;\n varying vec2 v_mapCoord;\n\n void main() {\n v_textureCoord = ").concat(al.TEXTURE_COORD,";\n v_mapCoord = vec2(\n ").concat(ul.TEXTURE_ORIGIN_X," + ").concat(ul.TEXTURE_RESOLUTION," * ").concat(ul.TEXTURE_PIXEL_WIDTH," * v_textureCoord[0],\n ").concat(ul.TEXTURE_ORIGIN_Y," - ").concat(ul.TEXTURE_RESOLUTION," * ").concat(ul.TEXTURE_PIXEL_HEIGHT," * v_textureCoord[1]\n );\n gl_Position = ").concat(ul.TILE_TRANSFORM," * vec4(").concat(al.TEXTURE_COORD,", ").concat(ul.DEPTH,", 1.0);\n }\n "),r={inFragmentShader:!0,variables:[],attributes:[],stringLiteralsMap:{},functions:{},bandCount:n},e=[];if(void 0!==t.color){var o=Cl(r,t.color,wl);e.push("color = ".concat(o,";"))}if(void 0!==t.contrast){var s=Cl(r,t.contrast,yl);e.push("color.rgb = clamp((".concat(s," + 1.0) * color.rgb - (").concat(s," / 2.0), vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0));"))}if(void 0!==t.exposure){var u=Cl(r,t.exposure,yl);e.push("color.rgb = clamp((".concat(u," + 1.0) * color.rgb, vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0));"))}if(void 0!==t.saturation){var a=Cl(r,t.saturation,yl);e.push("\n float saturation = ".concat(a," + 1.0;\n float sr = (1.0 - saturation) * 0.2126;\n float sg = (1.0 - saturation) * 0.7152;\n float sb = (1.0 - saturation) * 0.0722;\n mat3 saturationMatrix = mat3(\n sr + saturation, sr, sr,\n sg, sg + saturation, sg,\n sb, sb, sb + saturation\n );\n color.rgb = clamp(saturationMatrix * color.rgb, vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0));\n "))}if(void 0!==t.gamma){var h=Cl(r,t.gamma,yl);e.push("color.rgb = pow(color.rgb, vec3(1.0 / ".concat(h,"));"))}if(void 0!==t.brightness){var f=Cl(r,t.brightness,yl);e.push("color.rgb = clamp(color.rgb + ".concat(f,", vec3(0.0, 0.0, 0.0), vec3(1.0, 1.0, 1.0));"))}var c={},l=r.variables.length;if(l>1&&!t.variables)throw new Error("Missing variables in style (expected ".concat(r.variables,")"));for(var v=function(n){var i=r.variables[n];if(!(i in t.variables))throw new Error("Missing '".concat(i,"' in style variables"));var e=ql(i);c[e]=function(){var n=t.variables[i];return"string"==typeof n&&(n=Al(r,n)),void 0!==n?n:-9999999}},d=0;d ").concat(ul.RENDER_EXTENT,"[2] ||\n v_mapCoord[1] > ").concat(ul.RENDER_EXTENT,"[3]\n ) {\n discard;\n }\n\n vec4 color = texture2D(").concat(ul.TILE_TEXTURE_ARRAY,"[0], v_textureCoord);\n\n ").concat(e.join("\n"),"\n\n if (color.a == 0.0) {\n discard;\n }\n\n gl_FragColor = color;\n gl_FragColor.rgb *= gl_FragColor.a;\n gl_FragColor *= ").concat(ul.TRANSITION_ALPHA,";\n }"),uniforms:c,paletteTextures:r.paletteTextures}}var Z_=function(t){function n(n){var i=this,r=n?A({},n):{},e=r.style||{};delete r.style;var o=r.cacheSize;return delete r.cacheSize,(i=t.call(this,r)||this).yv=r.sources,i.mv=null,i.Ic=NaN,i.H=e,i.Jt=o,i.dv=i.H.variables||{},i.addChangeListener(ns,i.wv),i}return W_(n,t),n.prototype.getSources=function(t,n){var i=this.getSource();return this.yv?"function"==typeof this.yv?this.yv(t,n):this.yv:i?[i]:[]},n.prototype.getRenderSource=function(){return this.mv||this.getSource()},n.prototype.getSourceState=function(){var t=this.getRenderSource();return t?t.getState():"undefined"},n.prototype.wv=function(){this.getSource()&&this.setStyle(this.H)},n.prototype.gv=function(){var t=Number.MAX_SAFE_INTEGER,n=this.getSources([-t,-t,t,t],t);return n&&n.length&&"bandCount"in n[0]?n[0].bandCount:4},n.prototype.createRenderer=function(){var t=Y_(this.H,this.gv());return new pl(this,{vertexShader:t.vertexShader,fragmentShader:t.fragmentShader,uniforms:t.uniforms,cacheSize:this.Jt,paletteTextures:t.paletteTextures})},n.prototype.renderSources=function(t,n){for(var i,r=this.getRenderer(),e=0,o=n.length;e.5*r.resolution){var f=this.getSources(t.extent,this.Ic).filter((function(t){return!e.includes(t)}));if(f.length>0)return this.renderSources(t,f)}return h},n.prototype.setStyle=function(t){this.dv=t.variables||{},this.H=t;var n=Y_(this.H,this.gv());this.getRenderer().reset({vertexShader:n.vertexShader,fragmentShader:n.fragmentShader,uniforms:n.uniforms,paletteTextures:n.paletteTextures}),this.changed()},n.prototype.updateStyleVariables=function(t){A(this.dv,t),this.changed()},n}(am);Z_.prototype.dispose;var $_=Z_,K_=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),H_="addfeatures",J_=function(t){function n(n,i,r,e){var o=t.call(this,n)||this;return o.features=r,o.file=i,o.projection=e,o}return K_(n,t),n}(c),Q_=function(t){function n(n){var i=this,r=n||{};(i=t.call(this,{handleEvent:S})||this).on,i.once,i.un,i.bv=!1,i.xv=[];for(var e=r.formatConstructors?r.formatConstructors:[],o=0,s=e.length;o0){this._v&&(this._v.clear(),this._v.addFeatures(c)),this.dispatchEvent(new J_(H_,t,c,o));break}}},n.prototype.jv=function(){var t=this.getMap();if(t){var n=this.target?this.target:t.getViewport();this.Mv=[$(n,U,this.handleDrop,this),$(n,D,this.handleStop,this),$(n,q,this.handleStop,this),$(n,U,this.handleStop,this)]}},n.prototype.setActive=function(n){!this.getActive()&&n&&this.jv(),this.getActive()&&!n&&this.Ev(),t.prototype.setActive.call(this,n)},n.prototype.setMap=function(n){this.Ev(),t.prototype.setMap.call(this,n),this.getActive()&&this.jv()},n.prototype.Ov=function(t,n,i){try{return t.readFeatures(n,i)}catch(t){return null}},n.prototype.Ev=function(){this.Mv&&(this.Mv.forEach(H),this.Mv=null)},n.prototype.handleDrop=function(t){for(var n=t.dataTransfer.files,i=0,r=n.length;i1?1:-1;return n.endInteraction(this.Fr,i),this.je=0,!1},n.prototype.handleDownEvent=function(t){return!!La(t)&&(!!this.Zr(t)&&(t.map.getView().beginInteraction(),this.Kr=void 0,this.Tv=void 0,!0))},n}(Ma),iS=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),rS=function(t){function n(n,i,r){var e=t.call(this)||this;if(void 0!==r&&void 0===i)e.setFlatCoordinates(r,n);else{var o=i||0;e.setCenterAndRadius(n,o,r)}return e}return iS(n,t),n.prototype.clone=function(){var t=new n(this.flatCoordinates.slice(),void 0,this.layout);return t.applyProperties(this),t},n.prototype.closestPointXY=function(t,n,i,r){var e=this.flatCoordinates,o=t-e[0],s=n-e[1],u=o*o+s*s;if(u=n[0]||(t[1]<=n[1]&&t[3]>=n[1]||Rn(t,this.intersectsCoordinate.bind(this)))}return!1},n.prototype.setCenter=function(t){var n=this.stride,i=this.flatCoordinates[n]-this.flatCoordinates[0],r=t.slice();r[n]=r[0]+i;for(var e=1;e=this.Uv?(this.Cv=n.pixel,this.Pv=!this.Lv,i=!0):this.Iv=void 0,this.Pv&&void 0!==this.kv&&(clearTimeout(this.kv),this.kv=void 0));return this.Lv&&n.type===su.POINTERDRAG&&null!==this.Xv?(this.Qv(n.coordinate),r=!1):this.Lv&&n.type===su.POINTERDOWN?r=!1:i&&this.getPointerCount()<2?(r=n.type===su.POINTERMOVE)&&this.Lv?(this.Zn(n),this.Pv&&n.originalEvent.preventDefault()):("mouse"===n.originalEvent.pointerType||n.type===su.POINTERDRAG&&void 0===this.kv)&&this.Zn(n):n.type===su.DBLCLICK&&(r=!1),t.prototype.handleEvent.call(this,n)&&r},n.prototype.handleDownEvent=function(t){return this.Pv=!this.Lv,this.Lv?(this.Cv=t.pixel,this.Bv||this.td(t.coordinate),!0):this.Zr(t)?(this.Iv=Date.now(),this.kv=setTimeout(function(){this.Zn(new ou(su.POINTERMOVE,t.map,t.originalEvent,!1,t.frameState))}.bind(this),this.Uv),this.Cv=t.pixel,!0):(this.Iv=void 0,!1)},n.prototype.handleUpEvent=function(t){var n=!0;if(0===this.getPointerCount())if(this.kv&&(clearTimeout(this.kv),this.kv=void 0),this.Zn(t),this.Pv){var i=!this.Bv;i&&this.td(t.coordinate),!i&&this.Lv?this.finishDrawing():this.Lv||i&&this.pe!==sS||(this.rd(t.pixel)?this.Dv(t)&&this.finishDrawing():this.Qv(t.coordinate)),n=!1}else this.Lv&&this.abortDrawing();return!n&&this.Rv&&t.preventDefault(),n},n.prototype.Zn=function(t){if(this.Nv=t.originalEvent.pointerType,this.Cv&&(!this.Lv&&this.Pv||this.Lv&&!this.Pv)){var n=this.Cv,i=t.pixel,r=n[0]-i[0],e=n[1]-i[1],o=r*r+e*e;if(this.Pv=this.Lv?o>this.$v:o<=this.$v,!this.Pv)return}this.Bv?this.ed(t.coordinate):this.od(t.coordinate.slice())},n.prototype.rd=function(t){var n=!1;if(this.Xv){var i=!1,r=[this.Bv],e=this.pe;if(e===sS)n=!0;else if(e===hS)n=2===this.Wv.length;else if(e===uS)i=this.Wv.length>this.Fv;else if(e===aS){var o=this.Wv;i=o[0].length>this.Fv,r=[o[0][0],o[0][o[0].length-2]]}if(i)for(var s=this.getMap(),u=0,a=r.length;u=this.Gv&&(this.Lv?i.pop():n=!0),i.push(t.slice()),this.Bu(i,r,e)):o===aS&&((i=this.Wv[0]).length>=this.Gv&&(this.Lv?i.pop():n=!0),i.push(t.slice()),n&&(this.Bv=i[0]),this.Bu(this.Wv,r,e)),this.od(t.slice()),this.sd(),n&&this.finishDrawing()},n.prototype.removeLastPoint=function(){if(this.Xv){var t,n=this.Xv.getGeometry(),i=this.getMap().getView().getProjection(),r=this.pe;if(r===uS||r===hS){if((t=this.Wv).splice(-2,1),t.length>=2){this.Bv=t[t.length-2].slice();var e=this.Bv.slice();t[t.length-1]=e,this.od(e)}this.Bu(t,n,i),"Polygon"===n.getType()&&this.Yv&&this.ud(n)}else if(r===aS){(t=this.Wv[0]).splice(-2,1);var o=this.Yv.getGeometry();if(t.length>=2){e=t[t.length-2].slice();t[t.length-1]=e,this.od(e)}o.setCoordinates(t),this.Bu(this.Wv,n,i)}1===t.length&&this.abortDrawing(),this.sd()}},n.prototype.finishDrawing=function(){var t=this.ad();if(t){var n=this.Wv,i=t.getGeometry(),r=this.getMap().getView().getProjection();this.pe===uS?(n.pop(),this.Bu(n,i,r)):this.pe===aS&&(n[0].pop(),this.Bu(n,i,r),n=i.getCoordinates()),"MultiPoint"===this.rl?t.setGeometry(new Kw([n])):"MultiLineString"===this.rl?t.setGeometry(new rg([n])):"MultiPolygon"===this.rl&&t.setGeometry(new sg([n])),this.dispatchEvent(new vS(cS,t)),this.Re&&this.Re.push(t),this._v&&this._v.addFeature(t)}},n.prototype.ad=function(){this.Bv=null;var t=this.Xv;return this.Xv=null,this.Vv=null,this.Yv=null,this.Kv.getSource().clear(!0),t},n.prototype.abortDrawing=function(){var t=this.ad();t&&this.dispatchEvent(new vS(lS,t))},n.prototype.appendCoordinates=function(t){var n,i=this.pe,r=!this.Xv;if(r&&this.td(t[0]),i===uS||i===hS)n=this.Wv;else{if(i!==aS)return;n=this.Wv&&this.Wv.length?this.Wv[0]:[]}r&&n.shift(),n.pop();for(var e=0;ec?o[1]:o[0]),s}}return null},n.prototype.Zn=function(t){var n=t.pixel,i=t.map,r=this.wd(n,i);r||(r=i.getCoordinateFromPixelInternal(n)),this.gd(r)},n.prototype.bd=function(t){var n=this.vd;return n?t?n.setGeometry(Ze(t)):n.setGeometry(void 0):(n=new Et(t?Ze(t):{}),this.vd=n,this.yd.getSource().addFeature(n)),n},n.prototype.gd=function(t){var n=this.dd;n?n.getGeometry().setCoordinates(t):(n=new Et(new Se(t)),this.dd=n,this.md.getSource().addFeature(n));return n},n.prototype.handleEvent=function(n){return!n.originalEvent||!this.Zr(n)||(n.type!=su.POINTERMOVE||this.handlingDownUpSequence||this.Zn(n),t.prototype.handleEvent.call(this,n),!1)},n.prototype.handleDownEvent=function(t){var n=t.pixel,i=t.map,r=this.getExtentInternal(),e=this.wd(n,i),o=function(t){var n=null,i=null;return t[0]==r[0]?n=r[2]:t[0]==r[2]&&(n=r[0]),t[1]==r[1]?i=r[3]:t[1]==r[3]&&(i=r[1]),null!==n&&null!==i?[n,i]:null};if(e&&r){var s=e[0]==r[0]||e[0]==r[2]?e[0]:null,u=e[1]==r[1]||e[1]==r[3]?e[1]:null;null!==s&&null!==u?this.hd=gS(o(e)):null!==s?this.hd=bS(o([s,r[1]]),o([s,r[3]])):null!==u&&(this.hd=bS(o([r[0],u]),o([r[2],u])))}else e=i.getCoordinateFromPixelInternal(n),this.setExtent([e[0],e[1],e[0],e[1]]),this.hd=gS(e);return!0},n.prototype.handleDragEvent=function(t){if(this.hd){var n=t.coordinate;this.setExtent(this.hd(n)),this.gd(n)}},n.prototype.handleUpEvent=function(t){this.hd=null;var n=this.getExtentInternal();return n&&0!==Fn(n)||this.setExtent(null),!1},n.prototype.setMap=function(n){this.yd.setMap(n),this.md.setMap(n),t.prototype.setMap.call(this,n)},n.prototype.getExtent=function(){return Nr(this.getExtentInternal(),this.getMap().getView().getProjection())},n.prototype.getExtentInternal=function(){return this.st},n.prototype.setExtent=function(t){this.st=t||null,this.bd(t),this.dispatchEvent(new mS(this.st))},n}(Ma),MS=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}();function _S(t){return parseFloat(t)}function SS(t){return function(t){return pi(t,5)}(t).toString()}function OS(t,n){return!isNaN(t)&&t!==_S(SS(n))}var jS=function(t){function n(n){var i,r=t.call(this)||this,e=A({animate:!0,replace:!1,prefix:""},n||{});return i=!0===e.animate?{duration:250}:e.animate?e.animate:null,r.xd=i,r.Md=e.replace,r._d=e.prefix,r.gn=[],r.Sd=!0,r.Jv=r.Jv.bind(r),r}return MS(n,t),n.prototype.Od=function(t){return this._d?this._d+t:t},n.prototype.jd=function(t,n){return t.get(this.Od(n))},n.prototype.Ed=function(t,n,i){t.set(this.Od(n),i)},n.prototype.Td=function(t,n){t.delete(this.Od(n))},n.prototype.setMap=function(n){var i=this.getMap();t.prototype.setMap.call(this,n),n!==i&&(i&&this.Ev(i),n&&(this.Sd=!0,this.Jv(),this.jv(n)))},n.prototype.jv=function(t){this.gn.push($(t,pu,this.Ad,this),$(t.getLayerGroup(),L,this.Ad,this),$(t,"change:layergroup",this.Pd,this)),this.Md||addEventListener("popstate",this.Jv)},n.prototype.Ev=function(t){for(var n=0,i=this.gn.length;n=0;--r){for(var e=i[r],o=this.qd.length-1;o>=0;--o)this.qd[o][0]===e&&this.qd.splice(o,1);n.remove(e)}},n.prototype.setActive=function(n){this.dd&&!n&&(this.Kv.getSource().removeFeature(this.dd),this.dd=null),t.prototype.setActive.call(this,n)},n.prototype.setMap=function(n){this.Kv.setMap(n),t.prototype.setMap.call(this,n)},n.prototype.getOverlay=function(){return this.Kv},n.prototype.Jd=function(t){t.feature&&this.Re.push(t.feature)},n.prototype.Qd=function(t){t.feature&&this.Re.remove(t.feature)},n.prototype.np=function(t){this.tp(t.element)},n.prototype.$a=function(t){if(!this.Dd){var n=t.target;this.up(n),this.tp(n)}},n.prototype.ip=function(t){var n=t.element;this.up(n)},n.prototype.Bd=function(t,n){var i=n.getCoordinates(),r={feature:t,geometry:n,segment:[i,i]};this.Gd.insert(n.getExtent(),r)},n.prototype.Wd=function(t,n){for(var i=n.getCoordinates(),r=0,e=i.length;r=0;--m)this.cp(e[m],s)}return!!this.dd},n.prototype.handleUpEvent=function(t){for(var n=this.qd.length-1;n>=0;--n){var i=this.qd[n][0],r=i.geometry;if("Circle"===r.getType()){var e=r.getCenter(),o=i.featureSegments[0],s=i.featureSegments[1];o.segment[0]=e,o.segment[1]=e,s.segment[0]=e,s.segment[1]=e,this.Gd.update(En(e),o);var u=r,a=Cr();if(a){var h=t.map.getView().getProjection();u=$e(u=u.clone().transform(a,h)).transform(h,a)}this.Gd.update(u.getExtent(),s)}else this.Gd.update(yn(i.segment),i)}return this.Fd&&(this.dispatchEvent(new kS(CS,this.Fd,t)),this.Fd=null),!1},n.prototype.Zn=function(t){this.zd=t.pixel,this.op(t.pixel,t.map,t.coordinate)},n.prototype.op=function(t,n,i){var r,e,s=this,u=i||n.getCoordinateFromPixel(t),a=n.getView().getProjection();if(this.Hd){var h="object"==typeof this.Hd?function(t){return t===s.Hd}:void 0;n.forEachFeatureAtPixel(t,(function(t,n,i){if("Point"===(i=i||t.getGeometry()).getType()&&y(s.Re.getArray(),t)){e=i;var o=i.getFlatCoordinates().slice(0,2);r=[{feature:t,geometry:i,segment:[o,o]}]}return!0}),{layerFilter:h})}if(!r){var f=Nr(mn(Lr(En(u,TS),a),n.getView().getResolution()*this.fd,TS),a);r=this.Gd.getInExtent(f)}if(r&&r.length>0){var c=r.sort((function(t,n){return NS(u,t,a)-NS(u,n,a)}))[0],l=c.segment,v=LS(u,c,a),d=n.getPixelFromCoordinate(v),p=tr(t,d);if(e||p<=this.fd){var m={};if(m[o(l)]=!0,this.ep||(this.Br[0]=v[0]-u[0],this.Br[1]=v[1]-u[1]),"Circle"===c.geometry.getType()&&1===c.index)this.ld=!0,this.hp(v,[c.feature],[c.geometry]);else{var w=n.getPixelFromCoordinate(l[0]),g=n.getPixelFromCoordinate(l[1]),b=Qi(d,w),x=Qi(d,g);p=Math.sqrt(Math.min(b,x)),this.ld=p<=this.fd,this.ld&&(v=b>x?l[1]:l[0]),this.hp(v,[c.feature],[c.geometry]);var M={};M[o(c.geometry)]=!0;for(var _=1,S=r.length;_=0;--e)c=o((f=(i=l[e])[0]).feature),f.depth&&(c+="-"+f.depth.join("-")),c in v||(v[c]={}),0===i[1]?(v[c].right=f,v[c].index=f.index):1==i[1]&&(v[c].left=f,v[c].index=f.index+1);for(c in v){switch(h=v[c].right,u=v[c].left,(a=(s=v[c].index)-1)<0&&(a=0),t=n=(r=(f=void 0!==u?u:h).geometry).getCoordinates(),d=!1,r.getType()){case"MultiLineString":n[f.depth[0]].length>2&&(n[f.depth[0]].splice(s,1),d=!0);break;case"LineString":n.length>2&&(n.splice(s,1),d=!0);break;case"MultiPolygon":t=t[f.depth[1]];case"Polygon":(t=t[f.depth[0]]).length>4&&(s==t.length-1&&(s=0),t.splice(s,1),d=!0,0===s&&(t.pop(),t.push(t[0]),a=t.length-1))}if(d){this.fp(r,n);var p=[];if(void 0!==u&&(this.Gd.remove(u),p.push(u.segment[0])),void 0!==h&&(this.Gd.remove(h),p.push(h.segment[1])),void 0!==u&&void 0!==h){var y={depth:f.depth,feature:f.feature,geometry:f.geometry,index:a,segment:p};this.Gd.insert(yn(y.segment),y)}this.lp(r,s,f.depth,-1),this.dd&&(this.Kv.getSource().removeFeature(this.dd),this.dd=null),l.length=0}}return d},n.prototype.fp=function(t,n){this.Dd=!0,t.setCoordinates(n),this.Dd=!1},n.prototype.lp=function(t,n,i,r){this.Gd.forEachInExtent(t.getExtent(),(function(e){e.geometry===t&&(void 0===i||void 0===e.depth||x(e.depth,i))&&e.index>n&&(e.index+=r)}))},n}(Ma),RS=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),FS="select",GS=function(t){function n(n,i,r,e){var o=t.call(this,n)||this;return o.selected=i,o.deselected=r,o.mapBrowserEvent=e,o}return RS(n,t),n}(c),DS={};var qS=function(t){function n(n){var i=t.call(this)||this;i.on,i.once,i.un;var r,e,o=n||{};if(i.dp=i.tp.bind(i),i.pp=i.up.bind(i),i.Zr=o.condition?o.condition:Ca,i.yp=o.addCondition?o.addCondition:Pa,i.mp=o.removeCondition?o.removeCondition:Pa,i.wp=o.toggleCondition?o.toggleCondition:Ia,i.gp=!!o.multi&&o.multi,i.bp=o.filter?o.filter:S,i.xp=o.hitTolerance?o.hitTolerance:0,i.H=void 0!==o.style?o.style:(g((r=Mv()).Polygon,r.LineString),g(r.GeometryCollection,r.LineString),function(t){return t.getGeometry()?r[t.getGeometry().getType()]:null}),i.Re=o.features||new ft,o.layers)if("function"==typeof o.layers)e=o.layers;else{var s=o.layers;e=function(t){return y(s,t)}}else e=S;return i.Mp=e,i._p={},i}return RS(n,t),n.prototype.Sp=function(t,n){this._p[o(t)]=n},n.prototype.getFeatures=function(){return this.Re},n.prototype.getHitTolerance=function(){return this.xp},n.prototype.getLayer=function(t){return this._p[o(t)]},n.prototype.setHitTolerance=function(t){this.xp=t},n.prototype.setMap=function(n){this.getMap()&&this.H&&this.Re.forEach(this.Op.bind(this)),t.prototype.setMap.call(this,n),n?(this.Re.addEventListener(ot,this.dp),this.Re.addEventListener(st,this.pp),this.H&&this.Re.forEach(this.jp.bind(this))):(this.Re.removeEventListener(ot,this.dp),this.Re.removeEventListener(st,this.pp))},n.prototype.tp=function(t){var n=t.element;if(this.H&&this.jp(n),!this.getLayer(n)){var i=this.getMap().getAllLayers().find((function(t){if(t instanceof lg&&t.getSource()&&t.getSource().hasFeature(n))return t}));i&&this.Sp(n,i)}},n.prototype.up=function(t){var n=t.element;this.H&&this.Op(n)},n.prototype.getStyle=function(){return this.H},n.prototype.jp=function(t){var n=o(t);n in DS||(DS[n]=t.getStyle()),t.setStyle(this.H)},n.prototype.Op=function(t){for(var i=this.getMap().getInteractions().getArray(),r=i.length-1;r>=0;--r){var e=i[r];if(e!==this&&e instanceof n&&e.getStyle()&&-1!==e.getFeatures().getArray().lastIndexOf(t))return void t.setStyle(e.getStyle())}var s=o(t);t.setStyle(DS[s]),delete DS[s]},n.prototype.Ep=function(t){delete this._p[o(t)]},n.prototype.handleEvent=function(t){if(!this.Zr(t))return!0;var n=this.yp(t),i=this.mp(t),r=this.wp(t),e=!n&&!i&&!r,o=t.map,s=this.getFeatures(),u=[],a=[];if(e){P(this._p),o.forEachFeatureAtPixel(t.pixel,function(t,n){if(this.bp(t,n))return this.Sp(t,n),a.push(t),!this.gp}.bind(this),{layerFilter:this.Mp,hitTolerance:this.xp});for(var h=s.getLength()-1;h>=0;--h){var f=s.item(h),c=a.indexOf(f);c>-1?a.splice(c,1):(s.remove(f),u.push(f))}0!==a.length&&s.extend(a)}else{o.forEachFeatureAtPixel(t.pixel,function(t,e){if(this.bp(t,e))return!n&&!r||y(s.getArray(),t)?(i||r)&&y(s.getArray(),t)&&(u.push(t),this.Ep(t)):(this.Sp(t,e),a.push(t)),!this.gp}.bind(this),{layerFilter:this.Mp,hitTolerance:this.xp});for(var l=u.length-1;l>=0;--l)s.remove(u[l]);s.extend(a)}return(a.length>0||u.length>0)&&this.dispatchEvent(new GS(FS,a,u,t)),!0},n}(ma),US=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}();function BS(t){return t.feature?t.feature:t.element?t.element:void 0}var XS=[],VS=function(t){function n(n){var i=this,r=n||{},e=r;return e.handleDownEvent||(e.handleDownEvent=S),e.stopDown||(e.stopDown=O),(i=t.call(this,e)||this)._v=r.source?r.source:null,i.Tp=void 0===r.vertex||r.vertex,i.Ap=void 0===r.edge||r.edge,i.Re=r.features?r.features:null,i.Pp=[],i.Cp={},i.kp={},i.Ip={},i.fd=void 0!==r.pixelTolerance?r.pixelTolerance:10,i.Gd=new Pv,i.Np={Point:i.Lp.bind(i),LineString:i.zp.bind(i),LinearRing:i.zp.bind(i),Polygon:i.Rp.bind(i),MultiPoint:i.Fp.bind(i),MultiLineString:i.Gp.bind(i),MultiPolygon:i.Dp.bind(i),GeometryCollection:i.qp.bind(i),Circle:i.Up.bind(i)},i}return US(n,t),n.prototype.addFeature=function(t,n){var i=void 0===n||n,r=o(t),e=t.getGeometry();if(e){var s=this.Np[e.getType()];if(s){this.kp[r]=e.getExtent([1/0,1/0,-1/0,-1/0]);var u=[];if(s(u,e),1===u.length)this.Gd.insert(yn(u[0]),{feature:t,segment:u[0]});else if(u.length>1){var a=u.map((function(t){return yn(t)})),h=u.map((function(n){return{feature:t,segment:n}}));this.Gd.load(a,h)}}}i&&(this.Cp[r]=$(t,L,this.$a,this))},n.prototype.Bp=function(t){this.addFeature(t)},n.prototype.Xp=function(t){this.removeFeature(t)},n.prototype.Vp=function(){var t;return this.Re?t=this.Re:this._v&&(t=this._v.getFeatures()),t},n.prototype.handleEvent=function(n){var i=this.snapTo(n.pixel,n.coordinate,n.map);return i&&(n.coordinate=i.vertex.slice(0,2),n.pixel=i.vertexPixel),t.prototype.handleEvent.call(this,n)},n.prototype.np=function(t){var n=BS(t);this.addFeature(n)},n.prototype.ip=function(t){var n=BS(t);this.removeFeature(n)},n.prototype.$a=function(t){var n=t.target;if(this.handlingDownUpSequence){var i=o(n);i in this.Ip||(this.Ip[i]=n)}else this.Wp(n)},n.prototype.handleUpEvent=function(t){var n=C(this.Ip);return n.length&&(n.forEach(this.Wp.bind(this)),this.Ip={}),!1},n.prototype.removeFeature=function(t,n){var i=void 0===n||n,r=o(t),e=this.kp[r];if(e){var s=this.Gd,u=[];s.forEachInExtent(e,(function(n){t===n.feature&&u.push(n)}));for(var a=u.length-1;a>=0;--a)s.remove(u[a])}i&&(H(this.Cp[r]),delete this.Cp[r])},n.prototype.setMap=function(n){var i=this.getMap(),r=this.Pp,e=this.Vp();i&&(r.forEach(H),r.length=0,e.forEach(this.Xp.bind(this))),t.prototype.setMap.call(this,n),n&&(this.Re?r.push($(this.Re,ot,this.np,this),$(this.Re,st,this.ip,this)):this._v&&r.push($(this._v,Qv,this.np,this),$(this._v,id,this.ip,this)),e.forEach(this.Bp.bind(this)))},n.prototype.snapTo=function(t,n,i){var r=yn([i.getCoordinateFromPixel([t[0]-this.fd,t[1]+this.fd]),i.getCoordinateFromPixel([t[0]+this.fd,t[1]-this.fd])]),e=this.Gd.getInExtent(r),o=e.length;if(0===o)return null;var s,u=i.getView().getProjection(),a=Ir(n,u),h=1/0,f=this.fd*this.fd,c=function(){if(s){var n=i.getPixelFromCoordinate(s);if(Qi(t,n)<=f)return{vertex:s,vertexPixel:[Math.round(n[0]),Math.round(n[1])]}}return null};if(this.Tp){for(var l=0;l=0;s--)e.push(r[o][s]);return{hasZ:i.hasZ,hasM:i.hasM,rings:e}}};function iO(t,n){var i,r,e;if(!t)return null;if("number"==typeof t.x&&"number"==typeof t.y)e="Point";else if(t.points)e="MultiPoint";else if(t.paths){e=1===t.paths.length?"LineString":"MultiLineString"}else if(t.rings){var o=t,s=rO(o),u=function(t,n){var i,r,e=[],o=[],s=[];for(i=0,r=t.length;i=0;i--){var h=o[i][0];if(xn(new Me(h).getExtent(),new Me(u).getExtent())){o[i].push(u),a=!0;break}}a||o.push([u.reverse()])}return o}(o.rings,s);1===u.length?(e="Polygon",t=A({},t,((i={}).rings=u[0],i))):(e="MultiPolygon",t=A({},t,((r={}).rings=u,r)))}return Eg((0,tO[e])(t),!1,n)}function rO(t){var n=Tt;return!0===t.hasZ&&!0===t.hasM?n=Ct:!0===t.hasZ?n=At:!0===t.hasM&&(n=Pt),n}function eO(t){var n=t.getLayout();return{hasZ:n===At||n===Ct,hasM:n===Pt||n===Ct}}function oO(t,n){return(0,nO[t.getType()])(Eg(t,!0,n),n)}var sO=function(t){function n(n){var i=this,r=n||{};return(i=t.call(this)||this).K=r.geometryName,i}return QS(n,t),n.prototype.readFeatureFromObject=function(t,n,i){var r=t,e=iO(r.geometry,n),o=new Et;if(this.K&&o.setGeometryName(this.K),o.setGeometry(e),r.attributes){o.setProperties(r.attributes,!0);var s=r.attributes[i];void 0!==s&&o.setId(s)}return o},n.prototype.readFeaturesFromObject=function(t,n){var i=n||{};if(t.features){for(var r=[],e=t.features,o=0,s=e.length;o0?i[0]:null},n.prototype.readFeatureFromNode=function(t,n){return null},n.prototype.readFeatures=function(t,n){if(t){if("string"==typeof t){var i=$f(t);return this.readFeaturesFromDocument(i,n)}return Yf(t)?this.readFeaturesFromDocument(t,n):this.readFeaturesFromNode(t,n)}return[]},n.prototype.readFeaturesFromDocument=function(t,n){for(var i=[],r=t.firstChild;r;r=r.nextSibling)r.nodeType==Node.ELEMENT_NODE&&g(i,this.readFeaturesFromNode(r,n));return i},n.prototype.readFeaturesFromNode=function(t,n){return r()},n.prototype.readGeometry=function(t,n){if(t){if("string"==typeof t){var i=$f(t);return this.readGeometryFromDocument(i,n)}return Yf(t)?this.readGeometryFromDocument(t,n):this.readGeometryFromNode(t,n)}return null},n.prototype.readGeometryFromDocument=function(t,n){return null},n.prototype.readGeometryFromNode=function(t,n){return null},n.prototype.readProjection=function(t){if(t){if("string"==typeof t){var n=$f(t);return this.readProjectionFromDocument(n)}return Yf(t)?this.readProjectionFromDocument(t):this.readProjectionFromNode(t)}return null},n.prototype.readProjectionFromDocument=function(t){return this.dataProjection},n.prototype.readProjectionFromNode=function(t){return this.dataProjection},n.prototype.writeFeature=function(t,n){var i=this.writeFeatureNode(t,n);return this.Jp.serializeToString(i)},n.prototype.writeFeatureNode=function(t,n){return null},n.prototype.writeFeatures=function(t,n){var i=this.writeFeaturesNode(t,n);return this.Jp.serializeToString(i)},n.prototype.writeFeaturesNode=function(t,n){return null},n.prototype.writeGeometry=function(t,n){var i=this.writeGeometryNode(t,n);return this.Jp.serializeToString(i)},n.prototype.writeGeometryNode=function(t,n){return null},n}(jg),hO=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),fO="http://www.opengis.net/gml",cO=/^[\s\xa0]*$/,lO=function(t){function n(n){var i=t.call(this)||this,r=n||{};return i.featureType=r.featureType,i.featureNS=r.featureNS,i.srsName=r.srsName,i.schemaLocation="",i.FEATURE_COLLECTION_PARSERS={},i.FEATURE_COLLECTION_PARSERS[i.namespace]={featureMember:Hf(i.readFeaturesInternal),featureMembers:Jf(i.readFeaturesInternal)},i.supportedMediaTypes=["application/gml+xml"],i}return hO(n,t),n.prototype.readFeaturesInternal=function(t,n){var i=t.localName,r=null;if("FeatureCollection"==i)r=ac([],this.FEATURE_COLLECTION_PARSERS,t,n,this);else if("featureMembers"==i||"featureMember"==i||"member"==i){var e=n[0],o=e.featureType,s=e.featureNS;if(!o&&t.childNodes){o=[],s={};for(var u=0,a=t.childNodes.length;u0){s={Qp:s};for(var h=0;h0;else{var c=f.getType();u="Point"===c||"MultiPoint"===c}}u&&(a=o.get("name"),(u=u&&!!a)&&a.search(/&[^&]+;/)>-1&&(eE||(eE=document.createElement("textarea")),eE.innerHTML=a,a=eE.value));var l=i;if(t?l=t:n&&(l=hE(n,i,r)),u){var v=function(t,n){var i=[0,0],r="start",e=t.getImage();if(e){var o=e.getSize();if(o&&2==o.length){var s=e.getScaleArray(),u=e.getAnchor();i[0]=s[0]*(o[0]-u[0]),i[1]=s[1]*(o[1]/2-u[1]),r="left"}}var a=t.getText();a?((a=a.clone()).setFont(a.getFont()||iE.getFont()),a.setScale(a.getScale()||iE.getScale()),a.setFill(a.getFill()||iE.getFill()),a.setStroke(a.getStroke()||tE)):a=iE.clone();return a.setText(n),a.setOffsetX(i[0]),a.setOffsetY(i[1]),a.setTextAlign(r),new Sv({image:e,text:a})}(l[0],a);return h.length>0?(v.setGeometry(new Dg(h)),[v,new Sv({geometry:l[0].getGeometry(),image:null,fill:l[0].getFill(),stroke:l[0].getStroke(),text:null})].concat(l.slice(1))):v}return l}}(i.Style,i.styleUrl,this.jy,this.Ay,this.Py);r.setStyle(u)}return delete i.Style,r.setProperties(i,!0),r}},n.prototype.Ny=function(t,n){var i=t.getAttribute("id");if(null!==i){var r=FE.call(this,t,n);if(r){var e=void 0,o=t.baseURI;if(o&&"about:blank"!=o||(o=window.location.href),o)e=new URL("#"+i,o).href;else e="#"+i;this.Ay[e]=r}}},n.prototype.Ly=function(t,n){var i=t.getAttribute("id");if(null!==i){var r=yE.call(this,t,n);if(r){var e,o=t.baseURI;if(o&&"about:blank"!=o||(o=window.location.href),o)e=new URL("#"+i,o).href;else e="#"+i;this.Ay[e]=r}}},n.prototype.readFeatureFromNode=function(t,n){if(!y(Bj,t.namespaceURI))return null;var i=this.Iy(t,[this.getReadOptions(t,n)]);return i||null},n.prototype.readFeaturesFromNode=function(t,n){if(!y(Bj,t.namespaceURI))return[];var i,r=t.localName;if("Document"==r||"Folder"==r)return(i=this.ky(t,[this.getReadOptions(t,n)]))||[];if("Placemark"==r){var e=this.Iy(t,[this.getReadOptions(t,n)]);return e?[e]:[]}if("kml"==r){i=[];for(var o=t.firstElementChild;o;o=o.nextElementSibling){var s=this.readFeaturesFromNode(o,n);s&&g(i,s)}return i}return[]},n.prototype.readName=function(t){if(t){if("string"==typeof t){var n=$f(t);return this.readNameFromDocument(n)}return Yf(t)?this.readNameFromDocument(t):this.readNameFromNode(t)}},n.prototype.readNameFromDocument=function(t){for(var n=t.firstChild;n;n=n.nextSibling)if(n.nodeType==Node.ELEMENT_NODE){var i=this.readNameFromNode(n);if(i)return i}},n.prototype.readNameFromNode=function(t){for(var n=t.firstElementChild;n;n=n.nextElementSibling)if(y(Bj,n.namespaceURI)&&"name"==n.localName)return xO(n);for(n=t.firstElementChild;n;n=n.nextElementSibling){var i=n.localName;if(y(Bj,n.namespaceURI)&&("Document"==i||"Folder"==i||"Placemark"==i||"kml"==i)){var r=this.readNameFromNode(n);if(r)return r}}},n.prototype.readNetworkLinks=function(t){var n=[];if("string"==typeof t){var i=$f(t);g(n,this.readNetworkLinksFromDocument(i))}else Yf(t)?g(n,this.readNetworkLinksFromDocument(t)):g(n,this.readNetworkLinksFromNode(t));return n},n.prototype.readNetworkLinksFromDocument=function(t){for(var n=[],i=t.firstChild;i;i=i.nextSibling)i.nodeType==Node.ELEMENT_NODE&&g(n,this.readNetworkLinksFromNode(i));return n},n.prototype.readNetworkLinksFromNode=function(t){for(var n=[],i=t.firstElementChild;i;i=i.nextElementSibling)if(y(Bj,i.namespaceURI)&&"NetworkLink"==i.localName){var r=ac({},Wj,i,[]);n.push(r)}for(i=t.firstElementChild;i;i=i.nextElementSibling){var e=i.localName;!y(Bj,i.namespaceURI)||"Document"!=e&&"Folder"!=e&&"kml"!=e||g(n,this.readNetworkLinksFromNode(i))}return n},n.prototype.readRegion=function(t){var n=[];if("string"==typeof t){var i=$f(t);g(n,this.readRegionFromDocument(i))}else Yf(t)?g(n,this.readRegionFromDocument(t)):g(n,this.readRegionFromNode(t));return n},n.prototype.readRegionFromDocument=function(t){for(var n=[],i=t.firstChild;i;i=i.nextSibling)i.nodeType==Node.ELEMENT_NODE&&g(n,this.readRegionFromNode(i));return n},n.prototype.readRegionFromNode=function(t){for(var n=[],i=t.firstElementChild;i;i=i.nextElementSibling)if(y(Bj,i.namespaceURI)&&"Region"==i.localName){var r=ac({},Zj,i,[]);n.push(r)}for(i=t.firstElementChild;i;i=i.nextElementSibling){var e=i.localName;!y(Bj,i.namespaceURI)||"Document"!=e&&"Folder"!=e&&"kml"!=e||g(n,this.readRegionFromNode(i))}return n},n.prototype.writeFeaturesNode=function(t,n){n=this.adaptOptions(n);var i=Xf(Bj[4],"kml"),r="http://www.w3.org/2000/xmlns/";i.setAttributeNS(r,"xmlns:gx",Uj[0]),i.setAttributeNS(r,"xmlns:xsi",Bf),i.setAttributeNS(Bf,"xsi:schemaLocation","http://www.opengis.net/kml/2.2 https://developers.google.com/kml/schema/kml22gx.xsd");var e={node:i},o={};t.length>1?o.Document=t:1==t.length&&(o.Placemark=t[0]);var s=$j[i.namespaceURI],u=oc(o,s);return fc(e,Kj,ec,u,[n],s,this),i},n}(aO);function hE(t,n,i){return Array.isArray(t)?t:"string"==typeof t?hE(i[t],n,i):n}function fE(t){var n=Vf(t,!1),i=/^\s*#?\s*([0-9A-Fa-f]{8})\s*$/.exec(n);if(i){var r=i[1];return[parseInt(r.substr(6,2),16),parseInt(r.substr(4,2),16),parseInt(r.substr(2,2),16),parseInt(r.substr(0,2),16)/255]}}function cE(t){var n=Vf(t,!1),i=[];n=n.replace(/\s*,\s*/g,",");for(var r,e=/^\s*([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?),([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?)(?:\s+|,|$)(?:([+\-]?\d*\.?\d+(?:e[+\-]?\d+)?)(?:\s+|$))?\s*/i;r=e.exec(n);){var o=parseFloat(r[1]),s=parseFloat(r[2]),u=r[3]?parseFloat(r[3]):0;i.push(o,s,u),n=n.substr(r[0].length)}if(""===n)return i}function lE(t){var n=Vf(t,!1).trim(),i=t.baseURI;return i&&"about:blank"!=i||(i=window.location.href),i?new URL(n,i).href:n}function vE(t){var n=Vf(t,!1).trim().replace(/^(?!.*#)/,"#"),i=t.baseURI;return i&&"about:blank"!=i||(i=window.location.href),i?new URL(n,i).href:n}function dE(t){return mO(t)}var pE=sc(Bj,{Pair:function(t,n){var i=ac({},XE,t,n,this);if(!i)return;var r=i.key;if(r&&"normal"==r){var e=i.styleUrl;e&&(n[n.length-1]=e);var o=i.Style;o&&(n[n.length-1]=o)}}});function yE(t,n){return ac(void 0,pE,t,n,this)}var mE=sc(Bj,{Icon:tc((function(t,n){var i=ac({},jE,t,n);return i||null})),color:tc(fE),heading:tc(mO),hotSpot:tc((function(t){var n,i=t.getAttribute("xunits"),r=t.getAttribute("yunits");return n="insetPixels"!==i?"insetPixels"!==r?sv:av:"insetPixels"!==r?uv:hv,{x:parseFloat(t.getAttribute("x")),xunits:Xj[i],y:parseFloat(t.getAttribute("y")),yunits:Xj[r],origin:n}})),scale:tc(dE)});var wE=sc(Bj,{color:tc(fE),scale:tc(dE)});var gE=sc(Bj,{color:tc(fE),width:tc(mO)});var bE=sc(Bj,{color:tc(fE),fill:tc(dO),outline:tc(dO)});var xE=sc(Bj,{coordinates:Jf(cE)});function ME(t,n){return ac(null,xE,t,n)}var _E=sc(Uj,{Track:Hf(OE)});var SE=sc(Bj,{when:function(t,n){var i=n[n.length-1].whens,r=Vf(t,!1),e=Date.parse(r);i.push(isNaN(e)?0:e)}},sc(Uj,{coord:function(t,n){var i=n[n.length-1].coordinates,r=Vf(t,!1),e=/^\s*([+\-]?\d+(?:\.\d*)?(?:e[+\-]?\d*)?)\s+([+\-]?\d+(?:\.\d*)?(?:e[+\-]?\d*)?)\s+([+\-]?\d+(?:\.\d*)?(?:e[+\-]?\d*)?)\s*$/i.exec(r);if(e){var o=parseFloat(e[1]),s=parseFloat(e[2]),u=parseFloat(e[3]);i.push([o,s,u])}else i.push([])}}));function OE(t,n){var i=ac({coordinates:[],whens:[]},SE,t,n);if(i){for(var r=[],e=i.coordinates,o=i.whens,s=0,u=Math.min(e.length,o.length);s0){var r=n[n.length-1];r.push.apply(r,i)}},outerBoundaryIs:function(t,n){var i=ac(void 0,$E,t,n);if(i){n[n.length-1][0]=i}}});function zE(t,n){var i=ac({},AE,t,n),r=ac([null],LE,t,n);if(r&&r[0]){for(var e=r[0],o=[e.length],s=1,u=r.length;s0,f=a.href;f?r=f:h&&(r=Pj);var c,l=sv,v=i.hotSpot;v?(e=[v.x,v.y],o=v.xunits,s=v.yunits,l=v.origin):/^http:\/\/maps\.(?:google|gstatic)\.com\//.test(r)&&(/pushpin/.test(r)?(e=jj,o=Ej,s=Tj):/arrow-reverse/.test(r)?(e=[54,42],o=Ej,s=Tj):/paddle/.test(r)&&(e=[32,1],o=Ej,s=Tj));var d,p=a.x,y=a.y;void 0!==p&&void 0!==y&&(c=[p,y]);var m,w=a.w,g=a.h;void 0!==w&&void 0!==g&&(d=[w,g]);var b=i.heading;void 0!==b&&(m=li(b));var x=i.scale,M=i.color;if(h){r==Pj&&(d=Aj);var _=new yv({anchor:e,anchorOrigin:l,anchorXUnits:o,anchorYUnits:s,crossOrigin:this.Bt,offset:c,offsetOrigin:sv,rotation:m,scale:x,size:d,src:this.Cy(r),color:M}),S=_.getScaleArray()[0],O=_.getSize();if(null===O){var j=_.getImageState();if(j===lo||j===vo){var E=function(){var t=_.getImageState();if(t!==lo&&t!==vo){var n=_.getSize();if(n&&2==n.length){var i=sE(n);_.setScale(S*i)}_.unlistenImageChange(E)}};_.listenImageChange(E),j===lo&&_.load()}}else if(2==O.length){var T=sE(O);_.setScale(S*T)}u.imageStyle=_}else u.imageStyle=Jj}},LabelStyle:function(t,n){var i=ac({},wE,t,n);if(i){var r=n[n.length-1],e=new Ev({fill:new rv({color:"color"in i?i.color:Oj}),scale:i.scale});r.textStyle=e}},LineStyle:function(t,n){var i=ac({},gE,t,n);if(i){var r=n[n.length-1],e=new mv({color:"color"in i?i.color:Oj,width:"width"in i?i.width:1});r.strokeStyle=e}},PolyStyle:function(t,n){var i=ac({},bE,t,n);if(i){var r=n[n.length-1],e=new rv({color:"color"in i?i.color:Oj});r.fillStyle=e;var o=i.fill;void 0!==o&&(r.fill=o);var s=i.outline;void 0!==s&&(r.outline=s)}}});function FE(t,n){var i=ac({},RE,t,n,this);if(!i)return null;var r,e="fillStyle"in i?i.fillStyle:Hj,o=i.fill;void 0===o||o||(e=null),"imageStyle"in i?i.imageStyle!=Jj&&(r=i.imageStyle):r=Qj;var s="textStyle"in i?i.textStyle:iE,u="strokeStyle"in i?i.strokeStyle:nE,a=i.outline;return void 0===a||a?[new Sv({fill:e,image:r,stroke:u,text:s,zIndex:void 0})]:[new Sv({geometry:function(t){var n=t.getGeometry(),i=n.getType();return"GeometryCollection"===i?new Dg(n.getGeometriesArrayRecursive().filter((function(t){var n=t.getType();return"Polygon"!==n&&"MultiPolygon"!==n}))):"Polygon"!==i&&"MultiPolygon"!==i?n:void 0},fill:e,image:r,stroke:u,text:s,zIndex:void 0}),new Sv({geometry:function(t){var n=t.getGeometry(),i=n.getType();return"GeometryCollection"===i?new Dg(n.getGeometriesArrayRecursive().filter((function(t){var n=t.getType();return"Polygon"===n||"MultiPolygon"===n}))):"Polygon"===i||"MultiPolygon"===i?n:void 0},fill:e,stroke:null,zIndex:void 0})]}function GE(t,n){var i,r,e,o=n.length,s=new Array(n.length),u=new Array(n.length),a=new Array(n.length);i=!1,r=!1,e=!1;for(var h=0;h0){var m=oc(e,s);fc(r,bT,MT,[{names:s,values:m}],i)}var w=i[0],g=n.getGeometry();g&&(g=Eg(g,!0,w)),fc(r,bT,cT,[g],i)}var ST=sc(Bj,["extrude","tessellate","altitudeMode","coordinates"]),OT=sc(Bj,{extrude:nc(MO),tessellate:nc(MO),altitudeMode:nc(EO),coordinates:nc((function(t,n,i){var r,e=i[i.length-1],o=e.layout,s=e.stride;o==Tt||o==Pt?r=2:o==At||o==Ct?r=3:St(!1,34);var u=n.length,a="";if(u>0){a+=n[0];for(var h=1;h>1):e>>1}return n}function wA(t){for(var n="",i=0,r=t.length;i=32;)n=63+(32|31&t),i+=String.fromCharCode(n),t>>=5;return n=t+63,i+=String.fromCharCode(n)}var xA=function(t){function n(n){var i=t.call(this)||this,r=n||{};return i.dataProjection=yr("EPSG:4326"),i.zy=r.factor?r.factor:1e5,i.qv=r.geometryLayout?r.geometryLayout:Tt,i}return cA(n,t),n.prototype.readFeatureFromText=function(t,n){var i=this.readGeometryFromText(t,n);return new Et(i)},n.prototype.readFeaturesFromText=function(t,n){return[this.readFeatureFromText(t,n)]},n.prototype.readGeometryFromText=function(t,n){var i=Zr(this.qv),r=vA(t,i,this.zy);JS(r,0,r.length,i,r);var e=pe(r,0,r.length,i);return Eg(new ng(e,this.qv),!1,this.adaptOptions(n))},n.prototype.writeFeatureText=function(t,n){var i=t.getGeometry();return i?this.writeGeometryText(i,n):(St(!1,40),"")},n.prototype.writeFeaturesText=function(t,n){return this.writeFeatureText(t[0],n)},n.prototype.writeGeometryText=function(t,n){var i=(t=Eg(t,!0,this.adaptOptions(n))).getFlatCoordinates(),r=t.getStride();return JS(i,0,i.length,r,i),lA(i,r,this.zy)},n}(Cj),MA=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),_A=function(t){function n(n){var i=t.call(this)||this,r=n||{};return i.iv=r.layerName,i.Uh=r.layers?r.layers:null,i.dataProjection=yr(r.dataProjection?r.dataProjection:"EPSG:4326"),i}return MA(n,t),n.prototype.readFeaturesFromObject=function(t,n){if("Topology"==t.type){var i=t,r=void 0,e=null,o=null;i.transform&&(e=(r=i.transform).scale,o=r.translate);var s=i.arcs;r&&function(t,n,i){for(var r=0,e=t.length;r0&&r.pop(),i>=0)for(var s=0,u=(a=n[i]).length;s=0;--s)r.push(a[s].slice(0))}return r}function jA(t,n,i,r,e,o,s){for(var u=t.geometries,a=[],h=0,f=u.length;h=2,57),r}return kA(n,t),n}(CA),NA=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),LA=function(t){function n(n){return t.call(this,"And",Array.prototype.slice.call(arguments))||this}return NA(n,t),n}(IA),zA=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),RA=function(t){function n(n,i,r){var e=t.call(this,"BBOX")||this;if(e.geometryName=n,e.extent=i,4!==i.length)throw new Error("Expected an extent with four values ([minX, minY, maxX, maxY])");return e.srsName=r,e}return zA(n,t),n}(CA),FA=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),GA=function(t){function n(n,i,r,e){var o=t.call(this,n)||this;return o.geometryName=i||"the_geom",o.geometry=r,o.srsName=e,o}return FA(n,t),n}(CA),DA=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),qA=function(t){function n(n,i,r){return t.call(this,"Contains",n,i,r)||this}return DA(n,t),n}(GA),UA=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),BA=function(t){function n(n,i,r,e,o){var s=t.call(this,"DWithin",n,i,o)||this;return s.distance=r,s.unit=e,s}return UA(n,t),n}(GA),XA=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),VA=function(t){function n(n,i,r){return t.call(this,"Disjoint",n,i,r)||this}return XA(n,t),n}(GA),WA=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),YA=function(t){function n(n,i){var r=t.call(this,n)||this;return r.propertyName=i,r}return WA(n,t),n}(CA),ZA=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),$A=function(t){function n(n,i,r){var e=t.call(this,"During",n)||this;return e.begin=i,e.end=r,e}return ZA(n,t),n}(YA),KA=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),HA=function(t){function n(n,i,r,e){var o=t.call(this,n,i)||this;return o.expression=r,o.matchCase=e,o}return KA(n,t),n}(YA),JA=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),QA=function(t){function n(n,i,r){return t.call(this,"PropertyIsEqualTo",n,i,r)||this}return JA(n,t),n}(HA),tP=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),nP=function(t){function n(n,i){return t.call(this,"PropertyIsGreaterThan",n,i)||this}return tP(n,t),n}(HA),iP=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),rP=function(t){function n(n,i){return t.call(this,"PropertyIsGreaterThanOrEqualTo",n,i)||this}return iP(n,t),n}(HA),eP=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),oP=function(t){function n(n,i,r){return t.call(this,"Intersects",n,i,r)||this}return eP(n,t),n}(GA),sP=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),uP=function(t){function n(n,i,r){var e=t.call(this,"PropertyIsBetween",n)||this;return e.lowerBoundary=i,e.upperBoundary=r,e}return sP(n,t),n}(YA),aP=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),hP=function(t){function n(n,i,r,e,o,s){var u=t.call(this,"PropertyIsLike",n)||this;return u.pattern=i,u.wildCard=void 0!==r?r:"*",u.singleChar=void 0!==e?e:".",u.escapeChar=void 0!==o?o:"!",u.matchCase=s,u}return aP(n,t),n}(YA),fP=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),cP=function(t){function n(n){return t.call(this,"PropertyIsNull",n)||this}return fP(n,t),n}(YA),lP=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),vP=function(t){function n(n,i){return t.call(this,"PropertyIsLessThan",n,i)||this}return lP(n,t),n}(HA),dP=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),pP=function(t){function n(n,i){return t.call(this,"PropertyIsLessThanOrEqualTo",n,i)||this}return dP(n,t),n}(HA),yP=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),mP=function(t){function n(n){var i=t.call(this,"Not")||this;return i.condition=n,i}return yP(n,t),n}(CA),wP=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),gP=function(t){function n(n,i,r){return t.call(this,"PropertyIsNotEqualTo",n,i,r)||this}return wP(n,t),n}(HA),bP=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),xP=function(t){function n(n){return t.call(this,"Or",Array.prototype.slice.call(arguments))||this}return bP(n,t),n}(IA),MP=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),_P=function(t){function n(n){var i=t.call(this,"ResourceId")||this;return i.rid=n,i}return MP(n,t),n}(CA),SP=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),OP=function(t){function n(n,i,r){return t.call(this,"Within",n,i,r)||this}return SP(n,t),n}(GA);function jP(t){var n=[null].concat(Array.prototype.slice.call(arguments));return new(Function.prototype.bind.apply(LA,n))}function EP(t,n,i){return new RA(t,n,i)}var TP=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),AP={"http://www.opengis.net/gml":{boundedBy:tc(vO.prototype.readExtentElement,"bounds")},"http://www.opengis.net/wfs/2.0":{member:Hf(vO.prototype.readFeaturesInternal)}},PP={"http://www.opengis.net/wfs":{totalInserted:tc(gO),totalUpdated:tc(gO),totalDeleted:tc(gO)},"http://www.opengis.net/wfs/2.0":{totalInserted:tc(gO),totalUpdated:tc(gO),totalDeleted:tc(gO)}},CP={"http://www.opengis.net/wfs":{TransactionSummary:tc(BP,"transactionSummary"),InsertResults:tc(YP,"insertIds")},"http://www.opengis.net/wfs/2.0":{TransactionSummary:tc(BP,"transactionSummary"),InsertResults:tc(YP,"insertIds")}},kP={"http://www.opengis.net/wfs":{PropertyName:nc(EO)},"http://www.opengis.net/wfs/2.0":{PropertyName:nc(EO)}},IP={"http://www.opengis.net/wfs":{Insert:nc(ZP),Update:nc(JP),Delete:nc(HP),Property:nc(QP),Native:nc(tC)},"http://www.opengis.net/wfs/2.0":{Insert:nc(ZP),Update:nc(JP),Delete:nc(HP),Property:nc(QP),Native:nc(tC)}},NP="feature",LP="http://www.w3.org/2000/xmlns/",zP={"2.0.0":"http://www.opengis.net/ogc/1.1","1.1.0":"http://www.opengis.net/ogc","1.0.0":"http://www.opengis.net/ogc"},RP={"2.0.0":"http://www.opengis.net/wfs/2.0","1.1.0":"http://www.opengis.net/wfs","1.0.0":"http://www.opengis.net/wfs"},FP={"2.0.0":"http://www.opengis.net/fes/2.0","1.1.0":"http://www.opengis.net/fes","1.0.0":"http://www.opengis.net/fes"},GP={"2.0.0":"http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd","1.1.0":"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd","1.0.0":"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd"},DP={"2.0.0":DO,"1.1.0":LO,"1.0.0":CO},qP=function(t){function n(n){var i=t.call(this)||this,r=n||{};return i.af=r.version?r.version:"1.1.0",i.Fy=r.featureType,i.Gy=r.featureNS,i.Dy=r.gmlFormat?r.gmlFormat:new DP[i.af],i.qy=r.schemaLocation?r.schemaLocation:GP[i.af],i}return TP(n,t),n.prototype.getFeatureType=function(){return this.Fy},n.prototype.setFeatureType=function(t){this.Fy=t},n.prototype.readFeaturesFromNode=function(t,n){var i={node:t};A(i,{featureType:this.Fy,featureNS:this.Gy}),A(i,this.getReadOptions(t,n||{}));var r=[i],e=ac([],"2.0.0"===this.af?AP:this.Dy.FEATURE_COLLECTION_PARSERS,t,r,this.Dy);return e||(e=[]),e},n.prototype.readTransactionResponse=function(t){if(t){if("string"==typeof t){var n=$f(t);return this.readTransactionResponseFromDocument(n)}return Yf(t)?this.readTransactionResponseFromDocument(t):this.readTransactionResponseFromNode(t)}},n.prototype.readFeatureCollectionMetadata=function(t){if(t){if("string"==typeof t){var n=$f(t);return this.readFeatureCollectionMetadataFromDocument(n)}return Yf(t)?this.readFeatureCollectionMetadataFromDocument(t):this.readFeatureCollectionMetadataFromNode(t)}},n.prototype.readFeatureCollectionMetadataFromDocument=function(t){for(var n=t.firstChild;n;n=n.nextSibling)if(n.nodeType==Node.ELEMENT_NODE)return this.readFeatureCollectionMetadataFromNode(n)},n.prototype.readFeatureCollectionMetadataFromNode=function(t){var n={},i=bO(t.getAttribute("numberOfFeatures"));return n.numberOfFeatures=i,ac(n,AP,t,[],this.Dy)},n.prototype.readTransactionResponseFromDocument=function(t){for(var n=t.firstChild;n;n=n.nextSibling)if(n.nodeType==Node.ELEMENT_NODE)return this.readTransactionResponseFromNode(n)},n.prototype.readTransactionResponseFromNode=function(t){return ac({},CP,t,[])},n.prototype.writeGetFeature=function(t){var n=this,i=Xf(RP[this.af],"GetFeature");i.setAttribute("service","WFS"),i.setAttribute("version",this.af),t.handle&&i.setAttribute("handle",t.handle),t.outputFormat&&i.setAttribute("outputFormat",t.outputFormat),void 0!==t.maxFeatures&&i.setAttribute("maxFeatures",String(t.maxFeatures)),t.resultType&&i.setAttribute("resultType",t.resultType),void 0!==t.startIndex&&i.setAttribute("startIndex",String(t.startIndex)),void 0!==t.count&&i.setAttribute("count",String(t.count)),void 0!==t.viewParams&&i.setAttribute("viewParams",t.viewParams),i.setAttributeNS(Bf,"xsi:schemaLocation",this.qy);var r={node:i};if(A(r,{version:this.af,srsName:t.srsName,featureNS:t.featureNS?t.featureNS:this.Gy,featurePrefix:t.featurePrefix,propertyNames:t.propertyNames?t.propertyNames:[]}),St(Array.isArray(t.featureTypes),11),"string"==typeof t.featureTypes[0]){var e=t.filter;t.bbox&&(St(t.geometryName,12),e=this.combineBboxAndFilter(t.geometryName,t.bbox,t.srsName,e)),A(r,{geometryName:t.geometryName,filter:e}),wC(i,t.featureTypes,[r])}else t.featureTypes.forEach((function(e){var o=n.combineBboxAndFilter(e.geometryName,e.bbox,t.srsName,t.filter);A(r,{geometryName:e.geometryName,filter:o}),wC(i,[e.name],[r])}));return i},n.prototype.combineBboxAndFilter=function(t,n,i,r){var e=EP(t,n,i);return r?jP(r,e):e},n.prototype.writeTransaction=function(t,n,i,r){var e,o=[],s=r.version?r.version:this.af,u=Xf(RP[s],"Transaction");u.setAttribute("service","WFS"),u.setAttribute("version",s),r&&(e=r.gmlOptions?r.gmlOptions:{},r.handle&&u.setAttribute("handle",r.handle)),u.setAttributeNS(Bf,"xsi:schemaLocation",GP[s]);var a=function(t,n,i,r){var e,o=r.featurePrefix?r.featurePrefix:NP;"1.0.0"===i?e=2:"1.1.0"===i?e=3:"2.0.0"===i&&(e=3.2);return A({node:t},{version:i,featureNS:r.featureNS,featureType:r.featureType,featurePrefix:o,gmlVersion:e,hasZ:r.hasZ,srsName:r.srsName},n)}(u,e,s,r);return t&&UP("Insert",t,o,a),n&&UP("Update",n,o,a),i&&UP("Delete",i,o,a),r.nativeElements&&UP("Native",r.nativeElements,o,a),u},n.prototype.readProjectionFromDocument=function(t){for(var n=t.firstChild;n;n=n.nextSibling)if(n.nodeType==Node.ELEMENT_NODE)return this.readProjectionFromNode(n);return null},n.prototype.readProjectionFromNode=function(t){if(t.firstElementChild&&t.firstElementChild.firstElementChild)for(var n=(t=t.firstElementChild.firstElementChild).firstElementChild;n;n=n.nextElementSibling)if(0!==n.childNodes.length&&(1!==n.childNodes.length||3!==n.firstChild.nodeType)){var i=[{}];return this.Dy.readGeometryElement(n,i),yr(i.pop().srsName)}return null},n}(aO);function UP(t,n,i,r){fc(r,IP,rc(t),n,i)}function BP(t,n){return ac({},PP,t,n)}var XP={"http://www.opengis.net/ogc":{FeatureId:Hf((function(t,n){return t.getAttribute("fid")}))},"http://www.opengis.net/ogc/1.1":{FeatureId:Hf((function(t,n){return t.getAttribute("fid")}))}};function VP(t,n){uc(XP,t,n)}var WP={"http://www.opengis.net/wfs":{Feature:VP},"http://www.opengis.net/wfs/2.0":{Feature:VP}};function YP(t,n){return ac([],WP,t,n)}function ZP(t,n,i){var r=i[i.length-1],e=r.featureType,o=r.featureNS,s=r.gmlVersion,u=Xf(o,e);t.appendChild(u),2===s?CO.prototype.writeFeatureElement(u,n,i):3===s?LO.prototype.writeFeatureElement(u,n,i):DO.prototype.writeFeatureElement(u,n,i)}function $P(t,n,i){var r=i[i.length-1].version,e=zP[r],o=Xf(e,"Filter"),s=Xf(e,"FeatureId");o.appendChild(s),s.setAttribute("fid",n),t.appendChild(o)}function KP(t,n){var i=(t=t||NP)+":";return 0===n.indexOf(i)?n:i+n}function HP(t,n,i){var r=i[i.length-1];St(void 0!==n.getId(),26);var e=r.featureType,o=r.featurePrefix,s=r.featureNS,u=KP(o,e);t.setAttribute("typeName",u),t.setAttributeNS(LP,"xmlns:"+o,s);var a=n.getId();void 0!==a&&$P(t,a,i)}function JP(t,n,i){var r=i[i.length-1];St(void 0!==n.getId(),27);var e=r.version,o=r.featureType,s=r.featurePrefix,u=r.featureNS,a=KP(s,o),h=n.getGeometryName();t.setAttribute("typeName",a),t.setAttributeNS(LP,"xmlns:"+s,u);var f=n.getId();if(void 0!==f){for(var c=n.getKeys(),l=[],v=0,d=c.length;v0,i=this.readUint32(n),r=Math.floor((268435455&i)/1e3),e=Boolean(2147483648&i)||1===r||3===r,o=Boolean(1073741824&i)||2===r||3===r,s=Boolean(536870912&i),u=(268435455&i)%1e3,a=["XY",e?"Z":"",o?"M":""].join(""),h=s?this.readUint32(n):null;if(void 0!==t&&t!==u)throw new Error("Unexpected WKB geometry type "+u);if(this.Xy){if(this.Vy!==n)throw new Error("Inconsistent endian");if(this.$y!==a)throw new Error("Inconsistent geometry layout");if(h&&this.Zy!==h)throw new Error("Inconsistent coordinate system (SRID)")}else this.Vy=n,this.Wy=e,this.Yy=o,this.$y=a,this.Zy=h,this.Xy=!0;return u},t.prototype.readWkbPayload=function(t){switch(t){case MC:return this.readPoint();case _C:return this.readLineString();case SC:case CC:return this.readPolygon();case OC:return this.readMultiPoint();case jC:return this.readMultiLineString();case EC:case AC:case PC:return this.readMultiPolygon();case TC:return this.readGeometryCollection();default:throw new Error("Unsupported WKB geometry type "+t+" is found")}},t.prototype.readWkbBlock=function(t){return this.readWkbPayload(this.readWkbHeader(t))},t.prototype.readWkbCollection=function(t,n){for(var i=this.readUint32(),r=[],e=0;e=0&&(t+=this.Ky?2147483648:1e3),this.$y.indexOf("M")>=0&&(t+=this.Ky?1073741824:2e3),this.Ky&&Number.isInteger(n)&&(t|=536870912),this.writeUint8(this.Vy?1:0),this.writeUint32(t),this.Ky&&Number.isInteger(n)&&this.writeUint32(n)},t.prototype.writeMultiPoint=function(t,n){this.writeUint32(t.length);for(var i=0;i="a"&&t<="z"||t>="A"&&t<="Z"},t.prototype.am=function(t,n){return t>="0"&&t<="9"||"."==t&&!(void 0!==n&&n)},t.prototype.hm=function(t){return" "==t||"\t"==t||"\r"==t||"\n"==t},t.prototype.fm=function(){return this.wkt.charAt(++this.sm)},t.prototype.nextToken=function(){var t,n=this.fm(),i=this.sm,r=n;if("("==n)t=qC;else if(","==n)t=XC;else if(")"==n)t=UC;else if(this.am(n)||"-"==n)t=BC,r=this.lm();else if(this.um(n))t=DC,r=this.vm();else{if(this.hm(n))return this.nextToken();if(""!==n)throw new Error("Unexpected character: "+n);t=VC}return{position:i,value:r,type:t}},t.prototype.lm=function(){var t,n=this.sm,i=!1,r=!1;do{"."==t?i=!0:"e"!=t&&"E"!=t||(r=!0),t=this.fm()}while(this.am(t,i)||!r&&("e"==t||"E"==t)||r&&("-"==t||"+"==t));return parseFloat(this.wkt.substring(n,this.sm--))},t.prototype.vm=function(){var t,n=this.sm;do{t=this.fm()}while(this.um(t));return this.wkt.substring(n,this.sm--).toUpperCase()},t}(),ZC=function(){function t(t){this.dm=t,this.pm={position:0,type:GC},this.$y=Tt}return t.prototype.ym=function(){this.pm=this.dm.nextToken()},t.prototype.isTokenType=function(t){return this.pm.type==t},t.prototype.match=function(t){var n=this.isTokenType(t);return n&&this.ym(),n},t.prototype.parse=function(){return this.ym(),this.wm()},t.prototype.gm=function(){var t=Tt,n=this.pm;if(this.isTokenType(DC)){var i=n.value;"Z"===i?t=At:"M"===i?t=Pt:"ZM"===i&&(t=Ct),t!==Tt&&this.ym()}return t},t.prototype.bm=function(){if(this.match(qC)){var t=[];do{t.push(this.wm())}while(this.match(XC));if(this.match(UC))return t}throw new Error(this.xm())},t.prototype.Mm=function(){if(this.match(qC)){var t=this._m();if(this.match(UC))return t}throw new Error(this.xm())},t.prototype.Sm=function(){if(this.match(qC)){var t=this.Om();if(this.match(UC))return t}throw new Error(this.xm())},t.prototype.jm=function(){if(this.match(qC)){var t=this.Em();if(this.match(UC))return t}throw new Error(this.xm())},t.prototype.Tm=function(){if(this.match(qC)){var t=void 0;if(t=this.pm.type==qC?this.Am():this.Om(),this.match(UC))return t}throw new Error(this.xm())},t.prototype.Pm=function(){if(this.match(qC)){var t=this.Em();if(this.match(UC))return t}throw new Error(this.xm())},t.prototype.Cm=function(){if(this.match(qC)){var t=this.km();if(this.match(UC))return t}throw new Error(this.xm())},t.prototype._m=function(){for(var t=[],n=this.$y.length,i=0;i0&&(r+=" "+e)}return 0===i.length?r+" "+FC:r+"("+i+")"}var nk=$C,ik=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),rk=[null,"http://www.opengis.net/wms"],ek=sc(rk,{Service:tc((function(t,n){return ac({},uk,t,n)})),Capability:tc((function(t,n){return ac({},ok,t,n)}))}),ok=sc(rk,{Request:tc((function(t,n){return ac({},pk,t,n)})),Exception:tc((function(t,n){return ac([],ck,t,n)})),Layer:tc((function(t,n){var i=ac({},lk,t,n);if(void 0===i.Layer)return Object.assign(i,Mk(t,n));return i}))}),sk=function(t){function n(){var n=t.call(this)||this;return n.version=void 0,n}return ik(n,t),n.prototype.readFromNode=function(t){this.version=t.getAttribute("version").trim();var n=ac({version:this.version},ek,t,[]);return n||null},n}(VT),uk=sc(rk,{Name:tc(xO),Title:tc(xO),Abstract:tc(xO),KeywordList:tc(jk),OnlineResource:tc(WT),ContactInformation:tc((function(t,n){return ac({},ak,t,n)})),Fees:tc(xO),AccessConstraints:tc(xO),LayerLimit:tc(gO),MaxWidth:tc(gO),MaxHeight:tc(gO)}),ak=sc(rk,{ContactPersonPrimary:tc((function(t,n){return ac({},hk,t,n)})),ContactPosition:tc(xO),ContactAddress:tc((function(t,n){return ac({},fk,t,n)})),ContactVoiceTelephone:tc(xO),ContactFacsimileTelephone:tc(xO),ContactElectronicMailAddress:tc(xO)}),hk=sc(rk,{ContactPerson:tc(xO),ContactOrganization:tc(xO)}),fk=sc(rk,{AddressType:tc(xO),Address:tc(xO),City:tc(xO),StateOrProvince:tc(xO),PostCode:tc(xO),Country:tc(xO)}),ck=sc(rk,{Format:Hf(xO)}),lk=sc(rk,{Name:tc(xO),Title:tc(xO),Abstract:tc(xO),KeywordList:tc(jk),CRS:Qf(xO),EX_GeographicBoundingBox:tc((function(t,n){var i=ac({},dk,t,n);if(!i)return;var r=i.westBoundLongitude,e=i.southBoundLatitude,o=i.eastBoundLongitude,s=i.northBoundLatitude;if(void 0===r||void 0===e||void 0===o||void 0===s)return;return[r,e,o,s]})),BoundingBox:Qf((function(t,n){var i=[wO(t.getAttribute("minx")),wO(t.getAttribute("miny")),wO(t.getAttribute("maxx")),wO(t.getAttribute("maxy"))],r=[wO(t.getAttribute("resx")),wO(t.getAttribute("resy"))];return{crs:t.getAttribute("CRS"),extent:i,res:r}})),Dimension:Qf((function(t,n){return{name:t.getAttribute("name"),units:t.getAttribute("units"),unitSymbol:t.getAttribute("unitSymbol"),default:t.getAttribute("default"),multipleValues:pO(t.getAttribute("multipleValues")),nearestValue:pO(t.getAttribute("nearestValue")),current:pO(t.getAttribute("current")),values:xO(t)}})),Attribution:tc((function(t,n){return ac({},vk,t,n)})),AuthorityURL:Qf((function(t,n){var i=_k(t,n);if(i)return i.name=t.getAttribute("name"),i;return})),Identifier:Qf(xO),MetadataURL:Qf((function(t,n){var i=_k(t,n);if(i)return i.type=t.getAttribute("type"),i;return})),DataURL:Qf(_k),FeatureListURL:Qf(_k),Style:Qf((function(t,n){return ac({},gk,t,n)})),MinScaleDenominator:tc(mO),MaxScaleDenominator:tc(mO),Layer:Qf(Mk)}),vk=sc(rk,{Title:tc(xO),OnlineResource:tc(WT),LogoURL:tc(Ok)}),dk=sc(rk,{westBoundLongitude:tc(mO),eastBoundLongitude:tc(mO),southBoundLatitude:tc(mO),northBoundLatitude:tc(mO)}),pk=sc(rk,{GetCapabilities:tc(Sk),GetMap:tc(Sk),GetFeatureInfo:tc(Sk)}),yk=sc(rk,{Format:Qf(xO),DCPType:Qf((function(t,n){return ac({},mk,t,n)}))}),mk=sc(rk,{HTTP:tc((function(t,n){return ac({},wk,t,n)}))}),wk=sc(rk,{Get:tc(_k),Post:tc(_k)}),gk=sc(rk,{Name:tc(xO),Title:tc(xO),Abstract:tc(xO),LegendURL:Qf(Ok),StyleSheetURL:tc(_k),StyleURL:tc(_k)}),bk=sc(rk,{Format:tc(xO),OnlineResource:tc(WT)}),xk=sc(rk,{Keyword:Hf(xO)});function Mk(t,n){var i=n[n.length-1],r=ac({},lk,t,n);if(r){var e=pO(t.getAttribute("queryable"));void 0===e&&(e=i.queryable),r.queryable=void 0!==e&&e;var o=bO(t.getAttribute("cascaded"));void 0===o&&(o=i.cascaded),r.cascaded=o;var s=pO(t.getAttribute("opaque"));void 0===s&&(s=i.opaque),r.opaque=void 0!==s&&s;var u=pO(t.getAttribute("noSubsets"));void 0===u&&(u=i.noSubsets),r.noSubsets=void 0!==u&&u;var a=wO(t.getAttribute("fixedWidth"));a||(a=i.fixedWidth),r.fixedWidth=a;var h=wO(t.getAttribute("fixedHeight"));h||(h=i.fixedHeight),r.fixedHeight=h;["Style","CRS","AuthorityURL"].forEach((function(t){if(t in i){var n=r[t]||[];r[t]=n.concat(i[t])}}));return["EX_GeographicBoundingBox","BoundingBox","Dimension","Attribution","MinScaleDenominator","MaxScaleDenominator"].forEach((function(t){if(!(t in r)){var n=i[t];r[t]=n}})),r}}function _k(t,n){return ac({},bk,t,n)}function Sk(t,n){return ac({},yk,t,n)}function Ok(t,n){var i=_k(t,n);if(i){var r=[bO(t.getAttribute("width")),bO(t.getAttribute("height"))];return i.size=r,i}}function jk(t,n){return ac([],xk,t,n)}var Ek=sk,Tk=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),Ak=function(t){function n(n){var i=t.call(this)||this,r=n||{};return i.Gy="http://mapserver.gis.umn.edu/mapserver",i.Dy=new CO,i.Uh=r.layers?r.layers:null,i}return Tk(n,t),n.prototype.getLayers=function(){return this.Uh},n.prototype.setLayers=function(t){this.Uh=t},n.prototype.zm=function(t,n){t.setAttribute("namespaceURI",this.Gy);var i=t.localName,r=[];if(0===t.childNodes.length)return r;if("msGMLOutput"==i)for(var e=0,o=t.childNodes.length;ef*uI||h>c*uI?this.cw():xn(o,r)||this.pw()}}},n.prototype.cw=function(){var t=this.getMap(),n=this.sw,i=t.getSize(),r=t.getView().calculateExtentInternal(i),e=n.getView(),o=Math.log(7.5)/Math.LN2;Qn(r,1/(Math.pow(2,o/2)*aI)),e.fitInternal(Ze(r))},n.prototype.pw=function(){var t=this.getMap(),n=this.sw,i=t.getView();n.getView().setCenterInternal(i.getCenterInternal())},n.prototype.yw=function(){var t=this.getMap(),n=this.sw;if(t.isRendered()&&n.isRendered()){var i=t.getSize(),r=t.getView(),e=n.getView(),o=this.su?0:-r.getRotation(),s=this.uw,u=this.uw.getElement(),a=r.getCenterInternal(),h=r.getResolution(),f=e.getResolution(),c=i[0]*h/f,l=i[1]*h/f;if(s.setPosition(a),u){u.style.width=c+"px",u.style.height=l+"px";var v="rotate("+o+"rad)";u.style.transform=v}}},n.prototype.lw=function(){this.mw||(this.mw=K(this.sw,vu,(function(t){delete this.mw,this.yw()}),this))},n.prototype.kr=function(t){t.preventDefault(),this.zr()},n.prototype.zr=function(){this.element.classList.toggle(_s),this.Sr?Eo(this.Ar,this.Pr):Eo(this.Pr,this.Ar),this.Sr=!this.Sr;var t=this.sw;if(!this.Sr){if(t.isRendered())return this.ew=void 0,void t.render();t.updateSize(),this.cw(),this.lw()}},n.prototype.getCollapsible=function(){return this.Tr},n.prototype.setCollapsible=function(t){this.Tr!==t&&(this.Tr=t,this.element.classList.toggle("ol-uncollapsible"),!t&&this.Sr&&this.zr())},n.prototype.setCollapsed=function(t){this.Tr&&this.Sr!==t&&this.zr()},n.prototype.getCollapsed=function(){return this.Sr},n.prototype.getRotateWithView=function(){return this.su},n.prototype.setRotateWithView=function(t){this.su!==t&&(this.su=t,0!==this.getMap().getView().getRotation()&&(this.su?this.rw():this.sw.getView().setRotation(0),this.ew=void 0,this.dw(),this.yw()))},n.prototype.getOverviewMap=function(){return this.sw},n.prototype.render=function(t){this.dw(),this.yw()},n}(oa),cI=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),lI="units",vI="degrees",dI="imperial",pI="nautical",yI="metric",mI="us",wI=[1,2,5],gI=25.4/.28,bI=function(t){function n(n){var i=this,r=n||{},e=void 0!==r.className?r.className:r.bar?"ol-scale-bar":"ol-scale-line";return(i=t.call(this,{element:document.createElement("div"),render:r.render,target:r.target})||this).on,i.once,i.un,i.ww=document.createElement("div"),i.ww.className=e+"-inner",i.element.className=e+" "+bs,i.element.appendChild(i.ww),i.gw=null,i.bw=void 0!==r.minWidth?r.minWidth:64,i.xw=r.maxWidth,i.mn=!1,i.Mw=void 0,i.Qm="",i.addChangeListener(lI,i._w),i.setUnits(r.units||yI),i.Sw=r.bar||!1,i.Ow=r.steps||4,i.jw=r.text||!1,i.Ew=r.dpi||void 0,i}return cI(n,t),n.prototype.getUnits=function(){return this.get(lI)},n.prototype._w=function(){this.Lr()},n.prototype.setUnits=function(t){this.set(lI,t)},n.prototype.setDpi=function(t){this.Ew=t},n.prototype.Lr=function(){var t=this.gw;if(t){var n=t.center,i=t.projection,r=this.getUnits(),e=r==vI?Rt.DEGREES:Rt.METERS,o=mr(i,t.resolution,n,e),s=this.bw*(this.Ew||gI)/gI,u=void 0!==this.xw?this.xw*(this.Ew||gI)/gI:void 0,a=s*o,h="";if(r==vI){var f=Lt[Rt.DEGREES];(a*=f)=u){c=d,l=p,v=y;break}if(l>=s)break;d=c,p=l,y=v,++w}m=this.Sw?this.createScaleBar(l,c,h):c.toFixed(v<0?-v:0)+" "+h,this.Qm!=m&&(this.ww.innerHTML=m,this.Qm=m),this.Mw!=l&&(this.ww.style.width=l+"px",this.Mw=l),this.mn||(this.element.style.display="",this.mn=!0)}else this.mn&&(this.element.style.display="none",this.mn=!1)},n.prototype.createScaleBar=function(t,n,i){for(var r="1 : "+Math.round(this.getScaleForResolution()).toLocaleString(),e=[],o=t/this.Ow,s="ol-scale-singlebar-odd",u=0;u
'+this.createMarker("relative",u)+(u%2==0||2===this.Ow?this.createStepText(u,t,!1,n,i):"")+""),u===this.Ow-1&&e.push(this.createStepText(u+1,t,!0,n,i)),s="ol-scale-singlebar-odd"===s?"ol-scale-singlebar-even":"ol-scale-singlebar-odd";return'
'+(this.jw?'
'+r+"
":"")+e.join("")+"
"},n.prototype.createMarker=function(t,n){return'
'},n.prototype.createStepText=function(t,n,i,r,e){var o=(0===t?0:Math.round(r/this.Ow*t*100)/100)+(0===t?"":" "+e);return'
'+o+"
"},n.prototype.getScaleForResolution=function(){var t=mr(this.gw.projection,this.gw.resolution,this.gw.center,Rt.METERS),n=this.Ew||gI;return parseFloat(t.toString())*(1e3/25.4)*n},n.prototype.render=function(t){var n=t.frameState;this.gw=n?n.viewState:null,this.Lr()},n}(oa),xI=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),MI=0,_I=1,SI=function(t){function n(n){var i=this,r=n||{};(i=t.call(this,{element:document.createElement("div"),render:r.render})||this).kn=[],i.Tw=void 0,i.Aw=MI,i.Cn,i.Pw=0,i.Cw=0,i.kw,i.Iw,i.Nw=null,i.Lw=!1,i.Fr=void 0!==r.duration?r.duration:200;var e=void 0!==r.className?r.className:"ol-zoomslider",o=document.createElement("button");o.setAttribute("type","button"),o.className=e+"-thumb "+bs;var s=i.element;return s.className=e+" "+"ol-unselectable "+Ms,s.appendChild(o),s.addEventListener(au,i.zw.bind(i),!1),s.addEventListener(uu,i.Rw.bind(i),!1),s.addEventListener(hu,i.Fw.bind(i),!1),s.addEventListener(F,i.Gw.bind(i),!1),o.addEventListener(F,f,!1),i}return xI(n,t),n.prototype.setMap=function(n){t.prototype.setMap.call(this,n),n&&n.render()},n.prototype.Dw=function(){var t=this.element,n=t.offsetWidth,i=t.offsetHeight;if(0===n&&0===i)return this.Lw=!1;var r=getComputedStyle(t);n-=parseFloat(r.paddingRight)+parseFloat(r.paddingLeft),i-=parseFloat(r.paddingTop)+parseFloat(r.paddingBottom);var e=t.firstElementChild,o=getComputedStyle(e),s=e.offsetWidth+parseFloat(o.marginRight)+parseFloat(o.marginLeft),u=e.offsetHeight+parseFloat(o.marginTop)+parseFloat(o.marginBottom);return this.Nw=[s,u],n>i?(this.Aw=_I,this.Cw=n-s):(this.Aw=MI,this.Pw=i-u),this.Lw=!0},n.prototype.Gw=function(t){var n=this.getMap().getView(),i=this.qw(t.offsetX-this.Nw[0]/2,t.offsetY-this.Nw[1]/2),r=this.Uw(i),e=n.getConstrainedZoom(n.getZoomForResolution(r));n.animateInternal({zoom:e,duration:this.Fr,easing:mt})},n.prototype.zw=function(t){if(!this.Cn&&t.target===this.element.firstElementChild){var n=this.element.firstElementChild;if(this.getMap().getView().beginInteraction(),this.kw=t.clientX-parseFloat(n.style.left),this.Iw=t.clientY-parseFloat(n.style.top),this.Cn=!0,0===this.kn.length){var i=this.Rw,r=this.Fw,e=this.getMap().getOwnerDocument();this.kn.push($(e,uu,i,this),$(e,hu,r,this))}}},n.prototype.Rw=function(t){if(this.Cn){var n=t.clientX-this.kw,i=t.clientY-this.Iw,r=this.qw(n,i);this.Tw=this.Uw(r),this.getMap().getView().setResolution(this.Tw)}},n.prototype.Fw=function(t){this.Cn&&(this.getMap().getView().endInteraction(),this.Cn=!1,this.kw=void 0,this.Iw=void 0,this.kn.forEach(H),this.kn.length=0)},n.prototype.Bw=function(t){var n=this.Xw(t),i=this.element.firstElementChild;this.Aw==_I?i.style.left=this.Cw*n+"px":i.style.top=this.Pw*n+"px"},n.prototype.qw=function(t,n){return oi(this.Aw===_I?t/this.Cw:n/this.Pw,0,1)},n.prototype.Uw=function(t){return this.getMap().getView().getResolutionForValueFunction()(1-t)},n.prototype.Xw=function(t){return oi(1-this.getMap().getView().getValueForResolutionFunction()(t),0,1)},n.prototype.render=function(t){if(t.frameState&&(this.Lw||this.Dw())){var n=t.frameState.viewState.resolution;this.Tw=n,this.Bw(n)}},n}(oa),OI=function(){var t=function(n,i){return(t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,n){t.__proto__=n}||function(t,n){for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])})(n,i)};return function(n,i){if("function"!=typeof i&&null!==i)throw new TypeError("Class extends value "+String(i)+" is not a constructor or null");function r(){this.constructor=n}t(n,i),n.prototype=null===i?Object.create(i):(r.prototype=i.prototype,new r)}}(),jI=function(t){function n(n){var i=this,r=n||{};(i=t.call(this,{element:document.createElement("div"),target:r.target})||this).extent=r.extent?r.extent:null;var e=void 0!==r.className?r.className:"ol-zoom-extent",o=void 0!==r.label?r.label:"E",s=void 0!==r.tipLabel?r.tipLabel:"Fit to extent",u=document.createElement("button");u.setAttribute("type","button"),u.title=s,u.appendChild("string"==typeof o?document.createTextNode(o):o),u.addEventListener(F,i.kr.bind(i),!1);var a=e+" "+"ol-unselectable "+Ms,h=i.element;return h.className=a,h.appendChild(u),i}return OI(n,t),n.prototype.kr=function(t){t.preventDefault(),this.handleZoomToExtent()},n.prototype.handleZoomToExtent=function(){var t=this.getMap().getView(),n=this.extent?this.extent:t.getProjection().getExtent();t.fitInternal(Ze(n))},n}(oa),EI={};EI.AssertionError=h,EI.Collection=ft,EI.Collection.CollectionEvent=ht,EI.DataTile=_t,EI.Disposable=v,EI.Feature=Et,EI.Feature.createStyleFunction=jt,EI.Geolocation=ho,EI.Image=bo,EI.Image.listenImage=go,EI.ImageBase=co,EI.ImageCanvas=Mo,EI.ImageTile=ko,EI.Kinetic=Io,EI.Map=yh,EI.MapBrowserEvent=ou,EI.MapBrowserEventHandler=lu,EI.MapEvent=ru,EI.Object=et,EI.Object.ObjectEvent=rt,EI.Observable=nt,EI.Observable.unByKey=tt,EI.Overlay=_h,EI.PluggableMap=ra,EI.Tile=xt,EI.TileCache=Ih,EI.TileQueue=Ou,EI.TileQueue.getTilePriority=ju,EI.TileRange=zh,EI.TileRange.createOrUpdate=Lh,EI.VectorRenderTile=Gh,EI.VectorTile=qh,EI.View=$u,EI.View.createCenterConstraint=Xu,EI.View.createResolutionConstraint=Vu,EI.View.createRotationConstraint=Wu,EI.View.isNoopAnimation=Yu,EI.array={},EI.array.binarySearch=d,EI.array.equals=x,EI.array.extend=g,EI.array.find=b,EI.array.findIndex=M,EI.array.includes=y,EI.array.isSorted=_,EI.array.linearFindNearest=m,EI.array.numberSafeCompareFunction=p,EI.array.remove=function(t,n){var i=t.indexOf(n),r=i>-1;return r&&t.splice(i,1),r},EI.array.reverseSubArray=w,EI.array.stableSort=function(t,n){var i,r=t.length,e=Array(t.length);for(i=0;i3&&!!we(t,n,i,r)},EI.geom.flat.transform={},EI.geom.flat.transform.rotate=qr,EI.geom.flat.transform.scale=Ur,EI.geom.flat.transform.transform2D=Dr,EI.geom.flat.transform.translate=Br,EI.has={},EI.has.DEVICE_PIXEL_RATIO=Xt,EI.has.FIREFOX=Gt,EI.has.IMAGE_DECODE=Wt,EI.has.MAC=Bt,EI.has.PASSIVE_EVENT_LISTENERS=Yt,EI.has.SAFARI=Dt,EI.has.SAFARI_BUG_237906=qt,EI.has.WEBKIT=Ut,EI.has.WORKER_OFFSCREEN_CANVAS=Vt,EI.interaction={},EI.interaction.DoubleClickZoom=ga,EI.interaction.DragAndDrop=Q_,EI.interaction.DragAndDrop.DragAndDropEvent=J_,EI.interaction.DragBox=$a,EI.interaction.DragBox.DragBoxEvent=Za,EI.interaction.DragPan=Fa,EI.interaction.DragRotate=Da,EI.interaction.DragRotateAndZoom=nS,EI.interaction.DragZoom=Ha,EI.interaction.Draw=dS,EI.interaction.Draw.DrawEvent=vS,EI.interaction.Draw.createBox=function(){return function(t,n,i){var r=yn([t[0],t[t.length-1]].map((function(t){return Ir(t,i)}))),e=[[Gn(r),Dn(r),Zn(r),Yn(r),Gn(r)]],o=n;o?o.setCoordinates(e):o=new We(e);var s=Cr();return s&&o.transform(i,s),o}},EI.interaction.Draw.createRegularPolygon=function(t,n){return function(i,r,e){var o=Ir(i[0],e),s=Ir(i[i.length-1],e),u=Math.sqrt(Qi(o,s)),a=r||$e(new eS(o),t),h=n;if(!n&&0!==n){var f=s[0]-o[0],c=s[1]-o[1];h=Math.atan2(c,f)}Ke(a,o,u,h);var l=Cr();return l&&a.transform(e,l),a}},EI.interaction.Extent=xS,EI.interaction.Extent.ExtentEvent=mS,EI.interaction.Interaction=ma,EI.interaction.Interaction.pan=pa,EI.interaction.Interaction.zoomByDelta=ya,EI.interaction.KeyboardPan=rh,EI.interaction.KeyboardZoom=oh,EI.interaction.Link=jS,EI.interaction.Modify=zS,EI.interaction.Modify.ModifyEvent=kS,EI.interaction.MouseWheelZoom=hh,EI.interaction.PinchRotate=ch,EI.interaction.PinchZoom=vh,EI.interaction.Pointer=Ma,EI.interaction.Pointer.centroid=xa,EI.interaction.Select=qS,EI.interaction.Select.SelectEvent=GS,EI.interaction.Snap=VS,EI.interaction.Translate=HS,EI.interaction.Translate.TranslateEvent=KS,EI.interaction.defaults=dh,EI.layer={},EI.layer.Base=es,EI.layer.BaseImage=$y,EI.layer.BaseTile=am,EI.layer.BaseVector=$m,EI.layer.Graticule=gg,EI.layer.Group=nu,EI.layer.Group.GroupEvent=Qs,EI.layer.Heatmap=Og,EI.layer.Image=em,EI.layer.Layer=ls,EI.layer.Layer.inView=cs,EI.layer.MapboxVector=q_,EI.layer.Tile=lm,EI.layer.Vector=lg,EI.layer.VectorImage=B_,EI.layer.VectorTile=Rg,EI.layer.WebGLPoints=V_,EI.layer.WebGLTile=$_,EI.loadingstrategy={},EI.loadingstrategy.all=Wh,EI.loadingstrategy.bbox=function(t,n){return[t]},EI.loadingstrategy.tile=function(t){return function(n,i,r){var e=t.getZForResolution(Rr(i,r)),o=t.getTileRangeForExtentAndZ(Lr(n,r),e),s=[],u=[e,0,0];for(u[1]=o.minX;u[1]<=o.maxX;++u[1])for(u[2]=o.minY;u[2]<=o.maxY;++u[2])s.push(Nr(t.getTileCoordExtent(u),r));return s}},EI.math={},EI.math.ceil=wi,EI.math.clamp=oi,EI.math.cosh=si,EI.math.floor=mi,EI.math.lerp=di,EI.math.log2=ui,EI.math.modulo=vi,EI.math.round=yi,EI.math.solveLinearSystem=fi,EI.math.squaredDistance=hi,EI.math.squaredSegmentDistance=ai,EI.math.toDegrees=ci,EI.math.toFixed=pi,EI.math.toRadians=li,EI.net={},EI.net.ClientError=Hh,EI.net.ResponseError=Kh,EI.net.getJSON=Jh,EI.net.jsonp=Zh,EI.net.overrideXHR=function(t){"undefined"!=typeof XMLHttpRequest&&($h=XMLHttpRequest),global.XMLHttpRequest=t},EI.net.resolveUrl=Qh,EI.net.restoreXHR=function(){global.XMLHttpRequest=$h},EI.obj={},EI.obj.assign=A,EI.obj.clear=P,EI.obj.getValues=C,EI.obj.isEmpty=k,EI.proj={},EI.proj.Projection=ei,EI.proj.Units={},EI.proj.Units.METERS_PER_UNIT=Lt,EI.proj.Units.fromCode=Nt,EI.proj.addCommon=Gr,EI.proj.addCoordinateTransforms=Mr,EI.proj.addEquivalentProjections=wr,EI.proj.addEquivalentTransforms=gr,EI.proj.addProjection=dr,EI.proj.addProjections=pr,EI.proj.clearAllProjections=function(){zi(),Di()},EI.proj.clearUserProjection=function(){Ar=null},EI.proj.cloneTransform=lr,EI.proj.createProjection=br,EI.proj.createSafeCoordinateTransform=Fr,EI.proj.createTransformFromCoordinateTransform=xr,EI.proj.disableCoordinateWarning=cr,EI.proj.epsg3857={},EI.proj.epsg3857.EXTENT=Mi,EI.proj.epsg3857.HALF_SIZE=xi,EI.proj.epsg3857.MAX_SAFE_Y=Si,EI.proj.epsg3857.PROJECTIONS=ji,EI.proj.epsg3857.RADIUS=bi,EI.proj.epsg3857.WORLD_EXTENT=_i,EI.proj.epsg3857.fromEPSG4326=Ei,EI.proj.epsg3857.toEPSG4326=Ti,EI.proj.epsg4326={},EI.proj.epsg4326.EXTENT=Ci,EI.proj.epsg4326.METERS_PER_UNIT=ki,EI.proj.epsg4326.PROJECTIONS=Ni,EI.proj.epsg4326.RADIUS=Pi,EI.proj.equivalent=Sr,EI.proj.fromLonLat=_r,EI.proj.fromUserCoordinate=Ir,EI.proj.fromUserExtent=Lr,EI.proj.fromUserResolution=Rr,EI.proj.get=yr,EI.proj.getPointResolution=mr,EI.proj.getTransform=jr,EI.proj.getTransformFromProjections=Or,EI.proj.getUserProjection=Cr,EI.proj.identityTransform=vr,EI.proj.proj4={},EI.proj.proj4.register=function(t){var n,i,r=Object.keys(t.defs),e=r.length;for(n=0;n180)&&(i[0]=vi(r+180,360)-180),i},EI.proj.toUserCoordinate=kr,EI.proj.toUserExtent=Nr,EI.proj.toUserResolution=zr,EI.proj.transform=Er,EI.proj.transformExtent=Tr,EI.proj.transformWithProjections=function(t,n,i){return Or(n,i)(t)},EI.proj.transforms={},EI.proj.transforms.add=qi,EI.proj.transforms.clear=Di,EI.proj.transforms.get=Ui,EI.proj.transforms.remove=function(t,n){var i=t.getCode(),r=n.getCode(),e=Gi[i][r];return delete Gi[i][r],k(Gi[i])&&delete Gi[i],e},EI.proj.useGeographic=function(){Pr("EPSG:4326")},EI.render={},EI.render.Box=Ua,EI.render.Event=ms,EI.render.Feature=fg,EI.render.Feature.toFeature=function(t,n){var i=t.getId(),r=hg(t),e=t.getProperties(),o=new Et;return void 0!==n&&o.setGeometryName(n),o.setGeometry(r),void 0!==i&&o.setId(i),o.setProperties(e,!0),o},EI.render.Feature.toGeometry=hg,EI.render.VectorContext=tf,EI.render.canvas={},EI.render.canvas.Builder=ow,EI.render.canvas.BuilderGroup=mw,EI.render.canvas.Executor=Aw,EI.render.canvas.ExecutorGroup=Nw,EI.render.canvas.ExecutorGroup.getPixelIndexArray=Iw,EI.render.canvas.ImageBuilder=uw,EI.render.canvas.Immediate=rf,EI.render.canvas.Instruction={},EI.render.canvas.Instruction.beginPathInstruction=nw,EI.render.canvas.Instruction.closePathInstruction=iw,EI.render.canvas.Instruction.fillInstruction=Qm,EI.render.canvas.Instruction.strokeInstruction=tw,EI.render.canvas.LineStringBuilder=hw,EI.render.canvas.PolygonBuilder=cw,EI.render.canvas.TextBuilder=pw,EI.render.canvas.checkedFonts=Rs,EI.render.canvas.defaultFillStyle=Ts,EI.render.canvas.defaultFont=Es,EI.render.canvas.defaultLineCap=As,EI.render.canvas.defaultLineDash=Ps,EI.render.canvas.defaultLineDashOffset=0,EI.render.canvas.defaultLineJoin=Cs,EI.render.canvas.defaultLineWidth=1,EI.render.canvas.defaultMiterLimit=ks,EI.render.canvas.defaultPadding=zs,EI.render.canvas.defaultStrokeStyle=Is,EI.render.canvas.defaultTextAlign=Ns,EI.render.canvas.defaultTextBaseline=Ls,EI.render.canvas.drawImageOrLabel=$s,EI.render.canvas.getTextDimensions=Zs,EI.render.canvas.hitdetect={},EI.render.canvas.hitdetect.HIT_DETECT_RESOLUTION=Lw,EI.render.canvas.hitdetect.createHitDetectionImageData=zw,EI.render.canvas.hitdetect.hitDetect=Rw,EI.render.canvas.labelCache=Fs,EI.render.canvas.measureAndCacheTextWidth=Ys,EI.render.canvas.measureTextHeight=Xs,EI.render.canvas.measureTextWidth=Ws,EI.render.canvas.registerFont=Bs,EI.render.canvas.rotateAtOffset=function(t,n,i,r){0!==n&&(t.translate(i,r),t.rotate(n),t.translate(-i,-r))},EI.render.canvas.textHeights=Us,EI.render.getRenderPixel=function(t,n){return tn(t.inversePixelTransform,n.slice(0))},EI.render.getVectorContext=ff,EI.render.toContext=function(t,n){var i=t.canvas,r=n||{},e=r.pixelRatio||Xt,o=r.size;o&&(i.width=o[0]*e,i.height=o[1]*e,i.style.width=o[0]+"px",i.style.height=o[1]+"px");var s=[0,0,i.width,i.height],u=rn([1,0,0,1,0,0],e,e);return new rf(t,e,s,u,0)},EI.renderer={},EI.renderer.Composite=Hs,EI.renderer.Layer=Kc,EI.renderer.Map=ps,EI.renderer.canvas={},EI.renderer.canvas.ImageLayer=im,EI.renderer.canvas.Layer=tm,EI.renderer.canvas.Layer.canvasPool=Hy,EI.renderer.canvas.TileLayer=fm,EI.renderer.canvas.VectorImageLayer=qw,EI.renderer.canvas.VectorLayer=Gw,EI.renderer.canvas.VectorTileLayer=Zw,EI.renderer.canvas.common={},EI.renderer.canvas.common.IMAGE_SMOOTHING_DISABLED=lf,EI.renderer.canvas.common.IMAGE_SMOOTHING_ENABLED=vf,EI.renderer.vector={},EI.renderer.vector.defaultOrder=of,EI.renderer.vector.getSquaredTolerance=sf,EI.renderer.vector.getTolerance=uf,EI.renderer.vector.renderFeature=af,EI.renderer.webgl={},EI.renderer.webgl.Layer=ol,EI.renderer.webgl.Layer.colorDecodeId=el,EI.renderer.webgl.Layer.colorEncodeId=rl,EI.renderer.webgl.Layer.getBlankImageData=function(){var t=document.createElement("canvas").getContext("2d").createImageData(1,1);return t.data[0]=255,t.data[1]=255,t.data[2]=255,t.data[3]=255,t},EI.renderer.webgl.Layer.writePointFeatureToBuffers=function(t,n,i,r,e,o){var s=3+e,u=t[n+0],a=t[n+1],h=tl;h.length=e;for(var f=0;f1?M(i.TileMatrixSetLink,"projection"in n?function(t,i,r){var o=b(e,(function(n){return n.Identifier==t.TileMatrixSet})).SupportedCRS,s=yr(o),u=yr(n.projection);return s&&u?Sr(s,u):o==n.projection}:function(t,i,r){return t.TileMatrixSet==n.matrixSet}):0)<0&&(r=0);var o=i.TileMatrixSetLink[r].TileMatrixSet,s=i.TileMatrixSetLink[r].TileMatrixSetLimits,u=i.Format[0];"format"in n&&(u=n.format),(r=M(i.Style,(function(t,i,r){return"style"in n?t.Title==n.style:t.isDefault})))<0&&(r=0);var a=i.Style[r].Identifier,h={};"Dimension"in i&&i.Dimension.forEach((function(t,n,i){var r=t.Identifier,e=t.Default;void 0===e&&(e=t.Value[0]),h[r]=e}));var f,c=b(t.Contents.TileMatrixSet,(function(t,n,i){return t.Identifier==o})),l=c.SupportedCRS;if(l&&(f=yr(l)),"projection"in n){var v=yr(n.projection);v&&(f&&!Sr(v,f)||(f=v))}var d=!1,p="ne"==f.getAxisOrientation().substr(0,2),m=c.TileMatrix[0],w={MinTileCol:0,MinTileRow:0,MaxTileCol:m.MatrixWidth-1,MaxTileRow:m.MatrixHeight-1};if(s){w=s[s.length-1];var g=b(c.TileMatrix,(function(t){return t.Identifier===w.TileMatrix||c.Identifier+":"+t.Identifier===w.TileMatrix}));g&&(m=g)}var x=28e-5*m.ScaleDenominator/f.getMetersPerUnit(),_=p?[m.TopLeftCorner[1],m.TopLeftCorner[0]]:m.TopLeftCorner,S=m.TileWidth*x,O=m.TileHeight*x,j=c.BoundingBox;j&&p&&(j=[j[1],j[0],j[3],j[2]]);var E=[_[0]+S*w.MinTileCol,_[1]-O*(1+w.MaxTileRow),_[0]+S*(1+w.MaxTileCol),_[1]-O*w.MinTileRow];if(void 0!==j&&!xn(j,E)){var T=i.WGS84BoundingBox,A=yr("EPSG:4326").getExtent();if(E=j,T)d=T[0]===A[0]&&T[2]===A[2];else{var P=Tr(j,c.SupportedCRS,"EPSG:4326");d=P[0]-1e-10<=A[0]&&P[2]+1e-10>=A[2]}}var C=Hl(c,E,s),k=[],I=n.requestEncoding;if(I=void 0!==I?I:"","OperationsMetadata"in t&&"GetTile"in t.OperationsMetadata)for(var N=t.OperationsMetadata.GetTile.DCP.HTTP.Get,L=0,z=N.length;L */\nexports.read = function (buffer, offset, isLE, mLen, nBytes) {\n var e, m\n var eLen = (nBytes * 8) - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var nBits = -7\n var i = isLE ? (nBytes - 1) : 0\n var d = isLE ? -1 : 1\n var s = buffer[offset + i]\n\n i += d\n\n e = s & ((1 << (-nBits)) - 1)\n s >>= (-nBits)\n nBits += eLen\n for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n m = e & ((1 << (-nBits)) - 1)\n e >>= (-nBits)\n nBits += mLen\n for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n if (e === 0) {\n e = 1 - eBias\n } else if (e === eMax) {\n return m ? NaN : ((s ? -1 : 1) * Infinity)\n } else {\n m = m + Math.pow(2, mLen)\n e = e - eBias\n }\n return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n var e, m, c\n var eLen = (nBytes * 8) - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n var i = isLE ? 0 : (nBytes - 1)\n var d = isLE ? 1 : -1\n var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n value = Math.abs(value)\n\n if (isNaN(value) || value === Infinity) {\n m = isNaN(value) ? 1 : 0\n e = eMax\n } else {\n e = Math.floor(Math.log(value) / Math.LN2)\n if (value * (c = Math.pow(2, -e)) < 1) {\n e--\n c *= 2\n }\n if (e + eBias >= 1) {\n value += rt / c\n } else {\n value += rt * Math.pow(2, 1 - eBias)\n }\n if (value * c >= 2) {\n e++\n c /= 2\n }\n\n if (e + eBias >= eMax) {\n m = 0\n e = eMax\n } else if (e + eBias >= 1) {\n m = ((value * c) - 1) * Math.pow(2, mLen)\n e = e + eBias\n } else {\n m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n e = 0\n }\n }\n\n for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n e = (e << mLen) | m\n eLen += mLen\n for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n buffer[offset + i - d] |= s * 128\n}\n","'use strict'\n\n// A linked list to keep track of recently-used-ness\nconst Yallist = require('yallist')\n\nconst MAX = Symbol('max')\nconst LENGTH = Symbol('length')\nconst LENGTH_CALCULATOR = Symbol('lengthCalculator')\nconst ALLOW_STALE = Symbol('allowStale')\nconst MAX_AGE = Symbol('maxAge')\nconst DISPOSE = Symbol('dispose')\nconst NO_DISPOSE_ON_SET = Symbol('noDisposeOnSet')\nconst LRU_LIST = Symbol('lruList')\nconst CACHE = Symbol('cache')\nconst UPDATE_AGE_ON_GET = Symbol('updateAgeOnGet')\n\nconst naiveLength = () => 1\n\n// lruList is a yallist where the head is the youngest\n// item, and the tail is the oldest. the list contains the Hit\n// objects as the entries.\n// Each Hit object has a reference to its Yallist.Node. This\n// never changes.\n//\n// cache is a Map (or PseudoMap) that matches the keys to\n// the Yallist.Node object.\nclass LRUCache {\n constructor (options) {\n if (typeof options === 'number')\n options = { max: options }\n\n if (!options)\n options = {}\n\n if (options.max && (typeof options.max !== 'number' || options.max < 0))\n throw new TypeError('max must be a non-negative number')\n // Kind of weird to have a default max of Infinity, but oh well.\n const max = this[MAX] = options.max || Infinity\n\n const lc = options.length || naiveLength\n this[LENGTH_CALCULATOR] = (typeof lc !== 'function') ? naiveLength : lc\n this[ALLOW_STALE] = options.stale || false\n if (options.maxAge && typeof options.maxAge !== 'number')\n throw new TypeError('maxAge must be a number')\n this[MAX_AGE] = options.maxAge || 0\n this[DISPOSE] = options.dispose\n this[NO_DISPOSE_ON_SET] = options.noDisposeOnSet || false\n this[UPDATE_AGE_ON_GET] = options.updateAgeOnGet || false\n this.reset()\n }\n\n // resize the cache when the max changes.\n set max (mL) {\n if (typeof mL !== 'number' || mL < 0)\n throw new TypeError('max must be a non-negative number')\n\n this[MAX] = mL || Infinity\n trim(this)\n }\n get max () {\n return this[MAX]\n }\n\n set allowStale (allowStale) {\n this[ALLOW_STALE] = !!allowStale\n }\n get allowStale () {\n return this[ALLOW_STALE]\n }\n\n set maxAge (mA) {\n if (typeof mA !== 'number')\n throw new TypeError('maxAge must be a non-negative number')\n\n this[MAX_AGE] = mA\n trim(this)\n }\n get maxAge () {\n return this[MAX_AGE]\n }\n\n // resize the cache when the lengthCalculator changes.\n set lengthCalculator (lC) {\n if (typeof lC !== 'function')\n lC = naiveLength\n\n if (lC !== this[LENGTH_CALCULATOR]) {\n this[LENGTH_CALCULATOR] = lC\n this[LENGTH] = 0\n this[LRU_LIST].forEach(hit => {\n hit.length = this[LENGTH_CALCULATOR](hit.value, hit.key)\n this[LENGTH] += hit.length\n })\n }\n trim(this)\n }\n get lengthCalculator () { return this[LENGTH_CALCULATOR] }\n\n get length () { return this[LENGTH] }\n get itemCount () { return this[LRU_LIST].length }\n\n rforEach (fn, thisp) {\n thisp = thisp || this\n for (let walker = this[LRU_LIST].tail; walker !== null;) {\n const prev = walker.prev\n forEachStep(this, fn, walker, thisp)\n walker = prev\n }\n }\n\n forEach (fn, thisp) {\n thisp = thisp || this\n for (let walker = this[LRU_LIST].head; walker !== null;) {\n const next = walker.next\n forEachStep(this, fn, walker, thisp)\n walker = next\n }\n }\n\n keys () {\n return this[LRU_LIST].toArray().map(k => k.key)\n }\n\n values () {\n return this[LRU_LIST].toArray().map(k => k.value)\n }\n\n reset () {\n if (this[DISPOSE] &&\n this[LRU_LIST] &&\n this[LRU_LIST].length) {\n this[LRU_LIST].forEach(hit => this[DISPOSE](hit.key, hit.value))\n }\n\n this[CACHE] = new Map() // hash of items by key\n this[LRU_LIST] = new Yallist() // list of items in order of use recency\n this[LENGTH] = 0 // length of items in the list\n }\n\n dump () {\n return this[LRU_LIST].map(hit =>\n isStale(this, hit) ? false : {\n k: hit.key,\n v: hit.value,\n e: hit.now + (hit.maxAge || 0)\n }).toArray().filter(h => h)\n }\n\n dumpLru () {\n return this[LRU_LIST]\n }\n\n set (key, value, maxAge) {\n maxAge = maxAge || this[MAX_AGE]\n\n if (maxAge && typeof maxAge !== 'number')\n throw new TypeError('maxAge must be a number')\n\n const now = maxAge ? Date.now() : 0\n const len = this[LENGTH_CALCULATOR](value, key)\n\n if (this[CACHE].has(key)) {\n if (len > this[MAX]) {\n del(this, this[CACHE].get(key))\n return false\n }\n\n const node = this[CACHE].get(key)\n const item = node.value\n\n // dispose of the old one before overwriting\n // split out into 2 ifs for better coverage tracking\n if (this[DISPOSE]) {\n if (!this[NO_DISPOSE_ON_SET])\n this[DISPOSE](key, item.value)\n }\n\n item.now = now\n item.maxAge = maxAge\n item.value = value\n this[LENGTH] += len - item.length\n item.length = len\n this.get(key)\n trim(this)\n return true\n }\n\n const hit = new Entry(key, value, len, now, maxAge)\n\n // oversized objects fall out of cache automatically.\n if (hit.length > this[MAX]) {\n if (this[DISPOSE])\n this[DISPOSE](key, value)\n\n return false\n }\n\n this[LENGTH] += hit.length\n this[LRU_LIST].unshift(hit)\n this[CACHE].set(key, this[LRU_LIST].head)\n trim(this)\n return true\n }\n\n has (key) {\n if (!this[CACHE].has(key)) return false\n const hit = this[CACHE].get(key).value\n return !isStale(this, hit)\n }\n\n get (key) {\n return get(this, key, true)\n }\n\n peek (key) {\n return get(this, key, false)\n }\n\n pop () {\n const node = this[LRU_LIST].tail\n if (!node)\n return null\n\n del(this, node)\n return node.value\n }\n\n del (key) {\n del(this, this[CACHE].get(key))\n }\n\n load (arr) {\n // reset the cache\n this.reset()\n\n const now = Date.now()\n // A previous serialized cache has the most recent items first\n for (let l = arr.length - 1; l >= 0; l--) {\n const hit = arr[l]\n const expiresAt = hit.e || 0\n if (expiresAt === 0)\n // the item was created without expiration in a non aged cache\n this.set(hit.k, hit.v)\n else {\n const maxAge = expiresAt - now\n // dont add already expired items\n if (maxAge > 0) {\n this.set(hit.k, hit.v, maxAge)\n }\n }\n }\n }\n\n prune () {\n this[CACHE].forEach((value, key) => get(this, key, false))\n }\n}\n\nconst get = (self, key, doUse) => {\n const node = self[CACHE].get(key)\n if (node) {\n const hit = node.value\n if (isStale(self, hit)) {\n del(self, node)\n if (!self[ALLOW_STALE])\n return undefined\n } else {\n if (doUse) {\n if (self[UPDATE_AGE_ON_GET])\n node.value.now = Date.now()\n self[LRU_LIST].unshiftNode(node)\n }\n }\n return hit.value\n }\n}\n\nconst isStale = (self, hit) => {\n if (!hit || (!hit.maxAge && !self[MAX_AGE]))\n return false\n\n const diff = Date.now() - hit.now\n return hit.maxAge ? diff > hit.maxAge\n : self[MAX_AGE] && (diff > self[MAX_AGE])\n}\n\nconst trim = self => {\n if (self[LENGTH] > self[MAX]) {\n for (let walker = self[LRU_LIST].tail;\n self[LENGTH] > self[MAX] && walker !== null;) {\n // We know that we're about to delete this one, and also\n // what the next least recently used key will be, so just\n // go ahead and set it now.\n const prev = walker.prev\n del(self, walker)\n walker = prev\n }\n }\n}\n\nconst del = (self, node) => {\n if (node) {\n const hit = node.value\n if (self[DISPOSE])\n self[DISPOSE](hit.key, hit.value)\n\n self[LENGTH] -= hit.length\n self[CACHE].delete(hit.key)\n self[LRU_LIST].removeNode(node)\n }\n}\n\nclass Entry {\n constructor (key, value, length, now, maxAge) {\n this.key = key\n this.value = value\n this.length = length\n this.now = now\n this.maxAge = maxAge || 0\n }\n}\n\nconst forEachStep = (self, fn, node, thisp) => {\n let hit = node.value\n if (isStale(self, hit)) {\n del(self, node)\n if (!self[ALLOW_STALE])\n hit = undefined\n }\n if (hit)\n fn.call(thisp, hit.value, hit.key, self)\n}\n\nmodule.exports = LRUCache\n","'use strict';\n\nmodule.exports = Pbf;\n\nvar ieee754 = require('ieee754');\n\nfunction Pbf(buf) {\n this.buf = ArrayBuffer.isView && ArrayBuffer.isView(buf) ? buf : new Uint8Array(buf || 0);\n this.pos = 0;\n this.type = 0;\n this.length = this.buf.length;\n}\n\nPbf.Varint = 0; // varint: int32, int64, uint32, uint64, sint32, sint64, bool, enum\nPbf.Fixed64 = 1; // 64-bit: double, fixed64, sfixed64\nPbf.Bytes = 2; // length-delimited: string, bytes, embedded messages, packed repeated fields\nPbf.Fixed32 = 5; // 32-bit: float, fixed32, sfixed32\n\nvar SHIFT_LEFT_32 = (1 << 16) * (1 << 16),\n SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32;\n\n// Threshold chosen based on both benchmarking and knowledge about browser string\n// data structures (which currently switch structure types at 12 bytes or more)\nvar TEXT_DECODER_MIN_LENGTH = 12;\nvar utf8TextDecoder = typeof TextDecoder === 'undefined' ? null : new TextDecoder('utf8');\n\nPbf.prototype = {\n\n destroy: function() {\n this.buf = null;\n },\n\n // === READING =================================================================\n\n readFields: function(readField, result, end) {\n end = end || this.length;\n\n while (this.pos < end) {\n var val = this.readVarint(),\n tag = val >> 3,\n startPos = this.pos;\n\n this.type = val & 0x7;\n readField(tag, result, this);\n\n if (this.pos === startPos) this.skip(val);\n }\n return result;\n },\n\n readMessage: function(readField, result) {\n return this.readFields(readField, result, this.readVarint() + this.pos);\n },\n\n readFixed32: function() {\n var val = readUInt32(this.buf, this.pos);\n this.pos += 4;\n return val;\n },\n\n readSFixed32: function() {\n var val = readInt32(this.buf, this.pos);\n this.pos += 4;\n return val;\n },\n\n // 64-bit int handling is based on github.com/dpw/node-buffer-more-ints (MIT-licensed)\n\n readFixed64: function() {\n var val = readUInt32(this.buf, this.pos) + readUInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32;\n this.pos += 8;\n return val;\n },\n\n readSFixed64: function() {\n var val = readUInt32(this.buf, this.pos) + readInt32(this.buf, this.pos + 4) * SHIFT_LEFT_32;\n this.pos += 8;\n return val;\n },\n\n readFloat: function() {\n var val = ieee754.read(this.buf, this.pos, true, 23, 4);\n this.pos += 4;\n return val;\n },\n\n readDouble: function() {\n var val = ieee754.read(this.buf, this.pos, true, 52, 8);\n this.pos += 8;\n return val;\n },\n\n readVarint: function(isSigned) {\n var buf = this.buf,\n val, b;\n\n b = buf[this.pos++]; val = b & 0x7f; if (b < 0x80) return val;\n b = buf[this.pos++]; val |= (b & 0x7f) << 7; if (b < 0x80) return val;\n b = buf[this.pos++]; val |= (b & 0x7f) << 14; if (b < 0x80) return val;\n b = buf[this.pos++]; val |= (b & 0x7f) << 21; if (b < 0x80) return val;\n b = buf[this.pos]; val |= (b & 0x0f) << 28;\n\n return readVarintRemainder(val, isSigned, this);\n },\n\n readVarint64: function() { // for compatibility with v2.0.1\n return this.readVarint(true);\n },\n\n readSVarint: function() {\n var num = this.readVarint();\n return num % 2 === 1 ? (num + 1) / -2 : num / 2; // zigzag encoding\n },\n\n readBoolean: function() {\n return Boolean(this.readVarint());\n },\n\n readString: function() {\n var end = this.readVarint() + this.pos;\n var pos = this.pos;\n this.pos = end;\n\n if (end - pos >= TEXT_DECODER_MIN_LENGTH && utf8TextDecoder) {\n // longer strings are fast with the built-in browser TextDecoder API\n return readUtf8TextDecoder(this.buf, pos, end);\n }\n // short strings are fast with our custom implementation\n return readUtf8(this.buf, pos, end);\n },\n\n readBytes: function() {\n var end = this.readVarint() + this.pos,\n buffer = this.buf.subarray(this.pos, end);\n this.pos = end;\n return buffer;\n },\n\n // verbose for performance reasons; doesn't affect gzipped size\n\n readPackedVarint: function(arr, isSigned) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readVarint(isSigned));\n var end = readPackedEnd(this);\n arr = arr || [];\n while (this.pos < end) arr.push(this.readVarint(isSigned));\n return arr;\n },\n readPackedSVarint: function(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readSVarint());\n var end = readPackedEnd(this);\n arr = arr || [];\n while (this.pos < end) arr.push(this.readSVarint());\n return arr;\n },\n readPackedBoolean: function(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readBoolean());\n var end = readPackedEnd(this);\n arr = arr || [];\n while (this.pos < end) arr.push(this.readBoolean());\n return arr;\n },\n readPackedFloat: function(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readFloat());\n var end = readPackedEnd(this);\n arr = arr || [];\n while (this.pos < end) arr.push(this.readFloat());\n return arr;\n },\n readPackedDouble: function(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readDouble());\n var end = readPackedEnd(this);\n arr = arr || [];\n while (this.pos < end) arr.push(this.readDouble());\n return arr;\n },\n readPackedFixed32: function(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readFixed32());\n var end = readPackedEnd(this);\n arr = arr || [];\n while (this.pos < end) arr.push(this.readFixed32());\n return arr;\n },\n readPackedSFixed32: function(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readSFixed32());\n var end = readPackedEnd(this);\n arr = arr || [];\n while (this.pos < end) arr.push(this.readSFixed32());\n return arr;\n },\n readPackedFixed64: function(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readFixed64());\n var end = readPackedEnd(this);\n arr = arr || [];\n while (this.pos < end) arr.push(this.readFixed64());\n return arr;\n },\n readPackedSFixed64: function(arr) {\n if (this.type !== Pbf.Bytes) return arr.push(this.readSFixed64());\n var end = readPackedEnd(this);\n arr = arr || [];\n while (this.pos < end) arr.push(this.readSFixed64());\n return arr;\n },\n\n skip: function(val) {\n var type = val & 0x7;\n if (type === Pbf.Varint) while (this.buf[this.pos++] > 0x7f) {}\n else if (type === Pbf.Bytes) this.pos = this.readVarint() + this.pos;\n else if (type === Pbf.Fixed32) this.pos += 4;\n else if (type === Pbf.Fixed64) this.pos += 8;\n else throw new Error('Unimplemented type: ' + type);\n },\n\n // === WRITING =================================================================\n\n writeTag: function(tag, type) {\n this.writeVarint((tag << 3) | type);\n },\n\n realloc: function(min) {\n var length = this.length || 16;\n\n while (length < this.pos + min) length *= 2;\n\n if (length !== this.length) {\n var buf = new Uint8Array(length);\n buf.set(this.buf);\n this.buf = buf;\n this.length = length;\n }\n },\n\n finish: function() {\n this.length = this.pos;\n this.pos = 0;\n return this.buf.subarray(0, this.length);\n },\n\n writeFixed32: function(val) {\n this.realloc(4);\n writeInt32(this.buf, val, this.pos);\n this.pos += 4;\n },\n\n writeSFixed32: function(val) {\n this.realloc(4);\n writeInt32(this.buf, val, this.pos);\n this.pos += 4;\n },\n\n writeFixed64: function(val) {\n this.realloc(8);\n writeInt32(this.buf, val & -1, this.pos);\n writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);\n this.pos += 8;\n },\n\n writeSFixed64: function(val) {\n this.realloc(8);\n writeInt32(this.buf, val & -1, this.pos);\n writeInt32(this.buf, Math.floor(val * SHIFT_RIGHT_32), this.pos + 4);\n this.pos += 8;\n },\n\n writeVarint: function(val) {\n val = +val || 0;\n\n if (val > 0xfffffff || val < 0) {\n writeBigVarint(val, this);\n return;\n }\n\n this.realloc(4);\n\n this.buf[this.pos++] = val & 0x7f | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return;\n this.buf[this.pos++] = ((val >>>= 7) & 0x7f) | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return;\n this.buf[this.pos++] = ((val >>>= 7) & 0x7f) | (val > 0x7f ? 0x80 : 0); if (val <= 0x7f) return;\n this.buf[this.pos++] = (val >>> 7) & 0x7f;\n },\n\n writeSVarint: function(val) {\n this.writeVarint(val < 0 ? -val * 2 - 1 : val * 2);\n },\n\n writeBoolean: function(val) {\n this.writeVarint(Boolean(val));\n },\n\n writeString: function(str) {\n str = String(str);\n this.realloc(str.length * 4);\n\n this.pos++; // reserve 1 byte for short string length\n\n var startPos = this.pos;\n // write the string directly to the buffer and see how much was written\n this.pos = writeUtf8(this.buf, str, this.pos);\n var len = this.pos - startPos;\n\n if (len >= 0x80) makeRoomForExtraLength(startPos, len, this);\n\n // finally, write the message length in the reserved place and restore the position\n this.pos = startPos - 1;\n this.writeVarint(len);\n this.pos += len;\n },\n\n writeFloat: function(val) {\n this.realloc(4);\n ieee754.write(this.buf, val, this.pos, true, 23, 4);\n this.pos += 4;\n },\n\n writeDouble: function(val) {\n this.realloc(8);\n ieee754.write(this.buf, val, this.pos, true, 52, 8);\n this.pos += 8;\n },\n\n writeBytes: function(buffer) {\n var len = buffer.length;\n this.writeVarint(len);\n this.realloc(len);\n for (var i = 0; i < len; i++) this.buf[this.pos++] = buffer[i];\n },\n\n writeRawMessage: function(fn, obj) {\n this.pos++; // reserve 1 byte for short message length\n\n // write the message directly to the buffer and see how much was written\n var startPos = this.pos;\n fn(obj, this);\n var len = this.pos - startPos;\n\n if (len >= 0x80) makeRoomForExtraLength(startPos, len, this);\n\n // finally, write the message length in the reserved place and restore the position\n this.pos = startPos - 1;\n this.writeVarint(len);\n this.pos += len;\n },\n\n writeMessage: function(tag, fn, obj) {\n this.writeTag(tag, Pbf.Bytes);\n this.writeRawMessage(fn, obj);\n },\n\n writePackedVarint: function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedVarint, arr); },\n writePackedSVarint: function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedSVarint, arr); },\n writePackedBoolean: function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedBoolean, arr); },\n writePackedFloat: function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedFloat, arr); },\n writePackedDouble: function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedDouble, arr); },\n writePackedFixed32: function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedFixed32, arr); },\n writePackedSFixed32: function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedSFixed32, arr); },\n writePackedFixed64: function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedFixed64, arr); },\n writePackedSFixed64: function(tag, arr) { if (arr.length) this.writeMessage(tag, writePackedSFixed64, arr); },\n\n writeBytesField: function(tag, buffer) {\n this.writeTag(tag, Pbf.Bytes);\n this.writeBytes(buffer);\n },\n writeFixed32Field: function(tag, val) {\n this.writeTag(tag, Pbf.Fixed32);\n this.writeFixed32(val);\n },\n writeSFixed32Field: function(tag, val) {\n this.writeTag(tag, Pbf.Fixed32);\n this.writeSFixed32(val);\n },\n writeFixed64Field: function(tag, val) {\n this.writeTag(tag, Pbf.Fixed64);\n this.writeFixed64(val);\n },\n writeSFixed64Field: function(tag, val) {\n this.writeTag(tag, Pbf.Fixed64);\n this.writeSFixed64(val);\n },\n writeVarintField: function(tag, val) {\n this.writeTag(tag, Pbf.Varint);\n this.writeVarint(val);\n },\n writeSVarintField: function(tag, val) {\n this.writeTag(tag, Pbf.Varint);\n this.writeSVarint(val);\n },\n writeStringField: function(tag, str) {\n this.writeTag(tag, Pbf.Bytes);\n this.writeString(str);\n },\n writeFloatField: function(tag, val) {\n this.writeTag(tag, Pbf.Fixed32);\n this.writeFloat(val);\n },\n writeDoubleField: function(tag, val) {\n this.writeTag(tag, Pbf.Fixed64);\n this.writeDouble(val);\n },\n writeBooleanField: function(tag, val) {\n this.writeVarintField(tag, Boolean(val));\n }\n};\n\nfunction readVarintRemainder(l, s, p) {\n var buf = p.buf,\n h, b;\n\n b = buf[p.pos++]; h = (b & 0x70) >> 4; if (b < 0x80) return toNum(l, h, s);\n b = buf[p.pos++]; h |= (b & 0x7f) << 3; if (b < 0x80) return toNum(l, h, s);\n b = buf[p.pos++]; h |= (b & 0x7f) << 10; if (b < 0x80) return toNum(l, h, s);\n b = buf[p.pos++]; h |= (b & 0x7f) << 17; if (b < 0x80) return toNum(l, h, s);\n b = buf[p.pos++]; h |= (b & 0x7f) << 24; if (b < 0x80) return toNum(l, h, s);\n b = buf[p.pos++]; h |= (b & 0x01) << 31; if (b < 0x80) return toNum(l, h, s);\n\n throw new Error('Expected varint not more than 10 bytes');\n}\n\nfunction readPackedEnd(pbf) {\n return pbf.type === Pbf.Bytes ?\n pbf.readVarint() + pbf.pos : pbf.pos + 1;\n}\n\nfunction toNum(low, high, isSigned) {\n if (isSigned) {\n return high * 0x100000000 + (low >>> 0);\n }\n\n return ((high >>> 0) * 0x100000000) + (low >>> 0);\n}\n\nfunction writeBigVarint(val, pbf) {\n var low, high;\n\n if (val >= 0) {\n low = (val % 0x100000000) | 0;\n high = (val / 0x100000000) | 0;\n } else {\n low = ~(-val % 0x100000000);\n high = ~(-val / 0x100000000);\n\n if (low ^ 0xffffffff) {\n low = (low + 1) | 0;\n } else {\n low = 0;\n high = (high + 1) | 0;\n }\n }\n\n if (val >= 0x10000000000000000 || val < -0x10000000000000000) {\n throw new Error('Given varint doesn\\'t fit into 10 bytes');\n }\n\n pbf.realloc(10);\n\n writeBigVarintLow(low, high, pbf);\n writeBigVarintHigh(high, pbf);\n}\n\nfunction writeBigVarintLow(low, high, pbf) {\n pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;\n pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;\n pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;\n pbf.buf[pbf.pos++] = low & 0x7f | 0x80; low >>>= 7;\n pbf.buf[pbf.pos] = low & 0x7f;\n}\n\nfunction writeBigVarintHigh(high, pbf) {\n var lsb = (high & 0x07) << 4;\n\n pbf.buf[pbf.pos++] |= lsb | ((high >>>= 3) ? 0x80 : 0); if (!high) return;\n pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;\n pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;\n pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;\n pbf.buf[pbf.pos++] = high & 0x7f | ((high >>>= 7) ? 0x80 : 0); if (!high) return;\n pbf.buf[pbf.pos++] = high & 0x7f;\n}\n\nfunction makeRoomForExtraLength(startPos, len, pbf) {\n var extraLen =\n len <= 0x3fff ? 1 :\n len <= 0x1fffff ? 2 :\n len <= 0xfffffff ? 3 : Math.floor(Math.log(len) / (Math.LN2 * 7));\n\n // if 1 byte isn't enough for encoding message length, shift the data to the right\n pbf.realloc(extraLen);\n for (var i = pbf.pos - 1; i >= startPos; i--) pbf.buf[i + extraLen] = pbf.buf[i];\n}\n\nfunction writePackedVarint(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeVarint(arr[i]); }\nfunction writePackedSVarint(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeSVarint(arr[i]); }\nfunction writePackedFloat(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeFloat(arr[i]); }\nfunction writePackedDouble(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeDouble(arr[i]); }\nfunction writePackedBoolean(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeBoolean(arr[i]); }\nfunction writePackedFixed32(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeFixed32(arr[i]); }\nfunction writePackedSFixed32(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeSFixed32(arr[i]); }\nfunction writePackedFixed64(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeFixed64(arr[i]); }\nfunction writePackedSFixed64(arr, pbf) { for (var i = 0; i < arr.length; i++) pbf.writeSFixed64(arr[i]); }\n\n// Buffer code below from https://github.com/feross/buffer, MIT-licensed\n\nfunction readUInt32(buf, pos) {\n return ((buf[pos]) |\n (buf[pos + 1] << 8) |\n (buf[pos + 2] << 16)) +\n (buf[pos + 3] * 0x1000000);\n}\n\nfunction writeInt32(buf, val, pos) {\n buf[pos] = val;\n buf[pos + 1] = (val >>> 8);\n buf[pos + 2] = (val >>> 16);\n buf[pos + 3] = (val >>> 24);\n}\n\nfunction readInt32(buf, pos) {\n return ((buf[pos]) |\n (buf[pos + 1] << 8) |\n (buf[pos + 2] << 16)) +\n (buf[pos + 3] << 24);\n}\n\nfunction readUtf8(buf, pos, end) {\n var str = '';\n var i = pos;\n\n while (i < end) {\n var b0 = buf[i];\n var c = null; // codepoint\n var bytesPerSequence =\n b0 > 0xEF ? 4 :\n b0 > 0xDF ? 3 :\n b0 > 0xBF ? 2 : 1;\n\n if (i + bytesPerSequence > end) break;\n\n var b1, b2, b3;\n\n if (bytesPerSequence === 1) {\n if (b0 < 0x80) {\n c = b0;\n }\n } else if (bytesPerSequence === 2) {\n b1 = buf[i + 1];\n if ((b1 & 0xC0) === 0x80) {\n c = (b0 & 0x1F) << 0x6 | (b1 & 0x3F);\n if (c <= 0x7F) {\n c = null;\n }\n }\n } else if (bytesPerSequence === 3) {\n b1 = buf[i + 1];\n b2 = buf[i + 2];\n if ((b1 & 0xC0) === 0x80 && (b2 & 0xC0) === 0x80) {\n c = (b0 & 0xF) << 0xC | (b1 & 0x3F) << 0x6 | (b2 & 0x3F);\n if (c <= 0x7FF || (c >= 0xD800 && c <= 0xDFFF)) {\n c = null;\n }\n }\n } else if (bytesPerSequence === 4) {\n b1 = buf[i + 1];\n b2 = buf[i + 2];\n b3 = buf[i + 3];\n if ((b1 & 0xC0) === 0x80 && (b2 & 0xC0) === 0x80 && (b3 & 0xC0) === 0x80) {\n c = (b0 & 0xF) << 0x12 | (b1 & 0x3F) << 0xC | (b2 & 0x3F) << 0x6 | (b3 & 0x3F);\n if (c <= 0xFFFF || c >= 0x110000) {\n c = null;\n }\n }\n }\n\n if (c === null) {\n c = 0xFFFD;\n bytesPerSequence = 1;\n\n } else if (c > 0xFFFF) {\n c -= 0x10000;\n str += String.fromCharCode(c >>> 10 & 0x3FF | 0xD800);\n c = 0xDC00 | c & 0x3FF;\n }\n\n str += String.fromCharCode(c);\n i += bytesPerSequence;\n }\n\n return str;\n}\n\nfunction readUtf8TextDecoder(buf, pos, end) {\n return utf8TextDecoder.decode(buf.subarray(pos, end));\n}\n\nfunction writeUtf8(buf, str, pos) {\n for (var i = 0, c, lead; i < str.length; i++) {\n c = str.charCodeAt(i); // code point\n\n if (c > 0xD7FF && c < 0xE000) {\n if (lead) {\n if (c < 0xDC00) {\n buf[pos++] = 0xEF;\n buf[pos++] = 0xBF;\n buf[pos++] = 0xBD;\n lead = c;\n continue;\n } else {\n c = lead - 0xD800 << 10 | c - 0xDC00 | 0x10000;\n lead = null;\n }\n } else {\n if (c > 0xDBFF || (i + 1 === str.length)) {\n buf[pos++] = 0xEF;\n buf[pos++] = 0xBF;\n buf[pos++] = 0xBD;\n } else {\n lead = c;\n }\n continue;\n }\n } else if (lead) {\n buf[pos++] = 0xEF;\n buf[pos++] = 0xBF;\n buf[pos++] = 0xBD;\n lead = null;\n }\n\n if (c < 0x80) {\n buf[pos++] = c;\n } else {\n if (c < 0x800) {\n buf[pos++] = c >> 0x6 | 0xC0;\n } else {\n if (c < 0x10000) {\n buf[pos++] = c >> 0xC | 0xE0;\n } else {\n buf[pos++] = c >> 0x12 | 0xF0;\n buf[pos++] = c >> 0xC & 0x3F | 0x80;\n }\n buf[pos++] = c >> 0x6 & 0x3F | 0x80;\n }\n buf[pos++] = c & 0x3F | 0x80;\n }\n }\n return pos;\n}\n","!function(t,i){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=i():\"function\"==typeof define&&define.amd?define(i):(t=t||self).RBush=i()}(this,function(){\"use strict\";function t(t,r,e,a,h){!function t(n,r,e,a,h){for(;a>e;){if(a-e>600){var o=a-e+1,s=r-e+1,l=Math.log(o),f=.5*Math.exp(2*l/3),u=.5*Math.sqrt(l*f*(o-f)/o)*(s-o/2<0?-1:1),m=Math.max(e,Math.floor(r-s*f/o+u)),c=Math.min(a,Math.floor(r+(o-s)*f/o+u));t(n,r,m,c,h)}var p=n[r],d=e,x=a;for(i(n,e,r),h(n[a],p)>0&&i(n,e,a);d0;)x--}0===h(n[e],p)?i(n,e,x):i(n,++x,a),x<=r&&(e=x+1),r<=x&&(a=x-1)}}(t,r,e||0,a||t.length-1,h||n)}function i(t,i,n){var r=t[i];t[i]=t[n],t[n]=r}function n(t,i){return ti?1:0}var r=function(t){void 0===t&&(t=9),this._maxEntries=Math.max(4,t),this._minEntries=Math.max(2,Math.ceil(.4*this._maxEntries)),this.clear()};function e(t,i,n){if(!n)return i.indexOf(t);for(var r=0;r=t.minX&&i.maxY>=t.minY}function p(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function d(i,n,r,e,a){for(var h=[n,r];h.length;)if(!((r=h.pop())-(n=h.pop())<=e)){var o=n+Math.ceil((r-n)/e/2)*e;t(i,o,n,r,a),h.push(n,o,o,r)}}return r.prototype.all=function(){return this._all(this.data,[])},r.prototype.search=function(t){var i=this.data,n=[];if(!c(t,i))return n;for(var r=this.toBBox,e=[];i;){for(var a=0;a=0&&e[i].children.length>this._maxEntries;)this._split(e,i),i--;this._adjustParentBBoxes(r,e,i)},r.prototype._split=function(t,i){var n=t[i],r=n.children.length,e=this._minEntries;this._chooseSplitAxis(n,e,r);var h=this._chooseSplitIndex(n,e,r),o=p(n.children.splice(h,n.children.length-h));o.height=n.height,o.leaf=n.leaf,a(n,this.toBBox),a(o,this.toBBox),i?t[i-1].children.push(o):this._splitRoot(n,o)},r.prototype._splitRoot=function(t,i){this.data=p([t,i]),this.data.height=t.height+1,this.data.leaf=!1,a(this.data,this.toBBox)},r.prototype._chooseSplitIndex=function(t,i,n){for(var r,e,a,o,s,l,u,m=1/0,c=1/0,p=i;p<=n-i;p++){var d=h(t,0,p,this.toBBox),x=h(t,p,n,this.toBBox),v=(e=d,a=x,o=void 0,s=void 0,l=void 0,u=void 0,o=Math.max(e.minX,a.minX),s=Math.max(e.minY,a.minY),l=Math.min(e.maxX,a.maxX),u=Math.min(e.maxY,a.maxY),Math.max(0,l-o)*Math.max(0,u-s)),M=f(d)+f(x);v=i;c--){var p=t.children[c];o(s,t.leaf?e(p):p),l+=u(s)}return l},r.prototype._adjustParentBBoxes=function(t,i,n){for(var r=n;r>=0;r--)o(i[r],t)},r.prototype._condense=function(t){for(var i=t.length-1,n=void 0;i>=0;i--)0===t[i].children.length?i>0?(n=t[i-1].children).splice(n.indexOf(t[i]),1):this.clear():a(t[i],this.toBBox)},r});\n","/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nvar runtime = (function (exports) {\n \"use strict\";\n\n var Op = Object.prototype;\n var hasOwn = Op.hasOwnProperty;\n var undefined; // More compressible than void 0.\n var $Symbol = typeof Symbol === \"function\" ? Symbol : {};\n var iteratorSymbol = $Symbol.iterator || \"@@iterator\";\n var asyncIteratorSymbol = $Symbol.asyncIterator || \"@@asyncIterator\";\n var toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n function define(obj, key, value) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n return obj[key];\n }\n try {\n // IE 8 has a broken Object.defineProperty that only works on DOM objects.\n define({}, \"\");\n } catch (err) {\n define = function(obj, key, value) {\n return obj[key] = value;\n };\n }\n\n function wrap(innerFn, outerFn, self, tryLocsList) {\n // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.\n var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;\n var generator = Object.create(protoGenerator.prototype);\n var context = new Context(tryLocsList || []);\n\n // The ._invoke method unifies the implementations of the .next,\n // .throw, and .return methods.\n generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n return generator;\n }\n exports.wrap = wrap;\n\n // Try/catch helper to minimize deoptimizations. Returns a completion\n // record like context.tryEntries[i].completion. This interface could\n // have been (and was previously) designed to take a closure to be\n // invoked without arguments, but in all the cases we care about we\n // already have an existing method we want to call, so there's no need\n // to create a new function object. We can even get away with assuming\n // the method takes exactly one argument, since that happens to be true\n // in every case, so we don't have to touch the arguments object. The\n // only additional allocation required is the completion record, which\n // has a stable shape and so hopefully should be cheap to allocate.\n function tryCatch(fn, obj, arg) {\n try {\n return { type: \"normal\", arg: fn.call(obj, arg) };\n } catch (err) {\n return { type: \"throw\", arg: err };\n }\n }\n\n var GenStateSuspendedStart = \"suspendedStart\";\n var GenStateSuspendedYield = \"suspendedYield\";\n var GenStateExecuting = \"executing\";\n var GenStateCompleted = \"completed\";\n\n // Returning this object from the innerFn has the same effect as\n // breaking out of the dispatch switch statement.\n var ContinueSentinel = {};\n\n // Dummy constructor functions that we use as the .constructor and\n // .constructor.prototype properties for functions that return Generator\n // objects. For full spec compliance, you may wish to configure your\n // minifier not to mangle the names of these two functions.\n function Generator() {}\n function GeneratorFunction() {}\n function GeneratorFunctionPrototype() {}\n\n // This is a polyfill for %IteratorPrototype% for environments that\n // don't natively support it.\n var IteratorPrototype = {};\n define(IteratorPrototype, iteratorSymbol, function () {\n return this;\n });\n\n var getProto = Object.getPrototypeOf;\n var NativeIteratorPrototype = getProto && getProto(getProto(values([])));\n if (NativeIteratorPrototype &&\n NativeIteratorPrototype !== Op &&\n hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {\n // This environment has a native %IteratorPrototype%; use it instead\n // of the polyfill.\n IteratorPrototype = NativeIteratorPrototype;\n }\n\n var Gp = GeneratorFunctionPrototype.prototype =\n Generator.prototype = Object.create(IteratorPrototype);\n GeneratorFunction.prototype = GeneratorFunctionPrototype;\n define(Gp, \"constructor\", GeneratorFunctionPrototype);\n define(GeneratorFunctionPrototype, \"constructor\", GeneratorFunction);\n GeneratorFunction.displayName = define(\n GeneratorFunctionPrototype,\n toStringTagSymbol,\n \"GeneratorFunction\"\n );\n\n // Helper for defining the .next, .throw, and .return methods of the\n // Iterator interface in terms of a single ._invoke method.\n function defineIteratorMethods(prototype) {\n [\"next\", \"throw\", \"return\"].forEach(function(method) {\n define(prototype, method, function(arg) {\n return this._invoke(method, arg);\n });\n });\n }\n\n exports.isGeneratorFunction = function(genFun) {\n var ctor = typeof genFun === \"function\" && genFun.constructor;\n return ctor\n ? ctor === GeneratorFunction ||\n // For the native GeneratorFunction constructor, the best we can\n // do is to check its .name property.\n (ctor.displayName || ctor.name) === \"GeneratorFunction\"\n : false;\n };\n\n exports.mark = function(genFun) {\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);\n } else {\n genFun.__proto__ = GeneratorFunctionPrototype;\n define(genFun, toStringTagSymbol, \"GeneratorFunction\");\n }\n genFun.prototype = Object.create(Gp);\n return genFun;\n };\n\n // Within the body of any async function, `await x` is transformed to\n // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test\n // `hasOwn.call(value, \"__await\")` to determine if the yielded value is\n // meant to be awaited.\n exports.awrap = function(arg) {\n return { __await: arg };\n };\n\n function AsyncIterator(generator, PromiseImpl) {\n function invoke(method, arg, resolve, reject) {\n var record = tryCatch(generator[method], generator, arg);\n if (record.type === \"throw\") {\n reject(record.arg);\n } else {\n var result = record.arg;\n var value = result.value;\n if (value &&\n typeof value === \"object\" &&\n hasOwn.call(value, \"__await\")) {\n return PromiseImpl.resolve(value.__await).then(function(value) {\n invoke(\"next\", value, resolve, reject);\n }, function(err) {\n invoke(\"throw\", err, resolve, reject);\n });\n }\n\n return PromiseImpl.resolve(value).then(function(unwrapped) {\n // When a yielded Promise is resolved, its final value becomes\n // the .value of the Promise<{value,done}> result for the\n // current iteration.\n result.value = unwrapped;\n resolve(result);\n }, function(error) {\n // If a rejected Promise was yielded, throw the rejection back\n // into the async generator function so it can be handled there.\n return invoke(\"throw\", error, resolve, reject);\n });\n }\n }\n\n var previousPromise;\n\n function enqueue(method, arg) {\n function callInvokeWithMethodAndArg() {\n return new PromiseImpl(function(resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise =\n // If enqueue has been called before, then we want to wait until\n // all previous Promises have been resolved before calling invoke,\n // so that results are always delivered in the correct order. If\n // enqueue has not been called before, then it is important to\n // call invoke immediately, without waiting on a callback to fire,\n // so that the async generator function has the opportunity to do\n // any necessary setup in a predictable way. This predictability\n // is why the Promise constructor synchronously invokes its\n // executor callback, and why async functions synchronously\n // execute code before the first await. Since we implement simple\n // async functions in terms of async generators, it is especially\n // important to get this right, even though it requires care.\n previousPromise ? previousPromise.then(\n callInvokeWithMethodAndArg,\n // Avoid propagating failures to Promises returned by later\n // invocations of the iterator.\n callInvokeWithMethodAndArg\n ) : callInvokeWithMethodAndArg();\n }\n\n // Define the unified helper method that is used to implement .next,\n // .throw, and .return (see defineIteratorMethods).\n this._invoke = enqueue;\n }\n\n defineIteratorMethods(AsyncIterator.prototype);\n define(AsyncIterator.prototype, asyncIteratorSymbol, function () {\n return this;\n });\n exports.AsyncIterator = AsyncIterator;\n\n // Note that simple async functions are implemented on top of\n // AsyncIterator objects; they just return a Promise for the value of\n // the final result produced by the iterator.\n exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) {\n if (PromiseImpl === void 0) PromiseImpl = Promise;\n\n var iter = new AsyncIterator(\n wrap(innerFn, outerFn, self, tryLocsList),\n PromiseImpl\n );\n\n return exports.isGeneratorFunction(outerFn)\n ? iter // If outerFn is a generator, return the full iterator.\n : iter.next().then(function(result) {\n return result.done ? result.value : iter.next();\n });\n };\n\n function makeInvokeMethod(innerFn, self, context) {\n var state = GenStateSuspendedStart;\n\n return function invoke(method, arg) {\n if (state === GenStateExecuting) {\n throw new Error(\"Generator is already running\");\n }\n\n if (state === GenStateCompleted) {\n if (method === \"throw\") {\n throw arg;\n }\n\n // Be forgiving, per 25.3.3.3.3 of the spec:\n // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n return doneResult();\n }\n\n context.method = method;\n context.arg = arg;\n\n while (true) {\n var delegate = context.delegate;\n if (delegate) {\n var delegateResult = maybeInvokeDelegate(delegate, context);\n if (delegateResult) {\n if (delegateResult === ContinueSentinel) continue;\n return delegateResult;\n }\n }\n\n if (context.method === \"next\") {\n // Setting context._sent for legacy support of Babel's\n // function.sent implementation.\n context.sent = context._sent = context.arg;\n\n } else if (context.method === \"throw\") {\n if (state === GenStateSuspendedStart) {\n state = GenStateCompleted;\n throw context.arg;\n }\n\n context.dispatchException(context.arg);\n\n } else if (context.method === \"return\") {\n context.abrupt(\"return\", context.arg);\n }\n\n state = GenStateExecuting;\n\n var record = tryCatch(innerFn, self, context);\n if (record.type === \"normal\") {\n // If an exception is thrown from innerFn, we leave state ===\n // GenStateExecuting and loop back for another invocation.\n state = context.done\n ? GenStateCompleted\n : GenStateSuspendedYield;\n\n if (record.arg === ContinueSentinel) {\n continue;\n }\n\n return {\n value: record.arg,\n done: context.done\n };\n\n } else if (record.type === \"throw\") {\n state = GenStateCompleted;\n // Dispatch the exception by looping back around to the\n // context.dispatchException(context.arg) call above.\n context.method = \"throw\";\n context.arg = record.arg;\n }\n }\n };\n }\n\n // Call delegate.iterator[context.method](context.arg) and handle the\n // result, either by returning a { value, done } result from the\n // delegate iterator, or by modifying context.method and context.arg,\n // setting context.delegate to null, and returning the ContinueSentinel.\n function maybeInvokeDelegate(delegate, context) {\n var method = delegate.iterator[context.method];\n if (method === undefined) {\n // A .throw or .return when the delegate iterator has no .throw\n // method always terminates the yield* loop.\n context.delegate = null;\n\n if (context.method === \"throw\") {\n // Note: [\"return\"] must be used for ES3 parsing compatibility.\n if (delegate.iterator[\"return\"]) {\n // If the delegate iterator has a return method, give it a\n // chance to clean up.\n context.method = \"return\";\n context.arg = undefined;\n maybeInvokeDelegate(delegate, context);\n\n if (context.method === \"throw\") {\n // If maybeInvokeDelegate(context) changed context.method from\n // \"return\" to \"throw\", let that override the TypeError below.\n return ContinueSentinel;\n }\n }\n\n context.method = \"throw\";\n context.arg = new TypeError(\n \"The iterator does not provide a 'throw' method\");\n }\n\n return ContinueSentinel;\n }\n\n var record = tryCatch(method, delegate.iterator, context.arg);\n\n if (record.type === \"throw\") {\n context.method = \"throw\";\n context.arg = record.arg;\n context.delegate = null;\n return ContinueSentinel;\n }\n\n var info = record.arg;\n\n if (! info) {\n context.method = \"throw\";\n context.arg = new TypeError(\"iterator result is not an object\");\n context.delegate = null;\n return ContinueSentinel;\n }\n\n if (info.done) {\n // Assign the result of the finished delegate to the temporary\n // variable specified by delegate.resultName (see delegateYield).\n context[delegate.resultName] = info.value;\n\n // Resume execution at the desired location (see delegateYield).\n context.next = delegate.nextLoc;\n\n // If context.method was \"throw\" but the delegate handled the\n // exception, let the outer generator proceed normally. If\n // context.method was \"next\", forget context.arg since it has been\n // \"consumed\" by the delegate iterator. If context.method was\n // \"return\", allow the original .return call to continue in the\n // outer generator.\n if (context.method !== \"return\") {\n context.method = \"next\";\n context.arg = undefined;\n }\n\n } else {\n // Re-yield the result returned by the delegate method.\n return info;\n }\n\n // The delegate iterator is finished, so forget it and continue with\n // the outer generator.\n context.delegate = null;\n return ContinueSentinel;\n }\n\n // Define Generator.prototype.{next,throw,return} in terms of the\n // unified ._invoke helper method.\n defineIteratorMethods(Gp);\n\n define(Gp, toStringTagSymbol, \"Generator\");\n\n // A Generator should always return itself as the iterator object when the\n // @@iterator function is called on it. Some browsers' implementations of the\n // iterator prototype chain incorrectly implement this, causing the Generator\n // object to not be returned from this call. This ensures that doesn't happen.\n // See https://github.com/facebook/regenerator/issues/274 for more details.\n define(Gp, iteratorSymbol, function() {\n return this;\n });\n\n define(Gp, \"toString\", function() {\n return \"[object Generator]\";\n });\n\n function pushTryEntry(locs) {\n var entry = { tryLoc: locs[0] };\n\n if (1 in locs) {\n entry.catchLoc = locs[1];\n }\n\n if (2 in locs) {\n entry.finallyLoc = locs[2];\n entry.afterLoc = locs[3];\n }\n\n this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = \"normal\";\n delete record.arg;\n entry.completion = record;\n }\n\n function Context(tryLocsList) {\n // The root entry object (effectively a try statement without a catch\n // or a finally block) gives us a place to store values thrown from\n // locations where there is no enclosing try statement.\n this.tryEntries = [{ tryLoc: \"root\" }];\n tryLocsList.forEach(pushTryEntry, this);\n this.reset(true);\n }\n\n exports.keys = function(object) {\n var keys = [];\n for (var key in object) {\n keys.push(key);\n }\n keys.reverse();\n\n // Rather than returning an object with a next method, we keep\n // things simple and return the next function itself.\n return function next() {\n while (keys.length) {\n var key = keys.pop();\n if (key in object) {\n next.value = key;\n next.done = false;\n return next;\n }\n }\n\n // To avoid creating an additional object, we just hang the .value\n // and .done properties off the next function object itself. This\n // also ensures that the minifier will not anonymize the function.\n next.done = true;\n return next;\n };\n };\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) {\n return iteratorMethod.call(iterable);\n }\n\n if (typeof iterable.next === \"function\") {\n return iterable;\n }\n\n if (!isNaN(iterable.length)) {\n var i = -1, next = function next() {\n while (++i < iterable.length) {\n if (hasOwn.call(iterable, i)) {\n next.value = iterable[i];\n next.done = false;\n return next;\n }\n }\n\n next.value = undefined;\n next.done = true;\n\n return next;\n };\n\n return next.next = next;\n }\n }\n\n // Return an iterator with no values.\n return { next: doneResult };\n }\n exports.values = values;\n\n function doneResult() {\n return { value: undefined, done: true };\n }\n\n Context.prototype = {\n constructor: Context,\n\n reset: function(skipTempReset) {\n this.prev = 0;\n this.next = 0;\n // Resetting context._sent for legacy support of Babel's\n // function.sent implementation.\n this.sent = this._sent = undefined;\n this.done = false;\n this.delegate = null;\n\n this.method = \"next\";\n this.arg = undefined;\n\n this.tryEntries.forEach(resetTryEntry);\n\n if (!skipTempReset) {\n for (var name in this) {\n // Not sure about the optimal order of these conditions:\n if (name.charAt(0) === \"t\" &&\n hasOwn.call(this, name) &&\n !isNaN(+name.slice(1))) {\n this[name] = undefined;\n }\n }\n }\n },\n\n stop: function() {\n this.done = true;\n\n var rootEntry = this.tryEntries[0];\n var rootRecord = rootEntry.completion;\n if (rootRecord.type === \"throw\") {\n throw rootRecord.arg;\n }\n\n return this.rval;\n },\n\n dispatchException: function(exception) {\n if (this.done) {\n throw exception;\n }\n\n var context = this;\n function handle(loc, caught) {\n record.type = \"throw\";\n record.arg = exception;\n context.next = loc;\n\n if (caught) {\n // If the dispatched exception was caught by a catch block,\n // then let that catch block handle the exception normally.\n context.method = \"next\";\n context.arg = undefined;\n }\n\n return !! caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n var record = entry.completion;\n\n if (entry.tryLoc === \"root\") {\n // Exception thrown outside of any try block that could handle\n // it, so set the completion value of the entire function to\n // throw the exception.\n return handle(\"end\");\n }\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, \"catchLoc\");\n var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n } else if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n }\n\n } else if (hasFinally) {\n if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else {\n throw new Error(\"try statement without catch or finally\");\n }\n }\n }\n },\n\n abrupt: function(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc <= this.prev &&\n hasOwn.call(entry, \"finallyLoc\") &&\n this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n if (finallyEntry &&\n (type === \"break\" ||\n type === \"continue\") &&\n finallyEntry.tryLoc <= arg &&\n arg <= finallyEntry.finallyLoc) {\n // Ignore the finally entry if control is not jumping to a\n // location outside the try/catch block.\n finallyEntry = null;\n }\n\n var record = finallyEntry ? finallyEntry.completion : {};\n record.type = type;\n record.arg = arg;\n\n if (finallyEntry) {\n this.method = \"next\";\n this.next = finallyEntry.finallyLoc;\n return ContinueSentinel;\n }\n\n return this.complete(record);\n },\n\n complete: function(record, afterLoc) {\n if (record.type === \"throw\") {\n throw record.arg;\n }\n\n if (record.type === \"break\" ||\n record.type === \"continue\") {\n this.next = record.arg;\n } else if (record.type === \"return\") {\n this.rval = this.arg = record.arg;\n this.method = \"return\";\n this.next = \"end\";\n } else if (record.type === \"normal\" && afterLoc) {\n this.next = afterLoc;\n }\n\n return ContinueSentinel;\n },\n\n finish: function(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) {\n this.complete(entry.completion, entry.afterLoc);\n resetTryEntry(entry);\n return ContinueSentinel;\n }\n }\n },\n\n \"catch\": function(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n if (record.type === \"throw\") {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n return thrown;\n }\n }\n\n // The context.catch method must only be called with a location\n // argument that corresponds to a known catch block.\n throw new Error(\"illegal catch attempt\");\n },\n\n delegateYield: function(iterable, resultName, nextLoc) {\n this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n };\n\n if (this.method === \"next\") {\n // Deliberately forget the last sent value so that we don't\n // accidentally pass it on to the delegate.\n this.arg = undefined;\n }\n\n return ContinueSentinel;\n }\n };\n\n // Regardless of whether this script is executing as a CommonJS module\n // or not, return the runtime object so that we can declare the variable\n // regeneratorRuntime in the outer scope, which allows this module to be\n // injected easily by `bin/regenerator --include-runtime script.js`.\n return exports;\n\n}(\n // If this script is executing as a CommonJS module, use module.exports\n // as the regeneratorRuntime namespace. Otherwise create a new empty\n // object. Either way, the resulting object will be used to initialize\n // the regeneratorRuntime variable at the top of this file.\n typeof module === \"object\" ? module.exports : {}\n));\n\ntry {\n regeneratorRuntime = runtime;\n} catch (accidentalStrictMode) {\n // This module should not be running in strict mode, so the above\n // assignment should always work unless something is misconfigured. Just\n // in case runtime.js accidentally runs in strict mode, in modern engines\n // we can explicitly access globalThis. In older engines we can escape\n // strict mode using a global Function call. This could conceivably fail\n // if a Content Security Policy forbids using Function, but in that case\n // the proper solution is to fix the accidental strict mode problem. If\n // you've misconfigured your bundler to force strict mode and applied a\n // CSP to forbid Function, and you're not willing to fix either of those\n // problems, please detail your unique predicament in a GitHub issue.\n if (typeof globalThis === \"object\") {\n globalThis.regeneratorRuntime = runtime;\n } else {\n Function(\"r\", \"regeneratorRuntime = r\")(runtime);\n }\n}\n","const indexOfMatch = require(\"./index-of-match.js\");\n\nfunction findTagByName(xml, tagName, options) {\n const debug = (options && options.debug) || false;\n\n const startIndex = (options && options.startIndex) || 0;\n\n if (debug) console.log(\"starting findTagByName with\", tagName, \" and \", options);\n\n const start = indexOfMatch(xml, `\\<${tagName}[ \\>]`, startIndex);\n if (debug) console.log(\"start:\", start);\n if (start === -1) return undefined;\n\n const afterStart = xml.slice(start + tagName.length);\n let relativeEnd = indexOfMatch(afterStart, \"[ /]\" + tagName + \">\", 0);\n const selfClosing = relativeEnd === -1;\n\n if (selfClosing) {\n relativeEnd = indexOfMatch(afterStart, \"[ /]>\", 0);\n }\n\n const end = start + tagName.length + relativeEnd + 1 + (selfClosing ? 0 : tagName.length) + 1;\n if (debug) console.log(\"end:\", end);\n if (end === -1) return undefined;\n\n const outer = xml.slice(start, end);\n // tag is like urn:ogc:def:crs:EPSG::32617\n\n let inner;\n if (selfClosing) {\n inner = null;\n } else {\n inner = outer.slice(outer.indexOf(\">\") + 1, outer.lastIndexOf(\"<\"));\n }\n\n return { inner, outer, start, end };\n}\n\nmodule.exports = findTagByName;\n","const findTagByName = require(\"./find-tag-by-name.js\");\n\nfunction findTagsByName(xml, tagName, options) {\n const tags = [];\n const debug = (options && options.debug) || false;\n let startIndex = (options && options.startIndex) || 0;\n let tag;\n while ((tag = findTagByName(xml, tagName, { debug, startIndex }))) {\n startIndex = tag.end;\n tags.push(tag);\n }\n if (debug) console.log(\"findTagsByName found\", tags.length, \"tags\");\n return tags;\n}\n\nmodule.exports = findTagsByName;\n","function getAttribute(tag, attributeName, options) {\n const debug = (options && options.debug) || false;\n if (debug) console.log(\"getting \" + attributeName + \" in \" + tag);\n\n const xml = typeof tag === \"object\" ? tag.outer : tag;\n\n const pattern = `${attributeName}\\\\=\"\\([^\"]*\\)\"`;\n if (debug) console.log(\"pattern:\", pattern);\n\n const re = new RegExp(pattern);\n const match = re.exec(xml);\n if (debug) console.log(\"match:\", match);\n if (match) return match[1];\n}\n\nmodule.exports = getAttribute;\n","function indexOfMatch(xml, pattern, startIndex) {\n const re = new RegExp(pattern);\n const match = re.exec(xml.slice(startIndex));\n if (match) return startIndex + match.index;\n else return -1;\n}\n\nmodule.exports = indexOfMatch;\n","'use strict'\nmodule.exports = function (Yallist) {\n Yallist.prototype[Symbol.iterator] = function* () {\n for (let walker = this.head; walker; walker = walker.next) {\n yield walker.value\n }\n }\n}\n","'use strict'\nmodule.exports = Yallist\n\nYallist.Node = Node\nYallist.create = Yallist\n\nfunction Yallist (list) {\n var self = this\n if (!(self instanceof Yallist)) {\n self = new Yallist()\n }\n\n self.tail = null\n self.head = null\n self.length = 0\n\n if (list && typeof list.forEach === 'function') {\n list.forEach(function (item) {\n self.push(item)\n })\n } else if (arguments.length > 0) {\n for (var i = 0, l = arguments.length; i < l; i++) {\n self.push(arguments[i])\n }\n }\n\n return self\n}\n\nYallist.prototype.removeNode = function (node) {\n if (node.list !== this) {\n throw new Error('removing node which does not belong to this list')\n }\n\n var next = node.next\n var prev = node.prev\n\n if (next) {\n next.prev = prev\n }\n\n if (prev) {\n prev.next = next\n }\n\n if (node === this.head) {\n this.head = next\n }\n if (node === this.tail) {\n this.tail = prev\n }\n\n node.list.length--\n node.next = null\n node.prev = null\n node.list = null\n\n return next\n}\n\nYallist.prototype.unshiftNode = function (node) {\n if (node === this.head) {\n return\n }\n\n if (node.list) {\n node.list.removeNode(node)\n }\n\n var head = this.head\n node.list = this\n node.next = head\n if (head) {\n head.prev = node\n }\n\n this.head = node\n if (!this.tail) {\n this.tail = node\n }\n this.length++\n}\n\nYallist.prototype.pushNode = function (node) {\n if (node === this.tail) {\n return\n }\n\n if (node.list) {\n node.list.removeNode(node)\n }\n\n var tail = this.tail\n node.list = this\n node.prev = tail\n if (tail) {\n tail.next = node\n }\n\n this.tail = node\n if (!this.head) {\n this.head = node\n }\n this.length++\n}\n\nYallist.prototype.push = function () {\n for (var i = 0, l = arguments.length; i < l; i++) {\n push(this, arguments[i])\n }\n return this.length\n}\n\nYallist.prototype.unshift = function () {\n for (var i = 0, l = arguments.length; i < l; i++) {\n unshift(this, arguments[i])\n }\n return this.length\n}\n\nYallist.prototype.pop = function () {\n if (!this.tail) {\n return undefined\n }\n\n var res = this.tail.value\n this.tail = this.tail.prev\n if (this.tail) {\n this.tail.next = null\n } else {\n this.head = null\n }\n this.length--\n return res\n}\n\nYallist.prototype.shift = function () {\n if (!this.head) {\n return undefined\n }\n\n var res = this.head.value\n this.head = this.head.next\n if (this.head) {\n this.head.prev = null\n } else {\n this.tail = null\n }\n this.length--\n return res\n}\n\nYallist.prototype.forEach = function (fn, thisp) {\n thisp = thisp || this\n for (var walker = this.head, i = 0; walker !== null; i++) {\n fn.call(thisp, walker.value, i, this)\n walker = walker.next\n }\n}\n\nYallist.prototype.forEachReverse = function (fn, thisp) {\n thisp = thisp || this\n for (var walker = this.tail, i = this.length - 1; walker !== null; i--) {\n fn.call(thisp, walker.value, i, this)\n walker = walker.prev\n }\n}\n\nYallist.prototype.get = function (n) {\n for (var i = 0, walker = this.head; walker !== null && i < n; i++) {\n // abort out of the list early if we hit a cycle\n walker = walker.next\n }\n if (i === n && walker !== null) {\n return walker.value\n }\n}\n\nYallist.prototype.getReverse = function (n) {\n for (var i = 0, walker = this.tail; walker !== null && i < n; i++) {\n // abort out of the list early if we hit a cycle\n walker = walker.prev\n }\n if (i === n && walker !== null) {\n return walker.value\n }\n}\n\nYallist.prototype.map = function (fn, thisp) {\n thisp = thisp || this\n var res = new Yallist()\n for (var walker = this.head; walker !== null;) {\n res.push(fn.call(thisp, walker.value, this))\n walker = walker.next\n }\n return res\n}\n\nYallist.prototype.mapReverse = function (fn, thisp) {\n thisp = thisp || this\n var res = new Yallist()\n for (var walker = this.tail; walker !== null;) {\n res.push(fn.call(thisp, walker.value, this))\n walker = walker.prev\n }\n return res\n}\n\nYallist.prototype.reduce = function (fn, initial) {\n var acc\n var walker = this.head\n if (arguments.length > 1) {\n acc = initial\n } else if (this.head) {\n walker = this.head.next\n acc = this.head.value\n } else {\n throw new TypeError('Reduce of empty list with no initial value')\n }\n\n for (var i = 0; walker !== null; i++) {\n acc = fn(acc, walker.value, i)\n walker = walker.next\n }\n\n return acc\n}\n\nYallist.prototype.reduceReverse = function (fn, initial) {\n var acc\n var walker = this.tail\n if (arguments.length > 1) {\n acc = initial\n } else if (this.tail) {\n walker = this.tail.prev\n acc = this.tail.value\n } else {\n throw new TypeError('Reduce of empty list with no initial value')\n }\n\n for (var i = this.length - 1; walker !== null; i--) {\n acc = fn(acc, walker.value, i)\n walker = walker.prev\n }\n\n return acc\n}\n\nYallist.prototype.toArray = function () {\n var arr = new Array(this.length)\n for (var i = 0, walker = this.head; walker !== null; i++) {\n arr[i] = walker.value\n walker = walker.next\n }\n return arr\n}\n\nYallist.prototype.toArrayReverse = function () {\n var arr = new Array(this.length)\n for (var i = 0, walker = this.tail; walker !== null; i++) {\n arr[i] = walker.value\n walker = walker.prev\n }\n return arr\n}\n\nYallist.prototype.slice = function (from, to) {\n to = to || this.length\n if (to < 0) {\n to += this.length\n }\n from = from || 0\n if (from < 0) {\n from += this.length\n }\n var ret = new Yallist()\n if (to < from || to < 0) {\n return ret\n }\n if (from < 0) {\n from = 0\n }\n if (to > this.length) {\n to = this.length\n }\n for (var i = 0, walker = this.head; walker !== null && i < from; i++) {\n walker = walker.next\n }\n for (; walker !== null && i < to; i++, walker = walker.next) {\n ret.push(walker.value)\n }\n return ret\n}\n\nYallist.prototype.sliceReverse = function (from, to) {\n to = to || this.length\n if (to < 0) {\n to += this.length\n }\n from = from || 0\n if (from < 0) {\n from += this.length\n }\n var ret = new Yallist()\n if (to < from || to < 0) {\n return ret\n }\n if (from < 0) {\n from = 0\n }\n if (to > this.length) {\n to = this.length\n }\n for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) {\n walker = walker.prev\n }\n for (; walker !== null && i > from; i--, walker = walker.prev) {\n ret.push(walker.value)\n }\n return ret\n}\n\nYallist.prototype.splice = function (start, deleteCount, ...nodes) {\n if (start > this.length) {\n start = this.length - 1\n }\n if (start < 0) {\n start = this.length + start;\n }\n\n for (var i = 0, walker = this.head; walker !== null && i < start; i++) {\n walker = walker.next\n }\n\n var ret = []\n for (var i = 0; walker && i < deleteCount; i++) {\n ret.push(walker.value)\n walker = this.removeNode(walker)\n }\n if (walker === null) {\n walker = this.tail\n }\n\n if (walker !== this.head && walker !== this.tail) {\n walker = walker.prev\n }\n\n for (var i = 0; i < nodes.length; i++) {\n walker = insert(this, walker, nodes[i])\n }\n return ret;\n}\n\nYallist.prototype.reverse = function () {\n var head = this.head\n var tail = this.tail\n for (var walker = head; walker !== null; walker = walker.prev) {\n var p = walker.prev\n walker.prev = walker.next\n walker.next = p\n }\n this.head = tail\n this.tail = head\n return this\n}\n\nfunction insert (self, node, value) {\n var inserted = node === self.head ?\n new Node(value, null, node, self) :\n new Node(value, node, node.next, self)\n\n if (inserted.next === null) {\n self.tail = inserted\n }\n if (inserted.prev === null) {\n self.head = inserted\n }\n\n self.length++\n\n return inserted\n}\n\nfunction push (self, item) {\n self.tail = new Node(item, self.tail, null, self)\n if (!self.head) {\n self.head = self.tail\n }\n self.length++\n}\n\nfunction unshift (self, item) {\n self.head = new Node(item, null, self.head, self)\n if (!self.tail) {\n self.tail = self.head\n }\n self.length++\n}\n\nfunction Node (value, prev, next, list) {\n if (!(this instanceof Node)) {\n return new Node(value, prev, next, list)\n }\n\n this.list = list\n this.value = value\n\n if (prev) {\n prev.next = this\n this.prev = prev\n } else {\n this.prev = null\n }\n\n if (next) {\n next.prev = this\n this.next = next\n } else {\n this.next = null\n }\n}\n\ntry {\n // add if support for Symbol.iterator is present\n require('./iterator.js')(Yallist)\n} catch (er) {}\n",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"// algorithm: http://fox-toolkit.org/ftp/fasthalffloatconversion.pdf\n\nconst buffer = new ArrayBuffer(4);\nconst floatView = new Float32Array(buffer);\nconst uint32View = new Uint32Array(buffer);\n\nconst baseTable = new Uint32Array(512);\nconst shiftTable = new Uint32Array(512);\n\nfor (let i = 0; i < 256; ++i) {\n const e = i - 127;\n\n // very small number (0, -0)\n if (e < -27) {\n baseTable[i] = 0x0000;\n baseTable[i | 0x100] = 0x8000;\n shiftTable[i] = 24;\n shiftTable[i | 0x100] = 24;\n\n // small number (denorm)\n } else if (e < -14) {\n baseTable[i] = 0x0400 >> (-e - 14);\n baseTable[i | 0x100] = (0x0400 >> (-e - 14)) | 0x8000;\n shiftTable[i] = -e - 1;\n shiftTable[i | 0x100] = -e - 1;\n\n // normal number\n } else if (e <= 15) {\n baseTable[i] = (e + 15) << 10;\n baseTable[i | 0x100] = ((e + 15) << 10) | 0x8000;\n shiftTable[i] = 13;\n shiftTable[i | 0x100] = 13;\n\n // large number (Infinity, -Infinity)\n } else if (e < 128) {\n baseTable[i] = 0x7c00;\n baseTable[i | 0x100] = 0xfc00;\n shiftTable[i] = 24;\n shiftTable[i | 0x100] = 24;\n\n // stay (NaN, Infinity, -Infinity)\n } else {\n baseTable[i] = 0x7c00;\n baseTable[i | 0x100] = 0xfc00;\n shiftTable[i] = 13;\n shiftTable[i | 0x100] = 13;\n }\n}\n\n/**\n * round a number to a half float number bits.\n * @param {number} num - double float\n * @returns {number} half float number bits\n */\nexport function roundToFloat16Bits(num) {\n floatView[0] = num;\n const f = uint32View[0];\n const e = (f >> 23) & 0x1ff;\n return baseTable[e] + ((f & 0x007fffff) >> shiftTable[e]);\n}\n\nconst mantissaTable = new Uint32Array(2048);\nconst exponentTable = new Uint32Array(64);\nconst offsetTable = new Uint32Array(64);\n\nmantissaTable[0] = 0;\nfor (let i = 1; i < 1024; ++i) {\n let m = i << 13; // zero pad mantissa bits\n let e = 0; // zero exponent\n\n // normalized\n while((m & 0x00800000) === 0) {\n e -= 0x00800000; // decrement exponent\n m <<= 1;\n }\n\n m &= ~0x00800000; // clear leading 1 bit\n e += 0x38800000; // adjust bias\n\n mantissaTable[i] = m | e;\n}\nfor (let i = 1024; i < 2048; ++i) {\n mantissaTable[i] = 0x38000000 + ((i - 1024) << 13);\n}\n\nexponentTable[0] = 0;\nfor (let i = 1; i < 31; ++i) {\n exponentTable[i] = i << 23;\n}\nexponentTable[31] = 0x47800000;\nexponentTable[32] = 0x80000000;\nfor (let i = 33; i < 63; ++i) {\n exponentTable[i] = 0x80000000 + ((i - 32) << 23);\n}\nexponentTable[63] = 0xc7800000;\n\noffsetTable[0] = 0;\nfor (let i = 1; i < 64; ++i) {\n if (i === 32) {\n offsetTable[i] = 0;\n } else {\n offsetTable[i] = 1024;\n }\n}\n\n/**\n * convert a half float number bits to a number.\n * @param {number} float16bits - half float number bits\n * @returns {number} double float\n */\nexport function convertToNumber(float16bits) {\n const m = float16bits >> 10;\n uint32View[0] = mantissaTable[offsetTable[m] + (float16bits & 0x3ff)] + exponentTable[m];\n return floatView[0];\n}\n","/**\n * @param {unknown} value\n * @returns {value is object}\n */\nexport function isObject(value) {\n return (value !== null && typeof value === \"object\") || typeof value === \"function\";\n}\n\n/**\n * @param {unknown} value\n * @returns {value is object}\n */\nexport function isObjectLike(value) {\n return value !== null && typeof value === \"object\";\n}\n\n// Inspired by util.types implementation of Node.js\nconst TypedArrayPrototype = Reflect.getPrototypeOf(Uint8Array).prototype;\nconst getTypedArrayPrototypeSybolToStringTag = Reflect.getOwnPropertyDescriptor(TypedArrayPrototype, Symbol.toStringTag).get;\n\n/**\n * @param {unknown} value\n * @returns {value is Uint8Array|Uint8ClampedArray|Uint16Array|Uint32Array|Int8Array|Int16Array|Int32Array|Float32Array|Float64Array|BigUint64Array|BigInt64Array}\n */\nexport function isTypedArray(value) {\n return getTypedArrayPrototypeSybolToStringTag.call(value) !== undefined;\n}\n\n/**\n * @param {unknown} value\n * @returns {value is Uint16Array}\n */\nexport function isUint16Array(value) {\n return getTypedArrayPrototypeSybolToStringTag.call(value) === \"Uint16Array\";\n}\n\nconst toString = Object.prototype.toString;\n\n/**\n * @param {unknown} value\n * @returns {value is DataView}\n */\nexport function isDataView(value) {\n if (!ArrayBuffer.isView(value)) {\n return false;\n }\n\n if (isTypedArray(value)) {\n return false;\n }\n\n if (toString.call(value) !== \"[object DataView]\") {\n return false;\n }\n\n return true;\n}\n\n/**\n * @param {unknown} value\n * @returns {value is ArrayBuffer}\n */\nexport function isArrayBuffer(value) {\n return isObjectLike(value) && toString.call(value) === \"[object ArrayBuffer]\";\n}\n\n/**\n * @param {unknown} value\n * @returns {value is SharedArrayBuffer}\n */\nexport function isSharedArrayBuffer(value) {\n return isObjectLike(value) && toString.call(value) === \"[object SharedArrayBuffer]\";\n}\n\n/**\n * @param {unknown} value\n * @returns {value is Iterable}\n */\nexport function isIterable(value) {\n return isObject(value) && typeof value[Symbol.iterator] === \"function\";\n}\n\n/**\n * @param {unknown} value\n * @returns {value is any[]}\n */\nexport function isOrdinaryArray(value) {\n if (!Array.isArray(value)) {\n return false;\n }\n\n const iterator = value[Symbol.iterator]();\n if (toString.call(iterator) !== \"[object Array Iterator]\") {\n return false;\n }\n\n return true;\n}\n\n/**\n * @param {unknown} value\n * @returns {value is any[]}\n */\nexport function isOrdinaryTypedArray(value) {\n if (!isTypedArray(value)) {\n return false;\n }\n\n const iterator = value[Symbol.iterator]();\n if (toString.call(iterator) !== \"[object Array Iterator]\") {\n return false;\n }\n\n return true;\n}\n\n/**\n * @param {unknown} value\n * @returns {value is string}\n */\nexport function isCanonicalIntegerIndexString(value) {\n if (typeof value !== \"string\") {\n return false;\n }\n\n const number = Number(value);\n if (value !== number + \"\") {\n return false;\n }\n\n if (!Number.isFinite(number)) {\n return false;\n }\n\n if (number !== Math.trunc(number)) {\n return false;\n }\n\n return true;\n}\n","import { convertToNumber, roundToFloat16Bits } from \"./helper/converter.mjs\";\nimport { isDataView } from \"./helper/is.mjs\";\n\n/**\n * returns an unsigned 16-bit float at the specified byte offset from the start of the DataView.\n * @param {DataView} dataView\n * @param {number} byteOffset\n * @param {[boolean]} opts\n * @returns {number}\n */\nexport function getFloat16(dataView, byteOffset, ...opts) {\n if (!isDataView(dataView)) {\n throw new TypeError(\"First argument to getFloat16 function must be a DataView\");\n }\n\n return convertToNumber( dataView.getUint16(byteOffset, ...opts) );\n}\n\n/**\n * stores an unsigned 16-bit float value at the specified byte offset from the start of the DataView.\n * @param {DataView} dataView\n * @param {number} byteOffset\n * @param {number} value\n * @param {[boolean]} opts\n */\nexport function setFloat16(dataView, byteOffset, value, ...opts) {\n if (!isDataView(dataView)) {\n throw new TypeError(\"First argument to setFloat16 function must be a DataView\");\n }\n\n dataView.setUint16(byteOffset, roundToFloat16Bits(value), ...opts);\n}\n","const registry = new Map();\n\nexport function addDecoder(cases, importFn) {\n if (!Array.isArray(cases)) {\n cases = [cases]; // eslint-disable-line no-param-reassign\n }\n cases.forEach((c) => registry.set(c, importFn));\n}\n\nexport async function getDecoder(fileDirectory) {\n const importFn = registry.get(fileDirectory.Compression);\n if (!importFn) {\n throw new Error(`Unknown compression method identifier: ${fileDirectory.Compression}`);\n }\n const Decoder = await importFn();\n return new Decoder(fileDirectory);\n}\n\n// Add default decoders to registry (end-user may override with other implementations)\naddDecoder([undefined, 1], () => import('./raw.js').then((m) => m.default));\naddDecoder(5, () => import('./lzw.js').then((m) => m.default));\naddDecoder(6, () => {\n throw new Error('old style JPEG compression is not supported.');\n});\naddDecoder(7, () => import('./jpeg.js').then((m) => m.default));\naddDecoder([8, 32946], () => import('./deflate.js').then((m) => m.default));\naddDecoder(32773, () => import('./packbits.js').then((m) => m.default));\naddDecoder(34887, () => import('./lerc.js').then((m) => m.default));\naddDecoder(50001, () => import('./webimage.js').then((m) => m.default));\n","/**\n * @module resample\n */\n\nfunction copyNewSize(array, width, height, samplesPerPixel = 1) {\n return new (Object.getPrototypeOf(array).constructor)(width * height * samplesPerPixel);\n}\n\n/**\n * Resample the input arrays using nearest neighbor value selection.\n * @param {TypedArray[]} valueArrays The input arrays to resample\n * @param {number} inWidth The width of the input rasters\n * @param {number} inHeight The height of the input rasters\n * @param {number} outWidth The desired width of the output rasters\n * @param {number} outHeight The desired height of the output rasters\n * @returns {TypedArray[]} The resampled rasters\n */\nexport function resampleNearest(valueArrays, inWidth, inHeight, outWidth, outHeight) {\n const relX = inWidth / outWidth;\n const relY = inHeight / outHeight;\n return valueArrays.map((array) => {\n const newArray = copyNewSize(array, outWidth, outHeight);\n for (let y = 0; y < outHeight; ++y) {\n const cy = Math.min(Math.round(relY * y), inHeight - 1);\n for (let x = 0; x < outWidth; ++x) {\n const cx = Math.min(Math.round(relX * x), inWidth - 1);\n const value = array[(cy * inWidth) + cx];\n newArray[(y * outWidth) + x] = value;\n }\n }\n return newArray;\n });\n}\n\n// simple linear interpolation, code from:\n// https://en.wikipedia.org/wiki/Linear_interpolation#Programming_language_support\nfunction lerp(v0, v1, t) {\n return ((1 - t) * v0) + (t * v1);\n}\n\n/**\n * Resample the input arrays using bilinear interpolation.\n * @param {TypedArray[]} valueArrays The input arrays to resample\n * @param {number} inWidth The width of the input rasters\n * @param {number} inHeight The height of the input rasters\n * @param {number} outWidth The desired width of the output rasters\n * @param {number} outHeight The desired height of the output rasters\n * @returns {TypedArray[]} The resampled rasters\n */\nexport function resampleBilinear(valueArrays, inWidth, inHeight, outWidth, outHeight) {\n const relX = inWidth / outWidth;\n const relY = inHeight / outHeight;\n\n return valueArrays.map((array) => {\n const newArray = copyNewSize(array, outWidth, outHeight);\n for (let y = 0; y < outHeight; ++y) {\n const rawY = relY * y;\n\n const yl = Math.floor(rawY);\n const yh = Math.min(Math.ceil(rawY), (inHeight - 1));\n\n for (let x = 0; x < outWidth; ++x) {\n const rawX = relX * x;\n const tx = rawX % 1;\n\n const xl = Math.floor(rawX);\n const xh = Math.min(Math.ceil(rawX), (inWidth - 1));\n\n const ll = array[(yl * inWidth) + xl];\n const hl = array[(yl * inWidth) + xh];\n const lh = array[(yh * inWidth) + xl];\n const hh = array[(yh * inWidth) + xh];\n\n const value = lerp(\n lerp(ll, hl, tx),\n lerp(lh, hh, tx),\n rawY % 1,\n );\n newArray[(y * outWidth) + x] = value;\n }\n }\n return newArray;\n });\n}\n\n/**\n * Resample the input arrays using the selected resampling method.\n * @param {TypedArray[]} valueArrays The input arrays to resample\n * @param {number} inWidth The width of the input rasters\n * @param {number} inHeight The height of the input rasters\n * @param {number} outWidth The desired width of the output rasters\n * @param {number} outHeight The desired height of the output rasters\n * @param {string} [method = 'nearest'] The desired resampling method\n * @returns {TypedArray[]} The resampled rasters\n */\nexport function resample(valueArrays, inWidth, inHeight, outWidth, outHeight, method = 'nearest') {\n switch (method.toLowerCase()) {\n case 'nearest':\n return resampleNearest(valueArrays, inWidth, inHeight, outWidth, outHeight);\n case 'bilinear':\n case 'linear':\n return resampleBilinear(valueArrays, inWidth, inHeight, outWidth, outHeight);\n default:\n throw new Error(`Unsupported resampling method: '${method}'`);\n }\n}\n\n/**\n * Resample the pixel interleaved input array using nearest neighbor value selection.\n * @param {TypedArray} valueArrays The input arrays to resample\n * @param {number} inWidth The width of the input rasters\n * @param {number} inHeight The height of the input rasters\n * @param {number} outWidth The desired width of the output rasters\n * @param {number} outHeight The desired height of the output rasters\n * @param {number} samples The number of samples per pixel for pixel\n * interleaved data\n * @returns {TypedArray} The resampled raster\n */\nexport function resampleNearestInterleaved(\n valueArray, inWidth, inHeight, outWidth, outHeight, samples) {\n const relX = inWidth / outWidth;\n const relY = inHeight / outHeight;\n\n const newArray = copyNewSize(valueArray, outWidth, outHeight, samples);\n for (let y = 0; y < outHeight; ++y) {\n const cy = Math.min(Math.round(relY * y), inHeight - 1);\n for (let x = 0; x < outWidth; ++x) {\n const cx = Math.min(Math.round(relX * x), inWidth - 1);\n for (let i = 0; i < samples; ++i) {\n const value = valueArray[(cy * inWidth * samples) + (cx * samples) + i];\n newArray[(y * outWidth * samples) + (x * samples) + i] = value;\n }\n }\n }\n return newArray;\n}\n\n/**\n * Resample the pixel interleaved input array using bilinear interpolation.\n * @param {TypedArray} valueArrays The input arrays to resample\n * @param {number} inWidth The width of the input rasters\n * @param {number} inHeight The height of the input rasters\n * @param {number} outWidth The desired width of the output rasters\n * @param {number} outHeight The desired height of the output rasters\n * @param {number} samples The number of samples per pixel for pixel\n * interleaved data\n * @returns {TypedArray} The resampled raster\n */\nexport function resampleBilinearInterleaved(\n valueArray, inWidth, inHeight, outWidth, outHeight, samples) {\n const relX = inWidth / outWidth;\n const relY = inHeight / outHeight;\n const newArray = copyNewSize(valueArray, outWidth, outHeight, samples);\n for (let y = 0; y < outHeight; ++y) {\n const rawY = relY * y;\n\n const yl = Math.floor(rawY);\n const yh = Math.min(Math.ceil(rawY), (inHeight - 1));\n\n for (let x = 0; x < outWidth; ++x) {\n const rawX = relX * x;\n const tx = rawX % 1;\n\n const xl = Math.floor(rawX);\n const xh = Math.min(Math.ceil(rawX), (inWidth - 1));\n\n for (let i = 0; i < samples; ++i) {\n const ll = valueArray[(yl * inWidth * samples) + (xl * samples) + i];\n const hl = valueArray[(yl * inWidth * samples) + (xh * samples) + i];\n const lh = valueArray[(yh * inWidth * samples) + (xl * samples) + i];\n const hh = valueArray[(yh * inWidth * samples) + (xh * samples) + i];\n\n const value = lerp(\n lerp(ll, hl, tx),\n lerp(lh, hh, tx),\n rawY % 1,\n );\n newArray[(y * outWidth * samples) + (x * samples) + i] = value;\n }\n }\n }\n return newArray;\n}\n\n/**\n * Resample the pixel interleaved input array using the selected resampling method.\n * @param {TypedArray} valueArray The input array to resample\n * @param {number} inWidth The width of the input rasters\n * @param {number} inHeight The height of the input rasters\n * @param {number} outWidth The desired width of the output rasters\n * @param {number} outHeight The desired height of the output rasters\n * @param {number} samples The number of samples per pixel for pixel\n * interleaved data\n * @param {string} [method = 'nearest'] The desired resampling method\n * @returns {TypedArray} The resampled rasters\n */\nexport function resampleInterleaved(valueArray, inWidth, inHeight, outWidth, outHeight, samples, method = 'nearest') {\n switch (method.toLowerCase()) {\n case 'nearest':\n return resampleNearestInterleaved(\n valueArray, inWidth, inHeight, outWidth, outHeight, samples,\n );\n case 'bilinear':\n case 'linear':\n return resampleBilinearInterleaved(\n valueArray, inWidth, inHeight, outWidth, outHeight, samples,\n );\n default:\n throw new Error(`Unsupported resampling method: '${method}'`);\n }\n}\n","/** @module geotiffimage */\nimport { getFloat16 } from '@petamoriken/float16';\nimport getAttribute from 'xml-utils/get-attribute.js';\nimport findTagsByName from 'xml-utils/find-tags-by-name.js';\n\nimport { photometricInterpretations, ExtraSamplesValues } from './globals.js';\nimport { fromWhiteIsZero, fromBlackIsZero, fromPalette, fromCMYK, fromYCbCr, fromCIELab } from './rgb.js';\nimport { getDecoder } from './compression/index.js';\nimport { resample, resampleInterleaved } from './resample.js';\n\n/**\n * @typedef {Object} ReadRasterOptions\n * @property {Array} [window=whole window] the subset to read data from in pixels.\n * @property {Array} [bbox=whole image] the subset to read data from in\n * geographical coordinates.\n * @property {Array} [samples=all samples] the selection of samples to read from. Default is all samples.\n * @property {boolean} [interleave=false] whether the data shall be read\n * in one single array or separate\n * arrays.\n * @property {Pool} [pool=null] The optional decoder pool to use.\n * @property {number} [width] The desired width of the output. When the width is not the\n * same as the images, resampling will be performed.\n * @property {number} [height] The desired height of the output. When the width is not the\n * same as the images, resampling will be performed.\n * @property {string} [resampleMethod='nearest'] The desired resampling method.\n * @property {AbortSignal} [signal] An AbortSignal that may be signalled if the request is\n * to be aborted\n * @property {number|number[]} [fillValue] The value to use for parts of the image\n * outside of the images extent. When multiple\n * samples are requested, an array of fill values\n * can be passed.\n */\n\n/** @typedef {import(\"./geotiff.js\").TypedArray} TypedArray */\n\nfunction sum(array, start, end) {\n let s = 0;\n for (let i = start; i < end; ++i) {\n s += array[i];\n }\n return s;\n}\n\nfunction arrayForType(format, bitsPerSample, size) {\n switch (format) {\n case 1: // unsigned integer data\n if (bitsPerSample <= 8) {\n return new Uint8Array(size);\n } else if (bitsPerSample <= 16) {\n return new Uint16Array(size);\n } else if (bitsPerSample <= 32) {\n return new Uint32Array(size);\n }\n break;\n case 2: // twos complement signed integer data\n if (bitsPerSample === 8) {\n return new Int8Array(size);\n } else if (bitsPerSample === 16) {\n return new Int16Array(size);\n } else if (bitsPerSample === 32) {\n return new Int32Array(size);\n }\n break;\n case 3: // floating point data\n switch (bitsPerSample) {\n case 16:\n case 32:\n return new Float32Array(size);\n case 64:\n return new Float64Array(size);\n default:\n break;\n }\n break;\n default:\n break;\n }\n throw Error('Unsupported data format/bitsPerSample');\n}\n\nfunction needsNormalization(format, bitsPerSample) {\n if ((format === 1 || format === 2) && bitsPerSample <= 32 && bitsPerSample % 8 === 0) {\n return false;\n } else if (format === 3 && (bitsPerSample === 16 || bitsPerSample === 32 || bitsPerSample === 64)) {\n return false;\n }\n return true;\n}\n\nfunction normalizeArray(inBuffer, format, planarConfiguration, samplesPerPixel, bitsPerSample, tileWidth, tileHeight) {\n // const inByteArray = new Uint8Array(inBuffer);\n const view = new DataView(inBuffer);\n const outSize = planarConfiguration === 2\n ? tileHeight * tileWidth\n : tileHeight * tileWidth * samplesPerPixel;\n const samplesToTransfer = planarConfiguration === 2\n ? 1 : samplesPerPixel;\n const outArray = arrayForType(format, bitsPerSample, outSize);\n // let pixel = 0;\n\n const bitMask = parseInt('1'.repeat(bitsPerSample), 2);\n\n if (format === 1) { // unsigned integer\n // translation of https://github.com/OSGeo/gdal/blob/master/gdal/frmts/gtiff/geotiff.cpp#L7337\n let pixelBitSkip;\n // let sampleBitOffset = 0;\n if (planarConfiguration === 1) {\n pixelBitSkip = samplesPerPixel * bitsPerSample;\n // sampleBitOffset = (samplesPerPixel - 1) * bitsPerSample;\n } else {\n pixelBitSkip = bitsPerSample;\n }\n\n // Bits per line rounds up to next byte boundary.\n let bitsPerLine = tileWidth * pixelBitSkip;\n if ((bitsPerLine & 7) !== 0) {\n bitsPerLine = (bitsPerLine + 7) & (~7);\n }\n\n for (let y = 0; y < tileHeight; ++y) {\n const lineBitOffset = y * bitsPerLine;\n for (let x = 0; x < tileWidth; ++x) {\n const pixelBitOffset = lineBitOffset + (x * samplesToTransfer * bitsPerSample);\n for (let i = 0; i < samplesToTransfer; ++i) {\n const bitOffset = pixelBitOffset + (i * bitsPerSample);\n const outIndex = (((y * tileWidth) + x) * samplesToTransfer) + i;\n\n const byteOffset = Math.floor(bitOffset / 8);\n const innerBitOffset = bitOffset % 8;\n if (innerBitOffset + bitsPerSample <= 8) {\n outArray[outIndex] = (view.getUint8(byteOffset) >> (8 - bitsPerSample) - innerBitOffset) & bitMask;\n } else if (innerBitOffset + bitsPerSample <= 16) {\n outArray[outIndex] = (view.getUint16(byteOffset) >> (16 - bitsPerSample) - innerBitOffset) & bitMask;\n } else if (innerBitOffset + bitsPerSample <= 24) {\n const raw = (view.getUint16(byteOffset) << 8) | (view.getUint8(byteOffset + 2));\n outArray[outIndex] = (raw >> (24 - bitsPerSample) - innerBitOffset) & bitMask;\n } else {\n outArray[outIndex] = (view.getUint32(byteOffset) >> (32 - bitsPerSample) - innerBitOffset) & bitMask;\n }\n\n // let outWord = 0;\n // for (let bit = 0; bit < bitsPerSample; ++bit) {\n // if (inByteArray[bitOffset >> 3]\n // & (0x80 >> (bitOffset & 7))) {\n // outWord |= (1 << (bitsPerSample - 1 - bit));\n // }\n // ++bitOffset;\n // }\n\n // outArray[outIndex] = outWord;\n // outArray[pixel] = outWord;\n // pixel += 1;\n }\n // bitOffset = bitOffset + pixelBitSkip - bitsPerSample;\n }\n }\n } else if (format === 3) { // floating point\n // Float16 is handled elsewhere\n // normalize 16/24 bit floats to 32 bit floats in the array\n // console.time();\n // if (bitsPerSample === 16) {\n // for (let byte = 0, outIndex = 0; byte < inBuffer.byteLength; byte += 2, ++outIndex) {\n // outArray[outIndex] = getFloat16(view, byte);\n // }\n // }\n // console.timeEnd()\n }\n\n return outArray.buffer;\n}\n\n/**\n * GeoTIFF sub-file image.\n */\nclass GeoTIFFImage {\n /**\n * @constructor\n * @param {Object} fileDirectory The parsed file directory\n * @param {Object} geoKeys The parsed geo-keys\n * @param {DataView} dataView The DataView for the underlying file.\n * @param {Boolean} littleEndian Whether the file is encoded in little or big endian\n * @param {Boolean} cache Whether or not decoded tiles shall be cached\n * @param {Source} source The datasource to read from\n */\n constructor(fileDirectory, geoKeys, dataView, littleEndian, cache, source) {\n this.fileDirectory = fileDirectory;\n this.geoKeys = geoKeys;\n this.dataView = dataView;\n this.littleEndian = littleEndian;\n this.tiles = cache ? {} : null;\n this.isTiled = !fileDirectory.StripOffsets;\n const planarConfiguration = fileDirectory.PlanarConfiguration;\n this.planarConfiguration = (typeof planarConfiguration === 'undefined') ? 1 : planarConfiguration;\n if (this.planarConfiguration !== 1 && this.planarConfiguration !== 2) {\n throw new Error('Invalid planar configuration.');\n }\n\n this.source = source;\n }\n\n /**\n * Returns the associated parsed file directory.\n * @returns {Object} the parsed file directory\n */\n getFileDirectory() {\n return this.fileDirectory;\n }\n\n /**\n * Returns the associated parsed geo keys.\n * @returns {Object} the parsed geo keys\n */\n getGeoKeys() {\n return this.geoKeys;\n }\n\n /**\n * Returns the width of the image.\n * @returns {Number} the width of the image\n */\n getWidth() {\n return this.fileDirectory.ImageWidth;\n }\n\n /**\n * Returns the height of the image.\n * @returns {Number} the height of the image\n */\n getHeight() {\n return this.fileDirectory.ImageLength;\n }\n\n /**\n * Returns the number of samples per pixel.\n * @returns {Number} the number of samples per pixel\n */\n getSamplesPerPixel() {\n return typeof this.fileDirectory.SamplesPerPixel !== 'undefined'\n ? this.fileDirectory.SamplesPerPixel : 1;\n }\n\n /**\n * Returns the width of each tile.\n * @returns {Number} the width of each tile\n */\n getTileWidth() {\n return this.isTiled ? this.fileDirectory.TileWidth : this.getWidth();\n }\n\n /**\n * Returns the height of each tile.\n * @returns {Number} the height of each tile\n */\n getTileHeight() {\n if (this.isTiled) {\n return this.fileDirectory.TileLength;\n }\n if (typeof this.fileDirectory.RowsPerStrip !== 'undefined') {\n return Math.min(this.fileDirectory.RowsPerStrip, this.getHeight());\n }\n return this.getHeight();\n }\n\n getBlockWidth() {\n return this.getTileWidth();\n }\n\n getBlockHeight(y) {\n if (this.isTiled || (y + 1) * this.getTileHeight() <= this.getHeight()) {\n return this.getTileHeight();\n } else {\n return this.getHeight() - (y * this.getTileHeight());\n }\n }\n\n /**\n * Calculates the number of bytes for each pixel across all samples. Only full\n * bytes are supported, an exception is thrown when this is not the case.\n * @returns {Number} the bytes per pixel\n */\n getBytesPerPixel() {\n let bytes = 0;\n for (let i = 0; i < this.fileDirectory.BitsPerSample.length; ++i) {\n bytes += this.getSampleByteSize(i);\n }\n return bytes;\n }\n\n getSampleByteSize(i) {\n if (i >= this.fileDirectory.BitsPerSample.length) {\n throw new RangeError(`Sample index ${i} is out of range.`);\n }\n return Math.ceil(this.fileDirectory.BitsPerSample[i] / 8);\n }\n\n getReaderForSample(sampleIndex) {\n const format = this.fileDirectory.SampleFormat\n ? this.fileDirectory.SampleFormat[sampleIndex] : 1;\n const bitsPerSample = this.fileDirectory.BitsPerSample[sampleIndex];\n switch (format) {\n case 1: // unsigned integer data\n if (bitsPerSample <= 8) {\n return DataView.prototype.getUint8;\n } else if (bitsPerSample <= 16) {\n return DataView.prototype.getUint16;\n } else if (bitsPerSample <= 32) {\n return DataView.prototype.getUint32;\n }\n break;\n case 2: // twos complement signed integer data\n if (bitsPerSample <= 8) {\n return DataView.prototype.getInt8;\n } else if (bitsPerSample <= 16) {\n return DataView.prototype.getInt16;\n } else if (bitsPerSample <= 32) {\n return DataView.prototype.getInt32;\n }\n break;\n case 3:\n switch (bitsPerSample) {\n case 16:\n return function (offset, littleEndian) {\n return getFloat16(this, offset, littleEndian);\n };\n case 32:\n return DataView.prototype.getFloat32;\n case 64:\n return DataView.prototype.getFloat64;\n default:\n break;\n }\n break;\n default:\n break;\n }\n throw Error('Unsupported data format/bitsPerSample');\n }\n\n getSampleFormat(sampleIndex = 0) {\n return this.fileDirectory.SampleFormat\n ? this.fileDirectory.SampleFormat[sampleIndex] : 1;\n }\n\n getBitsPerSample(sampleIndex = 0) {\n return this.fileDirectory.BitsPerSample[sampleIndex];\n }\n\n getArrayForSample(sampleIndex, size) {\n const format = this.getSampleFormat(sampleIndex);\n const bitsPerSample = this.getBitsPerSample(sampleIndex);\n return arrayForType(format, bitsPerSample, size);\n }\n\n /**\n * Returns the decoded strip or tile.\n * @param {Number} x the strip or tile x-offset\n * @param {Number} y the tile y-offset (0 for stripped images)\n * @param {Number} sample the sample to get for separated samples\n * @param {import(\"./geotiff\").Pool|AbstractDecoder} poolOrDecoder the decoder or decoder pool\n * @param {AbortSignal} [signal] An AbortSignal that may be signalled if the request is\n * to be aborted\n * @returns {Promise.}\n */\n async getTileOrStrip(x, y, sample, poolOrDecoder, signal) {\n const numTilesPerRow = Math.ceil(this.getWidth() / this.getTileWidth());\n const numTilesPerCol = Math.ceil(this.getHeight() / this.getTileHeight());\n let index;\n const { tiles } = this;\n if (this.planarConfiguration === 1) {\n index = (y * numTilesPerRow) + x;\n } else if (this.planarConfiguration === 2) {\n index = (sample * numTilesPerRow * numTilesPerCol) + (y * numTilesPerRow) + x;\n }\n\n let offset;\n let byteCount;\n if (this.isTiled) {\n offset = this.fileDirectory.TileOffsets[index];\n byteCount = this.fileDirectory.TileByteCounts[index];\n } else {\n offset = this.fileDirectory.StripOffsets[index];\n byteCount = this.fileDirectory.StripByteCounts[index];\n }\n const slice = (await this.source.fetch([{ offset, length: byteCount }], signal))[0];\n\n let request;\n if (tiles === null || !tiles[index]) {\n // resolve each request by potentially applying array normalization\n request = (async () => {\n let data = await poolOrDecoder.decode(this.fileDirectory, slice);\n const sampleFormat = this.getSampleFormat();\n const bitsPerSample = this.getBitsPerSample();\n if (needsNormalization(sampleFormat, bitsPerSample)) {\n data = normalizeArray(\n data,\n sampleFormat,\n this.planarConfiguration,\n this.getSamplesPerPixel(),\n bitsPerSample,\n this.getTileWidth(),\n this.getBlockHeight(y),\n );\n }\n return data;\n })();\n\n // set the cache\n if (tiles !== null) {\n tiles[index] = request;\n }\n } else {\n // get from the cache\n request = tiles[index];\n }\n\n // cache the tile request\n return { x, y, sample, data: await request };\n }\n\n /**\n * Internal read function.\n * @private\n * @param {Array} imageWindow The image window in pixel coordinates\n * @param {Array} samples The selected samples (0-based indices)\n * @param {TypedArray[]|TypedArray} valueArrays The array(s) to write into\n * @param {Boolean} interleave Whether or not to write in an interleaved manner\n * @param {import(\"./geotiff\").Pool|AbstractDecoder} poolOrDecoder the decoder or decoder pool\n * @param {number} width the width of window to be read into\n * @param {number} height the height of window to be read into\n * @param {number} resampleMethod the resampling method to be used when interpolating\n * @param {AbortSignal} [signal] An AbortSignal that may be signalled if the request is\n * to be aborted\n * @returns {Promise|Promise}\n */\n async _readRaster(imageWindow, samples, valueArrays, interleave, poolOrDecoder, width,\n height, resampleMethod, signal) {\n const tileWidth = this.getTileWidth();\n const tileHeight = this.getTileHeight();\n const imageWidth = this.getWidth();\n const imageHeight = this.getHeight();\n\n const minXTile = Math.max(Math.floor(imageWindow[0] / tileWidth), 0);\n const maxXTile = Math.min(\n Math.ceil(imageWindow[2] / tileWidth),\n Math.ceil(imageWidth / tileWidth),\n );\n const minYTile = Math.max(Math.floor(imageWindow[1] / tileHeight), 0);\n const maxYTile = Math.min(\n Math.ceil(imageWindow[3] / tileHeight),\n Math.ceil(imageHeight / tileHeight),\n );\n const windowWidth = imageWindow[2] - imageWindow[0];\n\n let bytesPerPixel = this.getBytesPerPixel();\n\n const srcSampleOffsets = [];\n const sampleReaders = [];\n for (let i = 0; i < samples.length; ++i) {\n if (this.planarConfiguration === 1) {\n srcSampleOffsets.push(sum(this.fileDirectory.BitsPerSample, 0, samples[i]) / 8);\n } else {\n srcSampleOffsets.push(0);\n }\n sampleReaders.push(this.getReaderForSample(samples[i]));\n }\n\n const promises = [];\n const { littleEndian } = this;\n\n for (let yTile = minYTile; yTile < maxYTile; ++yTile) {\n for (let xTile = minXTile; xTile < maxXTile; ++xTile) {\n for (let sampleIndex = 0; sampleIndex < samples.length; ++sampleIndex) {\n const si = sampleIndex;\n const sample = samples[sampleIndex];\n if (this.planarConfiguration === 2) {\n bytesPerPixel = this.getSampleByteSize(sampleIndex);\n }\n const promise = this.getTileOrStrip(xTile, yTile, sample, poolOrDecoder, signal);\n promises.push(promise);\n promise.then((tile) => {\n const buffer = tile.data;\n const dataView = new DataView(buffer);\n const blockHeight = this.getBlockHeight(tile.y);\n const firstLine = tile.y * tileHeight;\n const firstCol = tile.x * tileWidth;\n const lastLine = firstLine + blockHeight;\n const lastCol = (tile.x + 1) * tileWidth;\n const reader = sampleReaders[si];\n\n const ymax = Math.min(blockHeight, blockHeight - (lastLine - imageWindow[3]), imageHeight - firstLine);\n const xmax = Math.min(tileWidth, tileWidth - (lastCol - imageWindow[2]), imageWidth - firstCol);\n\n for (let y = Math.max(0, imageWindow[1] - firstLine); y < ymax; ++y) {\n for (let x = Math.max(0, imageWindow[0] - firstCol); x < xmax; ++x) {\n const pixelOffset = ((y * tileWidth) + x) * bytesPerPixel;\n const value = reader.call(\n dataView, pixelOffset + srcSampleOffsets[si], littleEndian,\n );\n let windowCoordinate;\n if (interleave) {\n windowCoordinate = ((y + firstLine - imageWindow[1]) * windowWidth * samples.length)\n + ((x + firstCol - imageWindow[0]) * samples.length)\n + si;\n valueArrays[windowCoordinate] = value;\n } else {\n windowCoordinate = (\n (y + firstLine - imageWindow[1]) * windowWidth\n ) + x + firstCol - imageWindow[0];\n valueArrays[si][windowCoordinate] = value;\n }\n }\n }\n });\n }\n }\n }\n await Promise.all(promises);\n\n if ((width && (imageWindow[2] - imageWindow[0]) !== width)\n || (height && (imageWindow[3] - imageWindow[1]) !== height)) {\n let resampled;\n if (interleave) {\n resampled = resampleInterleaved(\n valueArrays,\n imageWindow[2] - imageWindow[0],\n imageWindow[3] - imageWindow[1],\n width, height,\n samples.length,\n resampleMethod,\n );\n } else {\n resampled = resample(\n valueArrays,\n imageWindow[2] - imageWindow[0],\n imageWindow[3] - imageWindow[1],\n width, height,\n resampleMethod,\n );\n }\n resampled.width = width;\n resampled.height = height;\n return resampled;\n }\n\n valueArrays.width = width || imageWindow[2] - imageWindow[0];\n valueArrays.height = height || imageWindow[3] - imageWindow[1];\n\n return valueArrays;\n }\n\n /**\n * Reads raster data from the image. This function reads all selected samples\n * into separate arrays of the correct type for that sample or into a single\n * combined array when `interleave` is set. When provided, only a subset\n * of the raster is read for each sample.\n *\n * @param {ReadRasterOptions} [options={}] optional parameters\n * @returns {Promise.<(TypedArray|TypedArray[])>} the decoded arrays as a promise\n */\n async readRasters({\n window: wnd, samples = [], interleave, pool = null,\n width, height, resampleMethod, fillValue, signal,\n } = {}) {\n const imageWindow = wnd || [0, 0, this.getWidth(), this.getHeight()];\n\n // check parameters\n if (imageWindow[0] > imageWindow[2] || imageWindow[1] > imageWindow[3]) {\n throw new Error('Invalid subsets');\n }\n\n const imageWindowWidth = imageWindow[2] - imageWindow[0];\n const imageWindowHeight = imageWindow[3] - imageWindow[1];\n const numPixels = imageWindowWidth * imageWindowHeight;\n const samplesPerPixel = this.getSamplesPerPixel();\n\n if (!samples || !samples.length) {\n for (let i = 0; i < samplesPerPixel; ++i) {\n samples.push(i);\n }\n } else {\n for (let i = 0; i < samples.length; ++i) {\n if (samples[i] >= samplesPerPixel) {\n return Promise.reject(new RangeError(`Invalid sample index '${samples[i]}'.`));\n }\n }\n }\n let valueArrays;\n if (interleave) {\n const format = this.fileDirectory.SampleFormat\n ? Math.max.apply(null, this.fileDirectory.SampleFormat) : 1;\n const bitsPerSample = Math.max.apply(null, this.fileDirectory.BitsPerSample);\n valueArrays = arrayForType(format, bitsPerSample, numPixels * samples.length);\n if (fillValue) {\n valueArrays.fill(fillValue);\n }\n } else {\n valueArrays = [];\n for (let i = 0; i < samples.length; ++i) {\n const valueArray = this.getArrayForSample(samples[i], numPixels);\n if (Array.isArray(fillValue) && i < fillValue.length) {\n valueArray.fill(fillValue[i]);\n } else if (fillValue && !Array.isArray(fillValue)) {\n valueArray.fill(fillValue);\n }\n valueArrays.push(valueArray);\n }\n }\n\n const poolOrDecoder = pool || await getDecoder(this.fileDirectory);\n\n const result = await this._readRaster(\n imageWindow, samples, valueArrays, interleave, poolOrDecoder, width, height, resampleMethod, signal,\n );\n return result;\n }\n\n /**\n * Reads raster data from the image as RGB. The result is always an\n * interleaved typed array.\n * Colorspaces other than RGB will be transformed to RGB, color maps expanded.\n * When no other method is applicable, the first sample is used to produce a\n * greayscale image.\n * When provided, only a subset of the raster is read for each sample.\n *\n * @param {Object} [options] optional parameters\n * @param {Array} [options.window] the subset to read data from in pixels.\n * @param {boolean} [options.interleave=true] whether the data shall be read\n * in one single array or separate\n * arrays.\n * @param {import(\"./geotiff\").Pool} [options.pool=null] The optional decoder pool to use.\n * @param {number} [options.width] The desired width of the output. When the width is no the\n * same as the images, resampling will be performed.\n * @param {number} [options.height] The desired height of the output. When the width is no the\n * same as the images, resampling will be performed.\n * @param {string} [options.resampleMethod='nearest'] The desired resampling method.\n * @param {boolean} [options.enableAlpha=false] Enable reading alpha channel if present.\n * @param {AbortSignal} [options.signal] An AbortSignal that may be signalled if the request is\n * to be aborted\n * @returns {Promise} the RGB array as a Promise\n */\n async readRGB({ window, interleave = true, pool = null, width, height,\n resampleMethod, enableAlpha = false, signal } = {}) {\n const imageWindow = window || [0, 0, this.getWidth(), this.getHeight()];\n\n // check parameters\n if (imageWindow[0] > imageWindow[2] || imageWindow[1] > imageWindow[3]) {\n throw new Error('Invalid subsets');\n }\n\n const pi = this.fileDirectory.PhotometricInterpretation;\n\n if (pi === photometricInterpretations.RGB) {\n let s = [0, 1, 2];\n if ((!(this.fileDirectory.ExtraSamples === ExtraSamplesValues.Unspecified)) && enableAlpha) {\n s = [];\n for (let i = 0; i < this.fileDirectory.BitsPerSample.length; i += 1) {\n s.push(i);\n }\n }\n return this.readRasters({\n window,\n interleave,\n samples: s,\n pool,\n width,\n height,\n resampleMethod,\n signal,\n });\n }\n\n let samples;\n switch (pi) {\n case photometricInterpretations.WhiteIsZero:\n case photometricInterpretations.BlackIsZero:\n case photometricInterpretations.Palette:\n samples = [0];\n break;\n case photometricInterpretations.CMYK:\n samples = [0, 1, 2, 3];\n break;\n case photometricInterpretations.YCbCr:\n case photometricInterpretations.CIELab:\n samples = [0, 1, 2];\n break;\n default:\n throw new Error('Invalid or unsupported photometric interpretation.');\n }\n\n const subOptions = {\n window: imageWindow,\n interleave: true,\n samples,\n pool,\n width,\n height,\n resampleMethod,\n signal,\n };\n const { fileDirectory } = this;\n const raster = await this.readRasters(subOptions);\n\n const max = 2 ** this.fileDirectory.BitsPerSample[0];\n let data;\n switch (pi) {\n case photometricInterpretations.WhiteIsZero:\n data = fromWhiteIsZero(raster, max);\n break;\n case photometricInterpretations.BlackIsZero:\n data = fromBlackIsZero(raster, max);\n break;\n case photometricInterpretations.Palette:\n data = fromPalette(raster, fileDirectory.ColorMap);\n break;\n case photometricInterpretations.CMYK:\n data = fromCMYK(raster);\n break;\n case photometricInterpretations.YCbCr:\n data = fromYCbCr(raster);\n break;\n case photometricInterpretations.CIELab:\n data = fromCIELab(raster);\n break;\n default:\n throw new Error('Unsupported photometric interpretation.');\n }\n\n // if non-interleaved data is requested, we must split the channels\n // into their respective arrays\n if (!interleave) {\n const red = new Uint8Array(data.length / 3);\n const green = new Uint8Array(data.length / 3);\n const blue = new Uint8Array(data.length / 3);\n for (let i = 0, j = 0; i < data.length; i += 3, ++j) {\n red[j] = data[i];\n green[j] = data[i + 1];\n blue[j] = data[i + 2];\n }\n data = [red, green, blue];\n }\n\n data.width = raster.width;\n data.height = raster.height;\n return data;\n }\n\n /**\n * Returns an array of tiepoints.\n * @returns {Object[]}\n */\n getTiePoints() {\n if (!this.fileDirectory.ModelTiepoint) {\n return [];\n }\n\n const tiePoints = [];\n for (let i = 0; i < this.fileDirectory.ModelTiepoint.length; i += 6) {\n tiePoints.push({\n i: this.fileDirectory.ModelTiepoint[i],\n j: this.fileDirectory.ModelTiepoint[i + 1],\n k: this.fileDirectory.ModelTiepoint[i + 2],\n x: this.fileDirectory.ModelTiepoint[i + 3],\n y: this.fileDirectory.ModelTiepoint[i + 4],\n z: this.fileDirectory.ModelTiepoint[i + 5],\n });\n }\n return tiePoints;\n }\n\n /**\n * Returns the parsed GDAL metadata items.\n *\n * If sample is passed to null, dataset-level metadata will be returned.\n * Otherwise only metadata specific to the provided sample will be returned.\n *\n * @param {number} [sample=null] The sample index.\n * @returns {Object}\n */\n getGDALMetadata(sample = null) {\n const metadata = {};\n if (!this.fileDirectory.GDAL_METADATA) {\n return null;\n }\n const string = this.fileDirectory.GDAL_METADATA;\n\n let items = findTagsByName(string, 'Item');\n\n if (sample === null) {\n items = items.filter((item) => getAttribute(item, 'sample') === undefined);\n } else {\n items = items.filter((item) => Number(getAttribute(item, 'sample')) === sample);\n }\n\n for (let i = 0; i < items.length; ++i) {\n const item = items[i];\n metadata[getAttribute(item, 'name')] = item.inner;\n }\n return metadata;\n }\n\n /**\n * Returns the GDAL nodata value\n * @returns {number|null}\n */\n getGDALNoData() {\n if (!this.fileDirectory.GDAL_NODATA) {\n return null;\n }\n const string = this.fileDirectory.GDAL_NODATA;\n return Number(string.substring(0, string.length - 1));\n }\n\n /**\n * Returns the image origin as a XYZ-vector. When the image has no affine\n * transformation, then an exception is thrown.\n * @returns {Array} The origin as a vector\n */\n getOrigin() {\n const tiePoints = this.fileDirectory.ModelTiepoint;\n const modelTransformation = this.fileDirectory.ModelTransformation;\n if (tiePoints && tiePoints.length === 6) {\n return [\n tiePoints[3],\n tiePoints[4],\n tiePoints[5],\n ];\n }\n if (modelTransformation) {\n return [\n modelTransformation[3],\n modelTransformation[7],\n modelTransformation[11],\n ];\n }\n throw new Error('The image does not have an affine transformation.');\n }\n\n /**\n * Returns the image resolution as a XYZ-vector. When the image has no affine\n * transformation, then an exception is thrown.\n * @param {GeoTIFFImage} [referenceImage=null] A reference image to calculate the resolution from\n * in cases when the current image does not have the\n * required tags on its own.\n * @returns {Array} The resolution as a vector\n */\n getResolution(referenceImage = null) {\n const modelPixelScale = this.fileDirectory.ModelPixelScale;\n const modelTransformation = this.fileDirectory.ModelTransformation;\n\n if (modelPixelScale) {\n return [\n modelPixelScale[0],\n -modelPixelScale[1],\n modelPixelScale[2],\n ];\n }\n if (modelTransformation) {\n return [\n modelTransformation[0],\n modelTransformation[5],\n modelTransformation[10],\n ];\n }\n\n if (referenceImage) {\n const [refResX, refResY, refResZ] = referenceImage.getResolution();\n return [\n refResX * referenceImage.getWidth() / this.getWidth(),\n refResY * referenceImage.getHeight() / this.getHeight(),\n refResZ * referenceImage.getWidth() / this.getWidth(),\n ];\n }\n\n throw new Error('The image does not have an affine transformation.');\n }\n\n /**\n * Returns whether or not the pixels of the image depict an area (or point).\n * @returns {Boolean} Whether the pixels are a point\n */\n pixelIsArea() {\n return this.geoKeys.GTRasterTypeGeoKey === 1;\n }\n\n /**\n * Returns the image bounding box as an array of 4 values: min-x, min-y,\n * max-x and max-y. When the image has no affine transformation, then an\n * exception is thrown.\n * @returns {Array} The bounding box\n */\n getBoundingBox() {\n const origin = this.getOrigin();\n const resolution = this.getResolution();\n\n const x1 = origin[0];\n const y1 = origin[1];\n\n const x2 = x1 + (resolution[0] * this.getWidth());\n const y2 = y1 + (resolution[1] * this.getHeight());\n\n return [\n Math.min(x1, x2),\n Math.min(y1, y2),\n Math.max(x1, x2),\n Math.max(y1, y2),\n ];\n }\n}\n\nexport default GeoTIFFImage;\n","export function fromWhiteIsZero(raster, max) {\n const { width, height } = raster;\n const rgbRaster = new Uint8Array(width * height * 3);\n let value;\n for (let i = 0, j = 0; i < raster.length; ++i, j += 3) {\n value = 256 - (raster[i] / max * 256);\n rgbRaster[j] = value;\n rgbRaster[j + 1] = value;\n rgbRaster[j + 2] = value;\n }\n return rgbRaster;\n}\n\nexport function fromBlackIsZero(raster, max) {\n const { width, height } = raster;\n const rgbRaster = new Uint8Array(width * height * 3);\n let value;\n for (let i = 0, j = 0; i < raster.length; ++i, j += 3) {\n value = raster[i] / max * 256;\n rgbRaster[j] = value;\n rgbRaster[j + 1] = value;\n rgbRaster[j + 2] = value;\n }\n return rgbRaster;\n}\n\nexport function fromPalette(raster, colorMap) {\n const { width, height } = raster;\n const rgbRaster = new Uint8Array(width * height * 3);\n const greenOffset = colorMap.length / 3;\n const blueOffset = colorMap.length / 3 * 2;\n for (let i = 0, j = 0; i < raster.length; ++i, j += 3) {\n const mapIndex = raster[i];\n rgbRaster[j] = colorMap[mapIndex] / 65536 * 256;\n rgbRaster[j + 1] = colorMap[mapIndex + greenOffset] / 65536 * 256;\n rgbRaster[j + 2] = colorMap[mapIndex + blueOffset] / 65536 * 256;\n }\n return rgbRaster;\n}\n\nexport function fromCMYK(cmykRaster) {\n const { width, height } = cmykRaster;\n const rgbRaster = new Uint8Array(width * height * 3);\n for (let i = 0, j = 0; i < cmykRaster.length; i += 4, j += 3) {\n const c = cmykRaster[i];\n const m = cmykRaster[i + 1];\n const y = cmykRaster[i + 2];\n const k = cmykRaster[i + 3];\n\n rgbRaster[j] = 255 * ((255 - c) / 256) * ((255 - k) / 256);\n rgbRaster[j + 1] = 255 * ((255 - m) / 256) * ((255 - k) / 256);\n rgbRaster[j + 2] = 255 * ((255 - y) / 256) * ((255 - k) / 256);\n }\n return rgbRaster;\n}\n\nexport function fromYCbCr(yCbCrRaster) {\n const { width, height } = yCbCrRaster;\n const rgbRaster = new Uint8ClampedArray(width * height * 3);\n for (let i = 0, j = 0; i < yCbCrRaster.length; i += 3, j += 3) {\n const y = yCbCrRaster[i];\n const cb = yCbCrRaster[i + 1];\n const cr = yCbCrRaster[i + 2];\n\n rgbRaster[j] = (y + (1.40200 * (cr - 0x80)));\n rgbRaster[j + 1] = (y - (0.34414 * (cb - 0x80)) - (0.71414 * (cr - 0x80)));\n rgbRaster[j + 2] = (y + (1.77200 * (cb - 0x80)));\n }\n return rgbRaster;\n}\n\nconst Xn = 0.95047;\nconst Yn = 1.00000;\nconst Zn = 1.08883;\n\n// from https://github.com/antimatter15/rgb-lab/blob/master/color.js\n\nexport function fromCIELab(cieLabRaster) {\n const { width, height } = cieLabRaster;\n const rgbRaster = new Uint8Array(width * height * 3);\n\n for (let i = 0, j = 0; i < cieLabRaster.length; i += 3, j += 3) {\n const L = cieLabRaster[i + 0];\n const a_ = cieLabRaster[i + 1] << 24 >> 24; // conversion from uint8 to int8\n const b_ = cieLabRaster[i + 2] << 24 >> 24; // same\n\n let y = (L + 16) / 116;\n let x = (a_ / 500) + y;\n let z = y - (b_ / 200);\n let r;\n let g;\n let b;\n\n x = Xn * ((x * x * x > 0.008856) ? x * x * x : (x - (16 / 116)) / 7.787);\n y = Yn * ((y * y * y > 0.008856) ? y * y * y : (y - (16 / 116)) / 7.787);\n z = Zn * ((z * z * z > 0.008856) ? z * z * z : (z - (16 / 116)) / 7.787);\n\n r = (x * 3.2406) + (y * -1.5372) + (z * -0.4986);\n g = (x * -0.9689) + (y * 1.8758) + (z * 0.0415);\n b = (x * 0.0557) + (y * -0.2040) + (z * 1.0570);\n\n r = (r > 0.0031308) ? ((1.055 * (r ** (1 / 2.4))) - 0.055) : 12.92 * r;\n g = (g > 0.0031308) ? ((1.055 * (g ** (1 / 2.4))) - 0.055) : 12.92 * g;\n b = (b > 0.0031308) ? ((1.055 * (b ** (1 / 2.4))) - 0.055) : 12.92 * b;\n\n rgbRaster[j] = Math.max(0, Math.min(1, r)) * 255;\n rgbRaster[j + 1] = Math.max(0, Math.min(1, g)) * 255;\n rgbRaster[j + 2] = Math.max(0, Math.min(1, b)) * 255;\n }\n return rgbRaster;\n}\n","import { getFloat16 } from '@petamoriken/float16';\n\nexport default class DataView64 {\n constructor(arrayBuffer) {\n this._dataView = new DataView(arrayBuffer);\n }\n\n get buffer() {\n return this._dataView.buffer;\n }\n\n getUint64(offset, littleEndian) {\n const left = this.getUint32(offset, littleEndian);\n const right = this.getUint32(offset + 4, littleEndian);\n let combined;\n if (littleEndian) {\n combined = left + ((2 ** 32) * right);\n if (!Number.isSafeInteger(combined)) {\n throw new Error(\n `${combined} exceeds MAX_SAFE_INTEGER. `\n + 'Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues',\n );\n }\n return combined;\n }\n combined = ((2 ** 32) * left) + right;\n if (!Number.isSafeInteger(combined)) {\n throw new Error(\n `${combined} exceeds MAX_SAFE_INTEGER. `\n + 'Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues',\n );\n }\n\n return combined;\n }\n\n // adapted from https://stackoverflow.com/a/55338384/8060591\n getInt64(offset, littleEndian) {\n let value = 0;\n const isNegative = (this._dataView.getUint8(offset + (littleEndian ? 7 : 0)) & 0x80) > 0;\n let carrying = true;\n for (let i = 0; i < 8; i++) {\n let byte = this._dataView.getUint8(offset + (littleEndian ? i : 7 - i));\n if (isNegative) {\n if (carrying) {\n if (byte !== 0x00) {\n byte = ~(byte - 1) & 0xff;\n carrying = false;\n }\n } else {\n byte = ~byte & 0xff;\n }\n }\n value += byte * (256 ** i);\n }\n if (isNegative) {\n value = -value;\n }\n return value;\n }\n\n getUint8(offset, littleEndian) {\n return this._dataView.getUint8(offset, littleEndian);\n }\n\n getInt8(offset, littleEndian) {\n return this._dataView.getInt8(offset, littleEndian);\n }\n\n getUint16(offset, littleEndian) {\n return this._dataView.getUint16(offset, littleEndian);\n }\n\n getInt16(offset, littleEndian) {\n return this._dataView.getInt16(offset, littleEndian);\n }\n\n getUint32(offset, littleEndian) {\n return this._dataView.getUint32(offset, littleEndian);\n }\n\n getInt32(offset, littleEndian) {\n return this._dataView.getInt32(offset, littleEndian);\n }\n\n getFloat16(offset, littleEndian) {\n return getFloat16(this._dataView, offset, littleEndian);\n }\n\n getFloat32(offset, littleEndian) {\n return this._dataView.getFloat32(offset, littleEndian);\n }\n\n getFloat64(offset, littleEndian) {\n return this._dataView.getFloat64(offset, littleEndian);\n }\n}\n","export default class DataSlice {\n constructor(arrayBuffer, sliceOffset, littleEndian, bigTiff) {\n this._dataView = new DataView(arrayBuffer);\n this._sliceOffset = sliceOffset;\n this._littleEndian = littleEndian;\n this._bigTiff = bigTiff;\n }\n\n get sliceOffset() {\n return this._sliceOffset;\n }\n\n get sliceTop() {\n return this._sliceOffset + this.buffer.byteLength;\n }\n\n get littleEndian() {\n return this._littleEndian;\n }\n\n get bigTiff() {\n return this._bigTiff;\n }\n\n get buffer() {\n return this._dataView.buffer;\n }\n\n covers(offset, length) {\n return this.sliceOffset <= offset && this.sliceTop >= offset + length;\n }\n\n readUint8(offset) {\n return this._dataView.getUint8(\n offset - this._sliceOffset, this._littleEndian,\n );\n }\n\n readInt8(offset) {\n return this._dataView.getInt8(\n offset - this._sliceOffset, this._littleEndian,\n );\n }\n\n readUint16(offset) {\n return this._dataView.getUint16(\n offset - this._sliceOffset, this._littleEndian,\n );\n }\n\n readInt16(offset) {\n return this._dataView.getInt16(\n offset - this._sliceOffset, this._littleEndian,\n );\n }\n\n readUint32(offset) {\n return this._dataView.getUint32(\n offset - this._sliceOffset, this._littleEndian,\n );\n }\n\n readInt32(offset) {\n return this._dataView.getInt32(\n offset - this._sliceOffset, this._littleEndian,\n );\n }\n\n readFloat32(offset) {\n return this._dataView.getFloat32(\n offset - this._sliceOffset, this._littleEndian,\n );\n }\n\n readFloat64(offset) {\n return this._dataView.getFloat64(\n offset - this._sliceOffset, this._littleEndian,\n );\n }\n\n readUint64(offset) {\n const left = this.readUint32(offset);\n const right = this.readUint32(offset + 4);\n let combined;\n if (this._littleEndian) {\n combined = left + ((2 ** 32) * right);\n if (!Number.isSafeInteger(combined)) {\n throw new Error(\n `${combined} exceeds MAX_SAFE_INTEGER. `\n + 'Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues',\n );\n }\n return combined;\n }\n combined = ((2 ** 32) * left) + right;\n if (!Number.isSafeInteger(combined)) {\n throw new Error(\n `${combined} exceeds MAX_SAFE_INTEGER. `\n + 'Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues',\n );\n }\n\n return combined;\n }\n\n // adapted from https://stackoverflow.com/a/55338384/8060591\n readInt64(offset) {\n let value = 0;\n const isNegative = (this._dataView.getUint8(offset + (this._littleEndian ? 7 : 0)) & 0x80)\n > 0;\n let carrying = true;\n for (let i = 0; i < 8; i++) {\n let byte = this._dataView.getUint8(\n offset + (this._littleEndian ? i : 7 - i),\n );\n if (isNegative) {\n if (carrying) {\n if (byte !== 0x00) {\n byte = ~(byte - 1) & 0xff;\n carrying = false;\n }\n } else {\n byte = ~byte & 0xff;\n }\n }\n value += byte * (256 ** i);\n }\n if (isNegative) {\n value = -value;\n }\n return value;\n }\n\n readOffset(offset) {\n if (this._bigTiff) {\n return this.readUint64(offset);\n }\n return this.readUint32(offset);\n }\n}\n","const CRLFCRLF = '\\r\\n\\r\\n';\n\n/*\n * Shim for 'Object.fromEntries'\n */\nfunction itemsToObject(items) {\n if (typeof Object.fromEntries !== 'undefined') {\n return Object.fromEntries(items);\n }\n const obj = {};\n for (const [key, value] of items) {\n obj[key.toLowerCase()] = value;\n }\n return obj;\n}\n\n/**\n * Parse HTTP headers from a given string.\n * @param {String} text the text to parse the headers from\n * @returns {Object} the parsed headers with lowercase keys\n */\nfunction parseHeaders(text) {\n const items = text\n .split('\\r\\n')\n .map((line) => {\n const kv = line.split(':').map((str) => str.trim());\n kv[0] = kv[0].toLowerCase();\n return kv;\n });\n\n return itemsToObject(items);\n}\n\n/**\n * Parse a 'Content-Type' header value to the content-type and parameters\n * @param {String} rawContentType the raw string to parse from\n * @returns {Object} the parsed content type with the fields: type and params\n */\nexport function parseContentType(rawContentType) {\n const [type, ...rawParams] = rawContentType.split(';').map((s) => s.trim());\n const paramsItems = rawParams.map((param) => param.split('='));\n return { type, params: itemsToObject(paramsItems) };\n}\n\n/**\n * Parse a 'Content-Range' header value to its start, end, and total parts\n * @param {String} rawContentRange the raw string to parse from\n * @returns {Object} the parsed parts\n */\nexport function parseContentRange(rawContentRange) {\n let start;\n let end;\n let total;\n\n if (rawContentRange) {\n [, start, end, total] = rawContentRange.match(/bytes (\\d+)-(\\d+)\\/(\\d+)/);\n start = parseInt(start, 10);\n end = parseInt(end, 10);\n total = parseInt(total, 10);\n }\n\n return { start, end, total };\n}\n\n/**\n * Parses a list of byteranges from the given 'multipart/byteranges' HTTP response.\n * Each item in the list has the following properties:\n * - headers: the HTTP headers\n * - data: the sliced ArrayBuffer for that specific part\n * - offset: the offset of the byterange within its originating file\n * - length: the length of the byterange\n * @param {ArrayBuffer} responseArrayBuffer the response to be parsed and split\n * @param {String} boundary the boundary string used to split the sections\n * @returns {Object[]} the parsed byteranges\n */\nexport function parseByteRanges(responseArrayBuffer, boundary) {\n let offset = null;\n const decoder = new TextDecoder('ascii');\n const out = [];\n\n const startBoundary = `--${boundary}`;\n const endBoundary = `${startBoundary}--`;\n\n // search for the initial boundary, may be offset by some bytes\n // TODO: more efficient to check for `--` in bytes directly\n for (let i = 0; i < 10; ++i) {\n const text = decoder.decode(\n new Uint8Array(responseArrayBuffer, i, startBoundary.length),\n );\n if (text === startBoundary) {\n offset = i;\n }\n }\n\n if (offset === null) {\n throw new Error('Could not find initial boundary');\n }\n\n while (offset < responseArrayBuffer.byteLength) {\n const text = decoder.decode(\n new Uint8Array(responseArrayBuffer, offset,\n Math.min(startBoundary.length + 1024, responseArrayBuffer.byteLength - offset),\n ),\n );\n\n // break if we arrived at the end\n if (text.length === 0 || text.startsWith(endBoundary)) {\n break;\n }\n\n // assert that we are actually dealing with a byterange and are at the correct offset\n if (!text.startsWith(startBoundary)) {\n throw new Error('Part does not start with boundary');\n }\n\n // get a substring from where we read the headers\n const innerText = text.substr(startBoundary.length + 2);\n\n if (innerText.length === 0) {\n break;\n }\n\n // find the double linebreak that denotes the end of the headers\n const endOfHeaders = innerText.indexOf(CRLFCRLF);\n\n // parse the headers to get the content range size\n const headers = parseHeaders(innerText.substr(0, endOfHeaders));\n const { start, end, total } = parseContentRange(headers['content-range']);\n\n // calculate the length of the slice and the next offset\n const startOfData = offset + startBoundary.length + endOfHeaders + CRLFCRLF.length;\n const length = parseInt(end, 10) + 1 - parseInt(start, 10);\n out.push({\n headers,\n data: responseArrayBuffer.slice(startOfData, startOfData + length),\n offset: start,\n length,\n fileSize: total,\n });\n\n offset = startOfData + length + 4;\n }\n\n return out;\n}\n","/**\n * @typedef Slice\n * @property {number} offset\n * @property {number} length\n */\n\nexport class BaseSource {\n /**\n *\n * @param {Slice[]} slices\n * @returns {ArrayBuffer[]}\n */\n async fetch(slices, signal = undefined) {\n return Promise.all(\n slices.map((slice) => this.fetchSlice(slice, signal)),\n );\n }\n\n /**\n *\n * @param {Slice} slice\n * @returns {ArrayBuffer}\n */\n async fetchSlice(slice) {\n throw new Error(`fetching of slice ${slice} not possible, not implemented`);\n }\n\n /**\n * Returns the filesize if already determined and null otherwise\n */\n get fileSize() {\n return null;\n }\n\n async close() {\n // no-op by default\n }\n}\n","export function assign(target, source) {\n for (const key in source) {\n if (source.hasOwnProperty(key)) {\n target[key] = source[key];\n }\n }\n}\n\nexport function chunk(iterable, length) {\n const results = [];\n const lengthOfIterable = iterable.length;\n for (let i = 0; i < lengthOfIterable; i += length) {\n const chunked = [];\n for (let ci = i; ci < i + length; ci++) {\n chunked.push(iterable[ci]);\n }\n results.push(chunked);\n }\n return results;\n}\n\nexport function endsWith(string, expectedEnding) {\n if (string.length < expectedEnding.length) {\n return false;\n }\n const actualEnding = string.substr(string.length - expectedEnding.length);\n return actualEnding === expectedEnding;\n}\n\nexport function forEach(iterable, func) {\n const { length } = iterable;\n for (let i = 0; i < length; i++) {\n func(iterable[i], i);\n }\n}\n\nexport function invert(oldObj) {\n const newObj = {};\n for (const key in oldObj) {\n if (oldObj.hasOwnProperty(key)) {\n const value = oldObj[key];\n newObj[value] = key;\n }\n }\n return newObj;\n}\n\nexport function range(n) {\n const results = [];\n for (let i = 0; i < n; i++) {\n results.push(i);\n }\n return results;\n}\n\nexport function times(numTimes, func) {\n const results = [];\n for (let i = 0; i < numTimes; i++) {\n results.push(func(i));\n }\n return results;\n}\n\nexport function toArray(iterable) {\n const results = [];\n const { length } = iterable;\n for (let i = 0; i < length; i++) {\n results.push(iterable[i]);\n }\n return results;\n}\n\nexport function toArrayRecursively(input) {\n if (input.length) {\n return toArray(input).map(toArrayRecursively);\n }\n return input;\n}\n\n// copied from https://github.com/academia-de-codigo/parse-content-range-header/blob/master/index.js\nexport function parseContentRange(headerValue) {\n if (!headerValue) {\n return null;\n }\n\n if (typeof headerValue !== 'string') {\n throw new Error('invalid argument');\n }\n\n const parseInt = (number) => Number.parseInt(number, 10);\n\n // Check for presence of unit\n let matches = headerValue.match(/^(\\w*) /);\n const unit = matches && matches[1];\n\n // check for start-end/size header format\n matches = headerValue.match(/(\\d+)-(\\d+)\\/(\\d+|\\*)/);\n if (matches) {\n return {\n unit,\n first: parseInt(matches[1]),\n last: parseInt(matches[2]),\n length: matches[3] === '*' ? null : parseInt(matches[3]),\n };\n }\n\n // check for size header format\n matches = headerValue.match(/(\\d+|\\*)/);\n if (matches) {\n return {\n unit,\n first: null,\n last: null,\n length: matches[1] === '*' ? null : parseInt(matches[1]),\n };\n }\n\n return null;\n}\n\n/*\n * Promisified wrapper around 'setTimeout' to allow 'await'\n */\nexport async function wait(milliseconds) {\n return new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n\nexport function zip(a, b) {\n const A = Array.isArray(a) ? a : Array.from(a);\n const B = Array.isArray(b) ? b : Array.from(b);\n return A.map((k, i) => [k, B[i]]);\n}\n\n// Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error\nexport class AbortError extends Error {\n constructor(params) {\n // Pass remaining arguments (including vendor specific ones) to parent constructor\n super(params);\n\n // Maintains proper stack trace for where our error was thrown (only available on V8)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, AbortError);\n }\n\n this.name = 'AbortError';\n }\n}\n\nexport class CustomAggregateError extends Error {\n constructor(errors, message) {\n super(message);\n this.errors = errors;\n this.message = message;\n this.name = 'AggregateError';\n }\n}\n\nexport const AggregateError = CustomAggregateError;\n","import LRUCache from 'lru-cache';\nimport { BaseSource } from './basesource.js';\nimport { AbortError, AggregateError, wait, zip } from '../utils.js';\n\nclass Block {\n /**\n *\n * @param {number} offset\n * @param {number} length\n * @param {ArrayBuffer} [data]\n */\n constructor(offset, length, data = null) {\n this.offset = offset;\n this.length = length;\n this.data = data;\n }\n\n /**\n * @returns {number} the top byte border\n */\n get top() {\n return this.offset + this.length;\n }\n}\n\nclass BlockGroup {\n /**\n *\n * @param {number} offset\n * @param {number} length\n * @param {number[]} blockIds\n */\n constructor(offset, length, blockIds) {\n this.offset = offset;\n this.length = length;\n this.blockIds = blockIds;\n }\n}\n\nexport class BlockedSource extends BaseSource {\n /**\n *\n * @param {Source} source The underlying source that shall be blocked and cached\n * @param {object} options\n */\n constructor(source, { blockSize = 65536, cacheSize = 100 } = {}) {\n super();\n this.source = source;\n this.blockSize = blockSize;\n\n this.blockCache = new LRUCache({ max: cacheSize });\n\n // mapping blockId -> Block instance\n this.blockRequests = new Map();\n\n // set of blockIds missing for the current requests\n this.blockIdsToFetch = new Set();\n }\n\n get fileSize() {\n return this.source.fileSize;\n }\n\n /**\n *\n * @param {basesource/Slice[]} slices\n */\n async fetch(slices, signal) {\n const cachedBlocks = new Map();\n const blockRequests = new Map();\n const missingBlockIds = new Set();\n\n for (const { offset, length } of slices) {\n let top = offset + length;\n\n const { fileSize } = this;\n if (fileSize !== null) {\n top = Math.min(top, fileSize);\n }\n\n const firstBlockOffset = Math.floor(offset / this.blockSize) * this.blockSize;\n\n // chunk the current slice into blocks\n for (let current = firstBlockOffset; current < top; current += this.blockSize) {\n // check if the block is cached, being requested or still missing\n const blockId = Math.floor(current / this.blockSize);\n\n if (this.blockCache.has(blockId)) {\n cachedBlocks.set(blockId, this.blockCache.get(blockId));\n } else if (this.blockRequests.has(blockId)) {\n blockRequests.set(blockId, this.blockRequests.get(blockId));\n } else if (this.blockIdsToFetch.has(blockId)) {\n missingBlockIds.add(blockId);\n } else {\n this.blockIdsToFetch.add(blockId);\n missingBlockIds.add(blockId);\n }\n }\n }\n\n // allow additional block requests to accumulate\n await wait();\n this.fetchBlocks(signal);\n\n for (const blockId of missingBlockIds) {\n const block = this.blockRequests.get(blockId);\n const cachedBlock = this.blockCache.get(blockId);\n\n if (block) {\n blockRequests.set(blockId, block);\n } else if (cachedBlock) {\n cachedBlocks.set(blockId, cachedBlock);\n } else {\n throw new Error(`Block ${blockId} is not in the block requests`);\n }\n }\n\n // actually await all pending requests\n let results = await Promise.allSettled(Array.from(blockRequests.values()));\n\n // perform retries if a block was interrupted by a previous signal\n if (results.some((result) => result.status === 'rejected')) {\n const retriedBlockRequests = new Set();\n for (const [blockId, result] of zip(blockRequests.keys(), results)) {\n const { rejected, reason } = result;\n if (rejected) {\n // push some blocks back to the to-fetch list if they were\n // aborted, but only when a different signal was used\n if (reason.name === 'AbortError' && reason.signal !== signal) {\n this.blockIdsToFetch.add(blockId);\n retriedBlockRequests.add(blockId);\n }\n }\n }\n\n // start the retry of some blocks if required\n if (this.blockIdsToFetch.length > 0) {\n this.fetchBlocks(signal);\n for (const blockId of retriedBlockRequests) {\n const block = this.blockRequests.get(blockId);\n if (!block) {\n throw new Error(`Block ${blockId} is not in the block requests`);\n }\n blockRequests.set(blockId, block);\n }\n results = await Promise.allSettled(Array.from(blockRequests.values()));\n }\n }\n\n // throw an error (either abort error or AggregateError if no abort was done)\n if (results.some((result) => result.status === 'rejected')) {\n if (signal && signal.aborted) {\n throw new AbortError('Request was aborted');\n }\n throw new AggregateError(\n results.filter((result) => result.status === 'rejected').map((result) => result.reason),\n 'Request failed',\n );\n }\n\n // extract the actual block responses\n const values = results.map((result) => result.value);\n\n // create a final Map, with all required blocks for this request to satisfy\n const requiredBlocks = new Map(zip(Array.from(blockRequests.keys()), values));\n for (const [blockId, block] of cachedBlocks) {\n requiredBlocks.set(blockId, block);\n }\n\n // TODO: satisfy each slice\n return this.readSliceData(slices, requiredBlocks);\n }\n\n /**\n *\n * @param {AbortSignal} signal\n */\n fetchBlocks(signal) {\n // check if we still need to\n if (this.blockIdsToFetch.size > 0) {\n const groups = this.groupBlocks(this.blockIdsToFetch);\n\n // start requesting slices of data\n const groupRequests = this.source.fetch(groups, signal);\n\n for (let groupIndex = 0; groupIndex < groups.length; ++groupIndex) {\n const group = groups[groupIndex];\n\n for (const blockId of group.blockIds) {\n // make an async IIFE for each block\n const blockRequest = (async () => {\n try {\n const response = (await groupRequests)[groupIndex];\n const blockOffset = blockId * this.blockSize;\n const o = blockOffset - response.offset;\n const t = Math.min(o + this.blockSize, response.data.byteLength);\n const data = response.data.slice(o, t);\n const block = new Block(\n blockOffset,\n data.byteLength,\n data,\n );\n this.blockCache.set(blockId, block);\n return block;\n } catch (err) {\n if (err.name === 'AbortError') {\n // store the signal here, we need it to determine later if an\n // error was caused by this signal\n err.signal = signal;\n }\n throw err;\n } finally {\n this.blockRequests.delete(blockId);\n }\n })();\n this.blockRequests.set(blockId, blockRequest);\n }\n }\n this.blockIdsToFetch.clear();\n }\n }\n\n /**\n *\n * @param {Set} blockIds\n * @returns {BlockGroup[]}\n */\n groupBlocks(blockIds) {\n const sortedBlockIds = Array.from(blockIds).sort((a, b) => a - b);\n if (sortedBlockIds.length === 0) {\n return [];\n }\n let current = [];\n let lastBlockId = null;\n const groups = [];\n\n for (const blockId of sortedBlockIds) {\n if (lastBlockId === null || lastBlockId + 1 === blockId) {\n current.push(blockId);\n lastBlockId = blockId;\n } else {\n groups.push(new BlockGroup(\n current[0] * this.blockSize,\n current.length * this.blockSize,\n current,\n ));\n current = [blockId];\n lastBlockId = blockId;\n }\n }\n\n groups.push(new BlockGroup(\n current[0] * this.blockSize,\n current.length * this.blockSize,\n current,\n ));\n\n return groups;\n }\n\n /**\n *\n * @param {Slice[]} slices\n * @param {Map} blocks\n */\n readSliceData(slices, blocks) {\n return slices.map((slice) => {\n const top = slice.offset + slice.length;\n const blockIdLow = Math.floor(slice.offset / this.blockSize);\n const blockIdHigh = Math.floor((slice.offset + slice.length) / this.blockSize);\n const sliceData = new ArrayBuffer(slice.length);\n const sliceView = new Uint8Array(sliceData);\n\n for (let blockId = blockIdLow; blockId <= blockIdHigh; ++blockId) {\n const block = blocks.get(blockId);\n const delta = block.offset - slice.offset;\n const topDelta = block.top - top;\n let blockInnerOffset = 0;\n let rangeInnerOffset = 0;\n let usedBlockLength;\n\n if (delta < 0) {\n blockInnerOffset = -delta;\n } else if (delta > 0) {\n rangeInnerOffset = delta;\n }\n\n if (topDelta < 0) {\n usedBlockLength = block.length - blockInnerOffset;\n } else {\n usedBlockLength = top - block.offset - blockInnerOffset;\n }\n\n const blockView = new Uint8Array(block.data, blockInnerOffset, usedBlockLength);\n sliceView.set(blockView, rangeInnerOffset);\n }\n\n return sliceData;\n });\n }\n}\n","export class BaseResponse {\n /**\n * Returns whether the response has an ok'ish status code\n */\n get ok() {\n return this.status >= 200 && this.status <= 299;\n }\n\n /**\n * Returns the status code of the response\n */\n get status() {\n throw new Error('not implemented');\n }\n\n /**\n * Returns the value of the specified header\n * @param {string} headerName the header name\n * @returns {string} the header value\n */\n getHeader(headerName) { // eslint-disable-line no-unused-vars\n throw new Error('not implemented');\n }\n\n /**\n * @returns {ArrayBuffer} the response data of the request\n */\n async getData() {\n throw new Error('not implemented');\n }\n}\n\nexport class BaseClient {\n constructor(url) {\n this.url = url;\n }\n\n /**\n * Send a request with the options\n * @param {object} [options]\n */\n async request({ headers, credentials, signal } = {}) { // eslint-disable-line no-unused-vars\n throw new Error('request is not implemented');\n }\n}\n","import { BaseClient, BaseResponse } from './base.js';\n\nclass FetchResponse extends BaseResponse {\n /**\n * BaseResponse facade for fetch API Response\n * @param {Response} response\n */\n constructor(response) {\n super();\n this.response = response;\n }\n\n get status() {\n return this.response.status;\n }\n\n getHeader(name) {\n return this.response.headers.get(name);\n }\n\n async getData() {\n const data = this.response.arrayBuffer\n ? await this.response.arrayBuffer()\n : (await this.response.buffer()).buffer;\n return data;\n }\n}\n\nexport class FetchClient extends BaseClient {\n constructor(url, credentials) {\n super(url);\n this.credentials = credentials;\n }\n\n async request({ headers, credentials, signal } = {}) {\n const response = await fetch(this.url, {\n headers, credentials, signal,\n });\n return new FetchResponse(response);\n }\n}\n","import { BaseClient, BaseResponse } from './base.js';\nimport { AbortError } from '../../utils.js';\n\nclass XHRResponse extends BaseResponse {\n /**\n * BaseResponse facade for XMLHttpRequest\n * @param {XMLHttpRequest} xhr\n * @param {ArrayBuffer} data\n */\n constructor(xhr, data) {\n super();\n this.xhr = xhr;\n this.data = data;\n }\n\n get status() {\n return this.xhr.status;\n }\n\n getHeader(name) {\n return this.xhr.getResponseHeader(name);\n }\n\n async getData() {\n return this.data;\n }\n}\n\nexport class XHRClient extends BaseClient {\n constructRequest(headers, signal) {\n return new Promise((resolve, reject) => {\n const xhr = new XMLHttpRequest();\n xhr.open('GET', this.url);\n xhr.responseType = 'arraybuffer';\n for (const [key, value] of Object.entries(headers)) {\n xhr.setRequestHeader(key, value);\n }\n\n // hook signals\n xhr.onload = () => {\n const data = xhr.response;\n resolve(new XHRResponse(xhr, data));\n };\n xhr.onerror = reject;\n xhr.onabort = () => reject(new AbortError('Request aborted'));\n xhr.send();\n\n if (signal) {\n if (signal.aborted) {\n xhr.abort();\n }\n signal.addEventListener('abort', () => xhr.abort());\n }\n });\n }\n\n async request({ headers, signal } = {}) {\n const response = await this.constructRequest(headers, signal);\n return response;\n }\n}\n","import http from 'http';\nimport https from 'https';\nimport urlMod from 'url';\n\nimport { BaseClient, BaseResponse } from './base.js';\nimport { AbortError } from '../../utils.js';\n\nclass HttpResponse extends BaseResponse {\n /**\n * BaseResponse facade for node HTTP/HTTPS API Response\n * @param {http.ServerResponse} response\n */\n constructor(response, dataPromise) {\n super();\n this.response = response;\n this.dataPromise = dataPromise;\n }\n\n get status() {\n return this.response.statusCode;\n }\n\n getHeader(name) {\n return this.response.headers[name];\n }\n\n async getData() {\n const data = await this.dataPromise;\n return data;\n }\n}\n\nexport class HttpClient extends BaseClient {\n constructor(url) {\n super(url);\n this.parsedUrl = urlMod.parse(this.url);\n this.httpApi = (this.parsedUrl.protocol === 'http:' ? http : https);\n }\n\n constructRequest(headers, signal) {\n return new Promise((resolve, reject) => {\n const request = this.httpApi.get(\n {\n ...this.parsedUrl,\n headers,\n },\n (response) => {\n const dataPromise = new Promise((resolveData) => {\n const chunks = [];\n\n // collect chunks\n response.on('data', (chunk) => {\n chunks.push(chunk);\n });\n\n // concatenate all chunks and resolve the promise with the resulting buffer\n response.on('end', () => {\n const data = Buffer.concat(chunks).buffer;\n resolveData(data);\n });\n response.on('error', reject);\n });\n resolve(new HttpResponse(response, dataPromise));\n },\n );\n request.on('error', reject);\n\n if (signal) {\n if (signal.aborted) {\n request.destroy(new AbortError('Request aborted'));\n }\n signal.addEventListener('abort', () => request.destroy(new AbortError('Request aborted')));\n }\n });\n }\n\n async request({ headers, signal } = {}) {\n const response = await this.constructRequest(headers, signal);\n return response;\n }\n}\n","import { parseByteRanges, parseContentRange, parseContentType } from './httputils.js';\nimport { BaseSource } from './basesource.js';\nimport { BlockedSource } from './blockedsource.js';\n\nimport { FetchClient } from './client/fetch.js';\nimport { XHRClient } from './client/xhr.js';\nimport { HttpClient } from './client/http.js';\n\nclass RemoteSource extends BaseSource {\n /**\n *\n * @param {BaseClient} client\n * @param {object} headers\n * @param {numbers} maxRanges\n * @param {boolean} allowFullFile\n */\n constructor(client, headers, maxRanges, allowFullFile) {\n super();\n this.client = client;\n this.headers = headers;\n this.maxRanges = maxRanges;\n this.allowFullFile = allowFullFile;\n this._fileSize = null;\n }\n\n /**\n *\n * @param {Slice[]} slices\n */\n async fetch(slices, signal) {\n // if we allow multi-ranges, split the incoming request into that many sub-requests\n // and join them afterwards\n if (this.maxRanges >= slices.length) {\n return this.fetchSlices(slices, signal);\n } else if (this.maxRanges > 0 && slices.length > 1) {\n // TODO: split into multiple multi-range requests\n\n // const subSlicesRequests = [];\n // for (let i = 0; i < slices.length; i += this.maxRanges) {\n // subSlicesRequests.push(\n // this.fetchSlices(slices.slice(i, i + this.maxRanges), signal),\n // );\n // }\n // return (await Promise.all(subSlicesRequests)).flat();\n }\n\n // otherwise make a single request for each slice\n return Promise.all(\n slices.map((slice) => this.fetchSlice(slice, signal)),\n );\n }\n\n async fetchSlices(slices, signal) {\n const response = await this.client.request({\n headers: {\n ...this.headers,\n Range: `bytes=${slices\n .map(({ offset, length }) => `${offset}-${offset + length}`)\n .join(',')\n }`,\n },\n signal,\n });\n\n if (!response.ok) {\n throw new Error('Error fetching data.');\n } else if (response.status === 206) {\n const { type, params } = parseContentType(response.getHeader('content-type'));\n if (type === 'multipart/byteranges') {\n const byteRanges = parseByteRanges(await response.getData(), params.boundary);\n this._fileSize = byteRanges[0].fileSize || null;\n return byteRanges;\n }\n\n const data = await response.getData();\n\n const { start, end, total } = parseContentRange(response.getHeader('content-range'));\n this._fileSize = total || null;\n const first = [{\n data,\n offset: start,\n length: end - start,\n }];\n\n if (slices.length > 1) {\n // we requested more than one slice, but got only the first\n // unfortunately, some HTTP Servers don't support multi-ranges\n // and return onyl the first\n\n // get the rest of the slices and fetch them iteratetively\n const others = await Promise.all(slices.slice(1).map((slice) => this.fetchSlice(slice, signal)));\n return first.concat(others);\n }\n return first;\n } else {\n if (!this.allowFullFile) {\n throw new Error('Server responded with full file');\n }\n const data = await response.getData();\n this._fileSize = data.byteLength;\n return [{\n data,\n offset: 0,\n length: data.byteLength,\n }];\n }\n }\n\n async fetchSlice(slice, signal) {\n const { offset, length } = slice;\n const response = await this.client.request({\n headers: {\n ...this.headers,\n Range: `bytes=${offset}-${offset + length}`,\n },\n signal,\n });\n\n // check the response was okay and if the server actually understands range requests\n if (!response.ok) {\n throw new Error('Error fetching data.');\n } else if (response.status === 206) {\n const data = await response.getData();\n\n const { total } = parseContentRange(response.getHeader('content-range'));\n this._fileSize = total || null;\n return {\n data,\n offset,\n length,\n };\n } else {\n if (!this.allowFullFile) {\n throw new Error('Server responded with full file');\n }\n\n const data = await response.getData();\n\n this._fileSize = data.byteLength;\n return {\n data,\n offset: 0,\n length: data.byteLength,\n };\n }\n }\n\n get fileSize() {\n return this._fileSize;\n }\n}\n\nfunction maybeWrapInBlockedSource(source, { blockSize, cacheSize }) {\n if (blockSize === null) {\n return source;\n }\n return new BlockedSource(source, blockSize, cacheSize);\n}\n\nexport function makeFetchSource(url, { headers = {}, credentials, maxRanges = 0, allowFullFile = false, ...blockOptions } = {}) {\n const client = new FetchClient(url, credentials);\n const source = new RemoteSource(client, headers, maxRanges, allowFullFile);\n return maybeWrapInBlockedSource(source, blockOptions);\n}\n\nexport function makeXHRSource(url, { headers = {}, maxRanges = 0, allowFullFile = false, ...blockOptions } = {}) {\n const client = new XHRClient(url);\n const source = new RemoteSource(client, headers, maxRanges, allowFullFile);\n return maybeWrapInBlockedSource(source, blockOptions);\n}\n\nexport function makeHttpSource(url, { headers = {}, maxRanges = 0, allowFullFile = false, ...blockOptions } = {}) {\n const client = new HttpClient(url);\n const source = new RemoteSource(client, headers, maxRanges, allowFullFile);\n return maybeWrapInBlockedSource(source, blockOptions);\n}\n\n/**\n *\n * @param {string} url\n * @param {object} options\n */\nexport function makeRemoteSource(url, { forceXHR = false, ...clientOptions } = {}) {\n if (typeof fetch === 'function' && !forceXHR) {\n return makeFetchSource(url, clientOptions);\n }\n if (typeof XMLHttpRequest !== 'undefined') {\n return makeXHRSource(url, clientOptions);\n }\n return makeHttpSource(url, clientOptions);\n}\n","import { BaseSource } from './basesource.js';\n\nclass FileReaderSource extends BaseSource {\n constructor(file) {\n super();\n this.file = file;\n }\n\n async fetchSlice(slice, signal) {\n return new Promise((resolve, reject) => {\n const blob = this.file.slice(slice.offset, slice.offset + slice.length);\n const reader = new FileReader();\n reader.onload = (event) => resolve(event.target.result);\n reader.onerror = reject;\n reader.onabort = reject;\n reader.readAsArrayBuffer(blob);\n\n if (signal) {\n signal.addEventListener('abort', () => reader.abort());\n }\n });\n }\n}\n\n/**\n * Create a new source from a given file/blob.\n * @param {Blob} file The file or blob to read from.\n * @returns The constructed source\n */\nexport function makeFileReaderSource(file) {\n return new FileReaderSource(file);\n}\n","/** @module geotiff */\nimport GeoTIFFImage from './geotiffimage.js';\nimport DataView64 from './dataview64.js';\nimport DataSlice from './dataslice.js';\nimport Pool from './pool.js';\n\nimport { makeRemoteSource } from './source/remote.js';\nimport { makeBufferSource } from './source/arraybuffer.js';\nimport { makeFileReaderSource } from './source/filereader.js';\nimport { makeFileSource } from './source/file.js';\n\nimport { fieldTypes, fieldTagNames, arrayFields, geoKeyNames } from './globals.js';\nimport { writeGeotiff } from './geotiffwriter.js';\nimport * as globals from './globals.js';\nimport * as rgb from './rgb.js';\nimport { getDecoder, addDecoder } from './compression/index.js';\nimport { setLogger } from './logging.js';\n\nexport { globals };\nexport { rgb };\nexport { getDecoder, addDecoder };\nexport { setLogger };\n\n/**\n * @typedef {Uint8Array | Int8Array | Uint16Array | Int16Array | Uint32Array | Int32Array | Float32Array | Float64Array}\n * TypedArray\n */\n\nfunction getFieldTypeLength(fieldType) {\n switch (fieldType) {\n case fieldTypes.BYTE: case fieldTypes.ASCII: case fieldTypes.SBYTE: case fieldTypes.UNDEFINED:\n return 1;\n case fieldTypes.SHORT: case fieldTypes.SSHORT:\n return 2;\n case fieldTypes.LONG: case fieldTypes.SLONG: case fieldTypes.FLOAT: case fieldTypes.IFD:\n return 4;\n case fieldTypes.RATIONAL: case fieldTypes.SRATIONAL: case fieldTypes.DOUBLE:\n case fieldTypes.LONG8: case fieldTypes.SLONG8: case fieldTypes.IFD8:\n return 8;\n default:\n throw new RangeError(`Invalid field type: ${fieldType}`);\n }\n}\n\nfunction parseGeoKeyDirectory(fileDirectory) {\n const rawGeoKeyDirectory = fileDirectory.GeoKeyDirectory;\n if (!rawGeoKeyDirectory) {\n return null;\n }\n\n const geoKeyDirectory = {};\n for (let i = 4; i <= rawGeoKeyDirectory[3] * 4; i += 4) {\n const key = geoKeyNames[rawGeoKeyDirectory[i]];\n const location = (rawGeoKeyDirectory[i + 1])\n ? (fieldTagNames[rawGeoKeyDirectory[i + 1]]) : null;\n const count = rawGeoKeyDirectory[i + 2];\n const offset = rawGeoKeyDirectory[i + 3];\n\n let value = null;\n if (!location) {\n value = offset;\n } else {\n value = fileDirectory[location];\n if (typeof value === 'undefined' || value === null) {\n throw new Error(`Could not get value of geoKey '${key}'.`);\n } else if (typeof value === 'string') {\n value = value.substring(offset, offset + count - 1);\n } else if (value.subarray) {\n value = value.subarray(offset, offset + count);\n if (count === 1) {\n value = value[0];\n }\n }\n }\n geoKeyDirectory[key] = value;\n }\n return geoKeyDirectory;\n}\n\nfunction getValues(dataSlice, fieldType, count, offset) {\n let values = null;\n let readMethod = null;\n const fieldTypeLength = getFieldTypeLength(fieldType);\n\n switch (fieldType) {\n case fieldTypes.BYTE: case fieldTypes.ASCII: case fieldTypes.UNDEFINED:\n values = new Uint8Array(count); readMethod = dataSlice.readUint8;\n break;\n case fieldTypes.SBYTE:\n values = new Int8Array(count); readMethod = dataSlice.readInt8;\n break;\n case fieldTypes.SHORT:\n values = new Uint16Array(count); readMethod = dataSlice.readUint16;\n break;\n case fieldTypes.SSHORT:\n values = new Int16Array(count); readMethod = dataSlice.readInt16;\n break;\n case fieldTypes.LONG: case fieldTypes.IFD:\n values = new Uint32Array(count); readMethod = dataSlice.readUint32;\n break;\n case fieldTypes.SLONG:\n values = new Int32Array(count); readMethod = dataSlice.readInt32;\n break;\n case fieldTypes.LONG8: case fieldTypes.IFD8:\n values = new Array(count); readMethod = dataSlice.readUint64;\n break;\n case fieldTypes.SLONG8:\n values = new Array(count); readMethod = dataSlice.readInt64;\n break;\n case fieldTypes.RATIONAL:\n values = new Uint32Array(count * 2); readMethod = dataSlice.readUint32;\n break;\n case fieldTypes.SRATIONAL:\n values = new Int32Array(count * 2); readMethod = dataSlice.readInt32;\n break;\n case fieldTypes.FLOAT:\n values = new Float32Array(count); readMethod = dataSlice.readFloat32;\n break;\n case fieldTypes.DOUBLE:\n values = new Float64Array(count); readMethod = dataSlice.readFloat64;\n break;\n default:\n throw new RangeError(`Invalid field type: ${fieldType}`);\n }\n\n // normal fields\n if (!(fieldType === fieldTypes.RATIONAL || fieldType === fieldTypes.SRATIONAL)) {\n for (let i = 0; i < count; ++i) {\n values[i] = readMethod.call(\n dataSlice, offset + (i * fieldTypeLength),\n );\n }\n } else { // RATIONAL or SRATIONAL\n for (let i = 0; i < count; i += 2) {\n values[i] = readMethod.call(\n dataSlice, offset + (i * fieldTypeLength),\n );\n values[i + 1] = readMethod.call(\n dataSlice, offset + ((i * fieldTypeLength) + 4),\n );\n }\n }\n\n if (fieldType === fieldTypes.ASCII) {\n return new TextDecoder('utf-8').decode(values);\n }\n return values;\n}\n\n/**\n * Data class to store the parsed file directory, geo key directory and\n * offset to the next IFD\n */\nclass ImageFileDirectory {\n constructor(fileDirectory, geoKeyDirectory, nextIFDByteOffset) {\n this.fileDirectory = fileDirectory;\n this.geoKeyDirectory = geoKeyDirectory;\n this.nextIFDByteOffset = nextIFDByteOffset;\n }\n}\n\n/**\n * Error class for cases when an IFD index was requested, that does not exist\n * in the file.\n */\nclass GeoTIFFImageIndexError extends Error {\n constructor(index) {\n super(`No image at index ${index}`);\n this.index = index;\n }\n}\n\nclass GeoTIFFBase {\n /**\n * (experimental) Reads raster data from the best fitting image. This function uses\n * the image with the lowest resolution that is still a higher resolution than the\n * requested resolution.\n * When specified, the `bbox` option is translated to the `window` option and the\n * `resX` and `resY` to `width` and `height` respectively.\n * Then, the [readRasters]{@link GeoTIFFImage#readRasters} method of the selected\n * image is called and the result returned.\n * @see GeoTIFFImage.readRasters\n * @param {import('./geotiffimage').ReadRasterOptions} [options={}] optional parameters\n * @returns {Promise<(TypedArray|TypedArray[])>} the decoded arrays as a promise\n */\n async readRasters(options = {}) {\n const { window: imageWindow, width, height } = options;\n let { resX, resY, bbox } = options;\n\n const firstImage = await this.getImage();\n let usedImage = firstImage;\n const imageCount = await this.getImageCount();\n const imgBBox = firstImage.getBoundingBox();\n\n if (imageWindow && bbox) {\n throw new Error('Both \"bbox\" and \"window\" passed.');\n }\n\n // if width/height is passed, transform it to resolution\n if (width || height) {\n // if we have an image window (pixel coordinates), transform it to a BBox\n // using the origin/resolution of the first image.\n if (imageWindow) {\n const [oX, oY] = firstImage.getOrigin();\n const [rX, rY] = firstImage.getResolution();\n\n bbox = [\n oX + (imageWindow[0] * rX),\n oY + (imageWindow[1] * rY),\n oX + (imageWindow[2] * rX),\n oY + (imageWindow[3] * rY),\n ];\n }\n\n // if we have a bbox (or calculated one)\n\n const usedBBox = bbox || imgBBox;\n\n if (width) {\n if (resX) {\n throw new Error('Both width and resX passed');\n }\n resX = (usedBBox[2] - usedBBox[0]) / width;\n }\n if (height) {\n if (resY) {\n throw new Error('Both width and resY passed');\n }\n resY = (usedBBox[3] - usedBBox[1]) / height;\n }\n }\n\n // if resolution is set or calculated, try to get the image with the worst acceptable resolution\n if (resX || resY) {\n const allImages = [];\n for (let i = 0; i < imageCount; ++i) {\n const image = await this.getImage(i);\n const { SubfileType: subfileType, NewSubfileType: newSubfileType } = image.fileDirectory;\n if (i === 0 || subfileType === 2 || newSubfileType & 1) {\n allImages.push(image);\n }\n }\n\n allImages.sort((a, b) => a.getWidth() - b.getWidth());\n for (let i = 0; i < allImages.length; ++i) {\n const image = allImages[i];\n const imgResX = (imgBBox[2] - imgBBox[0]) / image.getWidth();\n const imgResY = (imgBBox[3] - imgBBox[1]) / image.getHeight();\n\n usedImage = image;\n if ((resX && resX > imgResX) || (resY && resY > imgResY)) {\n break;\n }\n }\n }\n\n let wnd = imageWindow;\n if (bbox) {\n const [oX, oY] = firstImage.getOrigin();\n const [imageResX, imageResY] = usedImage.getResolution(firstImage);\n\n wnd = [\n Math.round((bbox[0] - oX) / imageResX),\n Math.round((bbox[1] - oY) / imageResY),\n Math.round((bbox[2] - oX) / imageResX),\n Math.round((bbox[3] - oY) / imageResY),\n ];\n wnd = [\n Math.min(wnd[0], wnd[2]),\n Math.min(wnd[1], wnd[3]),\n Math.max(wnd[0], wnd[2]),\n Math.max(wnd[1], wnd[3]),\n ];\n }\n\n return usedImage.readRasters({ ...options, window: wnd });\n }\n}\n\n/**\n * @typedef {Object} GeoTIFFOptions\n * @property {boolean} [cache=false] whether or not decoded tiles shall be cached.\n */\n\n/**\n * The abstraction for a whole GeoTIFF file.\n * @augments GeoTIFFBase\n */\nclass GeoTIFF extends GeoTIFFBase {\n /**\n * @constructor\n * @param {*} source The datasource to read from.\n * @param {boolean} littleEndian Whether the image uses little endian.\n * @param {boolean} bigTiff Whether the image uses bigTIFF conventions.\n * @param {number} firstIFDOffset The numeric byte-offset from the start of the image\n * to the first IFD.\n * @param {GeoTIFFOptions} [options] further options.\n */\n constructor(source, littleEndian, bigTiff, firstIFDOffset, options = {}) {\n super();\n this.source = source;\n this.littleEndian = littleEndian;\n this.bigTiff = bigTiff;\n this.firstIFDOffset = firstIFDOffset;\n this.cache = options.cache || false;\n this.ifdRequests = [];\n this.ghostValues = null;\n }\n\n async getSlice(offset, size) {\n const fallbackSize = this.bigTiff ? 4048 : 1024;\n return new DataSlice(\n (await this.source.fetch([{\n offset,\n length: typeof size !== 'undefined' ? size : fallbackSize,\n }]))[0],\n offset,\n this.littleEndian,\n this.bigTiff,\n );\n }\n\n /**\n * Instructs to parse an image file directory at the given file offset.\n * As there is no way to ensure that a location is indeed the start of an IFD,\n * this function must be called with caution (e.g only using the IFD offsets from\n * the headers or other IFDs).\n * @param {number} offset the offset to parse the IFD at\n * @returns {Promise} the parsed IFD\n */\n async parseFileDirectoryAt(offset) {\n const entrySize = this.bigTiff ? 20 : 12;\n const offsetSize = this.bigTiff ? 8 : 2;\n\n let dataSlice = await this.getSlice(offset);\n const numDirEntries = this.bigTiff\n ? dataSlice.readUint64(offset)\n : dataSlice.readUint16(offset);\n\n // if the slice does not cover the whole IFD, request a bigger slice, where the\n // whole IFD fits: num of entries + n x tag length + offset to next IFD\n const byteSize = (numDirEntries * entrySize) + (this.bigTiff ? 16 : 6);\n if (!dataSlice.covers(offset, byteSize)) {\n dataSlice = await this.getSlice(offset, byteSize);\n }\n\n const fileDirectory = {};\n\n // loop over the IFD and create a file directory object\n let i = offset + (this.bigTiff ? 8 : 2);\n for (let entryCount = 0; entryCount < numDirEntries; i += entrySize, ++entryCount) {\n const fieldTag = dataSlice.readUint16(i);\n const fieldType = dataSlice.readUint16(i + 2);\n const typeCount = this.bigTiff\n ? dataSlice.readUint64(i + 4)\n : dataSlice.readUint32(i + 4);\n\n let fieldValues;\n let value;\n const fieldTypeLength = getFieldTypeLength(fieldType);\n const valueOffset = i + (this.bigTiff ? 12 : 8);\n\n // check whether the value is directly encoded in the tag or refers to a\n // different external byte range\n if (fieldTypeLength * typeCount <= (this.bigTiff ? 8 : 4)) {\n fieldValues = getValues(dataSlice, fieldType, typeCount, valueOffset);\n } else {\n // resolve the reference to the actual byte range\n const actualOffset = dataSlice.readOffset(valueOffset);\n const length = getFieldTypeLength(fieldType) * typeCount;\n\n // check, whether we actually cover the referenced byte range; if not,\n // request a new slice of bytes to read from it\n if (dataSlice.covers(actualOffset, length)) {\n fieldValues = getValues(dataSlice, fieldType, typeCount, actualOffset);\n } else {\n const fieldDataSlice = await this.getSlice(actualOffset, length);\n fieldValues = getValues(fieldDataSlice, fieldType, typeCount, actualOffset);\n }\n }\n\n // unpack single values from the array\n if (typeCount === 1 && arrayFields.indexOf(fieldTag) === -1\n && !(fieldType === fieldTypes.RATIONAL || fieldType === fieldTypes.SRATIONAL)) {\n value = fieldValues[0];\n } else {\n value = fieldValues;\n }\n\n // write the tags value to the file directly\n fileDirectory[fieldTagNames[fieldTag]] = value;\n }\n const geoKeyDirectory = parseGeoKeyDirectory(fileDirectory);\n const nextIFDByteOffset = dataSlice.readOffset(\n offset + offsetSize + (entrySize * numDirEntries),\n );\n\n return new ImageFileDirectory(\n fileDirectory,\n geoKeyDirectory,\n nextIFDByteOffset,\n );\n }\n\n async requestIFD(index) {\n // see if we already have that IFD index requested.\n if (this.ifdRequests[index]) {\n // attach to an already requested IFD\n return this.ifdRequests[index];\n } else if (index === 0) {\n // special case for index 0\n this.ifdRequests[index] = this.parseFileDirectoryAt(this.firstIFDOffset);\n return this.ifdRequests[index];\n } else if (!this.ifdRequests[index - 1]) {\n // if the previous IFD was not yet loaded, load that one first\n // this is the recursive call.\n try {\n this.ifdRequests[index - 1] = this.requestIFD(index - 1);\n } catch (e) {\n // if the previous one already was an index error, rethrow\n // with the current index\n if (e instanceof GeoTIFFImageIndexError) {\n throw new GeoTIFFImageIndexError(index);\n }\n // rethrow anything else\n throw e;\n }\n }\n // if the previous IFD was loaded, we can finally fetch the one we are interested in.\n // we need to wrap this in an IIFE, otherwise this.ifdRequests[index] would be delayed\n this.ifdRequests[index] = (async () => {\n const previousIfd = await this.ifdRequests[index - 1];\n if (previousIfd.nextIFDByteOffset === 0) {\n throw new GeoTIFFImageIndexError(index);\n }\n return this.parseFileDirectoryAt(previousIfd.nextIFDByteOffset);\n })();\n return this.ifdRequests[index];\n }\n\n /**\n * Get the n-th internal subfile of an image. By default, the first is returned.\n *\n * @param {number} [index=0] the index of the image to return.\n * @returns {Promise} the image at the given index\n */\n async getImage(index = 0) {\n const ifd = await this.requestIFD(index);\n return new GeoTIFFImage(\n ifd.fileDirectory, ifd.geoKeyDirectory,\n this.dataView, this.littleEndian, this.cache, this.source,\n );\n }\n\n /**\n * Returns the count of the internal subfiles.\n *\n * @returns {Promise} the number of internal subfile images\n */\n async getImageCount() {\n let index = 0;\n // loop until we run out of IFDs\n let hasNext = true;\n while (hasNext) {\n try {\n await this.requestIFD(index);\n ++index;\n } catch (e) {\n if (e instanceof GeoTIFFImageIndexError) {\n hasNext = false;\n } else {\n throw e;\n }\n }\n }\n return index;\n }\n\n /**\n * Get the values of the COG ghost area as a parsed map.\n * See https://gdal.org/drivers/raster/cog.html#header-ghost-area for reference\n * @returns {Promise} the parsed ghost area or null, if no such area was found\n */\n async getGhostValues() {\n const offset = this.bigTiff ? 16 : 8;\n if (this.ghostValues) {\n return this.ghostValues;\n }\n const detectionString = 'GDAL_STRUCTURAL_METADATA_SIZE=';\n const heuristicAreaSize = detectionString.length + 100;\n let slice = await this.getSlice(offset, heuristicAreaSize);\n if (detectionString === getValues(slice, fieldTypes.ASCII, detectionString.length, offset)) {\n const valuesString = getValues(slice, fieldTypes.ASCII, heuristicAreaSize, offset);\n const firstLine = valuesString.split('\\n')[0];\n const metadataSize = Number(firstLine.split('=')[1].split(' ')[0]) + firstLine.length;\n if (metadataSize > heuristicAreaSize) {\n slice = await this.getSlice(offset, metadataSize);\n }\n const fullString = getValues(slice, fieldTypes.ASCII, metadataSize, offset);\n this.ghostValues = {};\n fullString\n .split('\\n')\n .filter((line) => line.length > 0)\n .map((line) => line.split('='))\n .forEach(([key, value]) => {\n this.ghostValues[key] = value;\n });\n }\n return this.ghostValues;\n }\n\n /**\n * Parse a (Geo)TIFF file from the given source.\n *\n * @param {*} source The source of data to parse from.\n * @param {GeoTIFFOptions} [options] Additional options.\n * @param {AbortSignal} [signal] An AbortSignal that may be signalled if the request is\n * to be aborted\n */\n static async fromSource(source, options, signal) {\n const headerData = (await source.fetch([{ offset: 0, length: 1024 }], signal))[0];\n const dataView = new DataView64(headerData);\n\n const BOM = dataView.getUint16(0, 0);\n let littleEndian;\n if (BOM === 0x4949) {\n littleEndian = true;\n } else if (BOM === 0x4D4D) {\n littleEndian = false;\n } else {\n throw new TypeError('Invalid byte order value.');\n }\n\n const magicNumber = dataView.getUint16(2, littleEndian);\n let bigTiff;\n if (magicNumber === 42) {\n bigTiff = false;\n } else if (magicNumber === 43) {\n bigTiff = true;\n const offsetByteSize = dataView.getUint16(4, littleEndian);\n if (offsetByteSize !== 8) {\n throw new Error('Unsupported offset byte-size.');\n }\n } else {\n throw new TypeError('Invalid magic number.');\n }\n\n const firstIFDOffset = bigTiff\n ? dataView.getUint64(8, littleEndian)\n : dataView.getUint32(4, littleEndian);\n return new GeoTIFF(source, littleEndian, bigTiff, firstIFDOffset, options);\n }\n\n /**\n * Closes the underlying file buffer\n * N.B. After the GeoTIFF has been completely processed it needs\n * to be closed but only if it has been constructed from a file.\n */\n close() {\n if (typeof this.source.close === 'function') {\n return this.source.close();\n }\n return false;\n }\n}\n\nexport { GeoTIFF };\nexport default GeoTIFF;\n\n/**\n * Wrapper for GeoTIFF files that have external overviews.\n * @augments GeoTIFFBase\n */\nclass MultiGeoTIFF extends GeoTIFFBase {\n /**\n * Construct a new MultiGeoTIFF from a main and several overview files.\n * @param {GeoTIFF} mainFile The main GeoTIFF file.\n * @param {GeoTIFF[]} overviewFiles An array of overview files.\n */\n constructor(mainFile, overviewFiles) {\n super();\n this.mainFile = mainFile;\n this.overviewFiles = overviewFiles;\n this.imageFiles = [mainFile].concat(overviewFiles);\n\n this.fileDirectoriesPerFile = null;\n this.fileDirectoriesPerFileParsing = null;\n this.imageCount = null;\n }\n\n async parseFileDirectoriesPerFile() {\n const requests = [this.mainFile.parseFileDirectoryAt(this.mainFile.firstIFDOffset)]\n .concat(this.overviewFiles.map((file) => file.parseFileDirectoryAt(file.firstIFDOffset)));\n\n this.fileDirectoriesPerFile = await Promise.all(requests);\n return this.fileDirectoriesPerFile;\n }\n\n /**\n * Get the n-th internal subfile of an image. By default, the first is returned.\n *\n * @param {number} [index=0] the index of the image to return.\n * @returns {Promise} the image at the given index\n */\n async getImage(index = 0) {\n await this.getImageCount();\n await this.parseFileDirectoriesPerFile();\n let visited = 0;\n let relativeIndex = 0;\n for (let i = 0; i < this.imageFiles.length; i++) {\n const imageFile = this.imageFiles[i];\n for (let ii = 0; ii < this.imageCounts[i]; ii++) {\n if (index === visited) {\n const ifd = await imageFile.requestIFD(relativeIndex);\n return new GeoTIFFImage(\n ifd.fileDirectory, ifd.geoKeyDirectory,\n imageFile.dataView, imageFile.littleEndian, imageFile.cache, imageFile.source,\n );\n }\n visited++;\n relativeIndex++;\n }\n relativeIndex = 0;\n }\n\n throw new RangeError('Invalid image index');\n }\n\n /**\n * Returns the count of the internal subfiles.\n *\n * @returns {Promise} the number of internal subfile images\n */\n async getImageCount() {\n if (this.imageCount !== null) {\n return this.imageCount;\n }\n const requests = [this.mainFile.getImageCount()]\n .concat(this.overviewFiles.map((file) => file.getImageCount()));\n this.imageCounts = await Promise.all(requests);\n this.imageCount = this.imageCounts.reduce((count, ifds) => count + ifds, 0);\n return this.imageCount;\n }\n}\n\nexport { MultiGeoTIFF };\n\n/**\n * Creates a new GeoTIFF from a remote URL.\n * @param {string} url The URL to access the image from\n * @param {object} [options] Additional options to pass to the source.\n * See {@link makeRemoteSource} for details.\n * @param {AbortSignal} [signal] An AbortSignal that may be signalled if the request is\n * to be aborted\n * @returns {Promise} The resulting GeoTIFF file.\n */\nexport async function fromUrl(url, options = {}, signal) {\n return GeoTIFF.fromSource(makeRemoteSource(url, options), signal);\n}\n\n/**\n * Construct a new GeoTIFF from an\n * [ArrayBuffer]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer}.\n * @param {ArrayBuffer} arrayBuffer The data to read the file from.\n * @param {AbortSignal} [signal] An AbortSignal that may be signalled if the request is\n * to be aborted\n * @returns {Promise} The resulting GeoTIFF file.\n */\nexport async function fromArrayBuffer(arrayBuffer, signal) {\n return GeoTIFF.fromSource(makeBufferSource(arrayBuffer), signal);\n}\n\n/**\n * Construct a GeoTIFF from a local file path. This uses the node\n * [filesystem API]{@link https://nodejs.org/api/fs.html} and is\n * not available on browsers.\n *\n * N.B. After the GeoTIFF has been completely processed it needs\n * to be closed but only if it has been constructed from a file.\n * @param {string} path The file path to read from.\n * @param {AbortSignal} [signal] An AbortSignal that may be signalled if the request is\n * to be aborted\n * @returns {Promise} The resulting GeoTIFF file.\n */\nexport async function fromFile(path, signal) {\n return GeoTIFF.fromSource(makeFileSource(path), signal);\n}\n\n/**\n * Construct a GeoTIFF from an HTML\n * [Blob]{@link https://developer.mozilla.org/en-US/docs/Web/API/Blob} or\n * [File]{@link https://developer.mozilla.org/en-US/docs/Web/API/File}\n * object.\n * @param {Blob|File} blob The Blob or File object to read from.\n * @param {AbortSignal} [signal] An AbortSignal that may be signalled if the request is\n * to be aborted\n * @returns {Promise} The resulting GeoTIFF file.\n */\nexport async function fromBlob(blob, signal) {\n return GeoTIFF.fromSource(makeFileReaderSource(blob), signal);\n}\n\n/**\n * Construct a MultiGeoTIFF from the given URLs.\n * @param {string} mainUrl The URL for the main file.\n * @param {string[]} overviewUrls An array of URLs for the overview images.\n * @param {Object} [options] Additional options to pass to the source.\n * See [makeRemoteSource]{@link module:source.makeRemoteSource}\n * for details.\n * @param {AbortSignal} [signal] An AbortSignal that may be signalled if the request is\n * to be aborted\n * @returns {Promise} The resulting MultiGeoTIFF file.\n */\nexport async function fromUrls(mainUrl, overviewUrls = [], options = {}, signal) {\n const mainFile = await GeoTIFF.fromSource(makeRemoteSource(mainUrl, options), signal);\n const overviewFiles = await Promise.all(\n overviewUrls.map((url) => GeoTIFF.fromSource(makeRemoteSource(url, options))),\n );\n\n return new MultiGeoTIFF(mainFile, overviewFiles);\n}\n\n/**\n * Main creating function for GeoTIFF files.\n * @param {(Array)} array of pixel values\n * @returns {metadata} metadata\n */\nexport function writeArrayBuffer(values, metadata) {\n return writeGeotiff(values, metadata);\n}\n\nexport { Pool };\nexport { GeoTIFFImage };\n","import { getDecoder } from './compression/index.js';\n\nconst defaultPoolSize = typeof navigator !== 'undefined' ? (navigator.hardwareConcurrency || 2) : 2;\n\n/**\n * @module pool\n */\n\n/**\n * Pool for workers to decode chunks of the images.\n */\nclass Pool {\n /**\n * @constructor\n * @param {Number} [size] The size of the pool. Defaults to the number of CPUs\n * available. When this parameter is `null` or 0, then the\n * decoding will be done in the main thread.\n * @param {function(): Worker} [createWorker] A function that creates the decoder worker.\n * Defaults to a worker with all decoders that ship with geotiff.js. The `createWorker()`\n * function is expected to return a `Worker` compatible with Web Workers. For code that\n * runs in Node, [web-worker](https://www.npmjs.com/package/web-worker) is a good choice.\n *\n * A worker that uses a custom lzw decoder would look like this `my-custom-worker.js` file:\n * ```js\n * import { addDecoder, getDecoder } from 'geotiff';\n * addDecoder(5, () => import ('./my-custom-lzw').then((m) => m.default));\n * self.addEventListener('message', async (e) => {\n * const { id, fileDirectory, buffer } = e.data;\n * const decoder = await getDecoder(fileDirectory);\n * const decoded = await decoder.decode(fileDirectory, buffer);\n * self.postMessage({ decoded, id }, [decoded]);\n * });\n * ```\n * The way the above code is built into a worker by the `createWorker()` function\n * depends on the used bundler. For most bundlers, something like this will work:\n * ```js\n * function createWorker() {\n * return new Worker(new URL('./my-custom-worker.js', import.meta.url));\n * }\n * ```\n */\n constructor(size = defaultPoolSize, createWorker) {\n this.workers = null;\n this._awaitingDecoder = null;\n this.size = size;\n this.messageId = 0;\n if (size) {\n this._awaitingDecoder = createWorker ? Promise.resolve(createWorker) : new Promise((resolve) => {\n import('./worker/decoder.js').then((module) => {\n resolve(module.create);\n });\n });\n this._awaitingDecoder.then((create) => {\n this._awaitingDecoder = null;\n this.workers = [];\n for (let i = 0; i < size; i++) {\n this.workers.push({ worker: create(), idle: true });\n }\n });\n }\n }\n\n /**\n * Decode the given block of bytes with the set compression method.\n * @param {ArrayBuffer} buffer the array buffer of bytes to decode.\n * @returns {Promise} the decoded result as a `Promise`\n */\n async decode(fileDirectory, buffer) {\n if (this._awaitingDecoder) {\n await this._awaitingDecoder;\n }\n return this.size === 0\n ? getDecoder(fileDirectory).then((decoder) => decoder.decode(fileDirectory, buffer))\n : new Promise((resolve) => {\n const worker = this.workers.find((candidate) => candidate.idle)\n || this.workers[Math.floor(Math.random() * this.size)];\n worker.idle = false;\n const id = this.messageId++;\n const onMessage = (e) => {\n if (e.data.id === id) {\n worker.idle = true;\n resolve(e.data.decoded);\n worker.worker.removeEventListener('message', onMessage);\n }\n };\n worker.worker.addEventListener('message', onMessage);\n worker.worker.postMessage({ fileDirectory, buffer, id }, [buffer]);\n });\n }\n\n destroy() {\n if (this.workers) {\n this.workers.forEach((worker) => {\n worker.worker.terminate();\n });\n this.workers = null;\n }\n }\n}\n\nexport default Pool;\n",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"// (c) Dean McNamee , 2012.\n//\n// https://github.com/deanm/css-color-parser-js\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to\n// deal in the Software without restriction, including without limitation the\n// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n// sell copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n// IN THE SOFTWARE.\n\n// http://www.w3.org/TR/css3-color/\nvar kCSSColorTable = {\n \"transparent\": [0,0,0,0], \"aliceblue\": [240,248,255,1],\n \"antiquewhite\": [250,235,215,1], \"aqua\": [0,255,255,1],\n \"aquamarine\": [127,255,212,1], \"azure\": [240,255,255,1],\n \"beige\": [245,245,220,1], \"bisque\": [255,228,196,1],\n \"black\": [0,0,0,1], \"blanchedalmond\": [255,235,205,1],\n \"blue\": [0,0,255,1], \"blueviolet\": [138,43,226,1],\n \"brown\": [165,42,42,1], \"burlywood\": [222,184,135,1],\n \"cadetblue\": [95,158,160,1], \"chartreuse\": [127,255,0,1],\n \"chocolate\": [210,105,30,1], \"coral\": [255,127,80,1],\n \"cornflowerblue\": [100,149,237,1], \"cornsilk\": [255,248,220,1],\n \"crimson\": [220,20,60,1], \"cyan\": [0,255,255,1],\n \"darkblue\": [0,0,139,1], \"darkcyan\": [0,139,139,1],\n \"darkgoldenrod\": [184,134,11,1], \"darkgray\": [169,169,169,1],\n \"darkgreen\": [0,100,0,1], \"darkgrey\": [169,169,169,1],\n \"darkkhaki\": [189,183,107,1], \"darkmagenta\": [139,0,139,1],\n \"darkolivegreen\": [85,107,47,1], \"darkorange\": [255,140,0,1],\n \"darkorchid\": [153,50,204,1], \"darkred\": [139,0,0,1],\n \"darksalmon\": [233,150,122,1], \"darkseagreen\": [143,188,143,1],\n \"darkslateblue\": [72,61,139,1], \"darkslategray\": [47,79,79,1],\n \"darkslategrey\": [47,79,79,1], \"darkturquoise\": [0,206,209,1],\n \"darkviolet\": [148,0,211,1], \"deeppink\": [255,20,147,1],\n \"deepskyblue\": [0,191,255,1], \"dimgray\": [105,105,105,1],\n \"dimgrey\": [105,105,105,1], \"dodgerblue\": [30,144,255,1],\n \"firebrick\": [178,34,34,1], \"floralwhite\": [255,250,240,1],\n \"forestgreen\": [34,139,34,1], \"fuchsia\": [255,0,255,1],\n \"gainsboro\": [220,220,220,1], \"ghostwhite\": [248,248,255,1],\n \"gold\": [255,215,0,1], \"goldenrod\": [218,165,32,1],\n \"gray\": [128,128,128,1], \"green\": [0,128,0,1],\n \"greenyellow\": [173,255,47,1], \"grey\": [128,128,128,1],\n \"honeydew\": [240,255,240,1], \"hotpink\": [255,105,180,1],\n \"indianred\": [205,92,92,1], \"indigo\": [75,0,130,1],\n \"ivory\": [255,255,240,1], \"khaki\": [240,230,140,1],\n \"lavender\": [230,230,250,1], \"lavenderblush\": [255,240,245,1],\n \"lawngreen\": [124,252,0,1], \"lemonchiffon\": [255,250,205,1],\n \"lightblue\": [173,216,230,1], \"lightcoral\": [240,128,128,1],\n \"lightcyan\": [224,255,255,1], \"lightgoldenrodyellow\": [250,250,210,1],\n \"lightgray\": [211,211,211,1], \"lightgreen\": [144,238,144,1],\n \"lightgrey\": [211,211,211,1], \"lightpink\": [255,182,193,1],\n \"lightsalmon\": [255,160,122,1], \"lightseagreen\": [32,178,170,1],\n \"lightskyblue\": [135,206,250,1], \"lightslategray\": [119,136,153,1],\n \"lightslategrey\": [119,136,153,1], \"lightsteelblue\": [176,196,222,1],\n \"lightyellow\": [255,255,224,1], \"lime\": [0,255,0,1],\n \"limegreen\": [50,205,50,1], \"linen\": [250,240,230,1],\n \"magenta\": [255,0,255,1], \"maroon\": [128,0,0,1],\n \"mediumaquamarine\": [102,205,170,1], \"mediumblue\": [0,0,205,1],\n \"mediumorchid\": [186,85,211,1], \"mediumpurple\": [147,112,219,1],\n \"mediumseagreen\": [60,179,113,1], \"mediumslateblue\": [123,104,238,1],\n \"mediumspringgreen\": [0,250,154,1], \"mediumturquoise\": [72,209,204,1],\n \"mediumvioletred\": [199,21,133,1], \"midnightblue\": [25,25,112,1],\n \"mintcream\": [245,255,250,1], \"mistyrose\": [255,228,225,1],\n \"moccasin\": [255,228,181,1], \"navajowhite\": [255,222,173,1],\n \"navy\": [0,0,128,1], \"oldlace\": [253,245,230,1],\n \"olive\": [128,128,0,1], \"olivedrab\": [107,142,35,1],\n \"orange\": [255,165,0,1], \"orangered\": [255,69,0,1],\n \"orchid\": [218,112,214,1], \"palegoldenrod\": [238,232,170,1],\n \"palegreen\": [152,251,152,1], \"paleturquoise\": [175,238,238,1],\n \"palevioletred\": [219,112,147,1], \"papayawhip\": [255,239,213,1],\n \"peachpuff\": [255,218,185,1], \"peru\": [205,133,63,1],\n \"pink\": [255,192,203,1], \"plum\": [221,160,221,1],\n \"powderblue\": [176,224,230,1], \"purple\": [128,0,128,1],\n \"rebeccapurple\": [102,51,153,1],\n \"red\": [255,0,0,1], \"rosybrown\": [188,143,143,1],\n \"royalblue\": [65,105,225,1], \"saddlebrown\": [139,69,19,1],\n \"salmon\": [250,128,114,1], \"sandybrown\": [244,164,96,1],\n \"seagreen\": [46,139,87,1], \"seashell\": [255,245,238,1],\n \"sienna\": [160,82,45,1], \"silver\": [192,192,192,1],\n \"skyblue\": [135,206,235,1], \"slateblue\": [106,90,205,1],\n \"slategray\": [112,128,144,1], \"slategrey\": [112,128,144,1],\n \"snow\": [255,250,250,1], \"springgreen\": [0,255,127,1],\n \"steelblue\": [70,130,180,1], \"tan\": [210,180,140,1],\n \"teal\": [0,128,128,1], \"thistle\": [216,191,216,1],\n \"tomato\": [255,99,71,1], \"turquoise\": [64,224,208,1],\n \"violet\": [238,130,238,1], \"wheat\": [245,222,179,1],\n \"white\": [255,255,255,1], \"whitesmoke\": [245,245,245,1],\n \"yellow\": [255,255,0,1], \"yellowgreen\": [154,205,50,1]}\n\nfunction clamp_css_byte(i) { // Clamp to integer 0 .. 255.\n i = Math.round(i); // Seems to be what Chrome does (vs truncation).\n return i < 0 ? 0 : i > 255 ? 255 : i;\n}\n\nfunction clamp_css_float(f) { // Clamp to float 0.0 .. 1.0.\n return f < 0 ? 0 : f > 1 ? 1 : f;\n}\n\nfunction parse_css_int(str) { // int or percentage.\n if (str[str.length - 1] === '%')\n return clamp_css_byte(parseFloat(str) / 100 * 255);\n return clamp_css_byte(parseInt(str));\n}\n\nfunction parse_css_float(str) { // float or percentage.\n if (str[str.length - 1] === '%')\n return clamp_css_float(parseFloat(str) / 100);\n return clamp_css_float(parseFloat(str));\n}\n\nfunction css_hue_to_rgb(m1, m2, h) {\n if (h < 0) h += 1;\n else if (h > 1) h -= 1;\n\n if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;\n if (h * 2 < 1) return m2;\n if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;\n return m1;\n}\n\nfunction parseCSSColor(css_str) {\n // Remove all whitespace, not compliant, but should just be more accepting.\n var str = css_str.replace(/ /g, '').toLowerCase();\n\n // Color keywords (and transparent) lookup.\n if (str in kCSSColorTable) return kCSSColorTable[str].slice(); // dup.\n\n // #abc and #abc123 syntax.\n if (str[0] === '#') {\n if (str.length === 4) {\n var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.\n if (!(iv >= 0 && iv <= 0xfff)) return null; // Covers NaN.\n return [((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8),\n (iv & 0xf0) | ((iv & 0xf0) >> 4),\n (iv & 0xf) | ((iv & 0xf) << 4),\n 1];\n } else if (str.length === 7) {\n var iv = parseInt(str.substr(1), 16); // TODO(deanm): Stricter parsing.\n if (!(iv >= 0 && iv <= 0xffffff)) return null; // Covers NaN.\n return [(iv & 0xff0000) >> 16,\n (iv & 0xff00) >> 8,\n iv & 0xff,\n 1];\n }\n\n return null;\n }\n\n var op = str.indexOf('('), ep = str.indexOf(')');\n if (op !== -1 && ep + 1 === str.length) {\n var fname = str.substr(0, op);\n var params = str.substr(op+1, ep-(op+1)).split(',');\n var alpha = 1; // To allow case fallthrough.\n switch (fname) {\n case 'rgba':\n if (params.length !== 4) return null;\n alpha = parse_css_float(params.pop());\n // Fall through.\n case 'rgb':\n if (params.length !== 3) return null;\n return [parse_css_int(params[0]),\n parse_css_int(params[1]),\n parse_css_int(params[2]),\n alpha];\n case 'hsla':\n if (params.length !== 4) return null;\n alpha = parse_css_float(params.pop());\n // Fall through.\n case 'hsl':\n if (params.length !== 3) return null;\n var h = (((parseFloat(params[0]) % 360) + 360) % 360) / 360; // 0 .. 1\n // NOTE(deanm): According to the CSS spec s/l should only be\n // percentages, but we don't bother and let float or percentage.\n var s = parse_css_float(params[1]);\n var l = parse_css_float(params[2]);\n var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;\n var m1 = l * 2 - m2;\n return [clamp_css_byte(css_hue_to_rgb(m1, m2, h+1/3) * 255),\n clamp_css_byte(css_hue_to_rgb(m1, m2, h) * 255),\n clamp_css_byte(css_hue_to_rgb(m1, m2, h-1/3) * 255),\n alpha];\n default:\n return null;\n }\n }\n\n return null;\n}\n\ntry { exports.parseCSSColor = parseCSSColor } catch(e) { }\n","// @flow\n\nimport {parseCSSColor} from 'csscolorparser';\n\n/**\n * An RGBA color value. Create instances from color strings using the static\n * method `Color.parse`. The constructor accepts RGB channel values in the range\n * `[0, 1]`, premultiplied by A.\n *\n * @param {number} r The red channel.\n * @param {number} g The green channel.\n * @param {number} b The blue channel.\n * @param {number} a The alpha channel.\n * @private\n */\nclass Color {\n r: number;\n g: number;\n b: number;\n a: number;\n\n constructor(r: number, g: number, b: number, a: number = 1) {\n this.r = r;\n this.g = g;\n this.b = b;\n this.a = a;\n }\n\n static black: Color;\n static white: Color;\n static transparent: Color;\n static red: Color;\n static blue: Color;\n\n /**\n * Parses valid CSS color strings and returns a `Color` instance.\n * @returns A `Color` instance, or `undefined` if the input is not a valid color string.\n */\n static parse(input?: string | Color | null): Color | void {\n if (!input) {\n return undefined;\n }\n\n if (input instanceof Color) {\n return input;\n }\n\n if (typeof input !== 'string') {\n return undefined;\n }\n\n const rgba = parseCSSColor(input);\n if (!rgba) {\n return undefined;\n }\n\n return new Color(\n rgba[0] / 255 * rgba[3],\n rgba[1] / 255 * rgba[3],\n rgba[2] / 255 * rgba[3],\n rgba[3]\n );\n }\n\n /**\n * Returns an RGBA string representing the color value.\n *\n * @returns An RGBA string.\n * @example\n * var purple = new Color.parse('purple');\n * purple.toString; // = \"rgba(128,0,128,1)\"\n * var translucentGreen = new Color.parse('rgba(26, 207, 26, .73)');\n * translucentGreen.toString(); // = \"rgba(26,207,26,0.73)\"\n */\n toString(): string {\n const [r, g, b, a] = this.toArray();\n return `rgba(${Math.round(r)},${Math.round(g)},${Math.round(b)},${a})`;\n }\n\n toArray(): [number, number, number, number] {\n const {r, g, b, a} = this;\n return a === 0 ? [0, 0, 0, 0] : [\n r * 255 / a,\n g * 255 / a,\n b * 255 / a,\n a\n ];\n }\n}\n\nColor.black = new Color(0, 0, 0, 1);\nColor.white = new Color(1, 1, 1, 1);\nColor.transparent = new Color(0, 0, 0, 0);\nColor.red = new Color(1, 0, 0, 1);\nColor.blue = new Color(0, 0, 1, 1);\n\nexport default Color;\n","// @flow\n\nimport assert from 'assert';\n\nimport type {StylePropertySpecification} from '../style-spec.js';\nimport type {ExpressionSpecification} from '../types.js';\n\nfunction convertLiteral(value) {\n return typeof value === 'object' ? ['literal', value] : value;\n}\n\nexport default function convertFunction(parameters: any, propertySpec: StylePropertySpecification): ExpressionSpecification {\n let stops = parameters.stops;\n if (!stops) {\n // identity function\n return convertIdentityFunction(parameters, propertySpec);\n }\n\n const zoomAndFeatureDependent = stops && typeof stops[0][0] === 'object';\n const featureDependent = zoomAndFeatureDependent || parameters.property !== undefined;\n const zoomDependent = zoomAndFeatureDependent || !featureDependent;\n\n stops = stops.map((stop) => {\n if (!featureDependent && propertySpec.tokens && typeof stop[1] === 'string') {\n return [stop[0], convertTokenString(stop[1])];\n }\n return [stop[0], convertLiteral(stop[1])];\n });\n\n if (zoomAndFeatureDependent) {\n return convertZoomAndPropertyFunction(parameters, propertySpec, stops);\n } else if (zoomDependent) {\n return convertZoomFunction(parameters, propertySpec, stops);\n } else {\n return convertPropertyFunction(parameters, propertySpec, stops);\n }\n}\n\nfunction convertIdentityFunction(parameters, propertySpec): Array {\n const get = ['get', parameters.property];\n\n if (parameters.default === undefined) {\n // By default, expressions for string-valued properties get coerced. To preserve\n // legacy function semantics, insert an explicit assertion instead.\n return propertySpec.type === 'string' ? ['string', get] : get;\n } else if (propertySpec.type === 'enum') {\n return [\n 'match',\n get,\n Object.keys(propertySpec.values),\n get,\n parameters.default\n ];\n } else {\n const expression = [propertySpec.type === 'color' ? 'to-color' : propertySpec.type, get, convertLiteral(parameters.default)];\n if (propertySpec.type === 'array') {\n expression.splice(1, 0, propertySpec.value, propertySpec.length || null);\n }\n return expression;\n }\n}\n\nfunction getInterpolateOperator(parameters) {\n switch (parameters.colorSpace) {\n case 'hcl': return 'interpolate-hcl';\n case 'lab': return 'interpolate-lab';\n default: return 'interpolate';\n }\n}\n\nfunction convertZoomAndPropertyFunction(parameters, propertySpec, stops) {\n const featureFunctionParameters = {};\n const featureFunctionStops = {};\n const zoomStops = [];\n for (let s = 0; s < stops.length; s++) {\n const stop = stops[s];\n const zoom = stop[0].zoom;\n if (featureFunctionParameters[zoom] === undefined) {\n featureFunctionParameters[zoom] = {\n zoom,\n type: parameters.type,\n property: parameters.property,\n default: parameters.default,\n };\n featureFunctionStops[zoom] = [];\n zoomStops.push(zoom);\n }\n featureFunctionStops[zoom].push([stop[0].value, stop[1]]);\n }\n\n // the interpolation type for the zoom dimension of a zoom-and-property\n // function is determined directly from the style property specification\n // for which it's being used: linear for interpolatable properties, step\n // otherwise.\n const functionType = getFunctionType({}, propertySpec);\n if (functionType === 'exponential') {\n const expression = [getInterpolateOperator(parameters), ['linear'], ['zoom']];\n\n for (const z of zoomStops) {\n const output = convertPropertyFunction(featureFunctionParameters[z], propertySpec, featureFunctionStops[z]);\n appendStopPair(expression, z, output, false);\n }\n\n return expression;\n } else {\n const expression = ['step', ['zoom']];\n\n for (const z of zoomStops) {\n const output = convertPropertyFunction(featureFunctionParameters[z], propertySpec, featureFunctionStops[z]);\n appendStopPair(expression, z, output, true);\n }\n\n fixupDegenerateStepCurve(expression);\n\n return expression;\n }\n}\n\nfunction coalesce(a, b) {\n if (a !== undefined) return a;\n if (b !== undefined) return b;\n}\n\nfunction getFallback(parameters, propertySpec) {\n const defaultValue = convertLiteral(coalesce(parameters.default, propertySpec.default));\n\n /*\n * Some fields with type: resolvedImage have an undefined default.\n * Because undefined is an invalid value for resolvedImage, set fallback to\n * an empty string instead of undefined to ensure output\n * passes validation.\n */\n if (defaultValue === undefined && propertySpec.type === 'resolvedImage') {\n return '';\n }\n return defaultValue;\n}\n\nfunction convertPropertyFunction(parameters, propertySpec, stops) {\n const type = getFunctionType(parameters, propertySpec);\n const get = ['get', parameters.property];\n if (type === 'categorical' && typeof stops[0][0] === 'boolean') {\n assert(parameters.stops.length > 0 && parameters.stops.length <= 2);\n const expression = ['case'];\n for (const stop of stops) {\n expression.push(['==', get, stop[0]], stop[1]);\n }\n\n expression.push(getFallback(parameters, propertySpec));\n return expression;\n } else if (type === 'categorical') {\n const expression = ['match', get];\n for (const stop of stops) {\n appendStopPair(expression, stop[0], stop[1], false);\n }\n expression.push(getFallback(parameters, propertySpec));\n return expression;\n } else if (type === 'interval') {\n const expression = ['step', ['number', get]];\n for (const stop of stops) {\n appendStopPair(expression, stop[0], stop[1], true);\n }\n fixupDegenerateStepCurve(expression);\n return parameters.default === undefined ? expression : [\n 'case',\n ['==', ['typeof', get], 'number'],\n expression,\n convertLiteral(parameters.default)\n ];\n } else if (type === 'exponential') {\n const base = parameters.base !== undefined ? parameters.base : 1;\n const expression = [\n getInterpolateOperator(parameters),\n base === 1 ? [\"linear\"] : [\"exponential\", base],\n [\"number\", get]\n ];\n\n for (const stop of stops) {\n appendStopPair(expression, stop[0], stop[1], false);\n }\n return parameters.default === undefined ? expression : [\n 'case',\n ['==', ['typeof', get], 'number'],\n expression,\n convertLiteral(parameters.default)\n ];\n } else {\n throw new Error(`Unknown property function type ${type}`);\n }\n}\n\nfunction convertZoomFunction(parameters, propertySpec, stops, input = ['zoom']) {\n const type = getFunctionType(parameters, propertySpec);\n let expression;\n let isStep = false;\n if (type === 'interval') {\n expression = ['step', input];\n isStep = true;\n } else if (type === 'exponential') {\n const base = parameters.base !== undefined ? parameters.base : 1;\n expression = [getInterpolateOperator(parameters), base === 1 ? [\"linear\"] : [\"exponential\", base], input];\n\n } else {\n throw new Error(`Unknown zoom function type \"${type}\"`);\n }\n\n for (const stop of stops) {\n appendStopPair(expression, stop[0], stop[1], isStep);\n }\n\n fixupDegenerateStepCurve(expression);\n\n return expression;\n}\n\nfunction fixupDegenerateStepCurve(expression) {\n // degenerate step curve (i.e. a constant function): add a noop stop\n if (expression[0] === 'step' && expression.length === 3) {\n expression.push(0);\n expression.push(expression[3]);\n }\n}\n\nfunction appendStopPair(curve, input, output, isStep) {\n // Skip duplicate stop values. They were not validated for functions, but they are for expressions.\n // https://github.com/mapbox/mapbox-gl-js/issues/4107\n if (curve.length > 3 && input === curve[curve.length - 2]) {\n return;\n }\n // step curves don't get the first input value, as it is redundant.\n if (!(isStep && curve.length === 2)) {\n curve.push(input);\n }\n curve.push(output);\n}\n\nfunction getFunctionType(parameters, propertySpec) {\n if (parameters.type) {\n return parameters.type;\n } else {\n assert(propertySpec.expression);\n return (propertySpec.expression: any).interpolated ? 'exponential' : 'interval';\n }\n}\n\n// \"String with {name} token\" => [\"concat\", \"String with \", [\"get\", \"name\"], \" token\"]\nexport function convertTokenString(s: string): string | ExpressionSpecification {\n const result = ['concat'];\n const re = /{([^{}]+)}/g;\n let pos = 0;\n for (let match = re.exec(s); match !== null; match = re.exec(s)) {\n const literal = s.slice(pos, re.lastIndex - match[0].length);\n pos = re.lastIndex;\n if (literal.length > 0) result.push(literal);\n result.push(['get', match[1]]);\n }\n\n if (result.length === 1) {\n return s;\n }\n\n if (pos < s.length) {\n result.push(s.slice(pos));\n } else if (result.length === 2) {\n return ['to-string', result[1]];\n }\n\n return result;\n}\n\n","// @flow\n\nclass ParsingError extends Error {\n key: string;\n message: string;\n constructor(key: string, message: string) {\n super(message);\n this.message = message;\n this.key = key;\n }\n}\n\nexport default ParsingError;\n","// @flow\n\nimport type {Expression} from './expression.js';\n\n/**\n * Tracks `let` bindings during expression parsing.\n * @private\n */\nclass Scope {\n parent: ?Scope;\n bindings: {[_: string]: Expression};\n constructor(parent?: Scope, bindings: Array<[string, Expression]> = []) {\n this.parent = parent;\n this.bindings = {};\n for (const [name, expression] of bindings) {\n this.bindings[name] = expression;\n }\n }\n\n concat(bindings: Array<[string, Expression]>): Scope {\n return new Scope(this, bindings);\n }\n\n get(name: string): Expression {\n if (this.bindings[name]) { return this.bindings[name]; }\n if (this.parent) { return this.parent.get(name); }\n throw new Error(`${name} not found in scope.`);\n }\n\n has(name: string): boolean {\n if (this.bindings[name]) return true;\n return this.parent ? this.parent.has(name) : false;\n }\n}\n\nexport default Scope;\n","// @flow\n\nexport type NullTypeT = { kind: 'null' };\nexport type NumberTypeT = { kind: 'number' };\nexport type StringTypeT = { kind: 'string' };\nexport type BooleanTypeT = { kind: 'boolean' };\nexport type ColorTypeT = { kind: 'color' };\nexport type ObjectTypeT = { kind: 'object' };\nexport type ValueTypeT = { kind: 'value' };\nexport type ErrorTypeT = { kind: 'error' };\nexport type CollatorTypeT = { kind: 'collator' };\nexport type FormattedTypeT = { kind: 'formatted' };\nexport type ResolvedImageTypeT = { kind: 'resolvedImage' };\n\nexport type EvaluationKind = 'constant' | 'source' | 'camera' | 'composite';\n\nexport type Type =\n NullTypeT |\n NumberTypeT |\n StringTypeT |\n BooleanTypeT |\n ColorTypeT |\n ObjectTypeT |\n ValueTypeT |\n ArrayType | // eslint-disable-line no-use-before-define\n ErrorTypeT |\n CollatorTypeT |\n FormattedTypeT |\n ResolvedImageTypeT\n\nexport type ArrayType = {\n kind: 'array',\n itemType: Type,\n N: ?number\n}\n\nexport type NativeType = 'number' | 'string' | 'boolean' | 'null' | 'array' | 'object'\n\nexport const NullType = {kind: 'null'};\nexport const NumberType = {kind: 'number'};\nexport const StringType = {kind: 'string'};\nexport const BooleanType = {kind: 'boolean'};\nexport const ColorType = {kind: 'color'};\nexport const ObjectType = {kind: 'object'};\nexport const ValueType = {kind: 'value'};\nexport const ErrorType = {kind: 'error'};\nexport const CollatorType = {kind: 'collator'};\nexport const FormattedType = {kind: 'formatted'};\nexport const ResolvedImageType = {kind: 'resolvedImage'};\n\nexport function array(itemType: Type, N: ?number): ArrayType {\n return {\n kind: 'array',\n itemType,\n N\n };\n}\n\nexport function toString(type: Type): string {\n if (type.kind === 'array') {\n const itemType = toString(type.itemType);\n return typeof type.N === 'number' ?\n `array<${itemType}, ${type.N}>` :\n type.itemType.kind === 'value' ? 'array' : `array<${itemType}>`;\n } else {\n return type.kind;\n }\n}\n\nconst valueMemberTypes = [\n NullType,\n NumberType,\n StringType,\n BooleanType,\n ColorType,\n FormattedType,\n ObjectType,\n array(ValueType),\n ResolvedImageType\n];\n\n/**\n * Returns null if `t` is a subtype of `expected`; otherwise returns an\n * error message.\n * @private\n */\nexport function checkSubtype(expected: Type, t: Type): ?string {\n if (t.kind === 'error') {\n // Error is a subtype of every type\n return null;\n } else if (expected.kind === 'array') {\n if (t.kind === 'array' &&\n ((t.N === 0 && t.itemType.kind === 'value') || !checkSubtype(expected.itemType, t.itemType)) &&\n (typeof expected.N !== 'number' || expected.N === t.N)) {\n return null;\n }\n } else if (expected.kind === t.kind) {\n return null;\n } else if (expected.kind === 'value') {\n for (const memberType of valueMemberTypes) {\n if (!checkSubtype(memberType, t)) {\n return null;\n }\n }\n }\n\n return `Expected ${toString(expected)} but found ${toString(t)} instead.`;\n}\n\nexport function isValidType(provided: Type, allowedTypes: Array): boolean {\n return allowedTypes.some(t => t.kind === provided.kind);\n}\n\nexport function isValidNativeType(provided: any, allowedTypes: Array): boolean {\n return allowedTypes.some(t => {\n if (t === 'null') {\n return provided === null;\n } else if (t === 'array') {\n return Array.isArray(provided);\n } else if (t === 'object') {\n return provided && !Array.isArray(provided) && typeof provided === 'object';\n } else {\n return t === typeof provided;\n }\n });\n}\n","// @flow\n\n// Flow type declarations for Intl cribbed from\n// https://github.com/facebook/flow/issues/1270\n\ndeclare var Intl: {\n Collator: Class\n};\n\ndeclare class Intl$Collator {\n constructor (\n locales?: string | string[],\n options?: CollatorOptions\n ): Intl$Collator;\n\n static (\n locales?: string | string[],\n options?: CollatorOptions\n ): Intl$Collator;\n\n compare (a: string, b: string): number;\n\n resolvedOptions(): any;\n}\n\ntype CollatorOptions = {\n localeMatcher?: 'lookup' | 'best fit',\n usage?: 'sort' | 'search',\n sensitivity?: 'base' | 'accent' | 'case' | 'variant',\n ignorePunctuation?: boolean,\n numeric?: boolean,\n caseFirst?: 'upper' | 'lower' | 'false'\n}\n\nexport default class Collator {\n locale: string | null;\n sensitivity: 'base' | 'accent' | 'case' | 'variant';\n collator: Intl$Collator;\n\n constructor(caseSensitive: boolean, diacriticSensitive: boolean, locale: string | null) {\n if (caseSensitive)\n this.sensitivity = diacriticSensitive ? 'variant' : 'case';\n else\n this.sensitivity = diacriticSensitive ? 'accent' : 'base';\n\n this.locale = locale;\n this.collator = new Intl.Collator(this.locale ? this.locale : [],\n {sensitivity: this.sensitivity, usage: 'search'});\n }\n\n compare(lhs: string, rhs: string): number {\n return this.collator.compare(lhs, rhs);\n }\n\n resolvedLocale(): string {\n // We create a Collator without \"usage: search\" because we don't want\n // the search options encoded in our result (e.g. \"en-u-co-search\")\n return new Intl.Collator(this.locale ? this.locale : [])\n .resolvedOptions().locale;\n }\n}\n","// @flow\nimport type Color from '../../util/color.js';\nimport type ResolvedImage from '../types/resolved_image.js';\n\nexport class FormattedSection {\n text: string;\n image: ResolvedImage | null;\n scale: number | null;\n fontStack: string | null;\n textColor: Color | null;\n\n constructor(text: string, image: ResolvedImage | null, scale: number | null, fontStack: string | null, textColor: Color | null) {\n // combine characters so that diacritic marks are not separate code points\n this.text = text.normalize ? text.normalize() : text;\n this.image = image;\n this.scale = scale;\n this.fontStack = fontStack;\n this.textColor = textColor;\n }\n}\n\nexport default class Formatted {\n sections: Array;\n\n constructor(sections: Array) {\n this.sections = sections;\n }\n\n static fromString(unformatted: string): Formatted {\n return new Formatted([new FormattedSection(unformatted, null, null, null, null)]);\n }\n\n isEmpty(): boolean {\n if (this.sections.length === 0) return true;\n return !this.sections.some(section => section.text.length !== 0 ||\n (section.image && section.image.name.length !== 0));\n }\n\n static factory(text: Formatted | string): Formatted {\n if (text instanceof Formatted) {\n return text;\n } else {\n return Formatted.fromString(text);\n }\n }\n\n toString(): string {\n if (this.sections.length === 0) return '';\n return this.sections.map(section => section.text).join('');\n }\n\n serialize(): Array {\n const serialized: Array = [\"format\"];\n for (const section of this.sections) {\n if (section.image) {\n serialized.push([\"image\", section.image.name]);\n continue;\n }\n serialized.push(section.text);\n const options: { [key: string]: mixed } = {};\n if (section.fontStack) {\n options[\"text-font\"] = [\"literal\", section.fontStack.split(',')];\n }\n if (section.scale) {\n options[\"font-scale\"] = section.scale;\n }\n if (section.textColor) {\n options[\"text-color\"] = ([\"rgba\"]: Array).concat(section.textColor.toArray());\n }\n serialized.push(options);\n }\n return serialized;\n }\n}\n","// @flow\n\nexport type ResolvedImageOptions = {\n name: string,\n available: boolean\n};\n\nexport default class ResolvedImage {\n name: string;\n available: boolean;\n\n constructor(options: ResolvedImageOptions) {\n this.name = options.name;\n this.available = options.available;\n }\n\n toString(): string {\n return this.name;\n }\n\n static fromString(name: string): ResolvedImage | null {\n if (!name) return null; // treat empty values as no image\n return new ResolvedImage({name, available: false});\n }\n\n serialize(): Array {\n return [\"image\", this.name];\n }\n}\n","// @flow\n\nimport assert from 'assert';\n\nimport Color from '../util/color.js';\nimport Collator from './types/collator.js';\nimport Formatted from './types/formatted.js';\nimport ResolvedImage from './types/resolved_image.js';\nimport {NullType, NumberType, StringType, BooleanType, ColorType, ObjectType, ValueType, CollatorType, FormattedType, ResolvedImageType, array} from './types.js';\n\nimport type {Type} from './types.js';\n\nexport function validateRGBA(r: mixed, g: mixed, b: mixed, a?: mixed): string | null {\n if (!(\n typeof r === 'number' && r >= 0 && r <= 255 &&\n typeof g === 'number' && g >= 0 && g <= 255 &&\n typeof b === 'number' && b >= 0 && b <= 255\n )) {\n const value = typeof a === 'number' ? [r, g, b, a] : [r, g, b];\n return `Invalid rgba value [${value.join(', ')}]: 'r', 'g', and 'b' must be between 0 and 255.`;\n }\n\n if (!(\n typeof a === 'undefined' || (typeof a === 'number' && a >= 0 && a <= 1)\n )) {\n return `Invalid rgba value [${[r, g, b, a].join(', ')}]: 'a' must be between 0 and 1.`;\n }\n\n return null;\n}\n\nexport type Value = null | string | boolean | number | Color | Collator | Formatted | ResolvedImage | $ReadOnlyArray | { +[string]: Value }\n\nexport function isValue(mixed: mixed): boolean {\n if (mixed === null) {\n return true;\n } else if (typeof mixed === 'string') {\n return true;\n } else if (typeof mixed === 'boolean') {\n return true;\n } else if (typeof mixed === 'number') {\n return true;\n } else if (mixed instanceof Color) {\n return true;\n } else if (mixed instanceof Collator) {\n return true;\n } else if (mixed instanceof Formatted) {\n return true;\n } else if (mixed instanceof ResolvedImage) {\n return true;\n } else if (Array.isArray(mixed)) {\n for (const item of mixed) {\n if (!isValue(item)) {\n return false;\n }\n }\n return true;\n } else if (typeof mixed === 'object') {\n for (const key in mixed) {\n if (!isValue(mixed[key])) {\n return false;\n }\n }\n return true;\n } else {\n return false;\n }\n}\n\nexport function typeOf(value: Value): Type {\n if (value === null) {\n return NullType;\n } else if (typeof value === 'string') {\n return StringType;\n } else if (typeof value === 'boolean') {\n return BooleanType;\n } else if (typeof value === 'number') {\n return NumberType;\n } else if (value instanceof Color) {\n return ColorType;\n } else if (value instanceof Collator) {\n return CollatorType;\n } else if (value instanceof Formatted) {\n return FormattedType;\n } else if (value instanceof ResolvedImage) {\n return ResolvedImageType;\n } else if (Array.isArray(value)) {\n const length = value.length;\n let itemType: Type | typeof undefined;\n\n for (const item of value) {\n const t = typeOf(item);\n if (!itemType) {\n itemType = t;\n } else if (itemType === t) {\n continue;\n } else {\n itemType = ValueType;\n break;\n }\n }\n\n return array(itemType || ValueType, length);\n } else {\n assert(typeof value === 'object');\n return ObjectType;\n }\n}\n\nexport function toString(value: Value): string {\n const type = typeof value;\n if (value === null) {\n return '';\n } else if (type === 'string' || type === 'number' || type === 'boolean') {\n return String(value);\n } else if (value instanceof Color || value instanceof Formatted || value instanceof ResolvedImage) {\n return value.toString();\n } else {\n return JSON.stringify(value);\n }\n}\n\nexport {Color, Collator};\n","// @flow\n\nimport assert from 'assert';\nimport {isValue, typeOf, Color} from '../values.js';\nimport Formatted from '../types/formatted.js';\n\nimport type {Type} from '../types.js';\nimport type {Value} from '../values.js';\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type ParsingContext from '../parsing_context.js';\n\nclass Literal implements Expression {\n type: Type;\n value: Value;\n\n constructor(type: Type, value: Value) {\n this.type = type;\n this.value = value;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): void | Literal {\n if (args.length !== 2)\n return context.error(`'literal' expression requires exactly one argument, but found ${args.length - 1} instead.`);\n\n if (!isValue(args[1]))\n return context.error(`invalid value`);\n\n const value = (args[1]: any);\n let type = typeOf(value);\n\n // special case: infer the item type if possible for zero-length arrays\n const expected = context.expectedType;\n if (\n type.kind === 'array' &&\n type.N === 0 &&\n expected &&\n expected.kind === 'array' &&\n (typeof expected.N !== 'number' || expected.N === 0)\n ) {\n type = expected;\n }\n\n return new Literal(type, value);\n }\n\n evaluate(): Value {\n return this.value;\n }\n\n eachChild() {}\n\n outputDefined(): boolean {\n return true;\n }\n\n serialize(): SerializedExpression {\n if (this.type.kind === 'array' || this.type.kind === 'object') {\n return [\"literal\", this.value];\n } else if (this.value instanceof Color) {\n // Constant-folding can generate Literal expressions that you\n // couldn't actually generate with a \"literal\" expression,\n // so we have to implement an equivalent serialization here\n return [\"rgba\"].concat(this.value.toArray());\n } else if (this.value instanceof Formatted) {\n // Same as Color\n return this.value.serialize();\n } else {\n assert(this.value === null ||\n typeof this.value === 'string' ||\n typeof this.value === 'number' ||\n typeof this.value === 'boolean');\n return (this.value: any);\n }\n }\n}\n\nexport default Literal;\n","// @flow\n\nclass RuntimeError {\n name: string;\n message: string;\n\n constructor(message: string) {\n this.name = 'ExpressionEvaluationError';\n this.message = message;\n }\n\n toJSON(): string {\n return this.message;\n }\n}\n\nexport default RuntimeError;\n","// @flow\n\nimport assert from 'assert';\n\nimport {\n ObjectType,\n ValueType,\n StringType,\n NumberType,\n BooleanType,\n checkSubtype,\n toString,\n array\n} from '../types.js';\nimport RuntimeError from '../runtime_error.js';\nimport {typeOf} from '../values.js';\n\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type {Type} from '../types.js';\n\nconst types = {\n string: StringType,\n number: NumberType,\n boolean: BooleanType,\n object: ObjectType\n};\n\nclass Assertion implements Expression {\n type: Type;\n args: Array;\n\n constructor(type: Type, args: Array) {\n this.type = type;\n this.args = args;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Expression {\n if (args.length < 2)\n return context.error(`Expected at least one argument.`);\n\n let i = 1;\n let type;\n\n const name: string = (args[0]: any);\n if (name === 'array') {\n let itemType;\n if (args.length > 2) {\n const type = args[1];\n if (typeof type !== 'string' || !(type in types) || type === 'object')\n return context.error('The item type argument of \"array\" must be one of string, number, boolean', 1);\n itemType = types[type];\n i++;\n } else {\n itemType = ValueType;\n }\n\n let N;\n if (args.length > 3) {\n if (args[2] !== null &&\n (typeof args[2] !== 'number' ||\n args[2] < 0 ||\n args[2] !== Math.floor(args[2]))\n ) {\n return context.error('The length argument to \"array\" must be a positive integer literal', 2);\n }\n N = args[2];\n i++;\n }\n\n type = array(itemType, N);\n } else {\n assert(types[name], name);\n type = types[name];\n }\n\n const parsed = [];\n for (; i < args.length; i++) {\n const input = context.parse(args[i], i, ValueType);\n if (!input) return null;\n parsed.push(input);\n }\n\n return new Assertion(type, parsed);\n }\n\n evaluate(ctx: EvaluationContext): any | null {\n for (let i = 0; i < this.args.length; i++) {\n const value = this.args[i].evaluate(ctx);\n const error = checkSubtype(this.type, typeOf(value));\n if (!error) {\n return value;\n } else if (i === this.args.length - 1) {\n throw new RuntimeError(`Expected value to be of type ${toString(this.type)}, but found ${toString(typeOf(value))} instead.`);\n }\n }\n\n assert(false);\n return null;\n }\n\n eachChild(fn: (_: Expression) => void) {\n this.args.forEach(fn);\n }\n\n outputDefined(): boolean {\n return this.args.every(arg => arg.outputDefined());\n }\n\n serialize(): SerializedExpression {\n const type = this.type;\n const serialized = [type.kind];\n if (type.kind === 'array') {\n const itemType = type.itemType;\n if (itemType.kind === 'string' ||\n itemType.kind === 'number' ||\n itemType.kind === 'boolean') {\n serialized.push(itemType.kind);\n const N = type.N;\n if (typeof N === 'number' || this.args.length > 1) {\n serialized.push(N);\n }\n }\n }\n return serialized.concat(this.args.map(arg => arg.serialize()));\n }\n}\n\nexport default Assertion;\n","// @flow\n\nimport {NumberType, ValueType, FormattedType, array, StringType, ColorType, ResolvedImageType} from '../types.js';\nimport Formatted, {FormattedSection} from '../types/formatted.js';\nimport {toString, typeOf} from '../values.js';\n\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type {Type} from '../types.js';\n\ntype FormattedSectionExpression = {\n // Content of a section may be Image expression or other\n // type of expression that is coercable to 'string'.\n content: Expression,\n scale: Expression | null;\n font: Expression | null;\n textColor: Expression | null;\n}\n\nexport default class FormatExpression implements Expression {\n type: Type;\n sections: Array;\n\n constructor(sections: Array) {\n this.type = FormattedType;\n this.sections = sections;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Expression {\n if (args.length < 2) {\n return context.error(`Expected at least one argument.`);\n }\n\n const firstArg = args[1];\n if (!Array.isArray(firstArg) && typeof firstArg === 'object') {\n return context.error(`First argument must be an image or text section.`);\n }\n\n const sections: Array = [];\n let nextTokenMayBeObject = false;\n for (let i = 1; i <= args.length - 1; ++i) {\n const arg = (args[i]: any);\n\n if (nextTokenMayBeObject && typeof arg === \"object\" && !Array.isArray(arg)) {\n nextTokenMayBeObject = false;\n\n let scale = null;\n if (arg['font-scale']) {\n scale = context.parse(arg['font-scale'], 1, NumberType);\n if (!scale) return null;\n }\n\n let font = null;\n if (arg['text-font']) {\n font = context.parse(arg['text-font'], 1, array(StringType));\n if (!font) return null;\n }\n\n let textColor = null;\n if (arg['text-color']) {\n textColor = context.parse(arg['text-color'], 1, ColorType);\n if (!textColor) return null;\n }\n\n const lastExpression = sections[sections.length - 1];\n lastExpression.scale = scale;\n lastExpression.font = font;\n lastExpression.textColor = textColor;\n } else {\n const content = context.parse(args[i], 1, ValueType);\n if (!content) return null;\n\n const kind = content.type.kind;\n if (kind !== 'string' && kind !== 'value' && kind !== 'null' && kind !== 'resolvedImage')\n return context.error(`Formatted text type must be 'string', 'value', 'image' or 'null'.`);\n\n nextTokenMayBeObject = true;\n sections.push({content, scale: null, font: null, textColor: null});\n }\n }\n\n return new FormatExpression(sections);\n }\n\n evaluate(ctx: EvaluationContext): Formatted {\n const evaluateSection = section => {\n const evaluatedContent = section.content.evaluate(ctx);\n if (typeOf(evaluatedContent) === ResolvedImageType) {\n return new FormattedSection('', evaluatedContent, null, null, null);\n }\n\n return new FormattedSection(\n toString(evaluatedContent),\n null,\n section.scale ? section.scale.evaluate(ctx) : null,\n section.font ? section.font.evaluate(ctx).join(',') : null,\n section.textColor ? section.textColor.evaluate(ctx) : null\n );\n };\n\n return new Formatted(this.sections.map(evaluateSection));\n }\n\n eachChild(fn: (_: Expression) => void) {\n for (const section of this.sections) {\n fn(section.content);\n if (section.scale) {\n fn(section.scale);\n }\n if (section.font) {\n fn(section.font);\n }\n if (section.textColor) {\n fn(section.textColor);\n }\n }\n }\n\n outputDefined(): boolean {\n // Technically the combinatoric set of all children\n // Usually, this.text will be undefined anyway\n return false;\n }\n\n serialize(): SerializedExpression {\n const serialized = [\"format\"];\n for (const section of this.sections) {\n serialized.push(section.content.serialize());\n const options = {};\n if (section.scale) {\n options['font-scale'] = section.scale.serialize();\n }\n if (section.font) {\n options['text-font'] = section.font.serialize();\n }\n if (section.textColor) {\n options['text-color'] = section.textColor.serialize();\n }\n serialized.push(options);\n }\n return serialized;\n }\n}\n","// @flow\n\nimport {ResolvedImageType, StringType} from '../types.js';\nimport ResolvedImage from '../types/resolved_image.js';\n\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type {Type} from '../types.js';\n\nexport default class ImageExpression implements Expression {\n type: Type;\n input: Expression;\n\n constructor(input: Expression) {\n this.type = ResolvedImageType;\n this.input = input;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Expression {\n if (args.length !== 2) {\n return context.error(`Expected two arguments.`);\n }\n\n const name = context.parse(args[1], 1, StringType);\n if (!name) return context.error(`No image name provided.`);\n\n return new ImageExpression(name);\n }\n\n evaluate(ctx: EvaluationContext): null | ResolvedImage {\n const evaluatedImageName = this.input.evaluate(ctx);\n\n const value = ResolvedImage.fromString(evaluatedImageName);\n if (value && ctx.availableImages) value.available = ctx.availableImages.indexOf(evaluatedImageName) > -1;\n\n return value;\n }\n\n eachChild(fn: (_: Expression) => void) {\n fn(this.input);\n }\n\n outputDefined(): boolean {\n // The output of image is determined by the list of available images in the evaluation context\n return false;\n }\n\n serialize(): SerializedExpression {\n return [\"image\", this.input.serialize()];\n }\n}\n","// @flow\n\nimport assert from 'assert';\n\nimport {BooleanType, ColorType, NumberType, StringType, ValueType} from '../types.js';\nimport {Color, toString as valueToString, validateRGBA} from '../values.js';\nimport RuntimeError from '../runtime_error.js';\nimport Formatted from '../types/formatted.js';\nimport FormatExpression from '../definitions/format.js';\nimport ImageExpression from '../definitions/image.js';\nimport ResolvedImage from '../types/resolved_image.js';\n\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type {Type} from '../types.js';\n\nconst types = {\n 'to-boolean': BooleanType,\n 'to-color': ColorType,\n 'to-number': NumberType,\n 'to-string': StringType\n};\n\n/**\n * Special form for error-coalescing coercion expressions \"to-number\",\n * \"to-color\". Since these coercions can fail at runtime, they accept multiple\n * arguments, only evaluating one at a time until one succeeds.\n *\n * @private\n */\nclass Coercion implements Expression {\n type: Type;\n args: Array;\n\n constructor(type: Type, args: Array) {\n this.type = type;\n this.args = args;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Expression {\n if (args.length < 2)\n return context.error(`Expected at least one argument.`);\n\n const name: string = (args[0]: any);\n assert(types[name], name);\n\n if ((name === 'to-boolean' || name === 'to-string') && args.length !== 2)\n return context.error(`Expected one argument.`);\n\n const type = types[name];\n\n const parsed = [];\n for (let i = 1; i < args.length; i++) {\n const input = context.parse(args[i], i, ValueType);\n if (!input) return null;\n parsed.push(input);\n }\n\n return new Coercion(type, parsed);\n }\n\n evaluate(ctx: EvaluationContext): null | boolean | number | string | Color | Formatted | ResolvedImage {\n if (this.type.kind === 'boolean') {\n return Boolean(this.args[0].evaluate(ctx));\n } else if (this.type.kind === 'color') {\n let input;\n let error;\n for (const arg of this.args) {\n input = arg.evaluate(ctx);\n error = null;\n if (input instanceof Color) {\n return input;\n } else if (typeof input === 'string') {\n const c = ctx.parseColor(input);\n if (c) return c;\n } else if (Array.isArray(input)) {\n if (input.length < 3 || input.length > 4) {\n error = `Invalid rbga value ${JSON.stringify(input)}: expected an array containing either three or four numeric values.`;\n } else {\n error = validateRGBA(input[0], input[1], input[2], input[3]);\n }\n if (!error) {\n return new Color((input[0]: any) / 255, (input[1]: any) / 255, (input[2]: any) / 255, (input[3]: any));\n }\n }\n }\n throw new RuntimeError(error || `Could not parse color from value '${typeof input === 'string' ? input : String(JSON.stringify(input))}'`);\n } else if (this.type.kind === 'number') {\n let value = null;\n for (const arg of this.args) {\n value = arg.evaluate(ctx);\n if (value === null) return 0;\n const num = Number(value);\n if (isNaN(num)) continue;\n return num;\n }\n throw new RuntimeError(`Could not convert ${JSON.stringify(value)} to number.`);\n } else if (this.type.kind === 'formatted') {\n // There is no explicit 'to-formatted' but this coercion can be implicitly\n // created by properties that expect the 'formatted' type.\n return Formatted.fromString(valueToString(this.args[0].evaluate(ctx)));\n } else if (this.type.kind === 'resolvedImage') {\n return ResolvedImage.fromString(valueToString(this.args[0].evaluate(ctx)));\n } else {\n return valueToString(this.args[0].evaluate(ctx));\n }\n }\n\n eachChild(fn: (_: Expression) => void) {\n this.args.forEach(fn);\n }\n\n outputDefined(): boolean {\n return this.args.every(arg => arg.outputDefined());\n }\n\n serialize(): SerializedExpression {\n if (this.type.kind === 'formatted') {\n return new FormatExpression([{content: this.args[0], scale: null, font: null, textColor: null}]).serialize();\n }\n\n if (this.type.kind === 'resolvedImage') {\n return new ImageExpression(this.args[0]).serialize();\n }\n\n const serialized = [`to-${this.type.kind}`];\n this.eachChild(child => { serialized.push(child.serialize()); });\n return serialized;\n }\n}\n\nexport default Coercion;\n","// @flow\n\nimport {Color} from './values.js';\n\nimport type Point from '@mapbox/point-geometry';\nimport type {FormattedSection} from './types/formatted.js';\nimport type {GlobalProperties, Feature, FeatureState} from './index.js';\nimport type {CanonicalTileID} from '../../source/tile_id.js';\nimport type {FeatureDistanceData} from '../feature_filter/index.js';\n\nconst geometryTypes = ['Unknown', 'Point', 'LineString', 'Polygon'];\n\nclass EvaluationContext {\n globals: GlobalProperties;\n feature: ?Feature;\n featureState: ?FeatureState;\n formattedSection: ?FormattedSection;\n availableImages: ?Array;\n canonical: null | CanonicalTileID;\n featureTileCoord: ?Point;\n featureDistanceData: ?FeatureDistanceData;\n\n _parseColorCache: {[_: string]: ?Color};\n\n constructor() {\n this.globals = (null: any);\n this.feature = null;\n this.featureState = null;\n this.formattedSection = null;\n this._parseColorCache = {};\n this.availableImages = null;\n this.canonical = null;\n this.featureTileCoord = null;\n this.featureDistanceData = null;\n }\n\n id(): number | null {\n return this.feature && 'id' in this.feature && this.feature.id ? this.feature.id : null;\n }\n\n geometryType(): null | string {\n return this.feature ? typeof this.feature.type === 'number' ? geometryTypes[this.feature.type] : this.feature.type : null;\n }\n\n geometry(): ?Array> {\n return this.feature && 'geometry' in this.feature ? this.feature.geometry : null;\n }\n\n canonicalID(): null | CanonicalTileID {\n return this.canonical;\n }\n\n properties(): {[string]: any} {\n return (this.feature && this.feature.properties) || {};\n }\n\n distanceFromCenter(): number {\n if (this.featureTileCoord && this.featureDistanceData) {\n\n const c = this.featureDistanceData.center;\n const scale = this.featureDistanceData.scale;\n const {x, y} = this.featureTileCoord;\n\n // Calculate the distance vector `d` (left handed)\n const dX = x * scale - c[0];\n const dY = y * scale - c[1];\n\n // The bearing vector `b` (left handed)\n const bX = this.featureDistanceData.bearing[0];\n const bY = this.featureDistanceData.bearing[1];\n\n // Distance is calculated as `dot(d, v)`\n const dist = (bX * dX + bY * dY);\n return dist;\n }\n\n return 0;\n }\n\n parseColor(input: string): ?Color {\n let cached = this._parseColorCache[input];\n if (!cached) {\n cached = this._parseColorCache[input] = Color.parse(input);\n }\n return cached;\n }\n}\n\nexport default EvaluationContext;\n","// @flow\n\nimport {toString} from './types.js';\n\nimport ParsingContext from './parsing_context.js';\nimport EvaluationContext from './evaluation_context.js';\nimport assert from 'assert';\n\nimport type {Expression, ExpressionRegistry} from './expression.js';\nimport type {Type} from './types.js';\nimport type {Value} from './values.js';\n\nexport type Varargs = {| type: Type |};\ntype Signature = Array | Varargs;\ntype Evaluate = (EvaluationContext, Array) => Value;\ntype Definition = [Type, Signature, Evaluate] |\n {|type: Type, overloads: Array<[Signature, Evaluate]>|};\n\nclass CompoundExpression implements Expression {\n name: string;\n type: Type;\n _evaluate: Evaluate;\n args: Array;\n\n static definitions: {[_: string]: Definition };\n\n constructor(name: string, type: Type, evaluate: Evaluate, args: Array) {\n this.name = name;\n this.type = type;\n this._evaluate = evaluate;\n this.args = args;\n }\n\n evaluate(ctx: EvaluationContext): Value {\n return this._evaluate(ctx, this.args);\n }\n\n eachChild(fn: (_: Expression) => void) {\n this.args.forEach(fn);\n }\n\n outputDefined(): boolean {\n return false;\n }\n\n serialize(): Array {\n return [this.name].concat(this.args.map(arg => arg.serialize()));\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Expression {\n const op: string = (args[0]: any);\n const definition = CompoundExpression.definitions[op];\n if (!definition) {\n return context.error(`Unknown expression \"${op}\". If you wanted a literal array, use [\"literal\", [...]].`, 0);\n }\n\n // Now check argument types against each signature\n const type = Array.isArray(definition) ?\n definition[0] : definition.type;\n\n const availableOverloads = Array.isArray(definition) ?\n [[definition[1], definition[2]]] :\n definition.overloads;\n\n const overloads = availableOverloads.filter(([signature]) => (\n !Array.isArray(signature) || // varags\n signature.length === args.length - 1 // correct param count\n ));\n\n let signatureContext: ParsingContext = (null: any);\n\n for (const [params, evaluate] of overloads) {\n // Use a fresh context for each attempted signature so that, if\n // we eventually succeed, we haven't polluted `context.errors`.\n signatureContext = new ParsingContext(context.registry, context.path, null, context.scope);\n\n // First parse all the args, potentially coercing to the\n // types expected by this overload.\n const parsedArgs: Array = [];\n let argParseFailed = false;\n for (let i = 1; i < args.length; i++) {\n const arg = args[i];\n const expectedType = Array.isArray(params) ?\n params[i - 1] :\n params.type;\n\n const parsed = signatureContext.parse(arg, 1 + parsedArgs.length, expectedType);\n if (!parsed) {\n argParseFailed = true;\n break;\n }\n parsedArgs.push(parsed);\n }\n if (argParseFailed) {\n // Couldn't coerce args of this overload to expected type, move\n // on to next one.\n continue;\n }\n\n if (Array.isArray(params)) {\n if (params.length !== parsedArgs.length) {\n signatureContext.error(`Expected ${params.length} arguments, but found ${parsedArgs.length} instead.`);\n continue;\n }\n }\n\n for (let i = 0; i < parsedArgs.length; i++) {\n const expected = Array.isArray(params) ? params[i] : params.type;\n const arg = parsedArgs[i];\n signatureContext.concat(i + 1).checkSubtype(expected, arg.type);\n }\n\n if (signatureContext.errors.length === 0) {\n return new CompoundExpression(op, type, evaluate, parsedArgs);\n }\n }\n\n assert(!signatureContext || signatureContext.errors.length > 0);\n\n if (overloads.length === 1) {\n context.errors.push(...signatureContext.errors);\n } else {\n const expected = overloads.length ? overloads : availableOverloads;\n const signatures = expected\n .map(([params]) => stringifySignature(params))\n .join(' | ');\n\n const actualTypes = [];\n // For error message, re-parse arguments without trying to\n // apply any coercions\n for (let i = 1; i < args.length; i++) {\n const parsed = context.parse(args[i], 1 + actualTypes.length);\n if (!parsed) return null;\n actualTypes.push(toString(parsed.type));\n }\n context.error(`Expected arguments of type ${signatures}, but found (${actualTypes.join(', ')}) instead.`);\n }\n\n return null;\n }\n\n static register(\n registry: ExpressionRegistry,\n definitions: {[_: string]: Definition }\n ) {\n assert(!CompoundExpression.definitions);\n CompoundExpression.definitions = definitions;\n for (const name in definitions) {\n registry[name] = CompoundExpression;\n }\n }\n}\n\nfunction stringifySignature(signature: Signature): string {\n if (Array.isArray(signature)) {\n return `(${signature.map(toString).join(', ')})`;\n } else {\n return `(${toString(signature.type)}...)`;\n }\n}\n\nexport default CompoundExpression;\n","// @flow\n\nimport {StringType, BooleanType, CollatorType} from '../types.js';\nimport Collator from '../types/collator.js';\n\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type {Type} from '../types.js';\n\nexport default class CollatorExpression implements Expression {\n type: Type;\n caseSensitive: Expression;\n diacriticSensitive: Expression;\n locale: Expression | null;\n\n constructor(caseSensitive: Expression, diacriticSensitive: Expression, locale: Expression | null) {\n this.type = CollatorType;\n this.locale = locale;\n this.caseSensitive = caseSensitive;\n this.diacriticSensitive = diacriticSensitive;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Expression {\n if (args.length !== 2)\n return context.error(`Expected one argument.`);\n\n const options = (args[1]: any);\n if (typeof options !== \"object\" || Array.isArray(options))\n return context.error(`Collator options argument must be an object.`);\n\n const caseSensitive = context.parse(\n options['case-sensitive'] === undefined ? false : options['case-sensitive'], 1, BooleanType);\n if (!caseSensitive) return null;\n\n const diacriticSensitive = context.parse(\n options['diacritic-sensitive'] === undefined ? false : options['diacritic-sensitive'], 1, BooleanType);\n if (!diacriticSensitive) return null;\n\n let locale = null;\n if (options['locale']) {\n locale = context.parse(options['locale'], 1, StringType);\n if (!locale) return null;\n }\n\n return new CollatorExpression(caseSensitive, diacriticSensitive, locale);\n }\n\n evaluate(ctx: EvaluationContext): Collator {\n return new Collator(this.caseSensitive.evaluate(ctx), this.diacriticSensitive.evaluate(ctx), this.locale ? this.locale.evaluate(ctx) : null);\n }\n\n eachChild(fn: (_: Expression) => void) {\n fn(this.caseSensitive);\n fn(this.diacriticSensitive);\n if (this.locale) {\n fn(this.locale);\n }\n }\n\n outputDefined(): boolean {\n // Technically the set of possible outputs is the combinatoric set of Collators produced\n // by all possible outputs of locale/caseSensitive/diacriticSensitive\n // But for the primary use of Collators in comparison operators, we ignore the Collator's\n // possible outputs anyway, so we can get away with leaving this false for now.\n return false;\n }\n\n serialize(): SerializedExpression {\n const options = {};\n options['case-sensitive'] = this.caseSensitive.serialize();\n options['diacritic-sensitive'] = this.diacriticSensitive.serialize();\n if (this.locale) {\n options['locale'] = this.locale.serialize();\n }\n return [\"collator\", options];\n }\n}\n","// @flow\n\nimport {isValue} from '../values.js';\nimport type {Type} from '../types.js';\nimport {BooleanType} from '../types.js';\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type {GeoJSON, GeoJSONPolygon, GeoJSONMultiPolygon} from '@mapbox/geojson-types';\nimport Point from '@mapbox/point-geometry';\nimport type {CanonicalTileID} from '../../../source/tile_id.js';\n\ntype GeoJSONPolygons =| GeoJSONPolygon | GeoJSONMultiPolygon;\n\n// minX, minY, maxX, maxY\ntype BBox = [number, number, number, number];\nconst EXTENT = 8192;\n\nfunction updateBBox(bbox: BBox, coord: Point) {\n bbox[0] = Math.min(bbox[0], coord[0]);\n bbox[1] = Math.min(bbox[1], coord[1]);\n bbox[2] = Math.max(bbox[2], coord[0]);\n bbox[3] = Math.max(bbox[3], coord[1]);\n}\n\nfunction mercatorXfromLng(lng: number) {\n return (180 + lng) / 360;\n}\n\nfunction mercatorYfromLat(lat: number) {\n return (180 - (180 / Math.PI * Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360)))) / 360;\n}\n\nfunction boxWithinBox(bbox1: BBox, bbox2: BBox) {\n if (bbox1[0] <= bbox2[0]) return false;\n if (bbox1[2] >= bbox2[2]) return false;\n if (bbox1[1] <= bbox2[1]) return false;\n if (bbox1[3] >= bbox2[3]) return false;\n return true;\n}\n\nfunction getTileCoordinates(p, canonical: CanonicalTileID) {\n const x = mercatorXfromLng(p[0]);\n const y = mercatorYfromLat(p[1]);\n const tilesAtZoom = Math.pow(2, canonical.z);\n return [Math.round(x * tilesAtZoom * EXTENT), Math.round(y * tilesAtZoom * EXTENT)];\n}\n\nfunction onBoundary(p, p1, p2) {\n const x1 = p[0] - p1[0];\n const y1 = p[1] - p1[1];\n const x2 = p[0] - p2[0];\n const y2 = p[1] - p2[1];\n return (x1 * y2 - x2 * y1 === 0) && (x1 * x2 <= 0) && (y1 * y2 <= 0);\n}\n\nfunction rayIntersect(p, p1, p2) {\n return ((p1[1] > p[1]) !== (p2[1] > p[1])) && (p[0] < (p2[0] - p1[0]) * (p[1] - p1[1]) / (p2[1] - p1[1]) + p1[0]);\n}\n\n// ray casting algorithm for detecting if point is in polygon\nfunction pointWithinPolygon(point, rings) {\n let inside = false;\n for (let i = 0, len = rings.length; i < len; i++) {\n const ring = rings[i];\n for (let j = 0, len2 = ring.length; j < len2 - 1; j++) {\n if (onBoundary(point, ring[j], ring[j + 1])) return false;\n if (rayIntersect(point, ring[j], ring[j + 1])) inside = !inside;\n }\n }\n return inside;\n}\n\nfunction pointWithinPolygons(point, polygons) {\n for (let i = 0; i < polygons.length; i++) {\n if (pointWithinPolygon(point, polygons[i])) return true;\n }\n return false;\n}\n\nfunction perp(v1, v2) {\n return (v1[0] * v2[1] - v1[1] * v2[0]);\n}\n\n// check if p1 and p2 are in different sides of line segment q1->q2\nfunction twoSided(p1, p2, q1, q2) {\n // q1->p1 (x1, y1), q1->p2 (x2, y2), q1->q2 (x3, y3)\n const x1 = p1[0] - q1[0];\n const y1 = p1[1] - q1[1];\n const x2 = p2[0] - q1[0];\n const y2 = p2[1] - q1[1];\n const x3 = q2[0] - q1[0];\n const y3 = q2[1] - q1[1];\n const det1 = (x1 * y3 - x3 * y1);\n const det2 = (x2 * y3 - x3 * y2);\n if ((det1 > 0 && det2 < 0) || (det1 < 0 && det2 > 0)) return true;\n return false;\n}\n// a, b are end points for line segment1, c and d are end points for line segment2\nfunction lineIntersectLine(a, b, c, d) {\n // check if two segments are parallel or not\n // precondition is end point a, b is inside polygon, if line a->b is\n // parallel to polygon edge c->d, then a->b won't intersect with c->d\n const vectorP = [b[0] - a[0], b[1] - a[1]];\n const vectorQ = [d[0] - c[0], d[1] - c[1]];\n if (perp(vectorQ, vectorP) === 0) return false;\n\n // If lines are intersecting with each other, the relative location should be:\n // a and b lie in different sides of segment c->d\n // c and d lie in different sides of segment a->b\n if (twoSided(a, b, c, d) && twoSided(c, d, a, b)) return true;\n return false;\n}\n\nfunction lineIntersectPolygon(p1, p2, polygon) {\n for (const ring of polygon) {\n // loop through every edge of the ring\n for (let j = 0; j < ring.length - 1; ++j) {\n if (lineIntersectLine(p1, p2, ring[j], ring[j + 1])) {\n return true;\n }\n }\n }\n return false;\n}\n\nfunction lineStringWithinPolygon(line, polygon) {\n // First, check if geometry points of line segments are all inside polygon\n for (let i = 0; i < line.length; ++i) {\n if (!pointWithinPolygon(line[i], polygon)) {\n return false;\n }\n }\n\n // Second, check if there is line segment intersecting polygon edge\n for (let i = 0; i < line.length - 1; ++i) {\n if (lineIntersectPolygon(line[i], line[i + 1], polygon)) {\n return false;\n }\n }\n return true;\n}\n\nfunction lineStringWithinPolygons(line, polygons) {\n for (let i = 0; i < polygons.length; i++) {\n if (lineStringWithinPolygon(line, polygons[i])) return true;\n }\n return false;\n}\n\nfunction getTilePolygon(coordinates, bbox: BBox, canonical: CanonicalTileID) {\n const polygon = [];\n for (let i = 0; i < coordinates.length; i++) {\n const ring = [];\n for (let j = 0; j < coordinates[i].length; j++) {\n const coord = getTileCoordinates(coordinates[i][j], canonical);\n updateBBox(bbox, coord);\n ring.push(coord);\n }\n polygon.push(ring);\n }\n return polygon;\n}\n\nfunction getTilePolygons(coordinates, bbox, canonical: CanonicalTileID) {\n const polygons = [];\n for (let i = 0; i < coordinates.length; i++) {\n const polygon = getTilePolygon(coordinates[i], bbox, canonical);\n polygons.push(polygon);\n }\n return polygons;\n}\n\nfunction updatePoint(p, bbox, polyBBox, worldSize) {\n if (p[0] < polyBBox[0] || p[0] > polyBBox[2]) {\n const halfWorldSize = worldSize * 0.5;\n let shift = (p[0] - polyBBox[0] > halfWorldSize) ? -worldSize : (polyBBox[0] - p[0] > halfWorldSize) ? worldSize : 0;\n if (shift === 0) {\n shift = (p[0] - polyBBox[2] > halfWorldSize) ? -worldSize : (polyBBox[2] - p[0] > halfWorldSize) ? worldSize : 0;\n }\n p[0] += shift;\n }\n updateBBox(bbox, p);\n}\n\nfunction resetBBox(bbox) {\n bbox[0] = bbox[1] = Infinity;\n bbox[2] = bbox[3] = -Infinity;\n}\n\nfunction getTilePoints(geometry, pointBBox, polyBBox, canonical: CanonicalTileID) {\n const worldSize = Math.pow(2, canonical.z) * EXTENT;\n const shifts = [canonical.x * EXTENT, canonical.y * EXTENT];\n const tilePoints = [];\n if (!geometry) return tilePoints;\n for (const points of geometry) {\n for (const point of points) {\n const p = [point.x + shifts[0], point.y + shifts[1]];\n updatePoint(p, pointBBox, polyBBox, worldSize);\n tilePoints.push(p);\n }\n }\n return tilePoints;\n}\n\nfunction getTileLines(geometry, lineBBox, polyBBox, canonical: CanonicalTileID) {\n const worldSize = Math.pow(2, canonical.z) * EXTENT;\n const shifts = [canonical.x * EXTENT, canonical.y * EXTENT];\n const tileLines = [];\n if (!geometry) return tileLines;\n for (const line of geometry) {\n const tileLine = [];\n for (const point of line) {\n const p = [point.x + shifts[0], point.y + shifts[1]];\n updateBBox(lineBBox, p);\n tileLine.push(p);\n }\n tileLines.push(tileLine);\n }\n if (lineBBox[2] - lineBBox[0] <= worldSize / 2) {\n resetBBox(lineBBox);\n for (const line of tileLines) {\n for (const p of line) {\n updatePoint(p, lineBBox, polyBBox, worldSize);\n }\n }\n }\n return tileLines;\n}\n\nfunction pointsWithinPolygons(ctx: EvaluationContext, polygonGeometry: GeoJSONPolygons) {\n const pointBBox = [Infinity, Infinity, -Infinity, -Infinity];\n const polyBBox = [Infinity, Infinity, -Infinity, -Infinity];\n\n const canonical = ctx.canonicalID();\n if (!canonical) {\n return false;\n }\n\n if (polygonGeometry.type === 'Polygon') {\n const tilePolygon = getTilePolygon(polygonGeometry.coordinates, polyBBox, canonical);\n const tilePoints = getTilePoints(ctx.geometry(), pointBBox, polyBBox, canonical);\n if (!boxWithinBox(pointBBox, polyBBox)) return false;\n\n for (const point of tilePoints) {\n if (!pointWithinPolygon(point, tilePolygon)) return false;\n }\n }\n if (polygonGeometry.type === 'MultiPolygon') {\n const tilePolygons = getTilePolygons(polygonGeometry.coordinates, polyBBox, canonical);\n const tilePoints = getTilePoints(ctx.geometry(), pointBBox, polyBBox, canonical);\n if (!boxWithinBox(pointBBox, polyBBox)) return false;\n\n for (const point of tilePoints) {\n if (!pointWithinPolygons(point, tilePolygons)) return false;\n }\n }\n\n return true;\n}\n\nfunction linesWithinPolygons(ctx: EvaluationContext, polygonGeometry: GeoJSONPolygons) {\n const lineBBox = [Infinity, Infinity, -Infinity, -Infinity];\n const polyBBox = [Infinity, Infinity, -Infinity, -Infinity];\n\n const canonical = ctx.canonicalID();\n if (!canonical) {\n return false;\n }\n\n if (polygonGeometry.type === 'Polygon') {\n const tilePolygon = getTilePolygon(polygonGeometry.coordinates, polyBBox, canonical);\n const tileLines = getTileLines(ctx.geometry(), lineBBox, polyBBox, canonical);\n if (!boxWithinBox(lineBBox, polyBBox)) return false;\n\n for (const line of tileLines) {\n if (!lineStringWithinPolygon(line, tilePolygon)) return false;\n }\n }\n if (polygonGeometry.type === 'MultiPolygon') {\n const tilePolygons = getTilePolygons(polygonGeometry.coordinates, polyBBox, canonical);\n const tileLines = getTileLines(ctx.geometry(), lineBBox, polyBBox, canonical);\n if (!boxWithinBox(lineBBox, polyBBox)) return false;\n\n for (const line of tileLines) {\n if (!lineStringWithinPolygons(line, tilePolygons)) return false;\n }\n }\n return true;\n}\n\nclass Within implements Expression {\n type: Type;\n geojson: GeoJSON\n geometries: GeoJSONPolygons;\n\n constructor(geojson: GeoJSON, geometries: GeoJSONPolygons) {\n this.type = BooleanType;\n this.geojson = geojson;\n this.geometries = geometries;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Within {\n if (args.length !== 2)\n return context.error(`'within' expression requires exactly one argument, but found ${args.length - 1} instead.`);\n if (isValue(args[1])) {\n const geojson = (args[1]: Object);\n if (geojson.type === 'FeatureCollection') {\n for (let i = 0; i < geojson.features.length; ++i) {\n const type = geojson.features[i].geometry.type;\n if (type === 'Polygon' || type === 'MultiPolygon') {\n return new Within(geojson, geojson.features[i].geometry);\n }\n }\n } else if (geojson.type === 'Feature') {\n const type = geojson.geometry.type;\n if (type === 'Polygon' || type === 'MultiPolygon') {\n return new Within(geojson, geojson.geometry);\n }\n } else if (geojson.type === 'Polygon' || geojson.type === 'MultiPolygon') {\n return new Within(geojson, geojson);\n }\n }\n return context.error(`'within' expression requires valid geojson object that contains polygon geometry type.`);\n }\n\n evaluate(ctx: EvaluationContext): boolean {\n if (ctx.geometry() != null && ctx.canonicalID() != null) {\n if (ctx.geometryType() === 'Point') {\n return pointsWithinPolygons(ctx, this.geometries);\n } else if (ctx.geometryType() === 'LineString') {\n return linesWithinPolygons(ctx, this.geometries);\n }\n }\n return false;\n }\n\n eachChild() {}\n\n outputDefined(): boolean {\n return true;\n }\n\n serialize(): SerializedExpression {\n return [\"within\", this.geojson];\n }\n\n}\n\nexport default Within;\n","// @flow\n\nimport CompoundExpression from './compound_expression.js';\nimport Within from './definitions/within.js';\nimport type {Expression} from './expression.js';\n\nfunction isFeatureConstant(e: Expression): boolean {\n if (e instanceof CompoundExpression) {\n if (e.name === 'get' && e.args.length === 1) {\n return false;\n } else if (e.name === 'feature-state') {\n return false;\n } else if (e.name === 'has' && e.args.length === 1) {\n return false;\n } else if (\n e.name === 'properties' ||\n e.name === 'geometry-type' ||\n e.name === 'id'\n ) {\n return false;\n } else if (/^filter-/.test(e.name)) {\n return false;\n }\n }\n\n if (e instanceof Within) {\n return false;\n }\n\n let result = true;\n e.eachChild(arg => {\n if (result && !isFeatureConstant(arg)) { result = false; }\n });\n return result;\n}\n\nfunction isStateConstant(e: Expression): boolean {\n if (e instanceof CompoundExpression) {\n if (e.name === 'feature-state') {\n return false;\n }\n }\n let result = true;\n e.eachChild(arg => {\n if (result && !isStateConstant(arg)) { result = false; }\n });\n return result;\n}\n\nfunction isGlobalPropertyConstant(e: Expression, properties: Array): boolean {\n if (e instanceof CompoundExpression && properties.indexOf(e.name) >= 0) { return false; }\n let result = true;\n e.eachChild((arg) => {\n if (result && !isGlobalPropertyConstant(arg, properties)) { result = false; }\n });\n return result;\n}\n\nexport {isFeatureConstant, isGlobalPropertyConstant, isStateConstant};\n","// @flow\n\nimport type {Type} from '../types.js';\nimport type {Expression} from '../expression.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type EvaluationContext from '../evaluation_context.js';\n\nclass Var implements Expression {\n type: Type;\n name: string;\n boundExpression: Expression;\n\n constructor(name: string, boundExpression: Expression) {\n this.type = boundExpression.type;\n this.name = name;\n this.boundExpression = boundExpression;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): void | Var {\n if (args.length !== 2 || typeof args[1] !== 'string')\n return context.error(`'var' expression requires exactly one string literal argument.`);\n\n const name = args[1];\n if (!context.scope.has(name)) {\n return context.error(`Unknown variable \"${name}\". Make sure \"${name}\" has been bound in an enclosing \"let\" expression before using it.`, 1);\n }\n\n return new Var(name, context.scope.get(name));\n }\n\n evaluate(ctx: EvaluationContext): any {\n return this.boundExpression.evaluate(ctx);\n }\n\n eachChild() {}\n\n outputDefined(): boolean {\n return false;\n }\n\n serialize(): Array {\n return [\"var\", this.name];\n }\n}\n\nexport default Var;\n","// @flow\n\nimport Scope from './scope.js';\nimport {checkSubtype} from './types.js';\nimport ParsingError from './parsing_error.js';\nimport Literal from './definitions/literal.js';\nimport Assertion from './definitions/assertion.js';\nimport Coercion from './definitions/coercion.js';\nimport EvaluationContext from './evaluation_context.js';\nimport CompoundExpression from './compound_expression.js';\nimport CollatorExpression from './definitions/collator.js';\nimport Within from './definitions/within.js';\nimport {isGlobalPropertyConstant, isFeatureConstant} from './is_constant.js';\nimport Var from './definitions/var.js';\n\nimport type {Expression, ExpressionRegistry} from './expression.js';\nimport type {Type} from './types.js';\n\n/**\n * State associated parsing at a given point in an expression tree.\n * @private\n */\nclass ParsingContext {\n registry: ExpressionRegistry;\n path: Array;\n key: string;\n scope: Scope;\n errors: Array;\n\n // The expected type of this expression. Provided only to allow Expression\n // implementations to infer argument types: Expression#parse() need not\n // check that the output type of the parsed expression matches\n // `expectedType`.\n expectedType: ?Type;\n\n constructor(\n registry: ExpressionRegistry,\n path: Array = [],\n expectedType: ?Type,\n scope: Scope = new Scope(),\n errors: Array = []\n ) {\n this.registry = registry;\n this.path = path;\n this.key = path.map(part => `[${part}]`).join('');\n this.scope = scope;\n this.errors = errors;\n this.expectedType = expectedType;\n }\n\n /**\n * @param expr the JSON expression to parse\n * @param index the optional argument index if this expression is an argument of a parent expression that's being parsed\n * @param options\n * @param options.omitTypeAnnotations set true to omit inferred type annotations. Caller beware: with this option set, the parsed expression's type will NOT satisfy `expectedType` if it would normally be wrapped in an inferred annotation.\n * @private\n */\n parse(\n expr: mixed,\n index?: number,\n expectedType?: ?Type,\n bindings?: Array<[string, Expression]>,\n options: {typeAnnotation?: 'assert' | 'coerce' | 'omit'} = {}\n ): ?Expression {\n if (index) {\n return this.concat(index, expectedType, bindings)._parse(expr, options);\n }\n return this._parse(expr, options);\n }\n\n _parse(expr: mixed, options: {typeAnnotation?: 'assert' | 'coerce' | 'omit'}): ?Expression {\n if (expr === null || typeof expr === 'string' || typeof expr === 'boolean' || typeof expr === 'number') {\n expr = ['literal', expr];\n }\n\n function annotate(parsed, type, typeAnnotation: 'assert' | 'coerce' | 'omit') {\n if (typeAnnotation === 'assert') {\n return new Assertion(type, [parsed]);\n } else if (typeAnnotation === 'coerce') {\n return new Coercion(type, [parsed]);\n } else {\n return parsed;\n }\n }\n\n if (Array.isArray(expr)) {\n if (expr.length === 0) {\n return this.error(`Expected an array with at least one element. If you wanted a literal array, use [\"literal\", []].`);\n }\n\n const op = expr[0];\n if (typeof op !== 'string') {\n this.error(`Expression name must be a string, but found ${typeof op} instead. If you wanted a literal array, use [\"literal\", [...]].`, 0);\n return null;\n }\n\n const Expr = this.registry[op];\n if (Expr) {\n let parsed = Expr.parse(expr, this);\n if (!parsed) return null;\n\n if (this.expectedType) {\n const expected = this.expectedType;\n const actual = parsed.type;\n\n // When we expect a number, string, boolean, or array but have a value, wrap it in an assertion.\n // When we expect a color or formatted string, but have a string or value, wrap it in a coercion.\n // Otherwise, we do static type-checking.\n //\n // These behaviors are overridable for:\n // * The \"coalesce\" operator, which needs to omit type annotations.\n // * String-valued properties (e.g. `text-field`), where coercion is more convenient than assertion.\n //\n if ((expected.kind === 'string' || expected.kind === 'number' || expected.kind === 'boolean' || expected.kind === 'object' || expected.kind === 'array') && actual.kind === 'value') {\n parsed = annotate(parsed, expected, options.typeAnnotation || 'assert');\n } else if ((expected.kind === 'color' || expected.kind === 'formatted' || expected.kind === 'resolvedImage') && (actual.kind === 'value' || actual.kind === 'string')) {\n parsed = annotate(parsed, expected, options.typeAnnotation || 'coerce');\n } else if (this.checkSubtype(expected, actual)) {\n return null;\n }\n }\n\n // If an expression's arguments are all literals, we can evaluate\n // it immediately and replace it with a literal value in the\n // parsed/compiled result. Expressions that expect an image should\n // not be resolved here so we can later get the available images.\n if (!(parsed instanceof Literal) && (parsed.type.kind !== 'resolvedImage') && isConstant(parsed)) {\n const ec = new EvaluationContext();\n try {\n parsed = new Literal(parsed.type, parsed.evaluate(ec));\n } catch (e) {\n this.error(e.message);\n return null;\n }\n }\n\n return parsed;\n }\n\n return this.error(`Unknown expression \"${op}\". If you wanted a literal array, use [\"literal\", [...]].`, 0);\n } else if (typeof expr === 'undefined') {\n return this.error(`'undefined' value invalid. Use null instead.`);\n } else if (typeof expr === 'object') {\n return this.error(`Bare objects invalid. Use [\"literal\", {...}] instead.`);\n } else {\n return this.error(`Expected an array, but found ${typeof expr} instead.`);\n }\n }\n\n /**\n * Returns a copy of this context suitable for parsing the subexpression at\n * index `index`, optionally appending to 'let' binding map.\n *\n * Note that `errors` property, intended for collecting errors while\n * parsing, is copied by reference rather than cloned.\n * @private\n */\n concat(index: number, expectedType?: ?Type, bindings?: Array<[string, Expression]>): ParsingContext {\n const path = typeof index === 'number' ? this.path.concat(index) : this.path;\n const scope = bindings ? this.scope.concat(bindings) : this.scope;\n return new ParsingContext(\n this.registry,\n path,\n expectedType || null,\n scope,\n this.errors\n );\n }\n\n /**\n * Push a parsing (or type checking) error into the `this.errors`\n * @param error The message\n * @param keys Optionally specify the source of the error at a child\n * of the current expression at `this.key`.\n * @private\n */\n error(error: string, ...keys: Array) {\n const key = `${this.key}${keys.map(k => `[${k}]`).join('')}`;\n this.errors.push(new ParsingError(key, error));\n }\n\n /**\n * Returns null if `t` is a subtype of `expected`; otherwise returns an\n * error message and also pushes it to `this.errors`.\n */\n checkSubtype(expected: Type, t: Type): ?string {\n const error = checkSubtype(expected, t);\n if (error) this.error(error);\n return error;\n }\n}\n\nexport default ParsingContext;\n\nfunction isConstant(expression: Expression) {\n if (expression instanceof Var) {\n return isConstant(expression.boundExpression);\n } else if (expression instanceof CompoundExpression && expression.name === 'error') {\n return false;\n } else if (expression instanceof CollatorExpression) {\n // Although the results of a Collator expression with fixed arguments\n // generally shouldn't change between executions, we can't serialize them\n // as constant expressions because results change based on environment.\n return false;\n } else if (expression instanceof Within) {\n return false;\n }\n\n const isTypeAnnotation = expression instanceof Coercion ||\n expression instanceof Assertion;\n\n let childrenConstant = true;\n expression.eachChild(child => {\n // We can _almost_ assume that if `expressions` children are constant,\n // they would already have been evaluated to Literal values when they\n // were parsed. Type annotations are the exception, because they might\n // have been inferred and added after a child was parsed.\n\n // So we recurse into isConstant() for the children of type annotations,\n // but otherwise simply check whether they are Literals.\n if (isTypeAnnotation) {\n childrenConstant = childrenConstant && isConstant(child);\n } else {\n childrenConstant = childrenConstant && child instanceof Literal;\n }\n });\n if (!childrenConstant) {\n return false;\n }\n\n return isFeatureConstant(expression) &&\n isGlobalPropertyConstant(expression, ['zoom', 'heatmap-density', 'line-progress', 'sky-radial-progress', 'accumulated', 'is-supported-script', 'pitch', 'distance-from-center']);\n}\n","// @flow\n\nimport RuntimeError from './runtime_error.js';\n\nimport type {Expression} from './expression.js';\n\nexport type Stops = Array<[number, Expression]>;\n\n/**\n * Returns the index of the last stop <= input, or 0 if it doesn't exist.\n * @private\n */\nexport function findStopLessThanOrEqualTo(stops: Array, input: number): number {\n const lastIndex = stops.length - 1;\n let lowerIndex = 0;\n let upperIndex = lastIndex;\n let currentIndex = 0;\n let currentValue, nextValue;\n\n while (lowerIndex <= upperIndex) {\n currentIndex = Math.floor((lowerIndex + upperIndex) / 2);\n currentValue = stops[currentIndex];\n nextValue = stops[currentIndex + 1];\n\n if (currentValue <= input) {\n if (currentIndex === lastIndex || input < nextValue) { // Search complete\n return currentIndex;\n }\n\n lowerIndex = currentIndex + 1;\n } else if (currentValue > input) {\n upperIndex = currentIndex - 1;\n } else {\n throw new RuntimeError('Input is not a number.');\n }\n }\n\n return 0;\n}\n","// @flow\n\nimport {NumberType} from '../types.js';\n\nimport {findStopLessThanOrEqualTo} from '../stops.js';\n\nimport type {Stops} from '../stops.js';\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type {Type} from '../types.js';\n\nclass Step implements Expression {\n type: Type;\n\n input: Expression;\n labels: Array;\n outputs: Array;\n\n constructor(type: Type, input: Expression, stops: Stops) {\n this.type = type;\n this.input = input;\n\n this.labels = [];\n this.outputs = [];\n for (const [label, expression] of stops) {\n this.labels.push(label);\n this.outputs.push(expression);\n }\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Step {\n if (args.length - 1 < 4) {\n return context.error(`Expected at least 4 arguments, but found only ${args.length - 1}.`);\n }\n\n if ((args.length - 1) % 2 !== 0) {\n return context.error(`Expected an even number of arguments.`);\n }\n\n const input = context.parse(args[1], 1, NumberType);\n if (!input) return null;\n\n const stops: Stops = [];\n\n let outputType: Type = (null: any);\n if (context.expectedType && context.expectedType.kind !== 'value') {\n outputType = context.expectedType;\n }\n\n for (let i = 1; i < args.length; i += 2) {\n const label = i === 1 ? -Infinity : args[i];\n const value = args[i + 1];\n\n const labelKey = i;\n const valueKey = i + 1;\n\n if (typeof label !== 'number') {\n return context.error('Input/output pairs for \"step\" expressions must be defined using literal numeric values (not computed expressions) for the input values.', labelKey);\n }\n\n if (stops.length && stops[stops.length - 1][0] >= label) {\n return context.error('Input/output pairs for \"step\" expressions must be arranged with input values in strictly ascending order.', labelKey);\n }\n\n const parsed = context.parse(value, valueKey, outputType);\n if (!parsed) return null;\n outputType = outputType || parsed.type;\n stops.push([label, parsed]);\n }\n\n return new Step(outputType, input, stops);\n }\n\n evaluate(ctx: EvaluationContext): any {\n const labels = this.labels;\n const outputs = this.outputs;\n\n if (labels.length === 1) {\n return outputs[0].evaluate(ctx);\n }\n\n const value = ((this.input.evaluate(ctx): any): number);\n if (value <= labels[0]) {\n return outputs[0].evaluate(ctx);\n }\n\n const stopCount = labels.length;\n if (value >= labels[stopCount - 1]) {\n return outputs[stopCount - 1].evaluate(ctx);\n }\n\n const index = findStopLessThanOrEqualTo(labels, value);\n return outputs[index].evaluate(ctx);\n }\n\n eachChild(fn: (_: Expression) => void) {\n fn(this.input);\n for (const expression of this.outputs) {\n fn(expression);\n }\n }\n\n outputDefined(): boolean {\n return this.outputs.every(out => out.outputDefined());\n }\n\n serialize(): SerializedExpression {\n const serialized = [\"step\", this.input.serialize()];\n for (let i = 0; i < this.labels.length; i++) {\n if (i > 0) {\n serialized.push(this.labels[i]);\n }\n serialized.push(this.outputs[i].serialize());\n }\n return serialized;\n }\n}\n\nexport default Step;\n","/*\n * Copyright (C) 2008 Apple Inc. All Rights Reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n * notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n * notice, this list of conditions and the following disclaimer in the\n * documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR\n * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY\n * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * Ported from Webkit\n * http://svn.webkit.org/repository/webkit/trunk/Source/WebCore/platform/graphics/UnitBezier.h\n */\n\nmodule.exports = UnitBezier;\n\nfunction UnitBezier(p1x, p1y, p2x, p2y) {\n // Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1).\n this.cx = 3.0 * p1x;\n this.bx = 3.0 * (p2x - p1x) - this.cx;\n this.ax = 1.0 - this.cx - this.bx;\n\n this.cy = 3.0 * p1y;\n this.by = 3.0 * (p2y - p1y) - this.cy;\n this.ay = 1.0 - this.cy - this.by;\n\n this.p1x = p1x;\n this.p1y = p2y;\n this.p2x = p2x;\n this.p2y = p2y;\n}\n\nUnitBezier.prototype.sampleCurveX = function(t) {\n // `ax t^3 + bx t^2 + cx t' expanded using Horner's rule.\n return ((this.ax * t + this.bx) * t + this.cx) * t;\n};\n\nUnitBezier.prototype.sampleCurveY = function(t) {\n return ((this.ay * t + this.by) * t + this.cy) * t;\n};\n\nUnitBezier.prototype.sampleCurveDerivativeX = function(t) {\n return (3.0 * this.ax * t + 2.0 * this.bx) * t + this.cx;\n};\n\nUnitBezier.prototype.solveCurveX = function(x, epsilon) {\n if (typeof epsilon === 'undefined') epsilon = 1e-6;\n\n var t0, t1, t2, x2, i;\n\n // First try a few iterations of Newton's method -- normally very fast.\n for (t2 = x, i = 0; i < 8; i++) {\n\n x2 = this.sampleCurveX(t2) - x;\n if (Math.abs(x2) < epsilon) return t2;\n\n var d2 = this.sampleCurveDerivativeX(t2);\n if (Math.abs(d2) < 1e-6) break;\n\n t2 = t2 - x2 / d2;\n }\n\n // Fall back to the bisection method for reliability.\n t0 = 0.0;\n t1 = 1.0;\n t2 = x;\n\n if (t2 < t0) return t0;\n if (t2 > t1) return t1;\n\n while (t0 < t1) {\n\n x2 = this.sampleCurveX(t2);\n if (Math.abs(x2 - x) < epsilon) return t2;\n\n if (x > x2) {\n t0 = t2;\n } else {\n t1 = t2;\n }\n\n t2 = (t1 - t0) * 0.5 + t0;\n }\n\n // Failure.\n return t2;\n};\n\nUnitBezier.prototype.solve = function(x, epsilon) {\n return this.sampleCurveY(this.solveCurveX(x, epsilon));\n};\n","// @flow\n\nimport Color from './color.js';\n\nexport function number(a: number, b: number, t: number): number {\n return (a * (1 - t)) + (b * t);\n}\n\nexport function color(from: Color, to: Color, t: number): Color {\n return new Color(\n number(from.r, to.r, t),\n number(from.g, to.g, t),\n number(from.b, to.b, t),\n number(from.a, to.a, t)\n );\n}\n\nexport function array(from: Array, to: Array, t: number): Array {\n return from.map((d, i) => {\n return number(d, to[i], t);\n });\n}\n","// @flow\n\nimport Color from './color.js';\n\nimport {number as interpolateNumber} from './interpolate.js';\n\ntype LABColor = {\n l: number,\n a: number,\n b: number,\n alpha: number\n};\n\ntype HCLColor = {\n h: number,\n c: number,\n l: number,\n alpha: number\n};\n\n// Constants\nconst Xn = 0.950470, // D65 standard referent\n Yn = 1,\n Zn = 1.088830,\n t0 = 4 / 29,\n t1 = 6 / 29,\n t2 = 3 * t1 * t1,\n t3 = t1 * t1 * t1,\n deg2rad = Math.PI / 180,\n rad2deg = 180 / Math.PI;\n\n// Utilities\nfunction xyz2lab(t: number) {\n return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;\n}\n\nfunction lab2xyz(t: number) {\n return t > t1 ? t * t * t : t2 * (t - t0);\n}\n\nfunction xyz2rgb(x: number) {\n return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);\n}\n\nfunction rgb2xyz(x: number) {\n x /= 255;\n return x <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);\n}\n\n// LAB\nfunction rgbToLab(rgbColor: Color): LABColor {\n const b = rgb2xyz(rgbColor.r),\n a = rgb2xyz(rgbColor.g),\n l = rgb2xyz(rgbColor.b),\n x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn),\n y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn),\n z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn);\n\n return {\n l: 116 * y - 16,\n a: 500 * (x - y),\n b: 200 * (y - z),\n alpha: rgbColor.a\n };\n}\n\nfunction labToRgb(labColor: LABColor): Color {\n let y = (labColor.l + 16) / 116,\n x = isNaN(labColor.a) ? y : y + labColor.a / 500,\n z = isNaN(labColor.b) ? y : y - labColor.b / 200;\n y = Yn * lab2xyz(y);\n x = Xn * lab2xyz(x);\n z = Zn * lab2xyz(z);\n return new Color(\n xyz2rgb(3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB\n xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z),\n xyz2rgb(0.0556434 * x - 0.2040259 * y + 1.0572252 * z),\n labColor.alpha\n );\n}\n\nfunction interpolateLab(from: LABColor, to: LABColor, t: number): LABColor {\n return {\n l: interpolateNumber(from.l, to.l, t),\n a: interpolateNumber(from.a, to.a, t),\n b: interpolateNumber(from.b, to.b, t),\n alpha: interpolateNumber(from.alpha, to.alpha, t)\n };\n}\n\n// HCL\nfunction rgbToHcl(rgbColor: Color): HCLColor {\n const {l, a, b} = rgbToLab(rgbColor);\n const h = Math.atan2(b, a) * rad2deg;\n return {\n h: h < 0 ? h + 360 : h,\n c: Math.sqrt(a * a + b * b),\n l,\n alpha: rgbColor.a\n };\n}\n\nfunction hclToRgb(hclColor: HCLColor): Color {\n const h = hclColor.h * deg2rad,\n c = hclColor.c,\n l = hclColor.l;\n return labToRgb({\n l,\n a: Math.cos(h) * c,\n b: Math.sin(h) * c,\n alpha: hclColor.alpha\n });\n}\n\nfunction interpolateHue(a: number, b: number, t: number) {\n const d = b - a;\n return a + t * (d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d);\n}\n\nfunction interpolateHcl(from: HCLColor, to: HCLColor, t: number): HCLColor {\n return {\n h: interpolateHue(from.h, to.h, t),\n c: interpolateNumber(from.c, to.c, t),\n l: interpolateNumber(from.l, to.l, t),\n alpha: interpolateNumber(from.alpha, to.alpha, t)\n };\n}\n\nexport const lab = {\n forward: rgbToLab,\n reverse: labToRgb,\n interpolate: interpolateLab\n};\n\nexport const hcl = {\n forward: rgbToHcl,\n reverse: hclToRgb,\n interpolate: interpolateHcl\n};\n","// @flow\n\nimport UnitBezier from '@mapbox/unitbezier';\n\nimport * as interpolate from '../../util/interpolate.js';\nimport {toString, NumberType, ColorType} from '../types.js';\nimport {findStopLessThanOrEqualTo} from '../stops.js';\nimport {hcl, lab} from '../../util/color_spaces.js';\nimport Color from '../../util/color.js';\n\nimport type {Stops} from '../stops.js';\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type {Type} from '../types.js';\n\nexport type InterpolationType =\n { name: 'linear' } |\n { name: 'exponential', base: number } |\n { name: 'cubic-bezier', controlPoints: [number, number, number, number] };\n\nclass Interpolate implements Expression {\n type: Type;\n\n operator: 'interpolate' | 'interpolate-hcl' | 'interpolate-lab';\n interpolation: InterpolationType;\n input: Expression;\n labels: Array;\n outputs: Array;\n\n constructor(type: Type, operator: 'interpolate' | 'interpolate-hcl' | 'interpolate-lab', interpolation: InterpolationType, input: Expression, stops: Stops) {\n this.type = type;\n this.operator = operator;\n this.interpolation = interpolation;\n this.input = input;\n\n this.labels = [];\n this.outputs = [];\n for (const [label, expression] of stops) {\n this.labels.push(label);\n this.outputs.push(expression);\n }\n }\n\n static interpolationFactor(interpolation: InterpolationType, input: number, lower: number, upper: number): number {\n let t = 0;\n if (interpolation.name === 'exponential') {\n t = exponentialInterpolation(input, interpolation.base, lower, upper);\n } else if (interpolation.name === 'linear') {\n t = exponentialInterpolation(input, 1, lower, upper);\n } else if (interpolation.name === 'cubic-bezier') {\n const c = interpolation.controlPoints;\n const ub = new UnitBezier(c[0], c[1], c[2], c[3]);\n t = ub.solve(exponentialInterpolation(input, 1, lower, upper));\n }\n return t;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Interpolate {\n let [operator, interpolation, input, ...rest] = args;\n\n if (!Array.isArray(interpolation) || interpolation.length === 0) {\n return context.error(`Expected an interpolation type expression.`, 1);\n }\n\n if (interpolation[0] === 'linear') {\n interpolation = {name: 'linear'};\n } else if (interpolation[0] === 'exponential') {\n const base = interpolation[1];\n if (typeof base !== 'number')\n return context.error(`Exponential interpolation requires a numeric base.`, 1, 1);\n interpolation = {\n name: 'exponential',\n base\n };\n } else if (interpolation[0] === 'cubic-bezier') {\n const controlPoints = interpolation.slice(1);\n if (\n controlPoints.length !== 4 ||\n controlPoints.some(t => typeof t !== 'number' || t < 0 || t > 1)\n ) {\n return context.error('Cubic bezier interpolation requires four numeric arguments with values between 0 and 1.', 1);\n }\n\n interpolation = {\n name: 'cubic-bezier',\n controlPoints: (controlPoints: any)\n };\n } else {\n return context.error(`Unknown interpolation type ${String(interpolation[0])}`, 1, 0);\n }\n\n if (args.length - 1 < 4) {\n return context.error(`Expected at least 4 arguments, but found only ${args.length - 1}.`);\n }\n\n if ((args.length - 1) % 2 !== 0) {\n return context.error(`Expected an even number of arguments.`);\n }\n\n input = context.parse(input, 2, NumberType);\n if (!input) return null;\n\n const stops: Stops = [];\n\n let outputType: Type = (null: any);\n if (operator === 'interpolate-hcl' || operator === 'interpolate-lab') {\n outputType = ColorType;\n } else if (context.expectedType && context.expectedType.kind !== 'value') {\n outputType = context.expectedType;\n }\n\n for (let i = 0; i < rest.length; i += 2) {\n const label = rest[i];\n const value = rest[i + 1];\n\n const labelKey = i + 3;\n const valueKey = i + 4;\n\n if (typeof label !== 'number') {\n return context.error('Input/output pairs for \"interpolate\" expressions must be defined using literal numeric values (not computed expressions) for the input values.', labelKey);\n }\n\n if (stops.length && stops[stops.length - 1][0] >= label) {\n return context.error('Input/output pairs for \"interpolate\" expressions must be arranged with input values in strictly ascending order.', labelKey);\n }\n\n const parsed = context.parse(value, valueKey, outputType);\n if (!parsed) return null;\n outputType = outputType || parsed.type;\n stops.push([label, parsed]);\n }\n\n if (outputType.kind !== 'number' &&\n outputType.kind !== 'color' &&\n !(\n outputType.kind === 'array' &&\n outputType.itemType.kind === 'number' &&\n typeof outputType.N === 'number'\n )\n ) {\n return context.error(`Type ${toString(outputType)} is not interpolatable.`);\n }\n\n return new Interpolate(outputType, (operator: any), interpolation, input, stops);\n }\n\n evaluate(ctx: EvaluationContext): Color {\n const labels = this.labels;\n const outputs = this.outputs;\n\n if (labels.length === 1) {\n return outputs[0].evaluate(ctx);\n }\n\n const value = ((this.input.evaluate(ctx): any): number);\n if (value <= labels[0]) {\n return outputs[0].evaluate(ctx);\n }\n\n const stopCount = labels.length;\n if (value >= labels[stopCount - 1]) {\n return outputs[stopCount - 1].evaluate(ctx);\n }\n\n const index = findStopLessThanOrEqualTo(labels, value);\n const lower = labels[index];\n const upper = labels[index + 1];\n const t = Interpolate.interpolationFactor(this.interpolation, value, lower, upper);\n\n const outputLower = outputs[index].evaluate(ctx);\n const outputUpper = outputs[index + 1].evaluate(ctx);\n\n if (this.operator === 'interpolate') {\n return (interpolate[this.type.kind.toLowerCase()]: any)(outputLower, outputUpper, t); // eslint-disable-line import/namespace\n } else if (this.operator === 'interpolate-hcl') {\n return hcl.reverse(hcl.interpolate(hcl.forward(outputLower), hcl.forward(outputUpper), t));\n } else {\n return lab.reverse(lab.interpolate(lab.forward(outputLower), lab.forward(outputUpper), t));\n }\n }\n\n eachChild(fn: (_: Expression) => void) {\n fn(this.input);\n for (const expression of this.outputs) {\n fn(expression);\n }\n }\n\n outputDefined(): boolean {\n return this.outputs.every(out => out.outputDefined());\n }\n\n serialize(): SerializedExpression {\n let interpolation;\n if (this.interpolation.name === 'linear') {\n interpolation = [\"linear\"];\n } else if (this.interpolation.name === 'exponential') {\n if (this.interpolation.base === 1) {\n interpolation = [\"linear\"];\n } else {\n interpolation = [\"exponential\", this.interpolation.base];\n }\n } else {\n interpolation = [\"cubic-bezier\" ].concat(this.interpolation.controlPoints);\n }\n\n const serialized = [this.operator, interpolation, this.input.serialize()];\n\n for (let i = 0; i < this.labels.length; i++) {\n serialized.push(\n this.labels[i],\n this.outputs[i].serialize()\n );\n }\n return serialized;\n }\n}\n\n/**\n * Returns a ratio that can be used to interpolate between exponential function\n * stops.\n * How it works: Two consecutive stop values define a (scaled and shifted) exponential function `f(x) = a * base^x + b`, where `base` is the user-specified base,\n * and `a` and `b` are constants affording sufficient degrees of freedom to fit\n * the function to the given stops.\n *\n * Here's a bit of algebra that lets us compute `f(x)` directly from the stop\n * values without explicitly solving for `a` and `b`:\n *\n * First stop value: `f(x0) = y0 = a * base^x0 + b`\n * Second stop value: `f(x1) = y1 = a * base^x1 + b`\n * => `y1 - y0 = a(base^x1 - base^x0)`\n * => `a = (y1 - y0)/(base^x1 - base^x0)`\n *\n * Desired value: `f(x) = y = a * base^x + b`\n * => `f(x) = y0 + a * (base^x - base^x0)`\n *\n * From the above, we can replace the `a` in `a * (base^x - base^x0)` and do a\n * little algebra:\n * ```\n * a * (base^x - base^x0) = (y1 - y0)/(base^x1 - base^x0) * (base^x - base^x0)\n * = (y1 - y0) * (base^x - base^x0) / (base^x1 - base^x0)\n * ```\n *\n * If we let `(base^x - base^x0) / (base^x1 base^x0)`, then we have\n * `f(x) = y0 + (y1 - y0) * ratio`. In other words, `ratio` may be treated as\n * an interpolation factor between the two stops' output values.\n *\n * (Note: a slightly different form for `ratio`,\n * `(base^(x-x0) - 1) / (base^(x1-x0) - 1) `, is equivalent, but requires fewer\n * expensive `Math.pow()` operations.)\n *\n * @private\n*/\nfunction exponentialInterpolation(input, base, lowerValue, upperValue) {\n const difference = upperValue - lowerValue;\n const progress = input - lowerValue;\n\n if (difference === 0) {\n return 0;\n } else if (base === 1) {\n return progress / difference;\n } else {\n return (Math.pow(base, progress) - 1) / (Math.pow(base, difference) - 1);\n }\n}\n\nexport default Interpolate;\n","// @flow\n\nimport assert from 'assert';\n\nimport {checkSubtype, ValueType} from '../types.js';\nimport ResolvedImage from '../types/resolved_image.js';\n\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type {Type} from '../types.js';\n\nclass Coalesce implements Expression {\n type: Type;\n args: Array;\n\n constructor(type: Type, args: Array) {\n this.type = type;\n this.args = args;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Coalesce {\n if (args.length < 2) {\n return context.error(\"Expectected at least one argument.\");\n }\n let outputType: Type = (null: any);\n const expectedType = context.expectedType;\n if (expectedType && expectedType.kind !== 'value') {\n outputType = expectedType;\n }\n const parsedArgs = [];\n\n for (const arg of args.slice(1)) {\n const parsed = context.parse(arg, 1 + parsedArgs.length, outputType, undefined, {typeAnnotation: 'omit'});\n if (!parsed) return null;\n outputType = outputType || parsed.type;\n parsedArgs.push(parsed);\n }\n assert(outputType);\n\n // Above, we parse arguments without inferred type annotation so that\n // they don't produce a runtime error for `null` input, which would\n // preempt the desired null-coalescing behavior.\n // Thus, if any of our arguments would have needed an annotation, we\n // need to wrap the enclosing coalesce expression with it instead.\n const needsAnnotation = expectedType &&\n parsedArgs.some(arg => checkSubtype(expectedType, arg.type));\n\n return needsAnnotation ?\n new Coalesce(ValueType, parsedArgs) :\n new Coalesce((outputType: any), parsedArgs);\n }\n\n evaluate(ctx: EvaluationContext): any | null {\n let result = null;\n let argCount = 0;\n let firstImage;\n for (const arg of this.args) {\n argCount++;\n result = arg.evaluate(ctx);\n // we need to keep track of the first requested image in a coalesce statement\n // if coalesce can't find a valid image, we return the first image so styleimagemissing can fire\n if (result && result instanceof ResolvedImage && !result.available) {\n // set to first image\n if (!firstImage) {\n firstImage = result;\n }\n result = null;\n // if we reach the end, return the first image\n if (argCount === this.args.length) {\n return firstImage;\n }\n }\n\n if (result !== null) break;\n }\n return result;\n }\n\n eachChild(fn: (_: Expression) => void) {\n this.args.forEach(fn);\n }\n\n outputDefined(): boolean {\n return this.args.every(arg => arg.outputDefined());\n }\n\n serialize(): SerializedExpression {\n const serialized = [\"coalesce\"];\n this.eachChild(child => { serialized.push(child.serialize()); });\n return serialized;\n }\n}\n\nexport default Coalesce;\n","// @flow\n\nimport type {Type} from '../types.js';\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type EvaluationContext from '../evaluation_context.js';\n\nclass Let implements Expression {\n type: Type;\n bindings: Array<[string, Expression]>;\n result: Expression;\n\n constructor(bindings: Array<[string, Expression]>, result: Expression) {\n this.type = result.type;\n this.bindings = [].concat(bindings);\n this.result = result;\n }\n\n evaluate(ctx: EvaluationContext): any {\n return this.result.evaluate(ctx);\n }\n\n eachChild(fn: (_: Expression) => void) {\n for (const binding of this.bindings) {\n fn(binding[1]);\n }\n fn(this.result);\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Let {\n if (args.length < 4)\n return context.error(`Expected at least 3 arguments, but found ${args.length - 1} instead.`);\n\n const bindings: Array<[string, Expression]> = [];\n for (let i = 1; i < args.length - 1; i += 2) {\n const name = args[i];\n\n if (typeof name !== 'string') {\n return context.error(`Expected string, but found ${typeof name} instead.`, i);\n }\n\n if (/[^a-zA-Z0-9_]/.test(name)) {\n return context.error(`Variable names must contain only alphanumeric characters or '_'.`, i);\n }\n\n const value = context.parse(args[i + 1], i + 1);\n if (!value) return null;\n\n bindings.push([name, value]);\n }\n\n const result = context.parse(args[args.length - 1], args.length - 1, context.expectedType, bindings);\n if (!result) return null;\n\n return new Let(bindings, result);\n }\n\n outputDefined(): boolean {\n return this.result.outputDefined();\n }\n\n serialize(): SerializedExpression {\n const serialized = [\"let\"];\n for (const [name, expr] of this.bindings) {\n serialized.push(name, expr.serialize());\n }\n serialized.push(this.result.serialize());\n return serialized;\n }\n}\n\nexport default Let;\n","// @flow\n\nimport {array, ValueType, NumberType} from '../types.js';\n\nimport RuntimeError from '../runtime_error.js';\n\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type {Type, ArrayType} from '../types.js';\nimport type {Value} from '../values.js';\n\nclass At implements Expression {\n type: Type;\n index: Expression;\n input: Expression;\n\n constructor(type: Type, index: Expression, input: Expression) {\n this.type = type;\n this.index = index;\n this.input = input;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?At {\n if (args.length !== 3)\n return context.error(`Expected 2 arguments, but found ${args.length - 1} instead.`);\n\n const index = context.parse(args[1], 1, NumberType);\n const input = context.parse(args[2], 2, array(context.expectedType || ValueType));\n\n if (!index || !input) return null;\n\n const t: ArrayType = (input.type: any);\n return new At(t.itemType, index, input);\n }\n\n evaluate(ctx: EvaluationContext): Value {\n const index = ((this.index.evaluate(ctx): any): number);\n const array = ((this.input.evaluate(ctx): any): Array);\n\n if (index < 0) {\n throw new RuntimeError(`Array index out of bounds: ${index} < 0.`);\n }\n\n if (index >= array.length) {\n throw new RuntimeError(`Array index out of bounds: ${index} > ${array.length - 1}.`);\n }\n\n if (index !== Math.floor(index)) {\n throw new RuntimeError(`Array index must be an integer, but found ${index} instead.`);\n }\n\n return array[index];\n }\n\n eachChild(fn: (_: Expression) => void) {\n fn(this.index);\n fn(this.input);\n }\n\n outputDefined(): boolean {\n return false;\n }\n\n serialize(): SerializedExpression {\n return [\"at\", this.index.serialize(), this.input.serialize()];\n }\n}\n\nexport default At;\n","// @flow\n\nimport {BooleanType, StringType, ValueType, NullType, toString, NumberType, isValidType, isValidNativeType} from '../types.js';\nimport RuntimeError from '../runtime_error.js';\nimport {typeOf} from '../values.js';\n\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type {Type} from '../types.js';\n\nclass In implements Expression {\n type: Type;\n needle: Expression;\n haystack: Expression;\n\n constructor(needle: Expression, haystack: Expression) {\n this.type = BooleanType;\n this.needle = needle;\n this.haystack = haystack;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?In {\n if (args.length !== 3) {\n return context.error(`Expected 2 arguments, but found ${args.length - 1} instead.`);\n }\n\n const needle = context.parse(args[1], 1, ValueType);\n\n const haystack = context.parse(args[2], 2, ValueType);\n\n if (!needle || !haystack) return null;\n\n if (!isValidType(needle.type, [BooleanType, StringType, NumberType, NullType, ValueType])) {\n return context.error(`Expected first argument to be of type boolean, string, number or null, but found ${toString(needle.type)} instead`);\n }\n\n return new In(needle, haystack);\n }\n\n evaluate(ctx: EvaluationContext): boolean {\n const needle = (this.needle.evaluate(ctx): any);\n const haystack = (this.haystack.evaluate(ctx): any);\n\n if (haystack == null) return false;\n\n if (!isValidNativeType(needle, ['boolean', 'string', 'number', 'null'])) {\n throw new RuntimeError(`Expected first argument to be of type boolean, string, number or null, but found ${toString(typeOf(needle))} instead.`);\n }\n\n if (!isValidNativeType(haystack, ['string', 'array'])) {\n throw new RuntimeError(`Expected second argument to be of type array or string, but found ${toString(typeOf(haystack))} instead.`);\n }\n\n return haystack.indexOf(needle) >= 0;\n }\n\n eachChild(fn: (_: Expression) => void) {\n fn(this.needle);\n fn(this.haystack);\n }\n\n outputDefined(): boolean {\n return true;\n }\n\n serialize(): SerializedExpression {\n return [\"in\", this.needle.serialize(), this.haystack.serialize()];\n }\n}\n\nexport default In;\n","// @flow\n\nimport {BooleanType, StringType, ValueType, NullType, toString, NumberType, isValidType, isValidNativeType} from '../types.js';\nimport RuntimeError from '../runtime_error.js';\nimport {typeOf} from '../values.js';\n\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type {Type} from '../types.js';\n\nclass IndexOf implements Expression {\n type: Type;\n needle: Expression;\n haystack: Expression;\n fromIndex: ?Expression;\n\n constructor(needle: Expression, haystack: Expression, fromIndex?: Expression) {\n this.type = NumberType;\n this.needle = needle;\n this.haystack = haystack;\n this.fromIndex = fromIndex;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?IndexOf {\n if (args.length <= 2 || args.length >= 5) {\n return context.error(`Expected 3 or 4 arguments, but found ${args.length - 1} instead.`);\n }\n\n const needle = context.parse(args[1], 1, ValueType);\n\n const haystack = context.parse(args[2], 2, ValueType);\n\n if (!needle || !haystack) return null;\n if (!isValidType(needle.type, [BooleanType, StringType, NumberType, NullType, ValueType])) {\n return context.error(`Expected first argument to be of type boolean, string, number or null, but found ${toString(needle.type)} instead`);\n }\n\n if (args.length === 4) {\n const fromIndex = context.parse(args[3], 3, NumberType);\n if (!fromIndex) return null;\n return new IndexOf(needle, haystack, fromIndex);\n } else {\n return new IndexOf(needle, haystack);\n }\n }\n\n evaluate(ctx: EvaluationContext): any {\n const needle = (this.needle.evaluate(ctx): any);\n const haystack = (this.haystack.evaluate(ctx): any);\n\n if (!isValidNativeType(needle, ['boolean', 'string', 'number', 'null'])) {\n throw new RuntimeError(`Expected first argument to be of type boolean, string, number or null, but found ${toString(typeOf(needle))} instead.`);\n }\n\n if (!isValidNativeType(haystack, ['string', 'array'])) {\n throw new RuntimeError(`Expected second argument to be of type array or string, but found ${toString(typeOf(haystack))} instead.`);\n }\n\n if (this.fromIndex) {\n const fromIndex = (this.fromIndex.evaluate(ctx): number);\n return haystack.indexOf(needle, fromIndex);\n }\n\n return haystack.indexOf(needle);\n }\n\n eachChild(fn: (_: Expression) => void) {\n fn(this.needle);\n fn(this.haystack);\n if (this.fromIndex) {\n fn(this.fromIndex);\n }\n }\n\n outputDefined(): boolean {\n return false;\n }\n\n serialize(): SerializedExpression {\n if (this.fromIndex != null && this.fromIndex !== undefined) {\n const fromIndex = this.fromIndex.serialize();\n return [\"index-of\", this.needle.serialize(), this.haystack.serialize(), fromIndex];\n }\n return [\"index-of\", this.needle.serialize(), this.haystack.serialize()];\n }\n}\n\nexport default IndexOf;\n","// @flow\n\nimport assert from 'assert';\n\nimport {typeOf} from '../values.js';\nimport {ValueType, type Type} from '../types.js';\n\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type EvaluationContext from '../evaluation_context.js';\n\n// Map input label values to output expression index\ntype Cases = {[number | string]: number};\n\nclass Match implements Expression {\n type: Type;\n inputType: Type;\n\n input: Expression;\n cases: Cases;\n outputs: Array;\n otherwise: Expression;\n\n constructor(inputType: Type, outputType: Type, input: Expression, cases: Cases, outputs: Array, otherwise: Expression) {\n this.inputType = inputType;\n this.type = outputType;\n this.input = input;\n this.cases = cases;\n this.outputs = outputs;\n this.otherwise = otherwise;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Match {\n if (args.length < 5)\n return context.error(`Expected at least 4 arguments, but found only ${args.length - 1}.`);\n if (args.length % 2 !== 1)\n return context.error(`Expected an even number of arguments.`);\n\n let inputType;\n let outputType;\n if (context.expectedType && context.expectedType.kind !== 'value') {\n outputType = context.expectedType;\n }\n const cases = {};\n const outputs = [];\n for (let i = 2; i < args.length - 1; i += 2) {\n let labels = args[i];\n const value = args[i + 1];\n\n if (!Array.isArray(labels)) {\n labels = [labels];\n }\n\n const labelContext = context.concat(i);\n if (labels.length === 0) {\n return labelContext.error('Expected at least one branch label.');\n }\n\n for (const label of labels) {\n if (typeof label !== 'number' && typeof label !== 'string') {\n return labelContext.error(`Branch labels must be numbers or strings.`);\n } else if (typeof label === 'number' && Math.abs(label) > Number.MAX_SAFE_INTEGER) {\n return labelContext.error(`Branch labels must be integers no larger than ${Number.MAX_SAFE_INTEGER}.`);\n\n } else if (typeof label === 'number' && Math.floor(label) !== label) {\n return labelContext.error(`Numeric branch labels must be integer values.`);\n\n } else if (!inputType) {\n inputType = typeOf(label);\n } else if (labelContext.checkSubtype(inputType, typeOf(label))) {\n return null;\n }\n\n if (typeof cases[String(label)] !== 'undefined') {\n return labelContext.error('Branch labels must be unique.');\n }\n\n cases[String(label)] = outputs.length;\n }\n\n const result = context.parse(value, i, outputType);\n if (!result) return null;\n outputType = outputType || result.type;\n outputs.push(result);\n }\n\n const input = context.parse(args[1], 1, ValueType);\n if (!input) return null;\n\n const otherwise = context.parse(args[args.length - 1], args.length - 1, outputType);\n if (!otherwise) return null;\n\n assert(inputType && outputType);\n\n if (input.type.kind !== 'value' && context.concat(1).checkSubtype((inputType: any), input.type)) {\n return null;\n }\n\n return new Match((inputType: any), (outputType: any), input, cases, outputs, otherwise);\n }\n\n evaluate(ctx: EvaluationContext): any {\n const input = (this.input.evaluate(ctx): any);\n const output = (typeOf(input) === this.inputType && this.outputs[this.cases[input]]) || this.otherwise;\n return output.evaluate(ctx);\n }\n\n eachChild(fn: (_: Expression) => void) {\n fn(this.input);\n this.outputs.forEach(fn);\n fn(this.otherwise);\n }\n\n outputDefined(): boolean {\n return this.outputs.every(out => out.outputDefined()) && this.otherwise.outputDefined();\n }\n\n serialize(): SerializedExpression {\n const serialized = [\"match\", this.input.serialize()];\n\n // Sort so serialization has an arbitrary defined order, even though\n // branch order doesn't affect evaluation\n const sortedLabels = Object.keys(this.cases).sort();\n\n // Group branches by unique match expression to support condensed\n // serializations of the form [case1, case2, ...] -> matchExpression\n const groupedByOutput: Array<[number, Array]> = [];\n const outputLookup: {[index: number]: number} = {}; // lookup index into groupedByOutput for a given output expression\n for (const label of sortedLabels) {\n const outputIndex = outputLookup[this.cases[label]];\n if (outputIndex === undefined) {\n // First time seeing this output, add it to the end of the grouped list\n outputLookup[this.cases[label]] = groupedByOutput.length;\n groupedByOutput.push([this.cases[label], [label]]);\n } else {\n // We've seen this expression before, add the label to that output's group\n groupedByOutput[outputIndex][1].push(label);\n }\n }\n\n const coerceLabel = (label) => this.inputType.kind === 'number' ? Number(label) : label;\n\n for (const [outputIndex, labels] of groupedByOutput) {\n if (labels.length === 1) {\n // Only a single label matches this output expression\n serialized.push(coerceLabel(labels[0]));\n } else {\n // Array of literal labels pointing to this output expression\n serialized.push(labels.map(coerceLabel));\n }\n serialized.push(this.outputs[outputIndex].serialize());\n }\n serialized.push(this.otherwise.serialize());\n return serialized;\n }\n}\n\nexport default Match;\n","// @flow\n\nimport assert from 'assert';\n\nimport {BooleanType} from '../types.js';\n\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type {Type} from '../types.js';\n\ntype Branches = Array<[Expression, Expression]>;\n\nclass Case implements Expression {\n type: Type;\n\n branches: Branches;\n otherwise: Expression;\n\n constructor(type: Type, branches: Branches, otherwise: Expression) {\n this.type = type;\n this.branches = branches;\n this.otherwise = otherwise;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Case {\n if (args.length < 4)\n return context.error(`Expected at least 3 arguments, but found only ${args.length - 1}.`);\n if (args.length % 2 !== 0)\n return context.error(`Expected an odd number of arguments.`);\n\n let outputType: ?Type;\n if (context.expectedType && context.expectedType.kind !== 'value') {\n outputType = context.expectedType;\n }\n\n const branches = [];\n for (let i = 1; i < args.length - 1; i += 2) {\n const test = context.parse(args[i], i, BooleanType);\n if (!test) return null;\n\n const result = context.parse(args[i + 1], i + 1, outputType);\n if (!result) return null;\n\n branches.push([test, result]);\n\n outputType = outputType || result.type;\n }\n\n const otherwise = context.parse(args[args.length - 1], args.length - 1, outputType);\n if (!otherwise) return null;\n\n assert(outputType);\n return new Case((outputType: any), branches, otherwise);\n }\n\n evaluate(ctx: EvaluationContext): any {\n for (const [test, expression] of this.branches) {\n if (test.evaluate(ctx)) {\n return expression.evaluate(ctx);\n }\n }\n return this.otherwise.evaluate(ctx);\n }\n\n eachChild(fn: (_: Expression) => void) {\n for (const [test, expression] of this.branches) {\n fn(test);\n fn(expression);\n }\n fn(this.otherwise);\n }\n\n outputDefined(): boolean {\n return this.branches.every(([_, out]) => out.outputDefined()) && this.otherwise.outputDefined();\n }\n\n serialize(): SerializedExpression {\n const serialized = [\"case\"];\n this.eachChild(child => { serialized.push(child.serialize()); });\n return serialized;\n }\n}\n\nexport default Case;\n","// @flow\n\nimport {ValueType, NumberType, StringType, array, toString, isValidType, isValidNativeType} from '../types.js';\nimport RuntimeError from '../runtime_error.js';\nimport {typeOf} from '../values.js';\n\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type {Type} from '../types.js';\n\nclass Slice implements Expression {\n type: Type;\n input: Expression;\n beginIndex: Expression;\n endIndex: ?Expression;\n\n constructor(type: Type, input: Expression, beginIndex: Expression, endIndex?: Expression) {\n this.type = type;\n this.input = input;\n this.beginIndex = beginIndex;\n this.endIndex = endIndex;\n\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Slice {\n if (args.length <= 2 || args.length >= 5) {\n return context.error(`Expected 3 or 4 arguments, but found ${args.length - 1} instead.`);\n }\n\n const input = context.parse(args[1], 1, ValueType);\n const beginIndex = context.parse(args[2], 2, NumberType);\n\n if (!input || !beginIndex) return null;\n\n if (!isValidType(input.type, [array(ValueType), StringType, ValueType])) {\n return context.error(`Expected first argument to be of type array or string, but found ${toString(input.type)} instead`);\n }\n\n if (args.length === 4) {\n const endIndex = context.parse(args[3], 3, NumberType);\n if (!endIndex) return null;\n return new Slice(input.type, input, beginIndex, endIndex);\n } else {\n return new Slice(input.type, input, beginIndex);\n }\n }\n\n evaluate(ctx: EvaluationContext): any {\n const input = (this.input.evaluate(ctx): any);\n const beginIndex = (this.beginIndex.evaluate(ctx): number);\n\n if (!isValidNativeType(input, ['string', 'array'])) {\n throw new RuntimeError(`Expected first argument to be of type array or string, but found ${toString(typeOf(input))} instead.`);\n }\n\n if (this.endIndex) {\n const endIndex = (this.endIndex.evaluate(ctx): number);\n return input.slice(beginIndex, endIndex);\n }\n\n return input.slice(beginIndex);\n }\n\n eachChild(fn: (_: Expression) => void) {\n fn(this.input);\n fn(this.beginIndex);\n if (this.endIndex) {\n fn(this.endIndex);\n }\n }\n\n outputDefined(): boolean {\n return false;\n }\n\n serialize(): SerializedExpression {\n if (this.endIndex != null && this.endIndex !== undefined) {\n const endIndex = this.endIndex.serialize();\n return [\"slice\", this.input.serialize(), this.beginIndex.serialize(), endIndex];\n }\n return [\"slice\", this.input.serialize(), this.beginIndex.serialize()];\n }\n}\n\nexport default Slice;\n","// @flow\n\nimport {toString, ValueType, BooleanType, CollatorType} from '../types.js';\nimport Assertion from './assertion.js';\nimport {typeOf} from '../values.js';\nimport RuntimeError from '../runtime_error.js';\n\nimport type {Expression, SerializedExpression, ExpressionRegistration} from '../expression.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type {Type} from '../types.js';\n\ntype ComparisonOperator = '==' | '!=' | '<' | '>' | '<=' | '>=' ;\n\nfunction isComparableType(op: ComparisonOperator, type: Type) {\n if (op === '==' || op === '!=') {\n // equality operator\n return type.kind === 'boolean' ||\n type.kind === 'string' ||\n type.kind === 'number' ||\n type.kind === 'null' ||\n type.kind === 'value';\n } else {\n // ordering operator\n return type.kind === 'string' ||\n type.kind === 'number' ||\n type.kind === 'value';\n }\n}\n\nfunction eq(ctx: EvaluationContext, a: any, b: any): boolean { return a === b; }\nfunction neq(ctx: EvaluationContext, a: any, b: any): boolean { return a !== b; }\nfunction lt(ctx: EvaluationContext, a: any, b: any): boolean { return a < b; }\nfunction gt(ctx: EvaluationContext, a: any, b: any): boolean { return a > b; }\nfunction lteq(ctx: EvaluationContext, a: any, b: any): boolean { return a <= b; }\nfunction gteq(ctx: EvaluationContext, a: any, b: any): boolean { return a >= b; }\n\nfunction eqCollate(ctx: EvaluationContext, a: any, b: any, c: any): boolean { return c.compare(a, b) === 0; }\nfunction neqCollate(ctx: EvaluationContext, a: any, b: any, c: any): boolean { return !eqCollate(ctx, a, b, c); }\nfunction ltCollate(ctx: EvaluationContext, a: any, b: any, c: any): boolean { return c.compare(a, b) < 0; }\nfunction gtCollate(ctx: EvaluationContext, a: any, b: any, c: any): boolean { return c.compare(a, b) > 0; }\nfunction lteqCollate(ctx: EvaluationContext, a: any, b: any, c: any): boolean { return c.compare(a, b) <= 0; }\nfunction gteqCollate(ctx: EvaluationContext, a: any, b: any, c: any): boolean { return c.compare(a, b) >= 0; }\n\n/**\n * Special form for comparison operators, implementing the signatures:\n * - (T, T, ?Collator) => boolean\n * - (T, value, ?Collator) => boolean\n * - (value, T, ?Collator) => boolean\n *\n * For inequalities, T must be either value, string, or number. For ==/!=, it\n * can also be boolean or null.\n *\n * Equality semantics are equivalent to Javascript's strict equality (===/!==)\n * -- i.e., when the arguments' types don't match, == evaluates to false, != to\n * true.\n *\n * When types don't match in an ordering comparison, a runtime error is thrown.\n *\n * @private\n */\nfunction makeComparison(op: ComparisonOperator, compareBasic: (EvaluationContext, any, any) => boolean, compareWithCollator: (EvaluationContext, any, any, any) => boolean): ExpressionRegistration {\n const isOrderComparison = op !== '==' && op !== '!=';\n\n return class Comparison implements Expression {\n type: Type;\n lhs: Expression;\n rhs: Expression;\n collator: ?Expression;\n hasUntypedArgument: boolean;\n\n constructor(lhs: Expression, rhs: Expression, collator: ?Expression) {\n this.type = BooleanType;\n this.lhs = lhs;\n this.rhs = rhs;\n this.collator = collator;\n this.hasUntypedArgument = lhs.type.kind === 'value' || rhs.type.kind === 'value';\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Expression {\n if (args.length !== 3 && args.length !== 4)\n return context.error(`Expected two or three arguments.`);\n\n const op: ComparisonOperator = (args[0]: any);\n\n let lhs = context.parse(args[1], 1, ValueType);\n if (!lhs) return null;\n if (!isComparableType(op, lhs.type)) {\n return context.concat(1).error(`\"${op}\" comparisons are not supported for type '${toString(lhs.type)}'.`);\n }\n let rhs = context.parse(args[2], 2, ValueType);\n if (!rhs) return null;\n if (!isComparableType(op, rhs.type)) {\n return context.concat(2).error(`\"${op}\" comparisons are not supported for type '${toString(rhs.type)}'.`);\n }\n\n if (\n lhs.type.kind !== rhs.type.kind &&\n lhs.type.kind !== 'value' &&\n rhs.type.kind !== 'value'\n ) {\n return context.error(`Cannot compare types '${toString(lhs.type)}' and '${toString(rhs.type)}'.`);\n }\n\n if (isOrderComparison) {\n // typing rules specific to less/greater than operators\n if (lhs.type.kind === 'value' && rhs.type.kind !== 'value') {\n // (value, T)\n lhs = new Assertion(rhs.type, [lhs]);\n } else if (lhs.type.kind !== 'value' && rhs.type.kind === 'value') {\n // (T, value)\n rhs = new Assertion(lhs.type, [rhs]);\n }\n }\n\n let collator = null;\n if (args.length === 4) {\n if (\n lhs.type.kind !== 'string' &&\n rhs.type.kind !== 'string' &&\n lhs.type.kind !== 'value' &&\n rhs.type.kind !== 'value'\n ) {\n return context.error(`Cannot use collator to compare non-string types.`);\n }\n collator = context.parse(args[3], 3, CollatorType);\n if (!collator) return null;\n }\n\n return new Comparison(lhs, rhs, collator);\n }\n\n evaluate(ctx: EvaluationContext): boolean {\n const lhs = this.lhs.evaluate(ctx);\n const rhs = this.rhs.evaluate(ctx);\n\n if (isOrderComparison && this.hasUntypedArgument) {\n const lt = typeOf(lhs);\n const rt = typeOf(rhs);\n // check that type is string or number, and equal\n if (lt.kind !== rt.kind || !(lt.kind === 'string' || lt.kind === 'number')) {\n throw new RuntimeError(`Expected arguments for \"${op}\" to be (string, string) or (number, number), but found (${lt.kind}, ${rt.kind}) instead.`);\n }\n }\n\n if (this.collator && !isOrderComparison && this.hasUntypedArgument) {\n const lt = typeOf(lhs);\n const rt = typeOf(rhs);\n if (lt.kind !== 'string' || rt.kind !== 'string') {\n return compareBasic(ctx, lhs, rhs);\n }\n }\n\n return this.collator ?\n compareWithCollator(ctx, lhs, rhs, this.collator.evaluate(ctx)) :\n compareBasic(ctx, lhs, rhs);\n }\n\n eachChild(fn: (_: Expression) => void) {\n fn(this.lhs);\n fn(this.rhs);\n if (this.collator) {\n fn(this.collator);\n }\n }\n\n outputDefined(): boolean {\n return true;\n }\n\n serialize(): SerializedExpression {\n const serialized = [op];\n this.eachChild(child => { serialized.push(child.serialize()); });\n return serialized;\n }\n };\n}\n\nexport const Equals: $Call = makeComparison('==', eq, eqCollate);\nexport const NotEquals: $Call = makeComparison('<', lt, ltCollate);\nexport const GreaterThan: $Call', typeof gt, typeof gtCollate> = makeComparison('>', gt, gtCollate);\nexport const LessThanOrEqual: $Call=', typeof gteq, typeof gteqCollate> = makeComparison('>=', gteq, gteqCollate);\n","// @flow\n\nimport {StringType, NumberType} from '../types.js';\n\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type {Type} from '../types.js';\n\ndeclare var Intl: {\n NumberFormat: Class\n};\n\ndeclare class Intl$NumberFormat {\n constructor (\n locales?: string | string[],\n options?: NumberFormatOptions\n ): Intl$NumberFormat;\n\n static (\n locales?: string | string[],\n options?: NumberFormatOptions\n ): Intl$NumberFormat;\n\n format(a: number): string;\n\n resolvedOptions(): any;\n}\n\ntype NumberFormatOptions = {\n style?: 'decimal' | 'currency' | 'percent';\n currency?: null | string;\n minimumFractionDigits?: null | string;\n maximumFractionDigits?: null | string;\n};\n\nexport default class NumberFormat implements Expression {\n type: Type;\n number: Expression;\n locale: Expression | null; // BCP 47 language tag\n currency: Expression | null; // ISO 4217 currency code, required if style=currency\n minFractionDigits: Expression | null; // Default 0\n maxFractionDigits: Expression | null; // Default 3\n\n constructor(number: Expression,\n locale: Expression | null,\n currency: Expression | null,\n minFractionDigits: Expression | null,\n maxFractionDigits: Expression | null) {\n this.type = StringType;\n this.number = number;\n this.locale = locale;\n this.currency = currency;\n this.minFractionDigits = minFractionDigits;\n this.maxFractionDigits = maxFractionDigits;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Expression {\n if (args.length !== 3)\n return context.error(`Expected two arguments.`);\n\n const number = context.parse(args[1], 1, NumberType);\n if (!number) return null;\n\n const options = (args[2]: any);\n if (typeof options !== \"object\" || Array.isArray(options))\n return context.error(`NumberFormat options argument must be an object.`);\n\n let locale = null;\n if (options['locale']) {\n locale = context.parse(options['locale'], 1, StringType);\n if (!locale) return null;\n }\n\n let currency = null;\n if (options['currency']) {\n currency = context.parse(options['currency'], 1, StringType);\n if (!currency) return null;\n }\n\n let minFractionDigits = null;\n if (options['min-fraction-digits']) {\n minFractionDigits = context.parse(options['min-fraction-digits'], 1, NumberType);\n if (!minFractionDigits) return null;\n }\n\n let maxFractionDigits = null;\n if (options['max-fraction-digits']) {\n maxFractionDigits = context.parse(options['max-fraction-digits'], 1, NumberType);\n if (!maxFractionDigits) return null;\n }\n\n return new NumberFormat(number, locale, currency, minFractionDigits, maxFractionDigits);\n }\n\n evaluate(ctx: EvaluationContext): string {\n return new Intl.NumberFormat(this.locale ? this.locale.evaluate(ctx) : [],\n {\n style: this.currency ? \"currency\" : \"decimal\",\n currency: this.currency ? this.currency.evaluate(ctx) : undefined,\n minimumFractionDigits: this.minFractionDigits ? this.minFractionDigits.evaluate(ctx) : undefined,\n maximumFractionDigits: this.maxFractionDigits ? this.maxFractionDigits.evaluate(ctx) : undefined,\n }).format(this.number.evaluate(ctx));\n }\n\n eachChild(fn: (_: Expression) => void) {\n fn(this.number);\n if (this.locale) {\n fn(this.locale);\n }\n if (this.currency) {\n fn(this.currency);\n }\n if (this.minFractionDigits) {\n fn(this.minFractionDigits);\n }\n if (this.maxFractionDigits) {\n fn(this.maxFractionDigits);\n }\n }\n\n outputDefined(): boolean {\n return false;\n }\n\n serialize(): SerializedExpression {\n const options = {};\n if (this.locale) {\n options['locale'] = this.locale.serialize();\n }\n if (this.currency) {\n options['currency'] = this.currency.serialize();\n }\n if (this.minFractionDigits) {\n options['min-fraction-digits'] = this.minFractionDigits.serialize();\n }\n if (this.maxFractionDigits) {\n options['max-fraction-digits'] = this.maxFractionDigits.serialize();\n }\n return [\"number-format\", this.number.serialize(), options];\n }\n}\n","// @flow\n\nimport {NumberType, toString} from '../types.js';\n\nimport {typeOf} from '../values.js';\nimport RuntimeError from '../runtime_error.js';\n\nimport type {Expression, SerializedExpression} from '../expression.js';\nimport type ParsingContext from '../parsing_context.js';\nimport type EvaluationContext from '../evaluation_context.js';\nimport type {Type} from '../types.js';\n\nclass Length implements Expression {\n type: Type;\n input: Expression;\n\n constructor(input: Expression) {\n this.type = NumberType;\n this.input = input;\n }\n\n static parse(args: $ReadOnlyArray, context: ParsingContext): ?Length {\n if (args.length !== 2)\n return context.error(`Expected 1 argument, but found ${args.length - 1} instead.`);\n\n const input = context.parse(args[1], 1);\n if (!input) return null;\n\n if (input.type.kind !== 'array' && input.type.kind !== 'string' && input.type.kind !== 'value')\n return context.error(`Expected argument of type string or array, but found ${toString(input.type)} instead.`);\n\n return new Length(input);\n }\n\n evaluate(ctx: EvaluationContext): any | number {\n const input = this.input.evaluate(ctx);\n if (typeof input === 'string') {\n return input.length;\n } else if (Array.isArray(input)) {\n return input.length;\n } else {\n throw new RuntimeError(`Expected value to be of type string or array, but found ${toString(typeOf(input))} instead.`);\n }\n }\n\n eachChild(fn: (_: Expression) => void) {\n fn(this.input);\n }\n\n outputDefined(): boolean {\n return false;\n }\n\n serialize(): SerializedExpression {\n const serialized = [\"length\"];\n this.eachChild(child => { serialized.push(child.serialize()); });\n return serialized;\n }\n}\n\nexport default Length;\n","// @flow\n\nimport {\n type Type,\n NumberType,\n StringType,\n BooleanType,\n ColorType,\n ObjectType,\n ValueType,\n ErrorType,\n CollatorType,\n array,\n toString as typeToString\n} from '../types.js';\n\nimport {typeOf, Color, validateRGBA, toString as valueToString} from '../values.js';\nimport CompoundExpression from '../compound_expression.js';\nimport RuntimeError from '../runtime_error.js';\nimport Let from './let.js';\nimport Var from './var.js';\nimport Literal from './literal.js';\nimport Assertion from './assertion.js';\nimport Coercion from './coercion.js';\nimport At from './at.js';\nimport In from './in.js';\nimport IndexOf from './index_of.js';\nimport Match from './match.js';\nimport Case from './case.js';\nimport Slice from './slice.js';\nimport Step from './step.js';\nimport Interpolate from './interpolate.js';\nimport Coalesce from './coalesce.js';\nimport {\n Equals,\n NotEquals,\n LessThan,\n GreaterThan,\n LessThanOrEqual,\n GreaterThanOrEqual\n} from './comparison.js';\nimport CollatorExpression from './collator.js';\nimport NumberFormat from './number_format.js';\nimport FormatExpression from './format.js';\nimport ImageExpression from './image.js';\nimport Length from './length.js';\nimport Within from './within.js';\n\nimport type {Varargs} from '../compound_expression.js';\nimport type {ExpressionRegistry} from '../expression.js';\n\nconst expressions: ExpressionRegistry = {\n // special forms\n '==': Equals,\n '!=': NotEquals,\n '>': GreaterThan,\n '<': LessThan,\n '>=': GreaterThanOrEqual,\n '<=': LessThanOrEqual,\n 'array': Assertion,\n 'at': At,\n 'boolean': Assertion,\n 'case': Case,\n 'coalesce': Coalesce,\n 'collator': CollatorExpression,\n 'format': FormatExpression,\n 'image': ImageExpression,\n 'in': In,\n 'index-of': IndexOf,\n 'interpolate': Interpolate,\n 'interpolate-hcl': Interpolate,\n 'interpolate-lab': Interpolate,\n 'length': Length,\n 'let': Let,\n 'literal': Literal,\n 'match': Match,\n 'number': Assertion,\n 'number-format': NumberFormat,\n 'object': Assertion,\n 'slice': Slice,\n 'step': Step,\n 'string': Assertion,\n 'to-boolean': Coercion,\n 'to-color': Coercion,\n 'to-number': Coercion,\n 'to-string': Coercion,\n 'var': Var,\n 'within': Within\n};\n\nfunction rgba(ctx, [r, g, b, a]) {\n r = r.evaluate(ctx);\n g = g.evaluate(ctx);\n b = b.evaluate(ctx);\n const alpha = a ? a.evaluate(ctx) : 1;\n const error = validateRGBA(r, g, b, alpha);\n if (error) throw new RuntimeError(error);\n return new Color(r / 255 * alpha, g / 255 * alpha, b / 255 * alpha, alpha);\n}\n\nfunction has(key, obj) {\n return key in obj;\n}\n\nfunction get(key, obj) {\n const v = obj[key];\n return typeof v === 'undefined' ? null : v;\n}\n\nfunction binarySearch(v, a, i, j) {\n while (i <= j) {\n const m = (i + j) >> 1;\n if (a[m] === v)\n return true;\n if (a[m] > v)\n j = m - 1;\n else\n i = m + 1;\n }\n return false;\n}\n\nfunction varargs(type: Type): Varargs {\n return {type};\n}\n\nCompoundExpression.register(expressions, {\n 'error': [\n ErrorType,\n [StringType],\n (ctx, [v]) => { throw new RuntimeError(v.evaluate(ctx)); }\n ],\n 'typeof': [\n StringType,\n [ValueType],\n (ctx, [v]) => typeToString(typeOf(v.evaluate(ctx)))\n ],\n 'to-rgba': [\n array(NumberType, 4),\n [ColorType],\n (ctx, [v]) => {\n return v.evaluate(ctx).toArray();\n }\n ],\n 'rgb': [\n ColorType,\n [NumberType, NumberType, NumberType],\n rgba\n ],\n 'rgba': [\n ColorType,\n [NumberType, NumberType, NumberType, NumberType],\n rgba\n ],\n 'has': {\n type: BooleanType,\n overloads: [\n [\n [StringType],\n (ctx, [key]) => has(key.evaluate(ctx), ctx.properties())\n ], [\n [StringType, ObjectType],\n (ctx, [key, obj]) => has(key.evaluate(ctx), obj.evaluate(ctx))\n ]\n ]\n },\n 'get': {\n type: ValueType,\n overloads: [\n [\n [StringType],\n (ctx, [key]) => get(key.evaluate(ctx), ctx.properties())\n ], [\n [StringType, ObjectType],\n (ctx, [key, obj]) => get(key.evaluate(ctx), obj.evaluate(ctx))\n ]\n ]\n },\n 'feature-state': [\n ValueType,\n [StringType],\n (ctx, [key]) => get(key.evaluate(ctx), ctx.featureState || {})\n ],\n 'properties': [\n ObjectType,\n [],\n (ctx) => ctx.properties()\n ],\n 'geometry-type': [\n StringType,\n [],\n (ctx) => ctx.geometryType()\n ],\n 'id': [\n ValueType,\n [],\n (ctx) => ctx.id()\n ],\n 'zoom': [\n NumberType,\n [],\n (ctx) => ctx.globals.zoom\n ],\n 'pitch': [\n NumberType,\n [],\n (ctx) => ctx.globals.pitch || 0\n ],\n 'distance-from-center': [\n NumberType,\n [],\n (ctx) => ctx.distanceFromCenter()\n ],\n 'heatmap-density': [\n NumberType,\n [],\n (ctx) => ctx.globals.heatmapDensity || 0\n ],\n 'line-progress': [\n NumberType,\n [],\n (ctx) => ctx.globals.lineProgress || 0\n ],\n 'sky-radial-progress': [\n NumberType,\n [],\n (ctx) => ctx.globals.skyRadialProgress || 0\n ],\n 'accumulated': [\n ValueType,\n [],\n (ctx) => ctx.globals.accumulated === undefined ? null : ctx.globals.accumulated\n ],\n '+': [\n NumberType,\n varargs(NumberType),\n (ctx, args) => {\n let result = 0;\n for (const arg of args) {\n result += arg.evaluate(ctx);\n }\n return result;\n }\n ],\n '*': [\n NumberType,\n varargs(NumberType),\n (ctx, args) => {\n let result = 1;\n for (const arg of args) {\n result *= arg.evaluate(ctx);\n }\n return result;\n }\n ],\n '-': {\n type: NumberType,\n overloads: [\n [\n [NumberType, NumberType],\n (ctx, [a, b]) => a.evaluate(ctx) - b.evaluate(ctx)\n ], [\n [NumberType],\n (ctx, [a]) => -a.evaluate(ctx)\n ]\n ]\n },\n '/': [\n NumberType,\n [NumberType, NumberType],\n (ctx, [a, b]) => a.evaluate(ctx) / b.evaluate(ctx)\n ],\n '%': [\n NumberType,\n [NumberType, NumberType],\n (ctx, [a, b]) => a.evaluate(ctx) % b.evaluate(ctx)\n ],\n 'ln2': [\n NumberType,\n [],\n () => Math.LN2\n ],\n 'pi': [\n NumberType,\n [],\n () => Math.PI\n ],\n 'e': [\n NumberType,\n [],\n () => Math.E\n ],\n '^': [\n NumberType,\n [NumberType, NumberType],\n (ctx, [b, e]) => Math.pow(b.evaluate(ctx), e.evaluate(ctx))\n ],\n 'sqrt': [\n NumberType,\n [NumberType],\n (ctx, [x]) => Math.sqrt(x.evaluate(ctx))\n ],\n 'log10': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.log(n.evaluate(ctx)) / Math.LN10\n ],\n 'ln': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.log(n.evaluate(ctx))\n ],\n 'log2': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.log(n.evaluate(ctx)) / Math.LN2\n ],\n 'sin': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.sin(n.evaluate(ctx))\n ],\n 'cos': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.cos(n.evaluate(ctx))\n ],\n 'tan': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.tan(n.evaluate(ctx))\n ],\n 'asin': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.asin(n.evaluate(ctx))\n ],\n 'acos': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.acos(n.evaluate(ctx))\n ],\n 'atan': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.atan(n.evaluate(ctx))\n ],\n 'min': [\n NumberType,\n varargs(NumberType),\n (ctx, args) => Math.min(...args.map(arg => arg.evaluate(ctx)))\n ],\n 'max': [\n NumberType,\n varargs(NumberType),\n (ctx, args) => Math.max(...args.map(arg => arg.evaluate(ctx)))\n ],\n 'abs': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.abs(n.evaluate(ctx))\n ],\n 'round': [\n NumberType,\n [NumberType],\n (ctx, [n]) => {\n const v = n.evaluate(ctx);\n // Javascript's Math.round() rounds towards +Infinity for halfway\n // values, even when they're negative. It's more common to round\n // away from 0 (e.g., this is what python and C++ do)\n return v < 0 ? -Math.round(-v) : Math.round(v);\n }\n ],\n 'floor': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.floor(n.evaluate(ctx))\n ],\n 'ceil': [\n NumberType,\n [NumberType],\n (ctx, [n]) => Math.ceil(n.evaluate(ctx))\n ],\n 'filter-==': [\n BooleanType,\n [StringType, ValueType],\n (ctx, [k, v]) => ctx.properties()[(k: any).value] === (v: any).value\n ],\n 'filter-id-==': [\n BooleanType,\n [ValueType],\n (ctx, [v]) => ctx.id() === (v: any).value\n ],\n 'filter-type-==': [\n BooleanType,\n [StringType],\n (ctx, [v]) => ctx.geometryType() === (v: any).value\n ],\n 'filter-<': [\n BooleanType,\n [StringType, ValueType],\n (ctx, [k, v]) => {\n const a = ctx.properties()[(k: any).value];\n const b = (v: any).value;\n return typeof a === typeof b && a < b;\n }\n ],\n 'filter-id-<': [\n BooleanType,\n [ValueType],\n (ctx, [v]) => {\n const a = ctx.id();\n const b = (v: any).value;\n return typeof a === typeof b && a < b;\n }\n ],\n 'filter->': [\n BooleanType,\n [StringType, ValueType],\n (ctx, [k, v]) => {\n const a = ctx.properties()[(k: any).value];\n const b = (v: any).value;\n return typeof a === typeof b && a > b;\n }\n ],\n 'filter-id->': [\n BooleanType,\n [ValueType],\n (ctx, [v]) => {\n const a = ctx.id();\n const b = (v: any).value;\n return typeof a === typeof b && a > b;\n }\n ],\n 'filter-<=': [\n BooleanType,\n [StringType, ValueType],\n (ctx, [k, v]) => {\n const a = ctx.properties()[(k: any).value];\n const b = (v: any).value;\n return typeof a === typeof b && a <= b;\n }\n ],\n 'filter-id-<=': [\n BooleanType,\n [ValueType],\n (ctx, [v]) => {\n const a = ctx.id();\n const b = (v: any).value;\n return typeof a === typeof b && a <= b;\n }\n ],\n 'filter->=': [\n BooleanType,\n [StringType, ValueType],\n (ctx, [k, v]) => {\n const a = ctx.properties()[(k: any).value];\n const b = (v: any).value;\n return typeof a === typeof b && a >= b;\n }\n ],\n 'filter-id->=': [\n BooleanType,\n [ValueType],\n (ctx, [v]) => {\n const a = ctx.id();\n const b = (v: any).value;\n return typeof a === typeof b && a >= b;\n }\n ],\n 'filter-has': [\n BooleanType,\n [ValueType],\n (ctx, [k]) => (k: any).value in ctx.properties()\n ],\n 'filter-has-id': [\n BooleanType,\n [],\n (ctx) => (ctx.id() !== null && ctx.id() !== undefined)\n ],\n 'filter-type-in': [\n BooleanType,\n [array(StringType)],\n (ctx, [v]) => (v: any).value.indexOf(ctx.geometryType()) >= 0\n ],\n 'filter-id-in': [\n BooleanType,\n [array(ValueType)],\n (ctx, [v]) => (v: any).value.indexOf(ctx.id()) >= 0\n ],\n 'filter-in-small': [\n BooleanType,\n [StringType, array(ValueType)],\n // assumes v is an array literal\n (ctx, [k, v]) => (v: any).value.indexOf(ctx.properties()[(k: any).value]) >= 0\n ],\n 'filter-in-large': [\n BooleanType,\n [StringType, array(ValueType)],\n // assumes v is a array literal with values sorted in ascending order and of a single type\n (ctx, [k, v]) => binarySearch(ctx.properties()[(k: any).value], (v: any).value, 0, (v: any).value.length - 1)\n ],\n 'all': {\n type: BooleanType,\n overloads: [\n [\n [BooleanType, BooleanType],\n (ctx, [a, b]) => a.evaluate(ctx) && b.evaluate(ctx)\n ],\n [\n varargs(BooleanType),\n (ctx, args) => {\n for (const arg of args) {\n if (!arg.evaluate(ctx))\n return false;\n }\n return true;\n }\n ]\n ]\n },\n 'any': {\n type: BooleanType,\n overloads: [\n [\n [BooleanType, BooleanType],\n (ctx, [a, b]) => a.evaluate(ctx) || b.evaluate(ctx)\n ],\n [\n varargs(BooleanType),\n (ctx, args) => {\n for (const arg of args) {\n if (arg.evaluate(ctx))\n return true;\n }\n return false;\n }\n ]\n ]\n },\n '!': [\n BooleanType,\n [BooleanType],\n (ctx, [b]) => !b.evaluate(ctx)\n ],\n 'is-supported-script': [\n BooleanType,\n [StringType],\n // At parse time this will always return true, so we need to exclude this expression with isGlobalPropertyConstant\n (ctx, [s]) => {\n const isSupportedScript = ctx.globals && ctx.globals.isSupportedScript;\n if (isSupportedScript) {\n return isSupportedScript(s.evaluate(ctx));\n }\n return true;\n }\n ],\n 'upcase': [\n StringType,\n [StringType],\n (ctx, [s]) => s.evaluate(ctx).toUpperCase()\n ],\n 'downcase': [\n StringType,\n [StringType],\n (ctx, [s]) => s.evaluate(ctx).toLowerCase()\n ],\n 'concat': [\n StringType,\n varargs(ValueType),\n (ctx, args) => args.map(arg => valueToString(arg.evaluate(ctx))).join('')\n ],\n 'resolved-locale': [\n StringType,\n [CollatorType],\n (ctx, [collator]) => collator.evaluate(ctx).resolvedLocale()\n ]\n});\n\nexport default expressions;\n","// @flow\n\n/**\n * A type used for returning and propagating errors. The first element of the union\n * represents success and contains a value, and the second represents an error and\n * contains an error value.\n * @private\n */\nexport type Result =\n | {| result: 'success', value: T |}\n | {| result: 'error', value: E |};\n\nexport function success(value: T): Result {\n return {result: 'success', value};\n}\n\nexport function error(value: E): Result {\n return {result: 'error', value};\n}\n","\nimport * as colorSpaces from '../util/color_spaces.js';\nimport Color from '../util/color.js';\nimport extend from '../util/extend.js';\nimport getType from '../util/get_type.js';\nimport * as interpolate from '../util/interpolate.js';\nimport Interpolate from '../expression/definitions/interpolate.js';\nimport Formatted from '../expression/types/formatted.js';\nimport ResolvedImage from '../expression/types/resolved_image.js';\nimport {supportsInterpolation} from '../util/properties.js';\nimport {findStopLessThanOrEqualTo} from '../expression/stops.js';\n\nexport function isFunction(value) {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction identityFunction(x) {\n return x;\n}\n\nexport function createFunction(parameters, propertySpec) {\n const isColor = propertySpec.type === 'color';\n const zoomAndFeatureDependent = parameters.stops && typeof parameters.stops[0][0] === 'object';\n const featureDependent = zoomAndFeatureDependent || parameters.property !== undefined;\n const zoomDependent = zoomAndFeatureDependent || !featureDependent;\n const type = parameters.type || (supportsInterpolation(propertySpec) ? 'exponential' : 'interval');\n\n if (isColor) {\n parameters = extend({}, parameters);\n\n if (parameters.stops) {\n parameters.stops = parameters.stops.map((stop) => {\n return [stop[0], Color.parse(stop[1])];\n });\n }\n\n if (parameters.default) {\n parameters.default = Color.parse(parameters.default);\n } else {\n parameters.default = Color.parse(propertySpec.default);\n }\n }\n\n if (parameters.colorSpace && parameters.colorSpace !== 'rgb' && !colorSpaces[parameters.colorSpace]) { // eslint-disable-line import/namespace\n throw new Error(`Unknown color space: ${parameters.colorSpace}`);\n }\n\n let innerFun;\n let hashedStops;\n let categoricalKeyType;\n if (type === 'exponential') {\n innerFun = evaluateExponentialFunction;\n } else if (type === 'interval') {\n innerFun = evaluateIntervalFunction;\n } else if (type === 'categorical') {\n innerFun = evaluateCategoricalFunction;\n\n // For categorical functions, generate an Object as a hashmap of the stops for fast searching\n hashedStops = Object.create(null);\n for (const stop of parameters.stops) {\n hashedStops[stop[0]] = stop[1];\n }\n\n // Infer key type based on first stop key-- used to encforce strict type checking later\n categoricalKeyType = typeof parameters.stops[0][0];\n\n } else if (type === 'identity') {\n innerFun = evaluateIdentityFunction;\n } else {\n throw new Error(`Unknown function type \"${type}\"`);\n }\n\n if (zoomAndFeatureDependent) {\n const featureFunctions = {};\n const zoomStops = [];\n for (let s = 0; s < parameters.stops.length; s++) {\n const stop = parameters.stops[s];\n const zoom = stop[0].zoom;\n if (featureFunctions[zoom] === undefined) {\n featureFunctions[zoom] = {\n zoom,\n type: parameters.type,\n property: parameters.property,\n default: parameters.default,\n stops: []\n };\n zoomStops.push(zoom);\n }\n featureFunctions[zoom].stops.push([stop[0].value, stop[1]]);\n }\n\n const featureFunctionStops = [];\n for (const z of zoomStops) {\n featureFunctionStops.push([featureFunctions[z].zoom, createFunction(featureFunctions[z], propertySpec)]);\n }\n\n const interpolationType = {name: 'linear'};\n return {\n kind: 'composite',\n interpolationType,\n interpolationFactor: Interpolate.interpolationFactor.bind(undefined, interpolationType),\n zoomStops: featureFunctionStops.map(s => s[0]),\n evaluate({zoom}, properties) {\n return evaluateExponentialFunction({\n stops: featureFunctionStops,\n base: parameters.base\n }, propertySpec, zoom).evaluate(zoom, properties);\n }\n };\n } else if (zoomDependent) {\n const interpolationType = type === 'exponential' ?\n {name: 'exponential', base: parameters.base !== undefined ? parameters.base : 1} : null;\n return {\n kind: 'camera',\n interpolationType,\n interpolationFactor: Interpolate.interpolationFactor.bind(undefined, interpolationType),\n zoomStops: parameters.stops.map(s => s[0]),\n evaluate: ({zoom}) => innerFun(parameters, propertySpec, zoom, hashedStops, categoricalKeyType)\n };\n } else {\n return {\n kind: 'source',\n evaluate(_, feature) {\n const value = feature && feature.properties ? feature.properties[parameters.property] : undefined;\n if (value === undefined) {\n return coalesce(parameters.default, propertySpec.default);\n }\n return innerFun(parameters, propertySpec, value, hashedStops, categoricalKeyType);\n }\n };\n }\n}\n\nfunction coalesce(a, b, c) {\n if (a !== undefined) return a;\n if (b !== undefined) return b;\n if (c !== undefined) return c;\n}\n\nfunction evaluateCategoricalFunction(parameters, propertySpec, input, hashedStops, keyType) {\n const evaluated = typeof input === keyType ? hashedStops[input] : undefined; // Enforce strict typing on input\n return coalesce(evaluated, parameters.default, propertySpec.default);\n}\n\nfunction evaluateIntervalFunction(parameters, propertySpec, input) {\n // Edge cases\n if (getType(input) !== 'number') return coalesce(parameters.default, propertySpec.default);\n const n = parameters.stops.length;\n if (n === 1) return parameters.stops[0][1];\n if (input <= parameters.stops[0][0]) return parameters.stops[0][1];\n if (input >= parameters.stops[n - 1][0]) return parameters.stops[n - 1][1];\n\n const index = findStopLessThanOrEqualTo(parameters.stops.map((stop) => stop[0]), input);\n\n return parameters.stops[index][1];\n}\n\nfunction evaluateExponentialFunction(parameters, propertySpec, input) {\n const base = parameters.base !== undefined ? parameters.base : 1;\n\n // Edge cases\n if (getType(input) !== 'number') return coalesce(parameters.default, propertySpec.default);\n const n = parameters.stops.length;\n if (n === 1) return parameters.stops[0][1];\n if (input <= parameters.stops[0][0]) return parameters.stops[0][1];\n if (input >= parameters.stops[n - 1][0]) return parameters.stops[n - 1][1];\n\n const index = findStopLessThanOrEqualTo(parameters.stops.map((stop) => stop[0]), input);\n const t = interpolationFactor(\n input, base,\n parameters.stops[index][0],\n parameters.stops[index + 1][0]);\n\n const outputLower = parameters.stops[index][1];\n const outputUpper = parameters.stops[index + 1][1];\n let interp = interpolate[propertySpec.type] || identityFunction; // eslint-disable-line import/namespace\n\n if (parameters.colorSpace && parameters.colorSpace !== 'rgb') {\n const colorspace = colorSpaces[parameters.colorSpace]; // eslint-disable-line import/namespace\n interp = (a, b) => colorspace.reverse(colorspace.interpolate(colorspace.forward(a), colorspace.forward(b), t));\n }\n\n if (typeof outputLower.evaluate === 'function') {\n return {\n evaluate(...args) {\n const evaluatedLower = outputLower.evaluate.apply(undefined, args);\n const evaluatedUpper = outputUpper.evaluate.apply(undefined, args);\n // Special case for fill-outline-color, which has no spec default.\n if (evaluatedLower === undefined || evaluatedUpper === undefined) {\n return undefined;\n }\n return interp(evaluatedLower, evaluatedUpper, t);\n }\n };\n }\n\n return interp(outputLower, outputUpper, t);\n}\n\nfunction evaluateIdentityFunction(parameters, propertySpec, input) {\n if (propertySpec.type === 'color') {\n input = Color.parse(input);\n } else if (propertySpec.type === 'formatted') {\n input = Formatted.fromString(input.toString());\n } else if (propertySpec.type === 'resolvedImage') {\n input = ResolvedImage.fromString(input.toString());\n } else if (getType(input) !== propertySpec.type && (propertySpec.type !== 'enum' || !propertySpec.values[input])) {\n input = undefined;\n }\n return coalesce(input, parameters.default, propertySpec.default);\n}\n\n/**\n * Returns a ratio that can be used to interpolate between exponential function\n * stops.\n *\n * How it works:\n * Two consecutive stop values define a (scaled and shifted) exponential\n * function `f(x) = a * base^x + b`, where `base` is the user-specified base,\n * and `a` and `b` are constants affording sufficient degrees of freedom to fit\n * the function to the given stops.\n *\n * Here's a bit of algebra that lets us compute `f(x)` directly from the stop\n * values without explicitly solving for `a` and `b`:\n *\n * First stop value: `f(x0) = y0 = a * base^x0 + b`\n * Second stop value: `f(x1) = y1 = a * base^x1 + b`\n * => `y1 - y0 = a(base^x1 - base^x0)`\n * => `a = (y1 - y0)/(base^x1 - base^x0)`\n *\n * Desired value: `f(x) = y = a * base^x + b`\n * => `f(x) = y0 + a * (base^x - base^x0)`\n *\n * From the above, we can replace the `a` in `a * (base^x - base^x0)` and do a\n * little algebra:\n * ```\n * a * (base^x - base^x0) = (y1 - y0)/(base^x1 - base^x0) * (base^x - base^x0)\n * = (y1 - y0) * (base^x - base^x0) / (base^x1 - base^x0)\n * ```\n *\n * If we let `(base^x - base^x0) / (base^x1 base^x0)`, then we have\n * `f(x) = y0 + (y1 - y0) * ratio`. In other words, `ratio` may be treated as\n * an interpolation factor between the two stops' output values.\n *\n * (Note: a slightly different form for `ratio`,\n * `(base^(x-x0) - 1) / (base^(x1-x0) - 1) `, is equivalent, but requires fewer\n * expensive `Math.pow()` operations.)\n *\n * @private\n */\nfunction interpolationFactor(input, base, lowerValue, upperValue) {\n const difference = upperValue - lowerValue;\n const progress = input - lowerValue;\n\n if (difference === 0) {\n return 0;\n } else if (base === 1) {\n return progress / difference;\n } else {\n return (Math.pow(base, progress) - 1) / (Math.pow(base, difference) - 1);\n }\n}\n","// @flow\n\nimport assert from 'assert';\n\nimport extend from '../util/extend.js';\nimport ParsingError from './parsing_error.js';\nimport ParsingContext from './parsing_context.js';\nimport EvaluationContext from './evaluation_context.js';\nimport CompoundExpression from './compound_expression.js';\nimport Step from './definitions/step.js';\nimport Interpolate from './definitions/interpolate.js';\nimport Coalesce from './definitions/coalesce.js';\nimport Let from './definitions/let.js';\nimport definitions from './definitions/index.js';\nimport * as isConstant from './is_constant.js';\nimport RuntimeError from './runtime_error.js';\nimport {success, error} from '../util/result.js';\nimport {supportsPropertyExpression, supportsZoomExpression, supportsInterpolation} from '../util/properties.js';\n\nimport type {Type, EvaluationKind} from './types.js';\nimport type {Value} from './values.js';\nimport type {Expression} from './expression.js';\nimport type {StylePropertySpecification} from '../style-spec.js';\nimport type {Result} from '../util/result.js';\nimport type {InterpolationType} from './definitions/interpolate.js';\nimport type {PropertyValueSpecification} from '../types.js';\nimport type {FormattedSection} from './types/formatted.js';\nimport type Point from '@mapbox/point-geometry';\nimport type {CanonicalTileID} from '../../source/tile_id.js';\nimport type {FeatureDistanceData} from '../feature_filter/index.js';\n\nexport type Feature = {\n +type: 1 | 2 | 3 | 'Unknown' | 'Point' | 'MultiPoint' | 'LineString' | 'MultiLineString' | 'Polygon' | 'MultiPolygon',\n +id?: number | null,\n +properties: {[_: string]: any},\n +patterns?: {[_: string]: {\"min\": string, \"mid\": string, \"max\": string}},\n +geometry?: Array>\n};\n\nexport type FeatureState = {[_: string]: any};\n\nexport type GlobalProperties = $ReadOnly<{\n zoom: number,\n pitch?: number,\n heatmapDensity?: number,\n lineProgress?: number,\n skyRadialProgress?: number,\n isSupportedScript?: (_: string) => boolean,\n accumulated?: Value\n}>;\n\nexport class StyleExpression {\n expression: Expression;\n\n _evaluator: EvaluationContext;\n _defaultValue: Value;\n _warningHistory: {[key: string]: boolean};\n _enumValues: ?{[_: string]: any};\n\n constructor(expression: Expression, propertySpec: ?StylePropertySpecification) {\n this.expression = expression;\n this._warningHistory = {};\n this._evaluator = new EvaluationContext();\n this._defaultValue = propertySpec ? getDefaultValue(propertySpec) : null;\n this._enumValues = propertySpec && propertySpec.type === 'enum' ? propertySpec.values : null;\n }\n\n evaluateWithoutErrorHandling(globals: GlobalProperties, feature?: Feature, featureState?: FeatureState, canonical?: CanonicalTileID, availableImages?: Array, formattedSection?: FormattedSection, featureTileCoord?: Point, featureDistanceData?: FeatureDistanceData): any {\n this._evaluator.globals = globals;\n this._evaluator.feature = feature;\n this._evaluator.featureState = featureState;\n this._evaluator.canonical = canonical || null;\n this._evaluator.availableImages = availableImages || null;\n this._evaluator.formattedSection = formattedSection;\n this._evaluator.featureTileCoord = featureTileCoord || null;\n this._evaluator.featureDistanceData = featureDistanceData || null;\n\n return this.expression.evaluate(this._evaluator);\n }\n\n evaluate(globals: GlobalProperties, feature?: Feature, featureState?: FeatureState, canonical?: CanonicalTileID, availableImages?: Array, formattedSection?: FormattedSection, featureTileCoord?: Point, featureDistanceData?: FeatureDistanceData): any {\n this._evaluator.globals = globals;\n this._evaluator.feature = feature || null;\n this._evaluator.featureState = featureState || null;\n this._evaluator.canonical = canonical || null;\n this._evaluator.availableImages = availableImages || null;\n this._evaluator.formattedSection = formattedSection || null;\n this._evaluator.featureTileCoord = featureTileCoord || null;\n this._evaluator.featureDistanceData = featureDistanceData || null;\n\n try {\n const val = this.expression.evaluate(this._evaluator);\n // eslint-disable-next-line no-self-compare\n if (val === null || val === undefined || (typeof val === 'number' && val !== val)) {\n return this._defaultValue;\n }\n if (this._enumValues && !(val in this._enumValues)) {\n throw new RuntimeError(`Expected value to be one of ${Object.keys(this._enumValues).map(v => JSON.stringify(v)).join(', ')}, but found ${JSON.stringify(val)} instead.`);\n }\n return val;\n } catch (e) {\n if (!this._warningHistory[e.message]) {\n this._warningHistory[e.message] = true;\n if (typeof console !== 'undefined') {\n console.warn(e.message);\n }\n }\n return this._defaultValue;\n }\n }\n}\n\nexport function isExpression(expression: mixed): boolean {\n return Array.isArray(expression) && expression.length > 0 &&\n typeof expression[0] === 'string' && expression[0] in definitions;\n}\n\n/**\n * Parse and typecheck the given style spec JSON expression. If\n * options.defaultValue is provided, then the resulting StyleExpression's\n * `evaluate()` method will handle errors by logging a warning (once per\n * message) and returning the default value. Otherwise, it will throw\n * evaluation errors.\n *\n * @private\n */\nexport function createExpression(expression: mixed, propertySpec: ?StylePropertySpecification): Result> {\n const parser = new ParsingContext(definitions, [], propertySpec ? getExpectedType(propertySpec) : undefined);\n\n // For string-valued properties, coerce to string at the top level rather than asserting.\n const parsed = parser.parse(expression, undefined, undefined, undefined,\n propertySpec && propertySpec.type === 'string' ? {typeAnnotation: 'coerce'} : undefined);\n\n if (!parsed) {\n assert(parser.errors.length > 0);\n return error(parser.errors);\n }\n\n return success(new StyleExpression(parsed, propertySpec));\n}\n\nexport class ZoomConstantExpression {\n kind: Kind;\n isStateDependent: boolean;\n _styleExpression: StyleExpression;\n\n constructor(kind: Kind, expression: StyleExpression) {\n this.kind = kind;\n this._styleExpression = expression;\n this.isStateDependent = kind !== ('constant': EvaluationKind) && !isConstant.isStateConstant(expression.expression);\n }\n\n evaluateWithoutErrorHandling(globals: GlobalProperties, feature?: Feature, featureState?: FeatureState, canonical?: CanonicalTileID, availableImages?: Array, formattedSection?: FormattedSection): any {\n return this._styleExpression.evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection);\n }\n\n evaluate(globals: GlobalProperties, feature?: Feature, featureState?: FeatureState, canonical?: CanonicalTileID, availableImages?: Array, formattedSection?: FormattedSection): any {\n return this._styleExpression.evaluate(globals, feature, featureState, canonical, availableImages, formattedSection);\n }\n}\n\nexport class ZoomDependentExpression {\n kind: Kind;\n zoomStops: Array;\n isStateDependent: boolean;\n\n _styleExpression: StyleExpression;\n interpolationType: ?InterpolationType;\n\n constructor(kind: Kind, expression: StyleExpression, zoomStops: Array, interpolationType?: InterpolationType) {\n this.kind = kind;\n this.zoomStops = zoomStops;\n this._styleExpression = expression;\n this.isStateDependent = kind !== ('camera': EvaluationKind) && !isConstant.isStateConstant(expression.expression);\n this.interpolationType = interpolationType;\n }\n\n evaluateWithoutErrorHandling(globals: GlobalProperties, feature?: Feature, featureState?: FeatureState, canonical?: CanonicalTileID, availableImages?: Array, formattedSection?: FormattedSection): any {\n return this._styleExpression.evaluateWithoutErrorHandling(globals, feature, featureState, canonical, availableImages, formattedSection);\n }\n\n evaluate(globals: GlobalProperties, feature?: Feature, featureState?: FeatureState, canonical?: CanonicalTileID, availableImages?: Array, formattedSection?: FormattedSection): any {\n return this._styleExpression.evaluate(globals, feature, featureState, canonical, availableImages, formattedSection);\n }\n\n interpolationFactor(input: number, lower: number, upper: number): number {\n if (this.interpolationType) {\n return Interpolate.interpolationFactor(this.interpolationType, input, lower, upper);\n } else {\n return 0;\n }\n }\n}\n\nexport type ConstantExpression = {\n kind: 'constant',\n +evaluate: (globals: GlobalProperties, feature?: Feature, featureState?: FeatureState, canonical?: CanonicalTileID, availableImages?: Array) => any,\n}\n\nexport type SourceExpression = {\n kind: 'source',\n isStateDependent: boolean,\n +evaluate: (globals: GlobalProperties, feature?: Feature, featureState?: FeatureState, canonical?: CanonicalTileID, availableImages?: Array, formattedSection?: FormattedSection) => any,\n};\n\nexport type CameraExpression = {\n kind: 'camera',\n +evaluate: (globals: GlobalProperties, feature?: Feature, featureState?: FeatureState, canonical?: CanonicalTileID, availableImages?: Array) => any,\n +interpolationFactor: (input: number, lower: number, upper: number) => number,\n zoomStops: Array,\n interpolationType: ?InterpolationType\n};\n\nexport type CompositeExpression = {\n kind: 'composite',\n isStateDependent: boolean,\n +evaluate: (globals: GlobalProperties, feature?: Feature, featureState?: FeatureState, canonical?: CanonicalTileID, availableImages?: Array, formattedSection?: FormattedSection) => any,\n +interpolationFactor: (input: number, lower: number, upper: number) => number,\n zoomStops: Array,\n interpolationType: ?InterpolationType\n};\n\nexport type StylePropertyExpression =\n | ConstantExpression\n | SourceExpression\n | CameraExpression\n | CompositeExpression;\n\nexport function createPropertyExpression(expression: mixed, propertySpec: StylePropertySpecification): Result> {\n expression = createExpression(expression, propertySpec);\n if (expression.result === 'error') {\n return expression;\n }\n\n const parsed = expression.value.expression;\n\n const isFeatureConstant = isConstant.isFeatureConstant(parsed);\n if (!isFeatureConstant && !supportsPropertyExpression(propertySpec)) {\n return error([new ParsingError('', 'data expressions not supported')]);\n }\n\n const isZoomConstant = isConstant.isGlobalPropertyConstant(parsed, ['zoom', 'pitch', 'distance-from-center']);\n if (!isZoomConstant && !supportsZoomExpression(propertySpec)) {\n return error([new ParsingError('', 'zoom expressions not supported')]);\n }\n\n const zoomCurve = findZoomCurve(parsed);\n if (!zoomCurve && !isZoomConstant) {\n return error([new ParsingError('', '\"zoom\" expression may only be used as input to a top-level \"step\" or \"interpolate\" expression.')]);\n } else if (zoomCurve instanceof ParsingError) {\n return error([zoomCurve]);\n } else if (zoomCurve instanceof Interpolate && !supportsInterpolation(propertySpec)) {\n return error([new ParsingError('', '\"interpolate\" expressions cannot be used with this property')]);\n }\n\n if (!zoomCurve) {\n return success(isFeatureConstant ?\n (new ZoomConstantExpression('constant', expression.value): ConstantExpression) :\n (new ZoomConstantExpression('source', expression.value): SourceExpression));\n }\n\n const interpolationType = zoomCurve instanceof Interpolate ? zoomCurve.interpolation : undefined;\n\n return success(isFeatureConstant ?\n (new ZoomDependentExpression('camera', expression.value, zoomCurve.labels, interpolationType): CameraExpression) :\n (new ZoomDependentExpression('composite', expression.value, zoomCurve.labels, interpolationType): CompositeExpression));\n}\n\nimport {isFunction, createFunction} from '../function/index.js';\nimport {Color} from './values.js';\n\n// serialization wrapper for old-style stop functions normalized to the\n// expression interface\nexport class StylePropertyFunction {\n _parameters: PropertyValueSpecification;\n _specification: StylePropertySpecification;\n\n kind: EvaluationKind;\n evaluate: (globals: GlobalProperties, feature?: Feature) => any;\n interpolationFactor: ?(input: number, lower: number, upper: number) => number;\n zoomStops: ?Array;\n\n constructor(parameters: PropertyValueSpecification, specification: StylePropertySpecification) {\n this._parameters = parameters;\n this._specification = specification;\n extend(this, createFunction(this._parameters, this._specification));\n }\n\n static deserialize(serialized: {_parameters: PropertyValueSpecification, _specification: StylePropertySpecification}): StylePropertyFunction {\n return new StylePropertyFunction(serialized._parameters, serialized._specification);\n }\n\n static serialize(input: StylePropertyFunction): {_parameters: PropertyValueSpecification, _specification: StylePropertySpecification} {\n return {\n _parameters: input._parameters,\n _specification: input._specification\n };\n }\n}\n\nexport function normalizePropertyExpression(value: PropertyValueSpecification, specification: StylePropertySpecification): StylePropertyExpression {\n if (isFunction(value)) {\n return (new StylePropertyFunction(value, specification): any);\n\n } else if (isExpression(value)) {\n const expression = createPropertyExpression(value, specification);\n if (expression.result === 'error') {\n // this should have been caught in validation\n throw new Error(expression.value.map(err => `${err.key}: ${err.message}`).join(', '));\n }\n return expression.value;\n\n } else {\n let constant: any = value;\n if (typeof value === 'string' && specification.type === 'color') {\n constant = Color.parse(value);\n }\n return {\n kind: 'constant',\n evaluate: () => constant\n };\n }\n}\n\n// Zoom-dependent expressions may only use [\"zoom\"] as the input to a top-level \"step\" or \"interpolate\"\n// expression (collectively referred to as a \"curve\"). The curve may be wrapped in one or more \"let\" or\n// \"coalesce\" expressions.\nfunction findZoomCurve(expression: Expression): Step | Interpolate | ParsingError | null {\n let result = null;\n if (expression instanceof Let) {\n result = findZoomCurve(expression.result);\n\n } else if (expression instanceof Coalesce) {\n for (const arg of expression.args) {\n result = findZoomCurve(arg);\n if (result) {\n break;\n }\n }\n\n } else if ((expression instanceof Step || expression instanceof Interpolate) &&\n expression.input instanceof CompoundExpression &&\n expression.input.name === 'zoom') {\n\n result = expression;\n }\n\n if (result instanceof ParsingError) {\n return result;\n }\n\n expression.eachChild((child) => {\n const childResult = findZoomCurve(child);\n if (childResult instanceof ParsingError) {\n result = childResult;\n } else if (!result && childResult) {\n result = new ParsingError('', '\"zoom\" expression may only be used as input to a top-level \"step\" or \"interpolate\" expression.');\n } else if (result && childResult && result !== childResult) {\n result = new ParsingError('', 'Only one zoom-based \"step\" or \"interpolate\" subexpression may be used in an expression.');\n }\n });\n\n return result;\n}\n\nimport {ColorType, StringType, NumberType, BooleanType, ValueType, FormattedType, ResolvedImageType, array} from './types.js';\n\nfunction getExpectedType(spec: StylePropertySpecification): Type {\n const types = {\n color: ColorType,\n string: StringType,\n number: NumberType,\n enum: StringType,\n boolean: BooleanType,\n formatted: FormattedType,\n resolvedImage: ResolvedImageType\n };\n\n if (spec.type === 'array') {\n return array(types[spec.value] || ValueType, spec.length);\n }\n\n return types[spec.type];\n}\n\nfunction getDefaultValue(spec: StylePropertySpecification): Value {\n if (spec.type === 'color' && isFunction(spec.default)) {\n // Special case for heatmap-color: it uses the 'default:' to define a\n // default color ramp, but createExpression expects a simple value to fall\n // back to in case of runtime errors\n return new Color(0, 0, 0, 0);\n } else if (spec.type === 'color') {\n return Color.parse(spec.default) || null;\n } else if (spec.default === undefined) {\n return null;\n } else {\n return spec.default;\n }\n}\n","// @flow\n\nimport type {StylePropertySpecification} from '../style-spec.js';\n\nexport function supportsPropertyExpression(spec: StylePropertySpecification): boolean {\n return spec['property-type'] === 'data-driven' || spec['property-type'] === 'cross-faded-data-driven';\n}\n\nexport function supportsZoomExpression(spec: StylePropertySpecification): boolean {\n return !!spec.expression && spec.expression.parameters.indexOf('zoom') > -1;\n}\n\nexport function supportsInterpolation(spec: StylePropertySpecification): boolean {\n return !!spec.expression && spec.expression.interpolated;\n}\n","// @flow\n\n// Turn jsonlint-lines-primitives objects into primitive objects\nexport function unbundle(value: mixed): mixed {\n if (value instanceof Number || value instanceof String || value instanceof Boolean) {\n return value.valueOf();\n } else {\n return value;\n }\n}\n\nexport function deepUnbundle(value: mixed): mixed {\n if (Array.isArray(value)) {\n return value.map(deepUnbundle);\n } else if (value instanceof Object && !(value instanceof Number || value instanceof String || value instanceof Boolean)) {\n const unbundledValue: { [key: string]: mixed } = {};\n for (const key in value) {\n unbundledValue[key] = deepUnbundle(value[key]);\n }\n return unbundledValue;\n }\n\n return unbundle(value);\n}\n","{\n \"$version\": 8,\n \"$root\": {\n \"version\": {\n \"required\": true,\n \"type\": \"enum\",\n \"values\": [\n 8\n ],\n \"doc\": \"Style specification version number. Must be 8.\",\n \"example\": 8\n },\n \"name\": {\n \"type\": \"string\",\n \"doc\": \"A human-readable name for the style.\",\n \"example\": \"Bright\"\n },\n \"metadata\": {\n \"type\": \"*\",\n \"doc\": \"Arbitrary properties useful to track with the stylesheet, but do not influence rendering. Properties should be prefixed to avoid collisions, like 'mapbox:'.\"\n },\n \"center\": {\n \"type\": \"array\",\n \"value\": \"number\",\n \"doc\": \"Default map center in longitude and latitude. The style center will be used only if the map has not been positioned by other means (e.g. map options or user interaction).\",\n \"example\": [\n -73.9749,\n 40.7736\n ]\n },\n \"zoom\": {\n \"type\": \"number\",\n \"doc\": \"Default zoom level. The style zoom will be used only if the map has not been positioned by other means (e.g. map options or user interaction).\",\n \"example\": 12.5\n },\n \"bearing\": {\n \"type\": \"number\",\n \"default\": 0,\n \"period\": 360,\n \"units\": \"degrees\",\n \"doc\": \"Default bearing, in degrees. The bearing is the compass direction that is \\\"up\\\"; for example, a bearing of 90° orients the map so that east is up. This value will be used only if the map has not been positioned by other means (e.g. map options or user interaction).\",\n \"example\": 29\n },\n \"pitch\": {\n \"type\": \"number\",\n \"default\": 0,\n \"units\": \"degrees\",\n \"doc\": \"Default pitch, in degrees. Zero is perpendicular to the surface, for a look straight down at the map, while a greater value like 60 looks ahead towards the horizon. The style pitch will be used only if the map has not been positioned by other means (e.g. map options or user interaction).\",\n \"example\": 50\n },\n \"light\": {\n \"type\": \"light\",\n \"doc\": \"The global light source.\",\n \"example\": {\n \"anchor\": \"viewport\",\n \"color\": \"white\",\n \"intensity\": 0.4\n }\n },\n \"terrain\": {\n \"type\": \"terrain\",\n \"doc\": \"A global modifier that elevates layers and markers based on a DEM data source.\"\n },\n \"fog\": {\n \"type\": \"fog\",\n \"doc\": \"A global effect that fades layers and markers based on their distance to the camera. The fog can be used to approximate the effect of atmosphere on distant objects and enhance the depth perception of the map when used with terrain or 3D features.\"\n },\n \"sources\": {\n \"required\": true,\n \"type\": \"sources\",\n \"doc\": \"Data source specifications.\",\n \"example\": {\n \"mapbox-streets\": {\n \"type\": \"vector\",\n \"url\": \"mapbox://mapbox.mapbox-streets-v6\"\n }\n }\n },\n \"sprite\": {\n \"type\": \"string\",\n \"doc\": \"A base URL for retrieving the sprite image and metadata. The extensions `.png`, `.json` and scale factor `@2x.png` will be automatically appended. This property is required if any layer uses the `background-pattern`, `fill-pattern`, `line-pattern`, `fill-extrusion-pattern`, or `icon-image` properties. The URL must be absolute, containing the [scheme, authority and path components](https://en.wikipedia.org/wiki/URL#Syntax).\",\n \"example\": \"mapbox://sprites/mapbox/bright-v8\"\n },\n \"glyphs\": {\n \"type\": \"string\",\n \"doc\": \"A URL template for loading signed-distance-field glyph sets in PBF format. The URL must include `{fontstack}` and `{range}` tokens. This property is required if any layer uses the `text-field` layout property. The URL must be absolute, containing the [scheme, authority and path components](https://en.wikipedia.org/wiki/URL#Syntax).\",\n \"example\": \"mapbox://fonts/mapbox/{fontstack}/{range}.pbf\"\n },\n \"transition\": {\n \"type\": \"transition\",\n \"doc\": \"A global transition definition to use as a default across properties, to be used for timing transitions between one value and the next when no property-specific transition is set. Collision-based symbol fading is controlled independently of the style's `transition` property.\",\n \"example\": {\n \"duration\": 300,\n \"delay\": 0\n }\n },\n \"projection\": {\n \"type\": \"projection\",\n \"doc\": \"The projection the map should be rendered in. Supported projections are Albers, Equal Earth, Equirectangular (WGS84), Lambert conformal conic, Mercator, Natural Earth, and Winkel Tripel. Terrain, fog, sky and CustomLayerInterface are not supported for projections other than mercator.\",\n \"example\": {\n \"name\": \"albers\",\n \"center\": [-154, 50],\n \"parallels\": [55, 65]\n }\n },\n \"layers\": {\n \"required\": true,\n \"type\": \"array\",\n \"value\": \"layer\",\n \"doc\": \"Layers will be drawn in the order of this array.\",\n \"example\": [\n {\n \"id\": \"water\",\n \"source\": \"mapbox-streets\",\n \"source-layer\": \"water\",\n \"type\": \"fill\",\n \"paint\": {\n \"fill-color\": \"#00ffff\"\n }\n }\n ]\n }\n },\n \"sources\": {\n \"*\": {\n \"type\": \"source\",\n \"doc\": \"Specification of a data source. For vector and raster sources, either TileJSON or a URL to a TileJSON must be provided. For image and video sources, a URL must be provided. For GeoJSON sources, a URL or inline GeoJSON must be provided.\"\n }\n },\n \"source\": [\n \"source_vector\",\n \"source_raster\",\n \"source_raster_dem\",\n \"source_geojson\",\n \"source_video\",\n \"source_image\"\n ],\n \"source_vector\": {\n \"type\": {\n \"required\": true,\n \"type\": \"enum\",\n \"values\": {\n \"vector\": {\n \"doc\": \"A vector tile source.\"\n }\n },\n \"doc\": \"The type of the source.\"\n },\n \"url\": {\n \"type\": \"string\",\n \"doc\": \"A URL to a TileJSON resource. Supported protocols are `http:`, `https:`, and `mapbox://`.\"\n },\n \"tiles\": {\n \"type\": \"array\",\n \"value\": \"string\",\n \"doc\": \"An array of one or more tile source URLs, as in the TileJSON spec.\"\n },\n \"bounds\": {\n \"type\": \"array\",\n \"value\": \"number\",\n \"length\": 4,\n \"default\": [\n -180,\n -85.051129,\n 180,\n 85.051129\n ],\n \"doc\": \"An array containing the longitude and latitude of the southwest and northeast corners of the source's bounding box in the following order: `[sw.lng, sw.lat, ne.lng, ne.lat]`. When this property is included in a source, no tiles outside of the given bounds are requested by Mapbox GL.\"\n },\n \"scheme\": {\n \"type\": \"enum\",\n \"values\": {\n \"xyz\": {\n \"doc\": \"Slippy map tilenames scheme.\"\n },\n \"tms\": {\n \"doc\": \"OSGeo spec scheme.\"\n }\n },\n \"default\": \"xyz\",\n \"doc\": \"Influences the y direction of the tile coordinates. The global-mercator (aka Spherical Mercator) profile is assumed.\"\n },\n \"minzoom\": {\n \"type\": \"number\",\n \"default\": 0,\n \"doc\": \"Minimum zoom level for which tiles are available, as in the TileJSON spec.\"\n },\n \"maxzoom\": {\n \"type\": \"number\",\n \"default\": 22,\n \"doc\": \"Maximum zoom level for which tiles are available, as in the TileJSON spec. Data from tiles at the maxzoom are used when displaying the map at higher zoom levels.\"\n },\n \"attribution\": {\n \"type\": \"string\",\n \"doc\": \"Contains an attribution to be displayed when the map is shown to a user.\"\n },\n \"promoteId\": {\n \"type\": \"promoteId\",\n \"doc\": \"A property to use as a feature id (for feature state). Either a property name, or an object of the form `{: }`. If specified as a string for a vector tile source, the same property is used across all its source layers.\"\n },\n \"volatile\": {\n \"type\": \"boolean\",\n \"default\": false,\n \"doc\": \"A setting to determine whether a source's tiles are cached locally.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"android\": \"9.3.0\",\n \"ios\": \"5.10.0\"\n }\n }\n },\n \"*\": {\n \"type\": \"*\",\n \"doc\": \"Other keys to configure the data source.\"\n }\n },\n \"source_raster\": {\n \"type\": {\n \"required\": true,\n \"type\": \"enum\",\n \"values\": {\n \"raster\": {\n \"doc\": \"A raster tile source.\"\n }\n },\n \"doc\": \"The type of the source.\"\n },\n \"url\": {\n \"type\": \"string\",\n \"doc\": \"A URL to a TileJSON resource. Supported protocols are `http:`, `https:`, and `mapbox://`.\"\n },\n \"tiles\": {\n \"type\": \"array\",\n \"value\": \"string\",\n \"doc\": \"An array of one or more tile source URLs, as in the TileJSON spec.\"\n },\n \"bounds\": {\n \"type\": \"array\",\n \"value\": \"number\",\n \"length\": 4,\n \"default\": [\n -180,\n -85.051129,\n 180,\n 85.051129\n ],\n \"doc\": \"An array containing the longitude and latitude of the southwest and northeast corners of the source's bounding box in the following order: `[sw.lng, sw.lat, ne.lng, ne.lat]`. When this property is included in a source, no tiles outside of the given bounds are requested by Mapbox GL.\"\n },\n \"minzoom\": {\n \"type\": \"number\",\n \"default\": 0,\n \"doc\": \"Minimum zoom level for which tiles are available, as in the TileJSON spec.\"\n },\n \"maxzoom\": {\n \"type\": \"number\",\n \"default\": 22,\n \"doc\": \"Maximum zoom level for which tiles are available, as in the TileJSON spec. Data from tiles at the maxzoom are used when displaying the map at higher zoom levels.\"\n },\n \"tileSize\": {\n \"type\": \"number\",\n \"default\": 512,\n \"units\": \"pixels\",\n \"doc\": \"The minimum visual size to display tiles for this layer. Only configurable for raster layers.\"\n },\n \"scheme\": {\n \"type\": \"enum\",\n \"values\": {\n \"xyz\": {\n \"doc\": \"Slippy map tilenames scheme.\"\n },\n \"tms\": {\n \"doc\": \"OSGeo spec scheme.\"\n }\n },\n \"default\": \"xyz\",\n \"doc\": \"Influences the y direction of the tile coordinates. The global-mercator (aka Spherical Mercator) profile is assumed.\"\n },\n \"attribution\": {\n \"type\": \"string\",\n \"doc\": \"Contains an attribution to be displayed when the map is shown to a user.\"\n },\n \"volatile\": {\n \"type\": \"boolean\",\n \"default\": false,\n \"doc\": \"A setting to determine whether a source's tiles are cached locally.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"android\": \"9.3.0\",\n \"ios\": \"5.10.0\"\n }\n }\n },\n \"*\": {\n \"type\": \"*\",\n \"doc\": \"Other keys to configure the data source.\"\n }\n },\n \"source_raster_dem\": {\n \"type\": {\n \"required\": true,\n \"type\": \"enum\",\n \"values\": {\n \"raster-dem\": {\n \"doc\": \"A RGB-encoded raster DEM source\"\n }\n },\n \"doc\": \"The type of the source.\"\n },\n \"url\": {\n \"type\": \"string\",\n \"doc\": \"A URL to a TileJSON resource. Supported protocols are `http:`, `https:`, and `mapbox://`.\"\n },\n \"tiles\": {\n \"type\": \"array\",\n \"value\": \"string\",\n \"doc\": \"An array of one or more tile source URLs, as in the TileJSON spec.\"\n },\n \"bounds\": {\n \"type\": \"array\",\n \"value\": \"number\",\n \"length\": 4,\n \"default\": [\n -180,\n -85.051129,\n 180,\n 85.051129\n ],\n \"doc\": \"An array containing the longitude and latitude of the southwest and northeast corners of the source's bounding box in the following order: `[sw.lng, sw.lat, ne.lng, ne.lat]`. When this property is included in a source, no tiles outside of the given bounds are requested by Mapbox GL.\"\n },\n \"minzoom\": {\n \"type\": \"number\",\n \"default\": 0,\n \"doc\": \"Minimum zoom level for which tiles are available, as in the TileJSON spec.\"\n },\n \"maxzoom\": {\n \"type\": \"number\",\n \"default\": 22,\n \"doc\": \"Maximum zoom level for which tiles are available, as in the TileJSON spec. Data from tiles at the maxzoom are used when displaying the map at higher zoom levels.\"\n },\n \"tileSize\": {\n \"type\": \"number\",\n \"default\": 512,\n \"units\": \"pixels\",\n \"doc\": \"The minimum visual size to display tiles for this layer. Only configurable for raster layers.\"\n },\n \"attribution\": {\n \"type\": \"string\",\n \"doc\": \"Contains an attribution to be displayed when the map is shown to a user.\"\n },\n \"encoding\": {\n \"type\": \"enum\",\n \"values\": {\n \"terrarium\": {\n \"doc\": \"Terrarium format PNG tiles. See https://aws.amazon.com/es/public-datasets/terrain/ for more info.\"\n },\n \"mapbox\": {\n \"doc\": \"Mapbox Terrain RGB tiles. See https://www.mapbox.com/help/access-elevation-data/#mapbox-terrain-rgb for more info.\"\n }\n },\n \"default\": \"mapbox\",\n \"doc\": \"The encoding used by this source. Mapbox Terrain RGB is used by default\"\n },\n \"volatile\": {\n \"type\": \"boolean\",\n \"default\": false,\n \"doc\": \"A setting to determine whether a source's tiles are cached locally.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"android\": \"9.3.0\",\n \"ios\": \"5.10.0\"\n }\n }\n },\n \"*\": {\n \"type\": \"*\",\n \"doc\": \"Other keys to configure the data source.\"\n }\n },\n \"source_geojson\": {\n \"type\": {\n \"required\": true,\n \"type\": \"enum\",\n \"values\": {\n \"geojson\": {\n \"doc\": \"A GeoJSON data source.\"\n }\n },\n \"doc\": \"The data type of the GeoJSON source.\"\n },\n \"data\": {\n \"type\": \"*\",\n \"doc\": \"A URL to a GeoJSON file, or inline GeoJSON.\"\n },\n \"maxzoom\": {\n \"type\": \"number\",\n \"default\": 18,\n \"doc\": \"Maximum zoom level at which to create vector tiles (higher means greater detail at high zoom levels).\"\n },\n \"attribution\": {\n \"type\": \"string\",\n \"doc\": \"Contains an attribution to be displayed when the map is shown to a user.\"\n },\n \"buffer\": {\n \"type\": \"number\",\n \"default\": 128,\n \"maximum\": 512,\n \"minimum\": 0,\n \"doc\": \"Size of the tile buffer on each side. A value of 0 produces no buffer. A value of 512 produces a buffer as wide as the tile itself. Larger values produce fewer rendering artifacts near tile edges and slower performance.\"\n },\n \"filter\": {\n \"type\": \"*\",\n \"doc\": \"An expression for filtering features prior to processing them for rendering.\"\n },\n \"tolerance\": {\n \"type\": \"number\",\n \"default\": 0.375,\n \"doc\": \"Douglas-Peucker simplification tolerance (higher means simpler geometries and faster performance).\"\n },\n \"cluster\": {\n \"type\": \"boolean\",\n \"default\": false,\n \"doc\": \"If the data is a collection of point features, setting this to true clusters the points by radius into groups. Cluster groups become new `Point` features in the source with additional properties:\\n * `cluster` Is `true` if the point is a cluster \\n * `cluster_id` A unqiue id for the cluster to be used in conjunction with the [cluster inspection methods](https://www.mapbox.com/mapbox-gl-js/api/#geojsonsource#getclusterexpansionzoom)\\n * `point_count` Number of original points grouped into this cluster\\n * `point_count_abbreviated` An abbreviated point count\"\n },\n \"clusterRadius\": {\n \"type\": \"number\",\n \"default\": 50,\n \"minimum\": 0,\n \"doc\": \"Radius of each cluster if clustering is enabled. A value of 512 indicates a radius equal to the width of a tile.\"\n },\n \"clusterMaxZoom\": {\n \"type\": \"number\",\n \"doc\": \"Max zoom on which to cluster points if clustering is enabled. Defaults to one zoom less than maxzoom (so that last zoom features are not clustered). Clusters are re-evaluated at integer zoom levels so setting clusterMaxZoom to 14 means the clusters will be displayed until z15.\"\n },\n \"clusterMinPoints\": {\n \"type\": \"number\",\n \"doc\": \"Minimum number of points necessary to form a cluster if clustering is enabled. Defaults to `2`.\"\n },\n \"clusterProperties\": {\n \"type\": \"*\",\n \"doc\": \"An object defining custom properties on the generated clusters if clustering is enabled, aggregating values from clustered points. Has the form `{\\\"property_name\\\": [operator, map_expression]}`. `operator` is any expression function that accepts at least 2 operands (e.g. `\\\"+\\\"` or `\\\"max\\\"`) — it accumulates the property value from clusters/points the cluster contains; `map_expression` produces the value of a single point.\\n\\nExample: `{\\\"sum\\\": [\\\"+\\\", [\\\"get\\\", \\\"scalerank\\\"]]}`.\\n\\nFor more advanced use cases, in place of `operator`, you can use a custom reduce expression that references a special `[\\\"accumulated\\\"]` value, e.g.:\\n`{\\\"sum\\\": [[\\\"+\\\", [\\\"accumulated\\\"], [\\\"get\\\", \\\"sum\\\"]], [\\\"get\\\", \\\"scalerank\\\"]]}`\"\n },\n \"lineMetrics\": {\n \"type\": \"boolean\",\n \"default\": false,\n \"doc\": \"Whether to calculate line distance metrics. This is required for line layers that specify `line-gradient` values.\"\n },\n \"generateId\": {\n \"type\": \"boolean\",\n \"default\": false,\n \"doc\": \"Whether to generate ids for the geojson features. When enabled, the `feature.id` property will be auto assigned based on its index in the `features` array, over-writing any previous values.\"\n },\n \"promoteId\": {\n \"type\": \"promoteId\",\n \"doc\": \"A property to use as a feature id (for feature state). Either a property name, or an object of the form `{: }`.\"\n }\n },\n \"source_video\": {\n \"type\": {\n \"required\": true,\n \"type\": \"enum\",\n \"values\": {\n \"video\": {\n \"doc\": \"A video data source.\"\n }\n },\n \"doc\": \"The data type of the video source.\"\n },\n \"urls\": {\n \"required\": true,\n \"type\": \"array\",\n \"value\": \"string\",\n \"doc\": \"URLs to video content in order of preferred format.\"\n },\n \"coordinates\": {\n \"required\": true,\n \"doc\": \"Corners of video specified in longitude, latitude pairs.\",\n \"type\": \"array\",\n \"length\": 4,\n \"value\": {\n \"type\": \"array\",\n \"length\": 2,\n \"value\": \"number\",\n \"doc\": \"A single longitude, latitude pair.\"\n }\n }\n },\n \"source_image\": {\n \"type\": {\n \"required\": true,\n \"type\": \"enum\",\n \"values\": {\n \"image\": {\n \"doc\": \"An image data source.\"\n }\n },\n \"doc\": \"The data type of the image source.\"\n },\n \"url\": {\n \"required\": true,\n \"type\": \"string\",\n \"doc\": \"URL that points to an image.\"\n },\n \"coordinates\": {\n \"required\": true,\n \"doc\": \"Corners of image specified in longitude, latitude pairs.\",\n \"type\": \"array\",\n \"length\": 4,\n \"value\": {\n \"type\": \"array\",\n \"length\": 2,\n \"value\": \"number\",\n \"doc\": \"A single longitude, latitude pair.\"\n }\n }\n },\n \"layer\": {\n \"id\": {\n \"type\": \"string\",\n \"doc\": \"Unique layer name.\",\n \"required\": true\n },\n \"type\": {\n \"type\": \"enum\",\n \"values\": {\n \"fill\": {\n \"doc\": \"A filled polygon with an optional stroked border.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n }\n },\n \"line\": {\n \"doc\": \"A stroked line.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n }\n },\n \"symbol\": {\n \"doc\": \"An icon or a text label.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n }\n },\n \"circle\": {\n \"doc\": \"A filled circle.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n }\n },\n \"heatmap\": {\n \"doc\": \"A heatmap.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"fill-extrusion\": {\n \"doc\": \"An extruded (3D) polygon.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.27.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n }\n },\n \"raster\": {\n \"doc\": \"Raster map textures such as satellite imagery.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n }\n },\n \"hillshade\": {\n \"doc\": \"Client-side hillshading visualization based on DEM data. Currently, the implementation only supports Mapbox Terrain RGB and Mapzen Terrarium tiles.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.43.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"background\": {\n \"doc\": \"The background color or pattern of the map.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n }\n },\n \"sky\": {\n \"doc\": \"A spherical dome around the map that is always rendered behind all other layers.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.0.0\",\n \"ios\": \"10.0.0\",\n \"android\": \"10.0.0\"\n }\n }\n }\n },\n \"doc\": \"Rendering type of this layer.\",\n \"required\": true\n },\n \"metadata\": {\n \"type\": \"*\",\n \"doc\": \"Arbitrary properties useful to track with the layer, but do not influence rendering. Properties should be prefixed to avoid collisions, like 'mapbox:'.\"\n },\n \"source\": {\n \"type\": \"string\",\n \"doc\": \"Name of a source description to be used for this layer. Required for all layer types except `background`.\"\n },\n \"source-layer\": {\n \"type\": \"string\",\n \"doc\": \"Layer to use from a vector tile source. Required for vector tile sources; prohibited for all other source types, including GeoJSON sources.\"\n },\n \"minzoom\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 24,\n \"doc\": \"The minimum zoom level for the layer. At zoom levels less than the minzoom, the layer will be hidden.\"\n },\n \"maxzoom\": {\n \"type\": \"number\",\n \"minimum\": 0,\n \"maximum\": 24,\n \"doc\": \"The maximum zoom level for the layer. At zoom levels equal to or greater than the maxzoom, the layer will be hidden.\"\n },\n \"filter\": {\n \"type\": \"filter\",\n \"doc\": \"An expression specifying conditions on source features. Only features that match the filter are displayed. Zoom expressions in filters are only evaluated at integer zoom levels. The `[\\\"feature-state\\\", ...]` expression is not supported in filter expressions. The `[\\\"pitch\\\"]` and `[\\\"distance-from-center\\\"]` expressions are supported only for filter expressions on the symbol layer.\"\n },\n \"layout\": {\n \"type\": \"layout\",\n \"doc\": \"Layout properties for the layer.\"\n },\n \"paint\": {\n \"type\": \"paint\",\n \"doc\": \"Default paint properties for this layer.\"\n }\n },\n \"layout\": [\n \"layout_fill\",\n \"layout_line\",\n \"layout_circle\",\n \"layout_heatmap\",\n \"layout_fill-extrusion\",\n \"layout_symbol\",\n \"layout_raster\",\n \"layout_hillshade\",\n \"layout_background\",\n \"layout_sky\"\n ],\n \"layout_background\": {\n \"visibility\": {\n \"type\": \"enum\",\n \"values\": {\n \"visible\": {\n \"doc\": \"The layer is shown.\"\n },\n \"none\": {\n \"doc\": \"The layer is not shown.\"\n }\n },\n \"default\": \"visible\",\n \"doc\": \"Whether this layer is displayed.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"property-type\": \"constant\"\n }\n },\n \"layout_sky\": {\n \"visibility\": {\n \"type\": \"enum\",\n \"values\": {\n \"visible\": {\n \"doc\": \"The layer is shown.\"\n },\n \"none\": {\n \"doc\": \"The layer is not shown.\"\n }\n },\n \"default\": \"visible\",\n \"doc\": \"Whether this layer is displayed.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.0.0\",\n \"ios\": \"10.0.0\",\n \"android\": \"10.0.0\"\n }\n },\n \"property-type\": \"constant\"\n }\n },\n \"layout_fill\": {\n \"fill-sort-key\": {\n \"type\": \"number\",\n \"doc\": \"Sorts features in ascending order based on this value. Features with a higher sort key will appear above features with a lower sort key.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"1.2.0\",\n \"android\": \"9.1.0\",\n \"ios\": \"5.8.0\",\n \"macos\": \"0.15.0\"\n },\n \"data-driven styling\": {\n \"js\": \"1.2.0\",\n \"android\": \"9.1.0\",\n \"ios\": \"5.8.0\",\n \"macos\": \"0.15.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"visibility\": {\n \"type\": \"enum\",\n \"values\": {\n \"visible\": {\n \"doc\": \"The layer is shown.\"\n },\n \"none\": {\n \"doc\": \"The layer is not shown.\"\n }\n },\n \"default\": \"visible\",\n \"doc\": \"Whether this layer is displayed.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"property-type\": \"constant\"\n }\n },\n \"layout_circle\": {\n \"circle-sort-key\": {\n \"type\": \"number\",\n \"doc\": \"Sorts features in ascending order based on this value. Features with a higher sort key will appear above features with a lower sort key.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"1.2.0\",\n \"android\": \"9.2.0\",\n \"ios\": \"5.9.0\",\n \"macos\": \"0.16.0\"\n },\n \"data-driven styling\": {\n \"js\": \"1.2.0\",\n \"android\": \"9.2.0\",\n \"ios\": \"5.9.0\",\n \"macos\": \"0.16.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"visibility\": {\n \"type\": \"enum\",\n \"values\": {\n \"visible\": {\n \"doc\": \"The layer is shown.\"\n },\n \"none\": {\n \"doc\": \"The layer is not shown.\"\n }\n },\n \"default\": \"visible\",\n \"doc\": \"Whether this layer is displayed.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"property-type\": \"constant\"\n }\n },\n \"layout_heatmap\": {\n \"visibility\": {\n \"type\": \"enum\",\n \"values\": {\n \"visible\": {\n \"doc\": \"The layer is shown.\"\n },\n \"none\": {\n \"doc\": \"The layer is not shown.\"\n }\n },\n \"default\": \"visible\",\n \"doc\": \"Whether this layer is displayed.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n },\n \"property-type\": \"constant\"\n }\n },\n \"layout_fill-extrusion\": {\n \"visibility\": {\n \"type\": \"enum\",\n \"values\": {\n \"visible\": {\n \"doc\": \"The layer is shown.\"\n },\n \"none\": {\n \"doc\": \"The layer is not shown.\"\n }\n },\n \"default\": \"visible\",\n \"doc\": \"Whether this layer is displayed.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.27.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n },\n \"property-type\": \"constant\"\n }\n },\n \"layout_line\": {\n \"line-cap\": {\n \"type\": \"enum\",\n \"values\": {\n \"butt\": {\n \"doc\": \"A cap with a squared-off end which is drawn to the exact endpoint of the line.\"\n },\n \"round\": {\n \"doc\": \"A cap with a rounded end which is drawn beyond the endpoint of the line at a radius of one-half of the line's width and centered on the endpoint of the line.\"\n },\n \"square\": {\n \"doc\": \"A cap with a squared-off end which is drawn beyond the endpoint of the line at a distance of one-half of the line's width.\"\n }\n },\n \"default\": \"butt\",\n \"doc\": \"The display of line endings.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"2.3.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"line-join\": {\n \"type\": \"enum\",\n \"values\": {\n \"bevel\": {\n \"doc\": \"A join with a squared-off end which is drawn beyond the endpoint of the line at a distance of one-half of the line's width.\"\n },\n \"round\": {\n \"doc\": \"A join with a rounded end which is drawn beyond the endpoint of the line at a radius of one-half of the line's width and centered on the endpoint of the line.\"\n },\n \"miter\": {\n \"doc\": \"A join with a sharp, angled corner which is drawn with the outer sides beyond the endpoint of the path until they meet.\"\n }\n },\n \"default\": \"miter\",\n \"doc\": \"The display of lines when joining.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.40.0\",\n \"android\": \"5.2.0\",\n \"ios\": \"3.7.0\",\n \"macos\": \"0.6.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"line-miter-limit\": {\n \"type\": \"number\",\n \"default\": 2,\n \"doc\": \"Used to automatically convert miter joins to bevel joins for sharp angles.\",\n \"requires\": [\n {\n \"line-join\": \"miter\"\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"line-round-limit\": {\n \"type\": \"number\",\n \"default\": 1.05,\n \"doc\": \"Used to automatically convert round joins to miter joins for shallow angles.\",\n \"requires\": [\n {\n \"line-join\": \"round\"\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"line-sort-key\": {\n \"type\": \"number\",\n \"doc\": \"Sorts features in ascending order based on this value. Features with a higher sort key will appear above features with a lower sort key.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"1.2.0\",\n \"android\": \"9.1.0\",\n \"ios\": \"5.8.0\",\n \"macos\": \"0.15.0\"\n },\n \"data-driven styling\": {\n \"js\": \"1.2.0\",\n \"android\": \"9.1.0\",\n \"ios\": \"5.8.0\",\n \"macos\": \"0.15.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"visibility\": {\n \"type\": \"enum\",\n \"values\": {\n \"visible\": {\n \"doc\": \"The layer is shown.\"\n },\n \"none\": {\n \"doc\": \"The layer is not shown.\"\n }\n },\n \"default\": \"visible\",\n \"doc\": \"Whether this layer is displayed.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"property-type\": \"constant\"\n }\n },\n \"layout_symbol\": {\n \"symbol-placement\": {\n \"type\": \"enum\",\n \"values\": {\n \"point\": {\n \"doc\": \"The label is placed at the point where the geometry is located.\"\n },\n \"line\": {\n \"doc\": \"The label is placed along the line of the geometry. Can only be used on `LineString` and `Polygon` geometries.\"\n },\n \"line-center\": {\n \"doc\": \"The label is placed at the center of the line of the geometry. Can only be used on `LineString` and `Polygon` geometries. Note that a single feature in a vector tile may contain multiple line geometries.\"\n }\n },\n \"default\": \"point\",\n \"doc\": \"Label placement relative to its geometry.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"`line-center` value\": {\n \"js\": \"0.47.0\",\n \"android\": \"6.4.0\",\n \"ios\": \"4.3.0\",\n \"macos\": \"0.10.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"symbol-spacing\": {\n \"type\": \"number\",\n \"default\": 250,\n \"minimum\": 1,\n \"units\": \"pixels\",\n \"doc\": \"Distance between two symbol anchors.\",\n \"requires\": [\n {\n \"symbol-placement\": \"line\"\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"symbol-avoid-edges\": {\n \"type\": \"boolean\",\n \"default\": false,\n \"doc\": \"If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line symbol layer. When using a client that supports global collision detection, like Mapbox GL JS version 0.42.0 or greater, enabling this property is not needed to prevent clipped labels at tile boundaries.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"symbol-sort-key\": {\n \"type\": \"number\",\n \"doc\": \"Sorts features in ascending order based on this value. Features with lower sort keys are drawn and placed first. When `icon-allow-overlap` or `text-allow-overlap` is `false`, features with a lower sort key will have priority during placement. When `icon-allow-overlap` or `text-allow-overlap` is set to `true`, features with a higher sort key will overlap over features with a lower sort key.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.53.0\",\n \"android\": \"7.4.0\",\n \"ios\": \"4.11.0\",\n \"macos\": \"0.14.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.53.0\",\n \"android\": \"7.4.0\",\n \"ios\": \"4.11.0\",\n \"macos\": \"0.14.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"symbol-z-order\": {\n \"type\": \"enum\",\n \"values\": {\n \"auto\": {\n \"doc\": \"Sorts symbols by `symbol-sort-key` if set. Otherwise, sorts symbols by their y-position relative to the viewport if `icon-allow-overlap` or `text-allow-overlap` is set to `true` or `icon-ignore-placement` or `text-ignore-placement` is `false`.\"\n },\n \"viewport-y\": {\n \"doc\": \"Sorts symbols by their y-position relative to the viewport if `icon-allow-overlap` or `text-allow-overlap` is set to `true` or `icon-ignore-placement` or `text-ignore-placement` is `false`.\"\n },\n \"source\": {\n \"doc\": \"Sorts symbols by `symbol-sort-key` if set. Otherwise, no sorting is applied; symbols are rendered in the same order as the source data.\"\n }\n },\n \"default\": \"auto\",\n \"doc\": \"Determines whether overlapping symbols in the same layer are rendered in the order that they appear in the data source or by their y-position relative to the viewport. To control the order and prioritization of symbols otherwise, use `symbol-sort-key`.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.49.0\",\n \"android\": \"6.6.0\",\n \"ios\": \"4.5.0\",\n \"macos\": \"0.12.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"icon-allow-overlap\": {\n \"type\": \"boolean\",\n \"default\": false,\n \"doc\": \"If true, the icon will be visible even if it collides with other previously drawn symbols.\",\n \"requires\": [\n \"icon-image\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"icon-ignore-placement\": {\n \"type\": \"boolean\",\n \"default\": false,\n \"doc\": \"If true, other symbols can be visible even if they collide with the icon.\",\n \"requires\": [\n \"icon-image\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"icon-optional\": {\n \"type\": \"boolean\",\n \"default\": false,\n \"doc\": \"If true, text will display without their corresponding icons when the icon collides with other symbols and the text does not.\",\n \"requires\": [\n \"icon-image\",\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"icon-rotation-alignment\": {\n \"type\": \"enum\",\n \"values\": {\n \"map\": {\n \"doc\": \"When `symbol-placement` is set to `point`, aligns icons east-west. When `symbol-placement` is set to `line` or `line-center`, aligns icon x-axes with the line.\"\n },\n \"viewport\": {\n \"doc\": \"Produces icons whose x-axes are aligned with the x-axis of the viewport, regardless of the value of `symbol-placement`.\"\n },\n \"auto\": {\n \"doc\": \"When `symbol-placement` is set to `point`, this is equivalent to `viewport`. When `symbol-placement` is set to `line` or `line-center`, this is equivalent to `map`.\"\n }\n },\n \"default\": \"auto\",\n \"doc\": \"In combination with `symbol-placement`, determines the rotation behavior of icons.\",\n \"requires\": [\n \"icon-image\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"`auto` value\": {\n \"js\": \"0.25.0\",\n \"android\": \"4.2.0\",\n \"ios\": \"3.4.0\",\n \"macos\": \"0.3.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"icon-size\": {\n \"type\": \"number\",\n \"default\": 1,\n \"minimum\": 0,\n \"units\": \"factor of the original icon size\",\n \"doc\": \"Scales the original size of the icon by the provided factor. The new pixel size of the image will be the original pixel size multiplied by `icon-size`. 1 is the original size; 3 triples the size of the image.\",\n \"requires\": [\n \"icon-image\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.35.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"icon-text-fit\": {\n \"type\": \"enum\",\n \"values\": {\n \"none\": {\n \"doc\": \"The icon is displayed at its intrinsic aspect ratio.\"\n },\n \"width\": {\n \"doc\": \"The icon is scaled in the x-dimension to fit the width of the text.\"\n },\n \"height\": {\n \"doc\": \"The icon is scaled in the y-dimension to fit the height of the text.\"\n },\n \"both\": {\n \"doc\": \"The icon is scaled in both x- and y-dimensions.\"\n }\n },\n \"default\": \"none\",\n \"doc\": \"Scales the icon to fit around the associated text.\",\n \"requires\": [\n \"icon-image\",\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.21.0\",\n \"android\": \"4.2.0\",\n \"ios\": \"3.4.0\",\n \"macos\": \"0.2.1\"\n },\n \"stretchable icons\": {\n \"js\": \"1.6.0\",\n \"android\": \"9.2.0\",\n \"ios\": \"5.8.0\",\n \"macos\": \"0.15.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"icon-text-fit-padding\": {\n \"type\": \"array\",\n \"value\": \"number\",\n \"length\": 4,\n \"default\": [\n 0,\n 0,\n 0,\n 0\n ],\n \"units\": \"pixels\",\n \"doc\": \"Size of the additional area added to dimensions determined by `icon-text-fit`, in clockwise order: top, right, bottom, left.\",\n \"requires\": [\n \"icon-image\",\n \"text-field\",\n {\n \"icon-text-fit\": [\n \"both\",\n \"width\",\n \"height\"\n ]\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.21.0\",\n \"android\": \"4.2.0\",\n \"ios\": \"3.4.0\",\n \"macos\": \"0.2.1\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"icon-image\": {\n \"type\": \"resolvedImage\",\n \"doc\": \"Name of image in sprite to use for drawing an image background.\",\n \"tokens\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.35.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"icon-rotate\": {\n \"type\": \"number\",\n \"default\": 0,\n \"period\": 360,\n \"units\": \"degrees\",\n \"doc\": \"Rotates the icon clockwise.\",\n \"requires\": [\n \"icon-image\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.21.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"icon-padding\": {\n \"type\": \"number\",\n \"default\": 2,\n \"minimum\": 0,\n \"units\": \"pixels\",\n \"doc\": \"Size of the additional area around the icon bounding box used for detecting symbol collisions.\",\n \"requires\": [\n \"icon-image\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"icon-keep-upright\": {\n \"type\": \"boolean\",\n \"default\": false,\n \"doc\": \"If true, the icon may be flipped to prevent it from being rendered upside-down.\",\n \"requires\": [\n \"icon-image\",\n {\n \"icon-rotation-alignment\": \"map\"\n },\n {\n \"symbol-placement\": [\n \"line\",\n \"line-center\"\n ]\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"icon-offset\": {\n \"type\": \"array\",\n \"value\": \"number\",\n \"length\": 2,\n \"default\": [\n 0,\n 0\n ],\n \"doc\": \"Offset distance of icon from its anchor. Positive values indicate right and down, while negative values indicate left and up. Each component is multiplied by the value of `icon-size` to obtain the final offset in pixels. When combined with `icon-rotate` the offset will be as if the rotated direction was up.\",\n \"requires\": [\n \"icon-image\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.29.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"icon-anchor\": {\n \"type\": \"enum\",\n \"values\": {\n \"center\": {\n \"doc\": \"The center of the icon is placed closest to the anchor.\"\n },\n \"left\": {\n \"doc\": \"The left side of the icon is placed closest to the anchor.\"\n },\n \"right\": {\n \"doc\": \"The right side of the icon is placed closest to the anchor.\"\n },\n \"top\": {\n \"doc\": \"The top of the icon is placed closest to the anchor.\"\n },\n \"bottom\": {\n \"doc\": \"The bottom of the icon is placed closest to the anchor.\"\n },\n \"top-left\": {\n \"doc\": \"The top left corner of the icon is placed closest to the anchor.\"\n },\n \"top-right\": {\n \"doc\": \"The top right corner of the icon is placed closest to the anchor.\"\n },\n \"bottom-left\": {\n \"doc\": \"The bottom left corner of the icon is placed closest to the anchor.\"\n },\n \"bottom-right\": {\n \"doc\": \"The bottom right corner of the icon is placed closest to the anchor.\"\n }\n },\n \"default\": \"center\",\n \"doc\": \"Part of the icon placed closest to the anchor.\",\n \"requires\": [\n \"icon-image\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.40.0\",\n \"android\": \"5.2.0\",\n \"ios\": \"3.7.0\",\n \"macos\": \"0.6.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.40.0\",\n \"android\": \"5.2.0\",\n \"ios\": \"3.7.0\",\n \"macos\": \"0.6.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"icon-pitch-alignment\": {\n \"type\": \"enum\",\n \"values\": {\n \"map\": {\n \"doc\": \"The icon is aligned to the plane of the map.\"\n },\n \"viewport\": {\n \"doc\": \"The icon is aligned to the plane of the viewport.\"\n },\n \"auto\": {\n \"doc\": \"Automatically matches the value of `icon-rotation-alignment`.\"\n }\n },\n \"default\": \"auto\",\n \"doc\": \"Orientation of icon when map is pitched.\",\n \"requires\": [\n \"icon-image\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.39.0\",\n \"android\": \"5.2.0\",\n \"ios\": \"3.7.0\",\n \"macos\": \"0.6.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"text-pitch-alignment\": {\n \"type\": \"enum\",\n \"values\": {\n \"map\": {\n \"doc\": \"The text is aligned to the plane of the map.\"\n },\n \"viewport\": {\n \"doc\": \"The text is aligned to the plane of the viewport.\"\n },\n \"auto\": {\n \"doc\": \"Automatically matches the value of `text-rotation-alignment`.\"\n }\n },\n \"default\": \"auto\",\n \"doc\": \"Orientation of text when map is pitched.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.21.0\",\n \"android\": \"4.2.0\",\n \"ios\": \"3.4.0\",\n \"macos\": \"0.2.1\"\n },\n \"`auto` value\": {\n \"js\": \"0.25.0\",\n \"android\": \"4.2.0\",\n \"ios\": \"3.4.0\",\n \"macos\": \"0.3.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"text-rotation-alignment\": {\n \"type\": \"enum\",\n \"values\": {\n \"map\": {\n \"doc\": \"When `symbol-placement` is set to `point`, aligns text east-west. When `symbol-placement` is set to `line` or `line-center`, aligns text x-axes with the line.\"\n },\n \"viewport\": {\n \"doc\": \"Produces glyphs whose x-axes are aligned with the x-axis of the viewport, regardless of the value of `symbol-placement`.\"\n },\n \"auto\": {\n \"doc\": \"When `symbol-placement` is set to `point`, this is equivalent to `viewport`. When `symbol-placement` is set to `line` or `line-center`, this is equivalent to `map`.\"\n }\n },\n \"default\": \"auto\",\n \"doc\": \"In combination with `symbol-placement`, determines the rotation behavior of the individual glyphs forming the text.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"`auto` value\": {\n \"js\": \"0.25.0\",\n \"android\": \"4.2.0\",\n \"ios\": \"3.4.0\",\n \"macos\": \"0.3.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"text-field\": {\n \"type\": \"formatted\",\n \"default\": \"\",\n \"tokens\": true,\n \"doc\": \"Value to use for a text label. If a plain `string` is provided, it will be treated as a `formatted` with default/inherited formatting options. SDF images are not supported in formatted text and will be ignored.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.33.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"text-font\": {\n \"type\": \"array\",\n \"value\": \"string\",\n \"default\": [\n \"Open Sans Regular\",\n \"Arial Unicode MS Regular\"\n ],\n \"doc\": \"Font stack to use for displaying text.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.43.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"text-size\": {\n \"type\": \"number\",\n \"default\": 16,\n \"minimum\": 0,\n \"units\": \"pixels\",\n \"doc\": \"Font size.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.35.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"text-max-width\": {\n \"type\": \"number\",\n \"default\": 10,\n \"minimum\": 0,\n \"units\": \"ems\",\n \"doc\": \"The maximum line width for text wrapping.\",\n \"requires\": [\n \"text-field\",\n {\n \"symbol-placement\": [\n \"point\"\n ]\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.40.0\",\n \"android\": \"5.2.0\",\n \"ios\": \"3.7.0\",\n \"macos\": \"0.6.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"text-line-height\": {\n \"type\": \"number\",\n \"default\": 1.2,\n \"units\": \"ems\",\n \"doc\": \"Text leading value for multi-line text.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"2.3.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"text-letter-spacing\": {\n \"type\": \"number\",\n \"default\": 0,\n \"units\": \"ems\",\n \"doc\": \"Text tracking amount.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.40.0\",\n \"android\": \"5.2.0\",\n \"ios\": \"3.7.0\",\n \"macos\": \"0.6.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"text-justify\": {\n \"type\": \"enum\",\n \"values\": {\n \"auto\": {\n \"doc\": \"The text is aligned towards the anchor position.\"\n },\n \"left\": {\n \"doc\": \"The text is aligned to the left.\"\n },\n \"center\": {\n \"doc\": \"The text is centered.\"\n },\n \"right\": {\n \"doc\": \"The text is aligned to the right.\"\n }\n },\n \"default\": \"center\",\n \"doc\": \"Text justification options.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.39.0\",\n \"android\": \"5.2.0\",\n \"ios\": \"3.7.0\",\n \"macos\": \"0.6.0\"\n },\n \"auto\": {\n \"js\": \"0.54.0\",\n \"android\": \"7.4.0\",\n \"ios\": \"4.10.0\",\n \"macos\": \"0.14.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"text-radial-offset\": {\n \"type\": \"number\",\n \"units\": \"ems\",\n \"default\": 0,\n \"doc\": \"Radial offset of text, in the direction of the symbol's anchor. Useful in combination with `text-variable-anchor`, which defaults to using the two-dimensional `text-offset` if present.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.54.0\",\n \"android\": \"7.4.0\",\n \"ios\": \"4.10.0\",\n \"macos\": \"0.14.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.54.0\",\n \"android\": \"7.4.0\",\n \"ios\": \"4.10.0\",\n \"macos\": \"0.14.0\"\n }\n },\n \"requires\": [\n \"text-field\"\n ],\n \"property-type\": \"data-driven\",\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n }\n },\n \"text-variable-anchor\": {\n \"type\": \"array\",\n \"value\": \"enum\",\n \"values\": {\n \"center\": {\n \"doc\": \"The center of the text is placed closest to the anchor.\"\n },\n \"left\": {\n \"doc\": \"The left side of the text is placed closest to the anchor.\"\n },\n \"right\": {\n \"doc\": \"The right side of the text is placed closest to the anchor.\"\n },\n \"top\": {\n \"doc\": \"The top of the text is placed closest to the anchor.\"\n },\n \"bottom\": {\n \"doc\": \"The bottom of the text is placed closest to the anchor.\"\n },\n \"top-left\": {\n \"doc\": \"The top left corner of the text is placed closest to the anchor.\"\n },\n \"top-right\": {\n \"doc\": \"The top right corner of the text is placed closest to the anchor.\"\n },\n \"bottom-left\": {\n \"doc\": \"The bottom left corner of the text is placed closest to the anchor.\"\n },\n \"bottom-right\": {\n \"doc\": \"The bottom right corner of the text is placed closest to the anchor.\"\n }\n },\n \"requires\": [\n \"text-field\",\n {\n \"symbol-placement\": [\n \"point\"\n ]\n }\n ],\n \"doc\": \"To increase the chance of placing high-priority labels on the map, you can provide an array of `text-anchor` locations: the renderer will attempt to place the label at each location, in order, before moving onto the next label. Use `text-justify: auto` to choose justification based on anchor position. To apply an offset, use the `text-radial-offset` or the two-dimensional `text-offset`.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.54.0\",\n \"android\": \"7.4.0\",\n \"ios\": \"4.10.0\",\n \"macos\": \"0.14.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"text-anchor\": {\n \"type\": \"enum\",\n \"values\": {\n \"center\": {\n \"doc\": \"The center of the text is placed closest to the anchor.\"\n },\n \"left\": {\n \"doc\": \"The left side of the text is placed closest to the anchor.\"\n },\n \"right\": {\n \"doc\": \"The right side of the text is placed closest to the anchor.\"\n },\n \"top\": {\n \"doc\": \"The top of the text is placed closest to the anchor.\"\n },\n \"bottom\": {\n \"doc\": \"The bottom of the text is placed closest to the anchor.\"\n },\n \"top-left\": {\n \"doc\": \"The top left corner of the text is placed closest to the anchor.\"\n },\n \"top-right\": {\n \"doc\": \"The top right corner of the text is placed closest to the anchor.\"\n },\n \"bottom-left\": {\n \"doc\": \"The bottom left corner of the text is placed closest to the anchor.\"\n },\n \"bottom-right\": {\n \"doc\": \"The bottom right corner of the text is placed closest to the anchor.\"\n }\n },\n \"default\": \"center\",\n \"doc\": \"Part of the text placed closest to the anchor.\",\n \"requires\": [\n \"text-field\",\n {\n \"!\": \"text-variable-anchor\"\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.39.0\",\n \"android\": \"5.2.0\",\n \"ios\": \"3.7.0\",\n \"macos\": \"0.6.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"text-max-angle\": {\n \"type\": \"number\",\n \"default\": 45,\n \"units\": \"degrees\",\n \"doc\": \"Maximum angle change between adjacent characters.\",\n \"requires\": [\n \"text-field\",\n {\n \"symbol-placement\": [\n \"line\",\n \"line-center\"\n ]\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"text-writing-mode\": {\n \"type\": \"array\",\n \"value\": \"enum\",\n \"values\": {\n \"horizontal\": {\n \"doc\": \"If a text's language supports horizontal writing mode, symbols would be laid out horizontally.\"\n },\n \"vertical\": {\n \"doc\": \"If a text's language supports vertical writing mode, symbols would be laid out vertically.\"\n }\n },\n \"doc\": \"The property allows control over a symbol's orientation. Note that the property values act as a hint, so that a symbol whose language doesn’t support the provided orientation will be laid out in its natural orientation. Example: English point symbol will be rendered horizontally even if array value contains single 'vertical' enum value. For symbol with point placement, the order of elements in an array define priority order for the placement of an orientation variant. For symbol with line placement, the default text writing mode is either ['horizontal', 'vertical'] or ['vertical', 'horizontal'], the order doesn't affect the placement.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"1.3.0\",\n \"android\": \"8.3.0\",\n \"ios\": \"5.3.0\",\n \"macos\": \"0.15.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"text-rotate\": {\n \"type\": \"number\",\n \"default\": 0,\n \"period\": 360,\n \"units\": \"degrees\",\n \"doc\": \"Rotates the text clockwise.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.35.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"text-padding\": {\n \"type\": \"number\",\n \"default\": 2,\n \"minimum\": 0,\n \"units\": \"pixels\",\n \"doc\": \"Size of the additional area around the text bounding box used for detecting symbol collisions.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"text-keep-upright\": {\n \"type\": \"boolean\",\n \"default\": true,\n \"doc\": \"If true, the text may be flipped vertically to prevent it from being rendered upside-down.\",\n \"requires\": [\n \"text-field\",\n {\n \"text-rotation-alignment\": \"map\"\n },\n {\n \"symbol-placement\": [\n \"line\",\n \"line-center\"\n ]\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"text-transform\": {\n \"type\": \"enum\",\n \"values\": {\n \"none\": {\n \"doc\": \"The text is not altered.\"\n },\n \"uppercase\": {\n \"doc\": \"Forces all letters to be displayed in uppercase.\"\n },\n \"lowercase\": {\n \"doc\": \"Forces all letters to be displayed in lowercase.\"\n }\n },\n \"default\": \"none\",\n \"doc\": \"Specifies how to capitalize text, similar to the CSS `text-transform` property.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.33.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"text-offset\": {\n \"type\": \"array\",\n \"doc\": \"Offset distance of text from its anchor. Positive values indicate right and down, while negative values indicate left and up. If used with text-variable-anchor, input values will be taken as absolute values. Offsets along the x- and y-axis will be applied automatically based on the anchor position.\",\n \"value\": \"number\",\n \"units\": \"ems\",\n \"length\": 2,\n \"default\": [\n 0,\n 0\n ],\n \"requires\": [\n \"text-field\",\n {\n \"!\": \"text-radial-offset\"\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.35.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"text-allow-overlap\": {\n \"type\": \"boolean\",\n \"default\": false,\n \"doc\": \"If true, the text will be visible even if it collides with other previously drawn symbols.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"text-ignore-placement\": {\n \"type\": \"boolean\",\n \"default\": false,\n \"doc\": \"If true, other symbols can be visible even if they collide with the text.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"text-optional\": {\n \"type\": \"boolean\",\n \"default\": false,\n \"doc\": \"If true, icons will display without their corresponding text when the text collides with other symbols and the icon does not.\",\n \"requires\": [\n \"text-field\",\n \"icon-image\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"visibility\": {\n \"type\": \"enum\",\n \"values\": {\n \"visible\": {\n \"doc\": \"The layer is shown.\"\n },\n \"none\": {\n \"doc\": \"The layer is not shown.\"\n }\n },\n \"default\": \"visible\",\n \"doc\": \"Whether this layer is displayed.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"property-type\": \"constant\"\n }\n },\n \"layout_raster\": {\n \"visibility\": {\n \"type\": \"enum\",\n \"values\": {\n \"visible\": {\n \"doc\": \"The layer is shown.\"\n },\n \"none\": {\n \"doc\": \"The layer is not shown.\"\n }\n },\n \"default\": \"visible\",\n \"doc\": \"Whether this layer is displayed.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"property-type\": \"constant\"\n }\n },\n \"layout_hillshade\": {\n \"visibility\": {\n \"type\": \"enum\",\n \"values\": {\n \"visible\": {\n \"doc\": \"The layer is shown.\"\n },\n \"none\": {\n \"doc\": \"The layer is not shown.\"\n }\n },\n \"default\": \"visible\",\n \"doc\": \"Whether this layer is displayed.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.43.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n },\n \"property-type\": \"constant\"\n }\n },\n \"filter\": {\n \"type\": \"array\",\n \"value\": \"*\",\n \"doc\": \"A filter selects specific features from a layer.\"\n },\n \"filter_symbol\": {\n \"type\": \"boolean\",\n \"doc\": \"Expression which determines whether or not to display a symbol. Symbols support dynamic filtering, meaning this expression can use the `[\\\"pitch\\\"]` and `[\\\"distance-from-center\\\"]` expressions to reference the current state of the view.\",\n \"default\": false,\n \"transition\": false,\n \"property-type\": \"data-driven\",\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\"zoom\", \"feature\", \"pitch\", \"distance-from-center\"]\n }\n },\n \"filter_fill\": {\n \"type\": \"boolean\",\n \"doc\": \"Expression which determines whether or not to display a polygon. Fill layer does NOT support dynamic filtering, meaning this expression can NOT use the `[\\\"pitch\\\"]` and `[\\\"distance-from-center\\\"]` expressions to reference the current state of the view.\",\n \"default\": false,\n \"transition\": false,\n \"property-type\": \"data-driven\",\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\"zoom\", \"feature\"]\n }\n },\n \"filter_line\": {\n \"type\": \"boolean\",\n \"doc\": \"Expression which determines whether or not to display a Polygon or LineString. Line layer does NOT support dynamic filtering, meaning this expression can NOT use the `[\\\"pitch\\\"]` and `[\\\"distance-from-center\\\"]` expressions to reference the current state of the view.\",\n \"default\": false,\n \"transition\": false,\n \"property-type\": \"data-driven\",\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\"zoom\", \"feature\"]\n }\n },\n \"filter_circle\": {\n \"type\": \"boolean\",\n \"doc\": \"Expression which determines whether or not to display a circle. Circle layer does NOT support dynamic filtering, meaning this expression can NOT use the `[\\\"pitch\\\"]` and `[\\\"distance-from-center\\\"]` expressions to reference the current state of the view.\",\n \"default\": false,\n \"transition\": false,\n \"property-type\": \"data-driven\",\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\"zoom\", \"feature\"]\n }\n },\n \"filter_fill-extrusion\": {\n \"type\": \"boolean\",\n \"doc\": \"Expression which determines whether or not to display a Polygon. Fill-extrusion layer does NOT support dynamic filtering, meaning this expression can NOT use the `[\\\"pitch\\\"]` and `[\\\"distance-from-center\\\"]` expressions to reference the current state of the view.\",\n \"default\": false,\n \"transition\": false,\n \"property-type\": \"data-driven\",\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\"zoom\", \"feature\"]\n }\n },\n \"filter_heatmap\": {\n \"type\": \"boolean\",\n \"doc\": \"Expression used to determine whether a point is being displayed or not. Heatmap layer does NOT support dynamic filtering, meaning this expression can NOT use the `[\\\"pitch\\\"]` and `[\\\"distance-from-center\\\"]` expressions to reference the current state of the view.\",\n \"default\": false,\n \"transition\": false,\n \"property-type\": \"data-driven\",\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\"zoom\", \"feature\"]\n }\n },\n \"filter_operator\": {\n \"type\": \"enum\",\n \"values\": {\n \"==\": {\n \"doc\": \"`[\\\"==\\\", key, value]` equality: `feature[key] = value`\"\n },\n \"!=\": {\n \"doc\": \"`[\\\"!=\\\", key, value]` inequality: `feature[key] ≠ value`\"\n },\n \">\": {\n \"doc\": \"`[\\\">\\\", key, value]` greater than: `feature[key] > value`\"\n },\n \">=\": {\n \"doc\": \"`[\\\">=\\\", key, value]` greater than or equal: `feature[key] ≥ value`\"\n },\n \"<\": {\n \"doc\": \"`[\\\"<\\\", key, value]` less than: `feature[key] < value`\"\n },\n \"<=\": {\n \"doc\": \"`[\\\"<=\\\", key, value]` less than or equal: `feature[key] ≤ value`\"\n },\n \"in\": {\n \"doc\": \"`[\\\"in\\\", key, v0, ..., vn]` set inclusion: `feature[key] ∈ {v0, ..., vn}`\"\n },\n \"!in\": {\n \"doc\": \"`[\\\"!in\\\", key, v0, ..., vn]` set exclusion: `feature[key] ∉ {v0, ..., vn}`\"\n },\n \"all\": {\n \"doc\": \"`[\\\"all\\\", f0, ..., fn]` logical `AND`: `f0 ∧ ... ∧ fn`\"\n },\n \"any\": {\n \"doc\": \"`[\\\"any\\\", f0, ..., fn]` logical `OR`: `f0 ∨ ... ∨ fn`\"\n },\n \"none\": {\n \"doc\": \"`[\\\"none\\\", f0, ..., fn]` logical `NOR`: `¬f0 ∧ ... ∧ ¬fn`\"\n },\n \"has\": {\n \"doc\": \"`[\\\"has\\\", key]` `feature[key]` exists\"\n },\n \"!has\": {\n \"doc\": \"`[\\\"!has\\\", key]` `feature[key]` does not exist\"\n },\n \"within\": {\n \"doc\": \"`[\\\"within\\\", object]` feature geometry is within object geometry\"\n }\n },\n \"doc\": \"The filter operator.\"\n },\n \"geometry_type\": {\n \"type\": \"enum\",\n \"values\": {\n \"Point\": {\n \"doc\": \"Filter to point geometries.\"\n },\n \"LineString\": {\n \"doc\": \"Filter to line geometries.\"\n },\n \"Polygon\": {\n \"doc\": \"Filter to polygon geometries.\"\n }\n },\n \"doc\": \"The geometry type for the filter to select.\"\n },\n \"function\": {\n \"expression\": {\n \"type\": \"expression\",\n \"doc\": \"An expression.\"\n },\n \"stops\": {\n \"type\": \"array\",\n \"doc\": \"An array of stops.\",\n \"value\": \"function_stop\"\n },\n \"base\": {\n \"type\": \"number\",\n \"default\": 1,\n \"minimum\": 0,\n \"doc\": \"The exponential base of the interpolation curve. It controls the rate at which the result increases. Higher values make the result increase more towards the high end of the range. With `1` the stops are interpolated linearly.\"\n },\n \"property\": {\n \"type\": \"string\",\n \"doc\": \"The name of a feature property to use as the function input.\",\n \"default\": \"$zoom\"\n },\n \"type\": {\n \"type\": \"enum\",\n \"values\": {\n \"identity\": {\n \"doc\": \"Return the input value as the output value.\"\n },\n \"exponential\": {\n \"doc\": \"Generate an output by interpolating between stops just less than and just greater than the function input.\"\n },\n \"interval\": {\n \"doc\": \"Return the output value of the stop just less than the function input.\"\n },\n \"categorical\": {\n \"doc\": \"Return the output value of the stop equal to the function input.\"\n }\n },\n \"doc\": \"The interpolation strategy to use in function evaluation.\",\n \"default\": \"exponential\"\n },\n \"colorSpace\": {\n \"type\": \"enum\",\n \"values\": {\n \"rgb\": {\n \"doc\": \"Use the RGB color space to interpolate color values\"\n },\n \"lab\": {\n \"doc\": \"Use the LAB color space to interpolate color values.\"\n },\n \"hcl\": {\n \"doc\": \"Use the HCL color space to interpolate color values, interpolating the Hue, Chroma, and Luminance channels individually.\"\n }\n },\n \"doc\": \"The color space in which colors interpolated. Interpolating colors in perceptual color spaces like LAB and HCL tend to produce color ramps that look more consistent and produce colors that can be differentiated more easily than those interpolated in RGB space.\",\n \"default\": \"rgb\"\n },\n \"default\": {\n \"type\": \"*\",\n \"required\": false,\n \"doc\": \"A value to serve as a fallback function result when a value isn't otherwise available. It is used in the following circumstances:\\n* In categorical functions, when the feature value does not match any of the stop domain values.\\n* In property and zoom-and-property functions, when a feature does not contain a value for the specified property.\\n* In identity functions, when the feature value is not valid for the style property (for example, if the function is being used for a `circle-color` property but the feature property value is not a string or not a valid color).\\n* In interval or exponential property and zoom-and-property functions, when the feature value is not numeric.\\nIf no default is provided, the style property's default is used in these circumstances.\"\n }\n },\n \"function_stop\": {\n \"type\": \"array\",\n \"minimum\": 0,\n \"maximum\": 24,\n \"value\": [\n \"number\",\n \"color\"\n ],\n \"length\": 2,\n \"doc\": \"Zoom level and value pair.\"\n },\n \"expression\": {\n \"type\": \"array\",\n \"value\": \"*\",\n \"minimum\": 1,\n \"doc\": \"An expression defines a function that can be used for data-driven style properties or feature filters.\"\n },\n \"expression_name\": {\n \"doc\": \"\",\n \"type\": \"enum\",\n \"values\": {\n \"let\": {\n \"doc\": \"Binds expressions to named variables, which can then be referenced in the result expression using [\\\"var\\\", \\\"variable_name\\\"].\",\n \"group\": \"Variable binding\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"var\": {\n \"doc\": \"References variable bound using \\\"let\\\".\",\n \"group\": \"Variable binding\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"literal\": {\n \"doc\": \"Provides a literal array or object value.\",\n \"group\": \"Types\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"array\": {\n \"doc\": \"Asserts that the input is an array (optionally with a specific item type and length). If, when the input expression is evaluated, it is not of the asserted type, then this assertion will cause the whole expression to be aborted.\",\n \"group\": \"Types\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"at\": {\n \"doc\": \"Retrieves an item from an array.\",\n \"group\": \"Lookup\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"in\": {\n \"doc\": \"Determines whether an item exists in an array or a substring exists in a string. In the specific case when the second and third arguments are string literals, you must wrap at least one of them in a [`literal`](#types-literal) expression to hint correct interpretation to the [type system](#type-system).\",\n \"group\": \"Lookup\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"1.6.0\",\n \"android\": \"9.1.0\",\n \"ios\": \"5.8.0\",\n \"macos\": \"0.15.0\"\n }\n }\n },\n \"index-of\": {\n \"doc\": \"Returns the first position at which an item can be found in an array or a substring can be found in a string, or `-1` if the input cannot be found. Accepts an optional index from where to begin the search.\",\n \"group\": \"Lookup\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"1.10.0\"\n }\n }\n },\n \"slice\": {\n \"doc\": \"Returns an item from an array or a substring from a string from a specified start index, or between a start index and an end index if set. The return value is inclusive of the start index but not of the end index.\",\n \"group\": \"Lookup\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"1.10.0\"\n }\n }\n },\n \"case\": {\n \"doc\": \"Selects the first output whose corresponding test condition evaluates to true, or the fallback value otherwise.\",\n \"group\": \"Decision\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"match\": {\n \"doc\": \"Selects the output for which the label value matches the input value, or the fallback value if no match is found. The input can be any expression (for example, `[\\\"get\\\", \\\"building_type\\\"]`). Each label must be unique, and must be either:\\n - a single literal value; or\\n - an array of literal values, the values of which must be all strings or all numbers (for example `[100, 101]` or `[\\\"c\\\", \\\"b\\\"]`).\\n\\nThe input matches if any of the values in the array matches using strict equality, similar to the `\\\"in\\\"` operator.\\nIf the input type does not match the type of the labels, the result will be the fallback value.\",\n \"group\": \"Decision\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"coalesce\": {\n \"doc\": \"Evaluates each expression in turn until the first valid value is obtained. Invalid values are `null` and [`'image'`](#types-image) expressions that are unavailable in the style. If all values are invalid, `coalesce` returns the first value listed.\",\n \"group\": \"Decision\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"step\": {\n \"doc\": \"Produces discrete, stepped results by evaluating a piecewise-constant function defined by pairs of input and output values (\\\"stops\\\"). The `input` may be any numeric expression (e.g., `[\\\"get\\\", \\\"population\\\"]`). Stop inputs must be numeric literals in strictly ascending order. Returns the output value of the stop just less than the input, or the first output if the input is less than the first stop.\",\n \"group\": \"Ramps, scales, curves\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.42.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"interpolate\": {\n \"doc\": \"Produces continuous, smooth results by interpolating between pairs of input and output values (\\\"stops\\\"). The `input` may be any numeric expression (e.g., `[\\\"get\\\", \\\"population\\\"]`). Stop inputs must be numeric literals in strictly ascending order. The output type must be `number`, `array`, or `color`.\\n\\nInterpolation types:\\n- `[\\\"linear\\\"]`: Interpolates linearly between the pair of stops just less than and just greater than the input.\\n- `[\\\"exponential\\\", base]`: Interpolates exponentially between the stops just less than and just greater than the input. `base` controls the rate at which the output increases: higher values make the output increase more towards the high end of the range. With values close to 1 the output increases linearly.\\n- `[\\\"cubic-bezier\\\", x1, y1, x2, y2]`: Interpolates using the cubic bezier curve defined by the given control points.\",\n \"group\": \"Ramps, scales, curves\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.42.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"interpolate-hcl\": {\n \"doc\": \"Produces continuous, smooth results by interpolating between pairs of input and output values (\\\"stops\\\"). Works like `interpolate`, but the output type must be `color`, and the interpolation is performed in the Hue-Chroma-Luminance color space.\",\n \"group\": \"Ramps, scales, curves\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.49.0\"\n }\n }\n },\n \"interpolate-lab\": {\n \"doc\": \"Produces continuous, smooth results by interpolating between pairs of input and output values (\\\"stops\\\"). Works like `interpolate`, but the output type must be `color`, and the interpolation is performed in the CIELAB color space.\",\n \"group\": \"Ramps, scales, curves\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.49.0\"\n }\n }\n },\n \"ln2\": {\n \"doc\": \"Returns mathematical constant ln(2).\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"pi\": {\n \"doc\": \"Returns the mathematical constant pi.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"e\": {\n \"doc\": \"Returns the mathematical constant e.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"typeof\": {\n \"doc\": \"Returns a string describing the type of the given value.\",\n \"group\": \"Types\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"string\": {\n \"doc\": \"Asserts that the input value is a string. If multiple values are provided, each one is evaluated in order until a string is obtained. If none of the inputs are strings, the expression is an error.\",\n \"group\": \"Types\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"number\": {\n \"doc\": \"Asserts that the input value is a number. If multiple values are provided, each one is evaluated in order until a number is obtained. If none of the inputs are numbers, the expression is an error.\",\n \"group\": \"Types\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"boolean\": {\n \"doc\": \"Asserts that the input value is a boolean. If multiple values are provided, each one is evaluated in order until a boolean is obtained. If none of the inputs are booleans, the expression is an error.\",\n \"group\": \"Types\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"object\": {\n \"doc\": \"Asserts that the input value is an object. If multiple values are provided, each one is evaluated in order until an object is obtained. If none of the inputs are objects, the expression is an error.\",\n \"group\": \"Types\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"collator\": {\n \"doc\": \"Returns a `collator` for use in locale-dependent comparison operations. The `case-sensitive` and `diacritic-sensitive` options default to `false`. The `locale` argument specifies the IETF language tag of the locale to use. If none is provided, the default locale is used. If the requested locale is not available, the `collator` will use a system-defined fallback locale. Use `resolved-locale` to test the results of locale fallback behavior.\",\n \"group\": \"Types\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.45.0\",\n \"android\": \"6.5.0\",\n \"ios\": \"4.2.0\",\n \"macos\": \"0.9.0\"\n }\n }\n },\n \"format\": {\n \"doc\": \"Returns a `formatted` string for displaying mixed-format text in the `text-field` property. The input may contain a string literal or expression, including an [`'image'`](#types-image) expression. Strings may be followed by a style override object that supports the following properties:\\n- `\\\"text-font\\\"`: Overrides the font stack specified by the root layout property.\\n- `\\\"text-color\\\"`: Overrides the color specified by the root paint property.\\n- `\\\"font-scale\\\"`: Applies a scaling factor on `text-size` as specified by the root layout property.\",\n \"group\": \"Types\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.48.0\",\n \"android\": \"6.7.0\",\n \"ios\": \"4.6.0\",\n \"macos\": \"0.12.0\"\n },\n \"text-font\": {\n \"js\": \"0.48.0\",\n \"android\": \"6.7.0\",\n \"ios\": \"4.6.0\",\n \"macos\": \"0.12.0\"\n },\n \"font-scale\": {\n \"js\": \"0.48.0\",\n \"android\": \"6.7.0\",\n \"ios\": \"4.6.0\",\n \"macos\": \"0.12.0\"\n },\n \"text-color\": {\n \"js\": \"1.3.0\",\n \"android\": \"7.3.0\",\n \"ios\": \"4.10.0\",\n \"macos\": \"0.14.0\"\n },\n \"image\": {\n \"js\": \"1.6.0\",\n \"android\": \"8.6.0\",\n \"ios\": \"5.7.0\",\n \"macos\": \"0.15.0\"\n }\n }\n },\n \"image\": {\n \"doc\": \"Returns a [`ResolvedImage`](/mapbox-gl-js/style-spec/types/#resolvedimage) for use in [`icon-image`](/mapbox-gl-js/style-spec/layers/#layout-symbol-icon-image), `*-pattern` entries, and as a section in the [`'format'`](#types-format) expression. A [`'coalesce'`](#coalesce) expression containing `image` expressions will evaluate to the first listed image that is currently in the style. This validation process is synchronous and requires the image to have been added to the style before requesting it in the `'image'` argument.\",\n \"group\": \"Types\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"1.4.0\",\n \"android\": \"8.6.0\",\n \"ios\": \"5.7.0\",\n \"macos\": \"0.15.0\"\n }\n }\n },\n \"number-format\": {\n \"doc\": \"Converts the input number into a string representation using the providing formatting rules. If set, the `locale` argument specifies the locale to use, as a BCP 47 language tag. If set, the `currency` argument specifies an ISO 4217 code to use for currency-style formatting. If set, the `min-fraction-digits` and `max-fraction-digits` arguments specify the minimum and maximum number of fractional digits to include.\",\n \"group\": \"Types\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.54.0\",\n \"android\" : \"8.4.0\",\n \"ios\": \"5.4.0\",\n \"macos\": \"0.15.0\"\n }\n }\n },\n \"to-string\": {\n \"doc\": \"Converts the input value to a string. If the input is `null`, the result is `\\\"\\\"`. If the input is a [`boolean`](#types-boolean), the result is `\\\"true\\\"` or `\\\"false\\\"`. If the input is a number, it is converted to a string as specified by the [\\\"NumberToString\\\" algorithm](https://tc39.github.io/ecma262/#sec-tostring-applied-to-the-number-type) of the ECMAScript Language Specification. If the input is a [`color`](#color), it is converted to a string of the form `\\\"rgba(r,g,b,a)\\\"`, where `r`, `g`, and `b` are numerals ranging from 0 to 255, and `a` ranges from 0 to 1. If the input is an [`'image'`](#types-image) expression, `'to-string'` returns the image name. Otherwise, the input is converted to a string in the format specified by the [`JSON.stringify`](https://tc39.github.io/ecma262/#sec-json.stringify) function of the ECMAScript Language Specification.\",\n \"group\": \"Types\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"to-number\": {\n \"doc\": \"Converts the input value to a number, if possible. If the input is `null` or `false`, the result is 0. If the input is `true`, the result is 1. If the input is a string, it is converted to a number as specified by the [\\\"ToNumber Applied to the String Type\\\" algorithm](https://tc39.github.io/ecma262/#sec-tonumber-applied-to-the-string-type) of the ECMAScript Language Specification. If multiple values are provided, each one is evaluated in order until the first successful conversion is obtained. If none of the inputs can be converted, the expression is an error.\",\n \"group\": \"Types\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"to-boolean\": {\n \"doc\": \"Converts the input value to a boolean. The result is `false` when then input is an empty string, 0, `false`, `null`, or `NaN`; otherwise it is `true`.\",\n \"group\": \"Types\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"to-rgba\": {\n \"doc\": \"Returns a four-element array containing the input color's red, green, blue, and alpha components, in that order.\",\n \"group\": \"Color\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"to-color\": {\n \"doc\": \"Converts the input value to a color. If multiple values are provided, each one is evaluated in order until the first successful conversion is obtained. If none of the inputs can be converted, the expression is an error.\",\n \"group\": \"Types\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"rgb\": {\n \"doc\": \"Creates a color value from red, green, and blue components, which must range between 0 and 255, and an alpha component of 1. If any component is out of range, the expression is an error.\",\n \"group\": \"Color\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"rgba\": {\n \"doc\": \"Creates a color value from red, green, blue components, which must range between 0 and 255, and an alpha component which must range between 0 and 1. If any component is out of range, the expression is an error.\",\n \"group\": \"Color\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"get\": {\n \"doc\": \"Retrieves a property value from the current feature's properties, or from another object if a second argument is provided. Returns `null` if the requested property is missing.\",\n \"group\": \"Lookup\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"has\": {\n \"doc\": \"Tests for the presence of an property value in the current feature's properties, or from another object if a second argument is provided.\",\n \"group\": \"Lookup\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"length\": {\n \"doc\": \"Returns the length of an array or string.\",\n \"group\": \"Lookup\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"properties\": {\n \"doc\": \"Returns the feature properties object. Note that in some cases, it may be more efficient to use `[\\\"get\\\", \\\"property_name\\\"]` directly.\",\n \"group\": \"Feature data\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"feature-state\": {\n \"doc\": \"Retrieves a property value from the current feature's state. Returns `null` if the requested property is not present on the feature's state. A feature's state is not part of the GeoJSON or vector tile data, and must be set programmatically on each feature. Features are identified by their `id` attribute, which must be an integer or a string that can be cast to an integer. Note that [\\\"feature-state\\\"] can only be used with paint properties that support data-driven styling.\",\n \"group\": \"Feature data\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.46.0\"\n }\n }\n },\n \"geometry-type\": {\n \"doc\": \"Returns the feature's geometry type: `Point`, `MultiPoint`, `LineString`, `MultiLineString`, `Polygon`, `MultiPolygon`. `Multi*` feature types are only returned in GeoJSON sources. When working with vector tile sources, use the singular forms.\",\n \"group\": \"Feature data\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"id\": {\n \"doc\": \"Returns the feature's id, if it has one.\",\n \"group\": \"Feature data\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"zoom\": {\n \"doc\": \"Returns the current zoom level. Note that in style layout and paint properties, [\\\"zoom\\\"] may only appear as the input to a top-level \\\"step\\\" or \\\"interpolate\\\" expression.\",\n \"group\": \"Camera\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"pitch\": {\n \"doc\": \"Returns the current pitch in degrees. `[\\\"pitch\\\"]` may only be used in the `filter` expression for a `symbol` layer.\",\n \"group\": \"Camera\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.6.0\"\n }\n }\n },\n \"distance-from-center\": {\n \"doc\": \"Returns the distance of a `symbol` instance from the center of the map. The distance is measured in pixels divided by the height of the map container. It measures 0 at the center, decreases towards the camera and increase away from the camera. For example, if the height of the map is 1000px, a value of -1 means 1000px away from the center towards the camera, and a value of 1 means a distance of 1000px away from the camera from the center. `[\\\"distance-from-center\\\"]` may only be used in the `filter` expression for a `symbol` layer.\",\n \"group\": \"Camera\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.6.0\"\n }\n }\n },\n \"heatmap-density\": {\n \"doc\": \"Returns the kernel density estimation of a pixel in a heatmap layer, which is a relative measure of how many data points are crowded around a particular pixel. Can only be used in the `heatmap-color` property.\",\n \"group\": \"Heatmap\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"line-progress\": {\n \"doc\": \"Returns the progress along a gradient line. Can only be used in the `line-gradient` property.\",\n \"group\": \"Feature data\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.45.0\",\n \"android\": \"6.5.0\",\n \"ios\": \"4.6.0\",\n \"macos\": \"0.12.0\"\n }\n }\n },\n \"sky-radial-progress\": {\n \"doc\": \"Returns the distance of a point on the sky from the sun position. Returns 0 at sun position and 1 when the distance reaches `sky-gradient-radius`. Can only be used in the `sky-gradient` property.\",\n \"group\": \"sky\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.0.0\",\n \"ios\": \"10.0.0\",\n \"android\": \"10.0.0\"\n }\n }\n },\n \"accumulated\": {\n \"doc\": \"Returns the value of a cluster property accumulated so far. Can only be used in the `clusterProperties` option of a clustered GeoJSON source.\",\n \"group\": \"Feature data\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.53.0\",\n \"android\": \"8.4.0\",\n \"ios\": \"5.5.0\",\n \"macos\": \"0.15.0\"\n }\n }\n },\n \"+\": {\n \"doc\": \"Returns the sum of the inputs.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"*\": {\n \"doc\": \"Returns the product of the inputs.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"-\": {\n \"doc\": \"For two inputs, returns the result of subtracting the second input from the first. For a single input, returns the result of subtracting it from 0.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"/\": {\n \"doc\": \"Returns the result of floating point division of the first input by the second.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"%\": {\n \"doc\": \"Returns the remainder after integer division of the first input by the second.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"^\": {\n \"doc\": \"Returns the result of raising the first input to the power specified by the second.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"sqrt\": {\n \"doc\": \"Returns the square root of the input.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.42.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"log10\": {\n \"doc\": \"Returns the base-ten logarithm of the input.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"ln\": {\n \"doc\": \"Returns the natural logarithm of the input.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"log2\": {\n \"doc\": \"Returns the base-two logarithm of the input.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"sin\": {\n \"doc\": \"Returns the sine of the input.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"cos\": {\n \"doc\": \"Returns the cosine of the input.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"tan\": {\n \"doc\": \"Returns the tangent of the input.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"asin\": {\n \"doc\": \"Returns the arcsine of the input.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"acos\": {\n \"doc\": \"Returns the arccosine of the input.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"atan\": {\n \"doc\": \"Returns the arctangent of the input.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"min\": {\n \"doc\": \"Returns the minimum value of the inputs.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"max\": {\n \"doc\": \"Returns the maximum value of the inputs.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"round\": {\n \"doc\": \"Rounds the input to the nearest integer. Halfway values are rounded away from zero. For example, `[\\\"round\\\", -1.5]` evaluates to -2.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.45.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"abs\": {\n \"doc\": \"Returns the absolute value of the input.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.45.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"ceil\": {\n \"doc\": \"Returns the smallest integer that is greater than or equal to the input.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.45.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"floor\": {\n \"doc\": \"Returns the largest integer that is less than or equal to the input.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.45.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"distance\": {\n \"doc\": \"Returns the shortest distance in meters between the evaluated feature and the input geometry. The input value can be a valid GeoJSON of type `Point`, `MultiPoint`, `LineString`, `MultiLineString`, `Polygon`, `MultiPolygon`, `Feature`, or `FeatureCollection`. Distance values returned may vary in precision due to loss in precision from encoding geometries, particularly below zoom level 13.\",\n \"group\": \"Math\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"android\": \"9.2.0\",\n \"ios\": \"5.9.0\",\n \"macos\": \"0.16.0\"\n }\n }\n },\n \"==\": {\n \"doc\": \"Returns `true` if the input values are equal, `false` otherwise. The comparison is strictly typed: values of different runtime types are always considered unequal. Cases where the types are known to be different at parse time are considered invalid and will produce a parse error. Accepts an optional `collator` argument to control locale-dependent string comparisons.\",\n \"group\": \"Decision\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n },\n \"collator\": {\n \"js\": \"0.45.0\",\n \"android\": \"6.5.0\",\n \"ios\": \"4.2.0\",\n \"macos\": \"0.9.0\"\n }\n }\n },\n \"!=\": {\n \"doc\": \"Returns `true` if the input values are not equal, `false` otherwise. The comparison is strictly typed: values of different runtime types are always considered unequal. Cases where the types are known to be different at parse time are considered invalid and will produce a parse error. Accepts an optional `collator` argument to control locale-dependent string comparisons.\",\n \"group\": \"Decision\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n },\n \"collator\": {\n \"js\": \"0.45.0\",\n \"android\": \"6.5.0\",\n \"ios\": \"4.2.0\",\n \"macos\": \"0.9.0\"\n }\n }\n },\n \">\": {\n \"doc\": \"Returns `true` if the first input is strictly greater than the second, `false` otherwise. The arguments are required to be either both strings or both numbers; if during evaluation they are not, expression evaluation produces an error. Cases where this constraint is known not to hold at parse time are considered in valid and will produce a parse error. Accepts an optional `collator` argument to control locale-dependent string comparisons.\",\n \"group\": \"Decision\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n },\n \"collator\": {\n \"js\": \"0.45.0\",\n \"android\": \"6.5.0\",\n \"ios\": \"4.2.0\",\n \"macos\": \"0.9.0\"\n }\n }\n },\n \"<\": {\n \"doc\": \"Returns `true` if the first input is strictly less than the second, `false` otherwise. The arguments are required to be either both strings or both numbers; if during evaluation they are not, expression evaluation produces an error. Cases where this constraint is known not to hold at parse time are considered in valid and will produce a parse error. Accepts an optional `collator` argument to control locale-dependent string comparisons.\",\n \"group\": \"Decision\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n },\n \"collator\": {\n \"js\": \"0.45.0\",\n \"android\": \"6.5.0\",\n \"ios\": \"4.2.0\",\n \"macos\": \"0.9.0\"\n }\n }\n },\n \">=\": {\n \"doc\": \"Returns `true` if the first input is greater than or equal to the second, `false` otherwise. The arguments are required to be either both strings or both numbers; if during evaluation they are not, expression evaluation produces an error. Cases where this constraint is known not to hold at parse time are considered in valid and will produce a parse error. Accepts an optional `collator` argument to control locale-dependent string comparisons.\",\n \"group\": \"Decision\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n },\n \"collator\": {\n \"js\": \"0.45.0\",\n \"android\": \"6.5.0\",\n \"ios\": \"4.2.0\",\n \"macos\": \"0.9.0\"\n }\n }\n },\n \"<=\": {\n \"doc\": \"Returns `true` if the first input is less than or equal to the second, `false` otherwise. The arguments are required to be either both strings or both numbers; if during evaluation they are not, expression evaluation produces an error. Cases where this constraint is known not to hold at parse time are considered in valid and will produce a parse error. Accepts an optional `collator` argument to control locale-dependent string comparisons.\",\n \"group\": \"Decision\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n },\n \"collator\": {\n \"js\": \"0.45.0\",\n \"android\": \"6.5.0\",\n \"ios\": \"4.2.0\",\n \"macos\": \"0.9.0\"\n }\n }\n },\n \"all\": {\n \"doc\": \"Returns `true` if all the inputs are `true`, `false` otherwise. The inputs are evaluated in order, and evaluation is short-circuiting: once an input expression evaluates to `false`, the result is `false` and no further input expressions are evaluated.\",\n \"group\": \"Decision\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"any\": {\n \"doc\": \"Returns `true` if any of the inputs are `true`, `false` otherwise. The inputs are evaluated in order, and evaluation is short-circuiting: once an input expression evaluates to `true`, the result is `true` and no further input expressions are evaluated.\",\n \"group\": \"Decision\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"!\": {\n \"doc\": \"Logical negation. Returns `true` if the input is `false`, and `false` if the input is `true`.\",\n \"group\": \"Decision\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"within\": {\n \"doc\": \"Returns `true` if the evaluated feature is fully contained inside a boundary of the input geometry, `false` otherwise. The input value can be a valid GeoJSON of type `Polygon`, `MultiPolygon`, `Feature`, or `FeatureCollection`. Supported features for evaluation:\\n- `Point`: Returns `false` if a point is on the boundary or falls outside the boundary.\\n- `LineString`: Returns `false` if any part of a line falls outside the boundary, the line intersects the boundary, or a line's endpoint is on the boundary.\",\n \"group\": \"Decision\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"1.9.0\",\n \"android\": \"9.1.0\",\n \"ios\": \"5.8.0\",\n \"macos\": \"0.15.0\"\n }\n }\n },\n \"is-supported-script\": {\n \"doc\": \"Returns `true` if the input string is expected to render legibly. Returns `false` if the input string contains sections that cannot be rendered without potential loss of meaning (e.g. Indic scripts that require complex text shaping, or right-to-left scripts if the the `mapbox-gl-rtl-text` plugin is not in use in Mapbox GL JS).\",\n \"group\": \"String\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.45.0\",\n \"android\": \"6.6.0\"\n }\n }\n },\n \"upcase\": {\n \"doc\": \"Returns the input string converted to uppercase. Follows the Unicode Default Case Conversion algorithm and the locale-insensitive case mappings in the Unicode Character Database.\",\n \"group\": \"String\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"downcase\": {\n \"doc\": \"Returns the input string converted to lowercase. Follows the Unicode Default Case Conversion algorithm and the locale-insensitive case mappings in the Unicode Character Database.\",\n \"group\": \"String\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"concat\": {\n \"doc\": \"Returns a `string` consisting of the concatenation of the inputs. Each input is converted to a string as if by `to-string`.\",\n \"group\": \"String\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n }\n },\n \"resolved-locale\": {\n \"doc\": \"Returns the IETF language tag of the locale being used by the provided `collator`. This can be used to determine the default system locale, or to determine if a requested locale was successfully loaded.\",\n \"group\": \"String\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.45.0\",\n \"android\": \"6.5.0\",\n \"ios\": \"4.2.0\",\n \"macos\": \"0.9.0\"\n }\n }\n }\n }\n },\n \"fog\": {\n \"range\": {\n \"type\": \"array\",\n \"default\": [\n 0.5,\n 10\n ],\n \"minimum\": -20,\n \"maximum\": 20,\n \"length\": 2,\n \"value\": \"number\",\n \"property-type\": \"data-constant\",\n \"transition\": true,\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"doc\": \"The start and end distance range in which fog fades from fully transparent to fully opaque. The distance to the point at the center of the map is defined as zero, so that negative range values are closer to the camera, and positive values are farther away.\",\n \"example\": [\n 0.5,\n 10\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.3.0\"\n }\n }\n },\n \"color\": {\n \"type\": \"color\",\n \"property-type\": \"data-constant\",\n \"default\": \"#ffffff\",\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"transition\": true,\n \"doc\": \"The color of the fog. Using opacity is recommended only for smoothly transitioning fog on/off as anything less than 100% opacity results in more tiles loaded and drawn.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.3.0\"\n }\n }\n },\n \"horizon-blend\": {\n \"type\": \"number\",\n \"property-type\": \"data-constant\",\n \"default\": 0.1,\n \"minimum\": 0,\n \"maximum\": 1,\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"transition\": true,\n \"doc\": \"Horizon blend applies a smooth fade from the color of the fog to the color of the sky. A value of zero leaves a sharp transition from fog to sky. Increasing the value blends the color of fog into increasingly high angles of the sky.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.3.0\"\n }\n }\n }\n },\n \"light\": {\n \"anchor\": {\n \"type\": \"enum\",\n \"default\": \"viewport\",\n \"values\": {\n \"map\": {\n \"doc\": \"The position of the light source is aligned to the rotation of the map.\"\n },\n \"viewport\": {\n \"doc\": \"The position of the light source is aligned to the rotation of the viewport.\"\n }\n },\n \"property-type\": \"data-constant\",\n \"transition\": false,\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"doc\": \"Whether extruded geometries are lit relative to the map or viewport.\",\n \"example\": \"map\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.27.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n }\n },\n \"position\": {\n \"type\": \"array\",\n \"default\": [\n 1.15,\n 210,\n 30\n ],\n \"length\": 3,\n \"value\": \"number\",\n \"property-type\": \"data-constant\",\n \"transition\": true,\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"doc\": \"Position of the light source relative to lit (extruded) geometries, in [r radial coordinate, a azimuthal angle, p polar angle] where r indicates the distance from the center of the base of an object to its light, a indicates the position of the light relative to 0° (0° when `light.anchor` is set to `viewport` corresponds to the top of the viewport, or 0° when `light.anchor` is set to `map` corresponds to due north, and degrees proceed clockwise), and p indicates the height of the light (from 0°, directly above, to 180°, directly below).\",\n \"example\": [\n 1.5,\n 90,\n 80\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.27.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n }\n },\n \"color\": {\n \"type\": \"color\",\n \"property-type\": \"data-constant\",\n \"default\": \"#ffffff\",\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"transition\": true,\n \"doc\": \"Color tint for lighting extruded geometries.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.27.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n }\n },\n \"intensity\": {\n \"type\": \"number\",\n \"property-type\": \"data-constant\",\n \"default\": 0.5,\n \"minimum\": 0,\n \"maximum\": 1,\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"transition\": true,\n \"doc\": \"Intensity of lighting (on a scale from 0 to 1). Higher numbers will present as more extreme contrast.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.27.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n }\n }\n },\n \"projection\": {\n \"name\": {\n \"type\": \"enum\",\n \"values\": {\n \"albers\": {\n \"doc\": \"An Albers equal-area projection centered on the continental United States. You can configure the projection for a different region by setting `center` and `parallels` properties. You may want to set max bounds to constrain the map to the relevant region.\"\n },\n \"equalEarth\": {\n \"doc\": \"An Equal Earth projection.\"\n },\n \"equirectangular\": {\n \"doc\": \"An Equirectangular projection. This projection is very similar to the Plate Carrée projection.\"\n },\n \"lambertConformalConic\": {\n \"doc\": \"A Lambert conformal conic projection. You can configure the projection for a region by setting `center` and `parallels` properties. You may want to set max bounds to constrain the map to the relevant region.\"\n },\n \"mercator\": {\n \"doc\": \"The Mercator projection is the default projection.\"\n },\n \"naturalEarth\": {\n \"doc\": \"A Natural Earth projection.\"\n },\n \"winkelTripel\": {\n \"doc\": \"A Winkel Tripel projection.\"\n }\n },\n \"default\": \"mercator\",\n \"doc\": \"The name of the projection to be used for rendering the map.\",\n \"required\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.6.0\"\n }\n }\n },\n \"center\": {\n \"type\": \"array\",\n \"length\": 2,\n \"value\": \"number\",\n \"property-type\": \"data-constant\",\n \"transition\": false,\n \"doc\": \"The reference longitude and latitude of the projection. `center` takes the form of [lng, lat]. This property is only configurable for conic projections (Albers and Lambert Conformal Conic). All other projections are centered on [0, 0].\",\n \"example\": [\n -96,\n 37.5\n ],\n \"requires\": [\n {\n \"name\": [\n \"albers\",\n \"lambertConformalConic\"\n ]\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.6.0\"\n }\n }\n },\n \"parallels\": {\n \"type\": \"array\",\n \"length\": 2,\n \"value\": \"number\",\n \"property-type\": \"data-constant\",\n \"transition\": false,\n \"doc\": \"The standard parallels of the projection, denoting the desired latitude range with minimal distortion. `parallels` takes the form of [lat0, lat1]. This property is only configurable for conic projections (Albers and Lambert Conformal Conic).\",\n \"example\": [\n 29.5,\n 45.5\n ],\n \"requires\": [\n {\n \"name\": [\n \"albers\",\n \"lambertConformalConic\"\n ]\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.6.0\"\n }\n }\n }\n },\n \"terrain\" : {\n \"source\": {\n \"type\": \"string\",\n \"doc\": \"Name of a source of `raster_dem` type to be used for terrain elevation.\",\n \"required\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.0.0\",\n \"ios\": \"10.0.0\",\n \"android\": \"10.0.0\"\n }\n }\n },\n \"exaggeration\": {\n \"type\": \"number\",\n \"property-type\": \"data-constant\",\n \"default\": 1.0,\n \"minimum\": 0,\n \"maximum\": 1000,\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"transition\": true,\n \"doc\": \"Exaggerates the elevation of the terrain by multiplying the data from the DEM with this value.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.0.0\",\n \"ios\": \"10.0.0\",\n \"android\": \"10.0.0\"\n }\n }\n }\n },\n \"paint\": [\n \"paint_fill\",\n \"paint_line\",\n \"paint_circle\",\n \"paint_heatmap\",\n \"paint_fill-extrusion\",\n \"paint_symbol\",\n \"paint_raster\",\n \"paint_hillshade\",\n \"paint_background\",\n \"paint_sky\"\n ],\n \"paint_fill\": {\n \"fill-antialias\": {\n \"type\": \"boolean\",\n \"default\": true,\n \"doc\": \"Whether or not the fill should be antialiased.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"fill-opacity\": {\n \"type\": \"number\",\n \"default\": 1,\n \"minimum\": 0,\n \"maximum\": 1,\n \"doc\": \"The opacity of the entire fill layer. In contrast to the `fill-color`, this value will also affect the 1px stroke around the fill, if the stroke is used.\",\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.21.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"fill-color\": {\n \"type\": \"color\",\n \"default\": \"#000000\",\n \"doc\": \"The color of the filled part of this layer. This color can be specified as `rgba` with an alpha component and the color's opacity will not affect the opacity of the 1px stroke, if it is used.\",\n \"transition\": true,\n \"requires\": [\n {\n \"!\": \"fill-pattern\"\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.19.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"fill-outline-color\": {\n \"type\": \"color\",\n \"doc\": \"The outline color of the fill. Matches the value of `fill-color` if unspecified.\",\n \"transition\": true,\n \"requires\": [\n {\n \"!\": \"fill-pattern\"\n },\n {\n \"fill-antialias\": true\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.19.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"fill-translate\": {\n \"type\": \"array\",\n \"value\": \"number\",\n \"length\": 2,\n \"default\": [\n 0,\n 0\n ],\n \"transition\": true,\n \"units\": \"pixels\",\n \"doc\": \"The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"fill-translate-anchor\": {\n \"type\": \"enum\",\n \"values\": {\n \"map\": {\n \"doc\": \"The fill is translated relative to the map.\"\n },\n \"viewport\": {\n \"doc\": \"The fill is translated relative to the viewport.\"\n }\n },\n \"doc\": \"Controls the frame of reference for `fill-translate`.\",\n \"default\": \"map\",\n \"requires\": [\n \"fill-translate\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"fill-pattern\": {\n \"type\": \"resolvedImage\",\n \"transition\": true,\n \"doc\": \"Name of image in sprite to use for drawing image fills. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). Note that zoom-dependent expressions will be evaluated only at integer zoom levels.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.49.0\",\n \"android\": \"6.5.0\",\n \"macos\": \"0.11.0\",\n \"ios\": \"4.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"cross-faded-data-driven\"\n }\n },\n \"paint_fill-extrusion\": {\n \"fill-extrusion-opacity\": {\n \"type\": \"number\",\n \"default\": 1,\n \"minimum\": 0,\n \"maximum\": 1,\n \"doc\": \"The opacity of the entire fill extrusion layer. This is rendered on a per-layer, not per-feature, basis, and data-driven styling is not available.\",\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.27.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"fill-extrusion-color\": {\n \"type\": \"color\",\n \"default\": \"#000000\",\n \"doc\": \"The base color of the extruded fill. The extrusion's surfaces will be shaded differently based on this color in combination with the root `light` settings. If this color is specified as `rgba` with an alpha component, the alpha component will be ignored; use `fill-extrusion-opacity` to set layer opacity.\",\n \"transition\": true,\n \"requires\": [\n {\n \"!\": \"fill-extrusion-pattern\"\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.27.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.27.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"fill-extrusion-translate\": {\n \"type\": \"array\",\n \"value\": \"number\",\n \"length\": 2,\n \"default\": [\n 0,\n 0\n ],\n \"transition\": true,\n \"units\": \"pixels\",\n \"doc\": \"The geometry's offset. Values are [x, y] where negatives indicate left and up (on the flat plane), respectively.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.27.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"fill-extrusion-translate-anchor\": {\n \"type\": \"enum\",\n \"values\": {\n \"map\": {\n \"doc\": \"The fill extrusion is translated relative to the map.\"\n },\n \"viewport\": {\n \"doc\": \"The fill extrusion is translated relative to the viewport.\"\n }\n },\n \"doc\": \"Controls the frame of reference for `fill-extrusion-translate`.\",\n \"default\": \"map\",\n \"requires\": [\n \"fill-extrusion-translate\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.27.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"fill-extrusion-pattern\": {\n \"type\": \"resolvedImage\",\n \"transition\": true,\n \"doc\": \"Name of image in sprite to use for drawing images on extruded fills. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). Note that zoom-dependent expressions will be evaluated only at integer zoom levels.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.27.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.49.0\",\n \"android\": \"6.5.0\",\n \"macos\": \"0.11.0\",\n \"ios\": \"4.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"cross-faded-data-driven\"\n },\n \"fill-extrusion-height\": {\n \"type\": \"number\",\n \"default\": 0,\n \"minimum\": 0,\n \"units\": \"meters\",\n \"doc\": \"The height with which to extrude this layer.\",\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.27.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.27.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"fill-extrusion-base\": {\n \"type\": \"number\",\n \"default\": 0,\n \"minimum\": 0,\n \"units\": \"meters\",\n \"doc\": \"The height with which to extrude the base of this layer. Must be less than or equal to `fill-extrusion-height`.\",\n \"transition\": true,\n \"requires\": [\n \"fill-extrusion-height\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.27.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.27.0\",\n \"android\": \"5.1.0\",\n \"ios\": \"3.6.0\",\n \"macos\": \"0.5.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"fill-extrusion-vertical-gradient\": {\n \"type\": \"boolean\",\n \"default\": true,\n \"doc\": \"Whether to apply a vertical gradient to the sides of a fill-extrusion layer. If true, sides will be shaded slightly darker farther down.\",\n \"transition\": false,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.50.0\",\n \"android\": \"7.0.0\",\n \"ios\": \"4.7.0\",\n \"macos\": \"0.13.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n }\n },\n \"paint_line\": {\n \"line-opacity\": {\n \"type\": \"number\",\n \"doc\": \"The opacity at which the line will be drawn.\",\n \"default\": 1,\n \"minimum\": 0,\n \"maximum\": 1,\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.29.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"line-color\": {\n \"type\": \"color\",\n \"doc\": \"The color with which the line will be drawn.\",\n \"default\": \"#000000\",\n \"transition\": true,\n \"requires\": [\n {\n \"!\": \"line-pattern\"\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.23.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"line-translate\": {\n \"type\": \"array\",\n \"value\": \"number\",\n \"length\": 2,\n \"default\": [\n 0,\n 0\n ],\n \"transition\": true,\n \"units\": \"pixels\",\n \"doc\": \"The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"line-translate-anchor\": {\n \"type\": \"enum\",\n \"values\": {\n \"map\": {\n \"doc\": \"The line is translated relative to the map.\"\n },\n \"viewport\": {\n \"doc\": \"The line is translated relative to the viewport.\"\n }\n },\n \"doc\": \"Controls the frame of reference for `line-translate`.\",\n \"default\": \"map\",\n \"requires\": [\n \"line-translate\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"line-width\": {\n \"type\": \"number\",\n \"default\": 1,\n \"minimum\": 0,\n \"transition\": true,\n \"units\": \"pixels\",\n \"doc\": \"Stroke thickness.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.39.0\",\n \"android\": \"5.2.0\",\n \"ios\": \"3.7.0\",\n \"macos\": \"0.6.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"line-gap-width\": {\n \"type\": \"number\",\n \"default\": 0,\n \"minimum\": 0,\n \"doc\": \"Draws a line casing outside of a line's actual path. Value indicates the width of the inner gap.\",\n \"transition\": true,\n \"units\": \"pixels\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.29.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"line-offset\": {\n \"type\": \"number\",\n \"default\": 0,\n \"doc\": \"The line's offset. For linear features, a positive value offsets the line to the right, relative to the direction of the line, and a negative value to the left. For polygon features, a positive value results in an inset, and a negative value results in an outset.\",\n \"transition\": true,\n \"units\": \"pixels\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.12.1\",\n \"android\": \"3.0.0\",\n \"ios\": \"3.1.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.29.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"line-blur\": {\n \"type\": \"number\",\n \"default\": 0,\n \"minimum\": 0,\n \"transition\": true,\n \"units\": \"pixels\",\n \"doc\": \"Blur applied to the line, in pixels.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.29.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"line-dasharray\": {\n \"type\": \"array\",\n \"value\": \"number\",\n \"doc\": \"Specifies the lengths of the alternating dashes and gaps that form the dash pattern. The lengths are later scaled by the line width. To convert a dash length to pixels, multiply the length by the current line width. Note that GeoJSON sources with `lineMetrics: true` specified won't render dashed lines to the expected scale. Also note that zoom-dependent expressions will be evaluated only at integer zoom levels.\",\n \"minimum\": 0,\n \"transition\": true,\n \"units\": \"line widths\",\n \"requires\": [\n {\n \"!\": \"line-pattern\"\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"2.3.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"cross-faded-data-driven\"\n },\n \"line-pattern\": {\n \"type\": \"resolvedImage\",\n \"transition\": true,\n \"doc\": \"Name of image in sprite to use for drawing image lines. For seamless patterns, image width must be a factor of two (2, 4, 8, ..., 512). Note that zoom-dependent expressions will be evaluated only at integer zoom levels.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.49.0\",\n \"android\": \"6.5.0\",\n \"macos\": \"0.11.0\",\n \"ios\": \"4.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\",\n \"feature\"\n ]\n },\n \"property-type\": \"cross-faded-data-driven\"\n },\n \"line-gradient\": {\n \"type\": \"color\",\n \"doc\": \"Defines a gradient with which to color a line feature. Can only be used with GeoJSON sources that specify `\\\"lineMetrics\\\": true`.\",\n \"transition\": false,\n \"requires\": [\n {\n \"!\": \"line-pattern\"\n },\n {\n \"source\": \"geojson\",\n \"has\": {\n \"lineMetrics\": true\n }\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.45.0\",\n \"android\": \"6.5.0\",\n \"ios\": \"4.4.0\",\n \"macos\": \"0.11.0\"\n },\n \"data-driven styling\": {}\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"line-progress\"\n ]\n },\n \"property-type\": \"color-ramp\"\n }\n },\n \"paint_circle\": {\n \"circle-radius\": {\n \"type\": \"number\",\n \"default\": 5,\n \"minimum\": 0,\n \"transition\": true,\n \"units\": \"pixels\",\n \"doc\": \"Circle radius.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.18.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"circle-color\": {\n \"type\": \"color\",\n \"default\": \"#000000\",\n \"doc\": \"The fill color of the circle.\",\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.18.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"circle-blur\": {\n \"type\": \"number\",\n \"default\": 0,\n \"doc\": \"Amount to blur the circle. 1 blurs the circle such that only the centerpoint is full opacity.\",\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.20.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"circle-opacity\": {\n \"type\": \"number\",\n \"doc\": \"The opacity at which the circle will be drawn.\",\n \"default\": 1,\n \"minimum\": 0,\n \"maximum\": 1,\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.20.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"circle-translate\": {\n \"type\": \"array\",\n \"value\": \"number\",\n \"length\": 2,\n \"default\": [\n 0,\n 0\n ],\n \"transition\": true,\n \"units\": \"pixels\",\n \"doc\": \"The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"circle-translate-anchor\": {\n \"type\": \"enum\",\n \"values\": {\n \"map\": {\n \"doc\": \"The circle is translated relative to the map.\"\n },\n \"viewport\": {\n \"doc\": \"The circle is translated relative to the viewport.\"\n }\n },\n \"doc\": \"Controls the frame of reference for `circle-translate`.\",\n \"default\": \"map\",\n \"requires\": [\n \"circle-translate\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"circle-pitch-scale\": {\n \"type\": \"enum\",\n \"values\": {\n \"map\": {\n \"doc\": \"Circles are scaled according to their apparent distance to the camera.\"\n },\n \"viewport\": {\n \"doc\": \"Circles are not scaled.\"\n }\n },\n \"default\": \"map\",\n \"doc\": \"Controls the scaling behavior of the circle when the map is pitched.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.21.0\",\n \"android\": \"4.2.0\",\n \"ios\": \"3.4.0\",\n \"macos\": \"0.2.1\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"circle-pitch-alignment\": {\n \"type\": \"enum\",\n \"values\": {\n \"map\": {\n \"doc\": \"The circle is aligned to the plane of the map.\"\n },\n \"viewport\": {\n \"doc\": \"The circle is aligned to the plane of the viewport.\"\n }\n },\n \"default\": \"viewport\",\n \"doc\": \"Orientation of circle when map is pitched.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.39.0\",\n \"android\": \"5.2.0\",\n \"ios\": \"3.7.0\",\n \"macos\": \"0.6.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"circle-stroke-width\": {\n \"type\": \"number\",\n \"default\": 0,\n \"minimum\": 0,\n \"transition\": true,\n \"units\": \"pixels\",\n \"doc\": \"The width of the circle's stroke. Strokes are placed outside of the `circle-radius`.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.29.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.29.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"circle-stroke-color\": {\n \"type\": \"color\",\n \"default\": \"#000000\",\n \"doc\": \"The stroke color of the circle.\",\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.29.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.29.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"circle-stroke-opacity\": {\n \"type\": \"number\",\n \"doc\": \"The opacity of the circle's stroke.\",\n \"default\": 1,\n \"minimum\": 0,\n \"maximum\": 1,\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.29.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.29.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n }\n },\n \"paint_heatmap\": {\n \"heatmap-radius\": {\n \"type\": \"number\",\n \"default\": 30,\n \"minimum\": 1,\n \"transition\": true,\n \"units\": \"pixels\",\n \"doc\": \"Radius of influence of one heatmap point in pixels. Increasing the value makes the heatmap smoother, but less detailed. `queryRenderedFeatures` on heatmap layers will return points within this radius.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.43.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"heatmap-weight\": {\n \"type\": \"number\",\n \"default\": 1,\n \"minimum\": 0,\n \"transition\": false,\n \"doc\": \"A measure of how much an individual point contributes to the heatmap. A value of 10 would be equivalent to having 10 points of weight 1 in the same spot. Especially useful when combined with clustering.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"heatmap-intensity\": {\n \"type\": \"number\",\n \"default\": 1,\n \"minimum\": 0,\n \"transition\": true,\n \"doc\": \"Similar to `heatmap-weight` but controls the intensity of the heatmap globally. Primarily used for adjusting the heatmap based on zoom level.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"heatmap-color\": {\n \"type\": \"color\",\n \"default\": [\n \"interpolate\",\n [\n \"linear\"\n ],\n [\n \"heatmap-density\"\n ],\n 0,\n \"rgba(0, 0, 255, 0)\",\n 0.1,\n \"royalblue\",\n 0.3,\n \"cyan\",\n 0.5,\n \"lime\",\n 0.7,\n \"yellow\",\n 1,\n \"red\"\n ],\n \"doc\": \"Defines the color of each pixel based on its density value in a heatmap. Should be an expression that uses `[\\\"heatmap-density\\\"]` as input.\",\n \"transition\": false,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n },\n \"data-driven styling\": {}\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"heatmap-density\"\n ]\n },\n \"property-type\": \"color-ramp\"\n },\n \"heatmap-opacity\": {\n \"type\": \"number\",\n \"doc\": \"The global opacity at which the heatmap layer will be drawn.\",\n \"default\": 1,\n \"minimum\": 0,\n \"maximum\": 1,\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.41.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n }\n },\n \"paint_symbol\": {\n \"icon-opacity\": {\n \"doc\": \"The opacity at which the icon will be drawn.\",\n \"type\": \"number\",\n \"default\": 1,\n \"minimum\": 0,\n \"maximum\": 1,\n \"transition\": true,\n \"requires\": [\n \"icon-image\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.33.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"icon-color\": {\n \"type\": \"color\",\n \"default\": \"#000000\",\n \"transition\": true,\n \"doc\": \"The color of the icon. This can only be used with [SDF icons](/help/troubleshooting/using-recolorable-images-in-mapbox-maps/).\",\n \"requires\": [\n \"icon-image\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.33.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"icon-halo-color\": {\n \"type\": \"color\",\n \"default\": \"rgba(0, 0, 0, 0)\",\n \"transition\": true,\n \"doc\": \"The color of the icon's halo. Icon halos can only be used with [SDF icons](/help/troubleshooting/using-recolorable-images-in-mapbox-maps/).\",\n \"requires\": [\n \"icon-image\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.33.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"icon-halo-width\": {\n \"type\": \"number\",\n \"default\": 0,\n \"minimum\": 0,\n \"transition\": true,\n \"units\": \"pixels\",\n \"doc\": \"Distance of halo to the icon outline.\",\n \"requires\": [\n \"icon-image\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.33.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"icon-halo-blur\": {\n \"type\": \"number\",\n \"default\": 0,\n \"minimum\": 0,\n \"transition\": true,\n \"units\": \"pixels\",\n \"doc\": \"Fade out the halo towards the outside.\",\n \"requires\": [\n \"icon-image\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.33.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"icon-translate\": {\n \"type\": \"array\",\n \"value\": \"number\",\n \"length\": 2,\n \"default\": [\n 0,\n 0\n ],\n \"transition\": true,\n \"units\": \"pixels\",\n \"doc\": \"Distance that the icon's anchor is moved from its original placement. Positive values indicate right and down, while negative values indicate left and up.\",\n \"requires\": [\n \"icon-image\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"icon-translate-anchor\": {\n \"type\": \"enum\",\n \"values\": {\n \"map\": {\n \"doc\": \"Icons are translated relative to the map.\"\n },\n \"viewport\": {\n \"doc\": \"Icons are translated relative to the viewport.\"\n }\n },\n \"doc\": \"Controls the frame of reference for `icon-translate`.\",\n \"default\": \"map\",\n \"requires\": [\n \"icon-image\",\n \"icon-translate\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"text-opacity\": {\n \"type\": \"number\",\n \"doc\": \"The opacity at which the text will be drawn.\",\n \"default\": 1,\n \"minimum\": 0,\n \"maximum\": 1,\n \"transition\": true,\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.33.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"text-color\": {\n \"type\": \"color\",\n \"doc\": \"The color with which the text will be drawn.\",\n \"default\": \"#000000\",\n \"transition\": true,\n \"overridable\": true,\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.33.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"text-halo-color\": {\n \"type\": \"color\",\n \"default\": \"rgba(0, 0, 0, 0)\",\n \"transition\": true,\n \"doc\": \"The color of the text's halo, which helps it stand out from backgrounds.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.33.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"text-halo-width\": {\n \"type\": \"number\",\n \"default\": 0,\n \"minimum\": 0,\n \"transition\": true,\n \"units\": \"pixels\",\n \"doc\": \"Distance of halo to the font outline. Max text halo width is 1/4 of the font-size.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.33.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"text-halo-blur\": {\n \"type\": \"number\",\n \"default\": 0,\n \"minimum\": 0,\n \"transition\": true,\n \"units\": \"pixels\",\n \"doc\": \"The halo's fadeout distance towards the outside.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {\n \"js\": \"0.33.0\",\n \"android\": \"5.0.0\",\n \"ios\": \"3.5.0\",\n \"macos\": \"0.4.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\",\n \"feature\",\n \"feature-state\"\n ]\n },\n \"property-type\": \"data-driven\"\n },\n \"text-translate\": {\n \"type\": \"array\",\n \"value\": \"number\",\n \"length\": 2,\n \"default\": [\n 0,\n 0\n ],\n \"transition\": true,\n \"units\": \"pixels\",\n \"doc\": \"Distance that the text's anchor is moved from its original placement. Positive values indicate right and down, while negative values indicate left and up.\",\n \"requires\": [\n \"text-field\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"text-translate-anchor\": {\n \"type\": \"enum\",\n \"values\": {\n \"map\": {\n \"doc\": \"The text is translated relative to the map.\"\n },\n \"viewport\": {\n \"doc\": \"The text is translated relative to the viewport.\"\n }\n },\n \"doc\": \"Controls the frame of reference for `text-translate`.\",\n \"default\": \"map\",\n \"requires\": [\n \"text-field\",\n \"text-translate\"\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n }\n },\n \"paint_raster\": {\n \"raster-opacity\": {\n \"type\": \"number\",\n \"doc\": \"The opacity at which the image will be drawn.\",\n \"default\": 1,\n \"minimum\": 0,\n \"maximum\": 1,\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"raster-hue-rotate\": {\n \"type\": \"number\",\n \"default\": 0,\n \"period\": 360,\n \"transition\": true,\n \"units\": \"degrees\",\n \"doc\": \"Rotates hues around the color wheel.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"raster-brightness-min\": {\n \"type\": \"number\",\n \"doc\": \"Increase or reduce the brightness of the image. The value is the minimum brightness.\",\n \"default\": 0,\n \"minimum\": 0,\n \"maximum\": 1,\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"raster-brightness-max\": {\n \"type\": \"number\",\n \"doc\": \"Increase or reduce the brightness of the image. The value is the maximum brightness.\",\n \"default\": 1,\n \"minimum\": 0,\n \"maximum\": 1,\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"raster-saturation\": {\n \"type\": \"number\",\n \"doc\": \"Increase or reduce the saturation of the image.\",\n \"default\": 0,\n \"minimum\": -1,\n \"maximum\": 1,\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"raster-contrast\": {\n \"type\": \"number\",\n \"doc\": \"Increase or reduce the contrast of the image.\",\n \"default\": 0,\n \"minimum\": -1,\n \"maximum\": 1,\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"raster-resampling\": {\n \"type\": \"enum\",\n \"doc\": \"The resampling/interpolation method to use for overscaling, also known as texture magnification filter\",\n \"values\": {\n \"linear\": {\n \"doc\": \"(Bi)linear filtering interpolates pixel values using the weighted average of the four closest original source pixels creating a smooth but blurry look when overscaled\"\n },\n \"nearest\": {\n \"doc\": \"Nearest neighbor filtering interpolates pixel values using the nearest original source pixel creating a sharp but pixelated look when overscaled\"\n }\n },\n \"default\": \"linear\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.47.0\",\n \"android\": \"6.3.0\",\n \"ios\": \"4.2.0\",\n \"macos\": \"0.9.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"raster-fade-duration\": {\n \"type\": \"number\",\n \"default\": 300,\n \"minimum\": 0,\n \"transition\": false,\n \"units\": \"milliseconds\",\n \"doc\": \"Fade duration when a new tile is added.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n }\n },\n \"paint_hillshade\": {\n \"hillshade-illumination-direction\": {\n \"type\": \"number\",\n \"default\": 335,\n \"minimum\": 0,\n \"maximum\": 359,\n \"doc\": \"The direction of the light source used to generate the hillshading with 0 as the top of the viewport if `hillshade-illumination-anchor` is set to `viewport` and due north if `hillshade-illumination-anchor` is set to `map`.\",\n \"transition\": false,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.43.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"hillshade-illumination-anchor\": {\n \"type\": \"enum\",\n \"values\": {\n \"map\": {\n \"doc\": \"The hillshade illumination is relative to the north direction.\"\n },\n \"viewport\": {\n \"doc\": \"The hillshade illumination is relative to the top of the viewport.\"\n }\n },\n \"default\": \"viewport\",\n \"doc\": \"Direction of light source when map is rotated.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.43.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"hillshade-exaggeration\": {\n \"type\": \"number\",\n \"doc\": \"Intensity of the hillshade\",\n \"default\": 0.5,\n \"minimum\": 0,\n \"maximum\": 1,\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.43.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"hillshade-shadow-color\": {\n \"type\": \"color\",\n \"default\": \"#000000\",\n \"doc\": \"The shading color of areas that face away from the light source.\",\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.43.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"hillshade-highlight-color\": {\n \"type\": \"color\",\n \"default\": \"#FFFFFF\",\n \"doc\": \"The shading color of areas that faces towards the light source.\",\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.43.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"hillshade-accent-color\": {\n \"type\": \"color\",\n \"default\": \"#000000\",\n \"doc\": \"The shading color used to accentuate rugged terrain like sharp cliffs and gorges.\",\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.43.0\",\n \"android\": \"6.0.0\",\n \"ios\": \"4.0.0\",\n \"macos\": \"0.7.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n }\n },\n \"paint_background\": {\n \"background-color\": {\n \"type\": \"color\",\n \"default\": \"#000000\",\n \"doc\": \"The color with which the background will be drawn.\",\n \"transition\": true,\n \"requires\": [\n {\n \"!\": \"background-pattern\"\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"background-pattern\": {\n \"type\": \"resolvedImage\",\n \"transition\": true,\n \"doc\": \"Name of image in sprite to use for drawing an image background. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). Note that zoom-dependent expressions will be evaluated only at integer zoom levels.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n },\n \"data-driven styling\": {}\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"cross-faded\"\n },\n \"background-opacity\": {\n \"type\": \"number\",\n \"default\": 1,\n \"minimum\": 0,\n \"maximum\": 1,\n \"doc\": \"The opacity at which the background will be drawn.\",\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"0.10.0\",\n \"android\": \"2.0.1\",\n \"ios\": \"2.0.0\",\n \"macos\": \"0.1.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n }\n },\n \"paint_sky\": {\n \"sky-type\": {\n \"type\": \"enum\",\n \"values\": {\n \"gradient\": {\n \"doc\": \"Renders the sky with a gradient that can be configured with `sky-gradient-radius` and `sky-gradient`.\"\n },\n \"atmosphere\": {\n \"doc\": \"Renders the sky with a simulated atmospheric scattering algorithm, the sun direction can be attached to the light position or explicitly set through `sky-atmosphere-sun`.\"\n }\n },\n \"default\": \"atmosphere\",\n \"doc\": \"The type of the sky\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.0.0\",\n \"ios\": \"10.0.0\",\n \"android\": \"10.0.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"sky-atmosphere-sun\": {\n \"type\": \"array\",\n \"value\": \"number\",\n \"length\": 2,\n \"units\": \"degrees\",\n \"minimum\": [0, 0],\n \"maximum\": [360, 180],\n \"transition\": false,\n \"doc\": \"Position of the sun center [a azimuthal angle, p polar angle]. The azimuthal angle indicates the position of the sun relative to 0° north, where degrees proceed clockwise. The polar angle indicates the height of the sun, where 0° is directly above, at zenith, and 90° at the horizon. When this property is ommitted, the sun center is directly inherited from the light position.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.0.0\",\n \"ios\": \"10.0.0\",\n \"android\": \"10.0.0\"\n }\n },\n \"requires\": [\n {\n \"sky-type\": \"atmosphere\"\n }\n ],\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"sky-atmosphere-sun-intensity\": {\n \"type\": \"number\",\n \"requires\": [\n {\n \"sky-type\": \"atmosphere\"\n }\n ],\n \"default\": 10,\n \"minimum\": 0,\n \"maximum\": 100,\n \"transition\": false,\n \"doc\": \"Intensity of the sun as a light source in the atmosphere (on a scale from 0 to a 100). Setting higher values will brighten up the sky.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.0.0\",\n \"ios\": \"10.0.0\",\n \"android\": \"10.0.0\"\n }\n },\n \"property-type\": \"data-constant\"\n },\n \"sky-gradient-center\": {\n \"type\": \"array\",\n \"requires\": [\n {\n \"sky-type\": \"gradient\"\n }\n ],\n \"value\": \"number\",\n \"default\": [\n 0,\n 0\n ],\n \"length\": 2,\n \"units\": \"degrees\",\n \"minimum\": [0, 0],\n \"maximum\": [360, 180],\n \"transition\": false,\n \"doc\": \"Position of the gradient center [a azimuthal angle, p polar angle]. The azimuthal angle indicates the position of the gradient center relative to 0° north, where degrees proceed clockwise. The polar angle indicates the height of the gradient center, where 0° is directly above, at zenith, and 90° at the horizon.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.0.0\",\n \"ios\": \"10.0.0\",\n \"android\": \"10.0.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"sky-gradient-radius\": {\n \"type\": \"number\",\n \"requires\": [\n {\n \"sky-type\": \"gradient\"\n }\n ],\n \"default\": 90,\n \"minimum\": 0,\n \"maximum\": 180,\n \"transition\": false,\n \"doc\": \"The angular distance (measured in degrees) from `sky-gradient-center` up to which the gradient extends. A value of 180 causes the gradient to wrap around to the opposite direction from `sky-gradient-center`.\",\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.0.0\",\n \"ios\": \"10.0.0\",\n \"android\": \"10.0.0\"\n }\n },\n \"expression\": {\n \"interpolated\": false,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n },\n \"sky-gradient\": {\n \"type\": \"color\",\n \"default\": [\n \"interpolate\",\n [\n \"linear\"\n ],\n [\n \"sky-radial-progress\"\n ],\n 0.8,\n \"#87ceeb\",\n 1,\n \"white\"\n ],\n \"doc\": \"Defines a radial color gradient with which to color the sky. The color values can be interpolated with an expression using `sky-radial-progress`. The range [0, 1] for the interpolant covers a radial distance (in degrees) of [0, `sky-gradient-radius`] centered at the position specified by `sky-gradient-center`.\",\n \"transition\": false,\n \"requires\": [\n {\n \"sky-type\": \"gradient\"\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.0.0\",\n \"ios\": \"10.0.0\",\n \"android\": \"10.0.0\"\n },\n \"data-driven styling\": {}\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"sky-radial-progress\"\n ]\n },\n \"property-type\": \"color-ramp\"\n },\n \"sky-atmosphere-halo-color\": {\n \"type\": \"color\",\n \"default\": \"white\",\n \"doc\": \"A color applied to the atmosphere sun halo. The alpha channel describes how strongly the sun halo is represented in an atmosphere sky layer.\",\n \"transition\": false,\n \"requires\": [\n {\n \"sky-type\": \"atmosphere\"\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.0.0\",\n \"ios\": \"10.0.0\",\n \"android\": \"10.0.0\"\n }\n },\n \"property-type\": \"data-constant\"\n },\n \"sky-atmosphere-color\": {\n \"type\": \"color\",\n \"default\": \"white\",\n \"doc\": \"A color used to tweak the main atmospheric scattering coefficients. Using white applies the default coefficients giving the natural blue color to the atmosphere. This color affects how heavily the corresponding wavelength is represented during scattering. The alpha channel describes the density of the atmosphere, with 1 maximum density and 0 no density.\",\n \"transition\": false,\n \"requires\": [\n {\n \"sky-type\": \"atmosphere\"\n }\n ],\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.0.0\",\n \"ios\": \"10.0.0\",\n \"android\": \"10.0.0\"\n }\n },\n \"property-type\": \"data-constant\"\n },\n \"sky-opacity\": {\n \"type\": \"number\",\n \"default\": 1,\n \"minimum\": 0,\n \"maximum\": 1,\n \"doc\": \"The opacity of the entire sky layer.\",\n \"transition\": true,\n \"sdk-support\": {\n \"basic functionality\": {\n \"js\": \"2.0.0\",\n \"ios\": \"10.0.0\",\n \"android\": \"10.0.0\"\n }\n },\n \"expression\": {\n \"interpolated\": true,\n \"parameters\": [\n \"zoom\"\n ]\n },\n \"property-type\": \"data-constant\"\n }\n },\n \"transition\": {\n \"duration\": {\n \"type\": \"number\",\n \"default\": 300,\n \"minimum\": 0,\n \"units\": \"milliseconds\",\n \"doc\": \"Time allotted for transitions to complete.\"\n },\n \"delay\": {\n \"type\": \"number\",\n \"default\": 0,\n \"minimum\": 0,\n \"units\": \"milliseconds\",\n \"doc\": \"Length of time before a transition begins.\"\n }\n },\n \"property-type\": {\n \"data-driven\": {\n \"type\": \"property-type\",\n \"doc\": \"Property is interpolable and can be represented using a property expression.\"\n },\n \"cross-faded\": {\n \"type\": \"property-type\",\n \"doc\": \"Property is non-interpolable; rather, its values will be cross-faded to smoothly transition between integer zooms.\"\n },\n \"cross-faded-data-driven\": {\n \"type\": \"property-type\",\n \"doc\": \"Property is non-interpolable; rather, its values will be cross-faded to smoothly transition between integer zooms. It can be represented using a property expression.\"\n },\n \"color-ramp\": {\n \"type\": \"property-type\",\n \"doc\": \"Property should be specified using a color ramp from which the output color can be sampled based on a property calculation.\"\n },\n \"data-constant\": {\n \"type\": \"property-type\",\n \"doc\": \"Property is interpolable but cannot be represented using a property expression.\"\n },\n \"constant\": {\n \"type\": \"property-type\",\n \"doc\": \"Property is constant across all zoom levels and property values.\"\n }\n },\n \"promoteId\": {\n \"*\": {\n \"type\": \"string\",\n \"doc\": \"A name of a feature property to use as ID for feature state.\"\n }\n }\n}\n","// @flow\n\nimport {createExpression} from '../expression/index.js';\nimport {isFeatureConstant} from '../expression/is_constant.js';\nimport {deepUnbundle} from '../util/unbundle_jsonlint.js';\nimport latest from '../reference/latest.js';\nimport type {GlobalProperties, Feature} from '../expression/index.js';\nimport type {CanonicalTileID} from '../../source/tile_id.js';\nimport type Point from '@mapbox/point-geometry';\n\nexport type FeatureDistanceData = {bearing: [number, number], center: [number, number], scale: number};\nexport type FilterExpression = (globalProperties: GlobalProperties, feature: Feature, canonical?: CanonicalTileID, featureTileCoord?: Point, featureDistanceData?: FeatureDistanceData) => boolean;\nexport type FeatureFilter = {filter: FilterExpression, dynamicFilter?: FilterExpression, needGeometry: boolean, needFeature: boolean};\n\nexport default createFilter;\nexport {isExpressionFilter, isDynamicFilter, extractStaticFilter};\n\nfunction isExpressionFilter(filter: any): boolean {\n if (filter === true || filter === false) {\n return true;\n }\n\n if (!Array.isArray(filter) || filter.length === 0) {\n return false;\n }\n switch (filter[0]) {\n case 'has':\n return filter.length >= 2 && filter[1] !== '$id' && filter[1] !== '$type';\n\n case 'in':\n return filter.length >= 3 && (typeof filter[1] !== 'string' || Array.isArray(filter[2]));\n\n case '!in':\n case '!has':\n case 'none':\n return false;\n\n case '==':\n case '!=':\n case '>':\n case '>=':\n case '<':\n case '<=':\n return filter.length !== 3 || (Array.isArray(filter[1]) || Array.isArray(filter[2]));\n\n case 'any':\n case 'all':\n for (const f of filter.slice(1)) {\n if (!isExpressionFilter(f) && typeof f !== 'boolean') {\n return false;\n }\n }\n return true;\n\n default:\n return true;\n }\n}\n\n/**\n * Given a filter expressed as nested arrays, return a new function\n * that evaluates whether a given feature (with a .properties or .tags property)\n * passes its test.\n *\n * @private\n * @param {Array} filter mapbox gl filter\n * @param {string} layerType the type of the layer this filter will be applied to.\n * @returns {Function} filter-evaluating function\n */\nfunction createFilter(filter: any, layerType?: string = 'fill'): FeatureFilter {\n if (filter === null || filter === undefined) {\n return {filter: () => true, needGeometry: false, needFeature: false};\n }\n\n if (!isExpressionFilter(filter)) {\n filter = convertFilter(filter);\n }\n const filterExp = ((filter: any): string[] | string | boolean);\n\n let staticFilter = true;\n try {\n staticFilter = extractStaticFilter(filterExp);\n } catch (e) {\n console.warn(\n`Failed to extract static filter. Filter will continue working, but at higher memory usage and slower framerate.\nThis is most likely a bug, please report this via https://github.com/mapbox/mapbox-gl-js/issues/new?assignees=&labels=&template=Bug_report.md\nand paste the contents of this message in the report.\nThank you!\nFilter Expression:\n${JSON.stringify(filterExp, null, 2)}\n `);\n }\n\n // Compile the static component of the filter\n const filterSpec = latest[`filter_${layerType}`];\n const compiledStaticFilter = createExpression(staticFilter, filterSpec);\n\n let filterFunc = null;\n if (compiledStaticFilter.result === 'error') {\n throw new Error(compiledStaticFilter.value.map(err => `${err.key}: ${err.message}`).join(', '));\n } else {\n filterFunc = (globalProperties: GlobalProperties, feature: Feature, canonical?: CanonicalTileID) => compiledStaticFilter.value.evaluate(globalProperties, feature, {}, canonical);\n }\n\n // If the static component is not equal to the entire filter then we have a dynamic component\n // Compile the dynamic component separately\n let dynamicFilterFunc = null;\n let needFeature = null;\n if (staticFilter !== filterExp) {\n const compiledDynamicFilter = createExpression(filterExp, filterSpec);\n\n if (compiledDynamicFilter.result === 'error') {\n throw new Error(compiledDynamicFilter.value.map(err => `${err.key}: ${err.message}`).join(', '));\n } else {\n dynamicFilterFunc = (globalProperties: GlobalProperties, feature: Feature, canonical?: CanonicalTileID, featureTileCoord?: Point, featureDistanceData?: FeatureDistanceData) => compiledDynamicFilter.value.evaluate(globalProperties, feature, {}, canonical, undefined, undefined, featureTileCoord, featureDistanceData);\n needFeature = !isFeatureConstant(compiledDynamicFilter.value.expression);\n }\n }\n\n filterFunc = ((filterFunc: any): FilterExpression);\n const needGeometry = geometryNeeded(staticFilter);\n\n return {\n filter: filterFunc,\n dynamicFilter: dynamicFilterFunc ? dynamicFilterFunc : undefined,\n needGeometry,\n needFeature: !!needFeature\n };\n}\n\nfunction extractStaticFilter(filter: any): any {\n if (!isDynamicFilter(filter)) {\n return filter;\n }\n\n // Shallow copy so we can replace expressions in-place\n let result = deepUnbundle(filter);\n\n // 1. Union branches\n unionDynamicBranches(result);\n\n // 2. Collapse dynamic conditions to `true`\n result = collapseDynamicBooleanExpressions(result);\n\n return result;\n}\n\nfunction collapseDynamicBooleanExpressions(expression: any): any {\n if (!Array.isArray(expression)) {\n return expression;\n }\n\n const collapsed = collapsedExpression(expression);\n if (collapsed === true) {\n return collapsed;\n } else {\n return collapsed.map((subExpression) => collapseDynamicBooleanExpressions(subExpression));\n }\n}\n\n/**\n * Traverses the expression and replaces all instances of branching on a\n * `dynamic` conditional (such as `['pitch']` or `['distance-from-center']`)\n * into an `any` expression.\n * This ensures that all possible outcomes of a `dynamic` branch are considered\n * when evaluating the expression upfront during filtering.\n *\n * @param {Array} filter the filter expression mutated in-place.\n */\nfunction unionDynamicBranches(filter: any) {\n let isBranchingDynamically = false;\n const branches = [];\n\n if (filter[0] === 'case') {\n for (let i = 1; i < filter.length - 1; i += 2) {\n isBranchingDynamically = isBranchingDynamically || isDynamicFilter(filter[i]);\n branches.push(filter[i + 1]);\n }\n\n branches.push(filter[filter.length - 1]);\n } else if (filter[0] === 'match') {\n isBranchingDynamically = isBranchingDynamically || isDynamicFilter(filter[1]);\n\n for (let i = 2; i < filter.length - 1; i += 2) {\n branches.push(filter[i + 1]);\n }\n branches.push(filter[filter.length - 1]);\n } else if (filter[0] === 'step') {\n isBranchingDynamically = isBranchingDynamically || isDynamicFilter(filter[1]);\n\n for (let i = 1; i < filter.length - 1; i += 2) {\n branches.push(filter[i + 1]);\n }\n }\n\n if (isBranchingDynamically) {\n filter.length = 0;\n filter.push('any', ...branches);\n }\n\n // traverse and recurse into children\n for (let i = 1; i < filter.length; i++) {\n unionDynamicBranches(filter[i]);\n }\n}\n\nfunction isDynamicFilter(filter: any): boolean {\n // Base Cases\n if (!Array.isArray(filter)) {\n return false;\n }\n if (isRootExpressionDynamic(filter[0])) {\n return true;\n }\n\n for (let i = 1; i < filter.length; i++) {\n const child = filter[i];\n if (isDynamicFilter(child)) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction isRootExpressionDynamic(expression: string): boolean {\n return expression === 'pitch' ||\n expression === 'distance-from-center';\n}\n\nconst dynamicConditionExpressions = new Set([\n 'in',\n '==',\n '!=',\n '>',\n '>=',\n '<',\n '<=',\n 'to-boolean'\n]);\n\nfunction collapsedExpression(expression: any): any {\n if (dynamicConditionExpressions.has(expression[0])) {\n\n for (let i = 1; i < expression.length; i++) {\n const param = expression[i];\n if (isDynamicFilter(param)) {\n return true;\n }\n }\n }\n return expression;\n}\n\n// Comparison function to sort numbers and strings\nfunction compare(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\nfunction geometryNeeded(filter) {\n if (!Array.isArray(filter)) return false;\n if (filter[0] === 'within') return true;\n for (let index = 1; index < filter.length; index++) {\n if (geometryNeeded(filter[index])) return true;\n }\n return false;\n}\n\nfunction convertFilter(filter: ?Array): mixed {\n if (!filter) return true;\n const op = filter[0];\n if (filter.length <= 1) return (op !== 'any');\n const converted =\n op === '==' ? convertComparisonOp(filter[1], filter[2], '==') :\n op === '!=' ? convertNegation(convertComparisonOp(filter[1], filter[2], '==')) :\n op === '<' ||\n op === '>' ||\n op === '<=' ||\n op === '>=' ? convertComparisonOp(filter[1], filter[2], op) :\n op === 'any' ? convertDisjunctionOp(filter.slice(1)) :\n op === 'all' ? ['all'].concat(filter.slice(1).map(convertFilter)) :\n op === 'none' ? ['all'].concat(filter.slice(1).map(convertFilter).map(convertNegation)) :\n op === 'in' ? convertInOp(filter[1], filter.slice(2)) :\n op === '!in' ? convertNegation(convertInOp(filter[1], filter.slice(2))) :\n op === 'has' ? convertHasOp(filter[1]) :\n op === '!has' ? convertNegation(convertHasOp(filter[1])) :\n op === 'within' ? filter :\n true;\n return converted;\n}\n\nfunction convertComparisonOp(property: string, value: any, op: string) {\n switch (property) {\n case '$type':\n return [`filter-type-${op}`, value];\n case '$id':\n return [`filter-id-${op}`, value];\n default:\n return [`filter-${op}`, property, value];\n }\n}\n\nfunction convertDisjunctionOp(filters: Array>) {\n return ['any'].concat(filters.map(convertFilter));\n}\n\nfunction convertInOp(property: string, values: Array) {\n if (values.length === 0) { return false; }\n switch (property) {\n case '$type':\n return [`filter-type-in`, ['literal', values]];\n case '$id':\n return [`filter-id-in`, ['literal', values]];\n default:\n if (values.length > 200 && !values.some(v => typeof v !== typeof values[0])) {\n return ['filter-in-large', property, ['literal', values.sort(compare)]];\n } else {\n return ['filter-in-small', property, ['literal', values]];\n }\n }\n}\n\nfunction convertHasOp(property: string) {\n switch (property) {\n case '$type':\n return true;\n case '$id':\n return [`filter-has-id`];\n default:\n return [`filter-has`, property];\n }\n}\n\nfunction convertNegation(filter: mixed) {\n return ['!', filter];\n}\n","// @flow\nexport default ['type', 'source', 'source-layer', 'minzoom', 'maxzoom', 'filter', 'layout'];\n","// @flow\n\nimport refProperties from './util/ref_properties.js';\n\nimport type {LayerSpecification} from './types.js';\n\nfunction deref(layer: LayerSpecification, parent: LayerSpecification): LayerSpecification {\n const result = {};\n\n for (const k in layer) {\n if (k !== 'ref') {\n result[k] = layer[k];\n }\n }\n\n refProperties.forEach((k) => {\n if (k in parent) {\n result[k] = (parent: any)[k];\n }\n });\n\n return ((result: any): LayerSpecification);\n}\n\n/**\n * Given an array of layers, some of which may contain `ref` properties\n * whose value is the `id` of another property, return a new array where\n * such layers have been augmented with the 'type', 'source', etc. properties\n * from the parent layer, and the `ref` property has been removed.\n *\n * The input is not modified. The output may contain references to portions\n * of the input.\n *\n * @private\n * @param {Array} layers\n * @returns {Array}\n */\nexport default function derefLayers(layers: Array): Array {\n layers = layers.slice();\n\n const map = Object.create(null);\n for (let i = 0; i < layers.length; i++) {\n map[layers[i].id] = layers[i];\n }\n\n for (let i = 0; i < layers.length; i++) {\n if ('ref' in layers[i]) {\n layers[i] = deref(layers[i], map[(layers[i]: any).ref]);\n }\n }\n\n return layers;\n}\n","var fontWeights = {\n thin: 100,\n hairline: 100,\n 'ultra-light': 100,\n 'extra-light': 100,\n light: 200,\n book: 300,\n regular: 400,\n normal: 400,\n plain: 400,\n roman: 400,\n standard: 400,\n medium: 500,\n 'semi-bold': 600,\n 'demi-bold': 600,\n bold: 700,\n heavy: 800,\n black: 800,\n 'extra-bold': 800,\n 'ultra-black': 900,\n 'extra-black': 900,\n 'ultra-bold': 900,\n 'heavy-black': 900,\n fat: 900,\n poster: 900\n};\nvar sp = ' ';\nvar italicRE = /(italic|oblique)$/i;\n\nvar fontCache = {};\n\nmodule.exports = function(fonts, size, lineHeight) {\n var cssData = fontCache[fonts];\n if (!cssData) {\n if (!Array.isArray(fonts)) {\n fonts = [fonts];\n }\n var weight = 400;\n var style = 'normal';\n var fontFamilies = [];\n var haveWeight, haveStyle;\n for (var i = 0, ii = fonts.length; i < ii; ++i) {\n var font = fonts[i];\n var parts = font.split(' ');\n var maybeWeight = parts[parts.length - 1].toLowerCase();\n if (maybeWeight == 'normal' || maybeWeight == 'italic' || maybeWeight == 'oblique') {\n style = haveStyle ? style : maybeWeight;\n parts.pop();\n maybeWeight = parts[parts.length - 1].toLowerCase();\n } else if (italicRE.test(maybeWeight)) {\n maybeWeight = maybeWeight.replace(italicRE, '');\n style = haveStyle ? style : parts[parts.length - 1].replace(maybeWeight, '');\n }\n for (var w in fontWeights) {\n var previousPart = parts.length > 1 ? parts[parts.length - 2].toLowerCase() : '';\n if (maybeWeight == w || maybeWeight == w.replace('-', '') || previousPart + '-' + maybeWeight == w) {\n weight = haveWeight ? weight : fontWeights[w];\n parts.pop();\n if (previousPart && w.startsWith(previousPart)) {\n parts.pop();\n }\n break;\n }\n }\n if (!haveWeight && typeof maybeWeight == 'number') {\n weight = maybeWeight;\n }\n var fontFamily = parts.join(sp)\n .replace('Klokantech Noto Sans', 'Noto Sans');\n if (fontFamily.indexOf(sp) !== -1) {\n fontFamily = '\"' + fontFamily + '\"';\n }\n fontFamilies.push(fontFamily);\n }\n // CSS font property: font-style font-weight font-size/line-height font-family\n cssData = fontCache[fonts] = [style, weight, fontFamilies];\n }\n return cssData[0] + sp + cssData[1] + sp + size + 'px' + (lineHeight ? '/' + lineHeight : '') + sp + cssData[2];\n};\n","const mapboxBaseUrl = 'https://api.mapbox.com';\n\n/**\n * Gets the path from a mapbox:// URL.\n * @param {string} url The Mapbox URL.\n * @return {string} The path.\n * @private\n */\nexport function getMapboxPath(url) {\n const startsWith = 'mapbox://';\n if (url.indexOf(startsWith) !== 0) {\n return '';\n }\n return url.slice(startsWith.length);\n}\n\n/**\n * Turns mapbox:// sprite URLs into resolvable URLs.\n * @param {string} url The sprite URL.\n * @param {string} token The access token.\n * @param {string} styleUrl The style URL.\n * @return {string} A resolvable URL.\n * @private\n */\nexport function normalizeSpriteUrl(url, token, styleUrl) {\n const mapboxPath = getMapboxPath(url);\n if (!mapboxPath) {\n return decodeURI(new URL(url, styleUrl).href);\n }\n const startsWith = 'sprites/';\n if (mapboxPath.indexOf(startsWith) !== 0) {\n throw new Error(`unexpected sprites url: ${url}`);\n }\n const sprite = mapboxPath.slice(startsWith.length);\n\n return `${mapboxBaseUrl}/styles/v1/${sprite}/sprite?access_token=${token}`;\n}\n\n/**\n * Turns mapbox:// style URLs into resolvable URLs.\n * @param {string} url The style URL.\n * @param {string} token The access token.\n * @return {string} A resolvable URL.\n * @private\n */\nexport function normalizeStyleUrl(url, token) {\n const mapboxPath = getMapboxPath(url);\n if (!mapboxPath) {\n return decodeURI(new URL(url, location.href).href);\n }\n const startsWith = 'styles/';\n if (mapboxPath.indexOf(startsWith) !== 0) {\n throw new Error(`unexpected style url: ${url}`);\n }\n const style = mapboxPath.slice(startsWith.length);\n\n return `${mapboxBaseUrl}/styles/v1/${style}?&access_token=${token}`;\n}\n\n/**\n * Turns mapbox:// source URLs into vector tile URL templates.\n * @param {string} url The source URL.\n * @param {string} token The access token.\n * @param {string} tokenParam The access token key.\n * @param {string} styleUrl The style URL.\n * @return {string} A vector tile template.\n * @private\n */\nexport function normalizeSourceUrl(url, token, tokenParam, styleUrl) {\n const urlObject = new URL(url, styleUrl);\n const mapboxPath = getMapboxPath(url);\n if (!mapboxPath) {\n if (!token) {\n return decodeURI(urlObject.href);\n }\n urlObject.searchParams.set(tokenParam, token);\n return decodeURI(urlObject.href);\n }\n return `https://{a-d}.tiles.mapbox.com/v4/${mapboxPath}/{z}/{x}/{y}.vector.pbf?access_token=${token}`;\n}\n","import {assign} from 'ol/obj.js';\nimport {normalizeSourceUrl, normalizeStyleUrl} from './mapbox.js';\n\nexport function deg2rad(degrees) {\n return (degrees * Math.PI) / 180;\n}\n\nexport const defaultResolutions = (function () {\n const resolutions = [];\n for (let res = 78271.51696402048; resolutions.length <= 24; res /= 2) {\n resolutions.push(res);\n }\n return resolutions;\n})();\n\n/**\n * @param {number} width Width of the canvas.\n * @param {number} height Height of the canvas.\n * @return {HTMLCanvasElement} Canvas.\n */\nexport function createCanvas(width, height) {\n if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope && typeof OffscreenCanvas !== 'undefined') { // eslint-disable-line\n return /** @type {?} */ (new OffscreenCanvas(width, height));\n } else {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n }\n}\n\nexport function getZoomForResolution(resolution, resolutions) {\n let i = 0;\n const ii = resolutions.length;\n for (; i < ii; ++i) {\n const candidate = resolutions[i];\n if (candidate < resolution && i + 1 < ii) {\n const zoomFactor = resolutions[i] / resolutions[i + 1];\n return i + Math.log(resolutions[i] / resolution) / Math.log(zoomFactor);\n }\n }\n return ii - 1;\n}\n\nconst pendingRequests = {};\n/**\n * @param {ResourceType} resourceType Type of resource to load.\n * @param {string} url Url of the resource.\n * @param {Options} [options={}] Options.\n * @return {Promise} Promise that resolves with the loaded resource\n * or rejects with the Response object.\n * @private\n */\nexport function fetchResource(resourceType, url, options = {}) {\n if (url in pendingRequests) {\n return pendingRequests[url];\n } else {\n const request = options.transformRequest\n ? options.transformRequest(url, resourceType) || new Request(url)\n : new Request(url);\n if (!request.headers.get('Accept')) {\n request.headers.set('Accept', 'application/json');\n }\n const pendingRequest = fetch(request)\n .then(function (response) {\n delete pendingRequests[url];\n return response.ok\n ? response.json()\n : Promise.reject(new Error('Error fetching source ' + url));\n })\n .catch(function (error) {\n delete pendingRequests[url];\n return Promise.reject(new Error('Error fetching source ' + url));\n });\n pendingRequests[url] = pendingRequest;\n return pendingRequest;\n }\n}\n\nexport function getGlStyle(glStyleOrUrl, options) {\n if (typeof glStyleOrUrl === 'string') {\n if (glStyleOrUrl.trim().startsWith('{')) {\n try {\n const glStyle = JSON.parse(glStyleOrUrl);\n return Promise.resolve(glStyle);\n } catch (error) {\n return Promise.reject(error);\n }\n } else {\n glStyleOrUrl = normalizeStyleUrl(glStyleOrUrl, options.accessToken);\n return fetchResource('Style', glStyleOrUrl, options);\n }\n } else {\n return Promise.resolve(glStyleOrUrl);\n }\n}\n\nconst tilejsonCache = {};\n/**\n * @param {Object} glSource glStyle source object.\n * @param {string} styleUrl Style URL.\n * @param {Options} options Options.\n * @return {Object} TileJson\n */\nexport function getTileJson(glSource, styleUrl, options = {}) {\n const cacheKey = [styleUrl, JSON.stringify(glSource)].toString();\n let promise = tilejsonCache[cacheKey];\n if (!promise || options.transformRequest) {\n const url = glSource.url;\n if (url) {\n let normalizedSourceUrl = normalizeSourceUrl(\n url,\n options.accessToken,\n options.accessTokenParam || 'access_token',\n styleUrl || location.href\n );\n if (url.startsWith('mapbox://')) {\n promise = Promise.resolve(\n assign({}, glSource, {\n url: undefined,\n tiles: normalizedSourceUrl,\n })\n );\n } else {\n promise = fetchResource('Source', normalizedSourceUrl, options).then(\n function (tileJson) {\n for (let i = 0, ii = tileJson.tiles.length; i < ii; ++i) {\n const tileUrl = tileJson.tiles[i];\n if (options.transformRequest) {\n const request = options.transformRequest(\n normalizedSourceUrl,\n 'Source'\n );\n if (request) {\n normalizedSourceUrl = request.url;\n }\n }\n let normalizedTileUrl = normalizeSourceUrl(\n tileUrl,\n options.accessToken,\n options.accessTokenParam || 'access_token',\n normalizedSourceUrl\n );\n if (options.transformRequest) {\n const transformedRequest = options.transformRequest(\n normalizedTileUrl,\n 'Tiles'\n );\n if (transformedRequest instanceof Request) {\n normalizedTileUrl = decodeURI(transformedRequest.url);\n }\n }\n tileJson.tiles[i] = normalizedTileUrl;\n }\n return Promise.resolve(tileJson);\n }\n );\n }\n } else {\n glSource = assign({}, glSource, {\n tiles: glSource.tiles.map(function (tileUrl) {\n return normalizeSourceUrl(\n tileUrl,\n options.accessToken,\n options.accessTokenParam || 'access_token',\n styleUrl || location.href\n );\n }),\n });\n promise = Promise.resolve(assign({}, glSource));\n }\n tilejsonCache[cacheKey] = promise;\n }\n return promise;\n}\n\n/**\n * @typedef {import(\"./apply.js\").Options} Options\n * @typedef {import('./apply.js').ResourceType} ResourceType\n * @private\n */\n","import mb2css from 'mapbox-to-css-font';\nimport {checkedFonts, registerFont} from 'ol/render/canvas.js';\nimport {createCanvas} from './util.js';\n\nconst hairSpacePool = Array(256).join('\\u200A');\nexport function applyLetterSpacing(text, letterSpacing) {\n if (letterSpacing >= 0.05) {\n let textWithLetterSpacing = '';\n const lines = text.split('\\n');\n const joinSpaceString = hairSpacePool.slice(\n 0,\n Math.round(letterSpacing / 0.1)\n );\n for (let l = 0, ll = lines.length; l < ll; ++l) {\n if (l > 0) {\n textWithLetterSpacing += '\\n';\n }\n textWithLetterSpacing += lines[l].split('').join(joinSpaceString);\n }\n return textWithLetterSpacing;\n }\n return text;\n}\n\nlet measureContext;\nfunction getMeasureContext() {\n if (!measureContext) {\n measureContext = createCanvas(1, 1).getContext('2d');\n }\n return measureContext;\n}\n\nfunction measureText(text, letterSpacing) {\n return (\n getMeasureContext().measureText(text).width +\n (text.length - 1) * letterSpacing\n );\n}\n\nconst measureCache = {};\nexport function wrapText(text, font, em, letterSpacing) {\n if (text.indexOf('\\n') !== -1) {\n const hardLines = text.split('\\n');\n const lines = [];\n for (let i = 0, ii = hardLines.length; i < ii; ++i) {\n lines.push(wrapText(hardLines[i], font, em, letterSpacing));\n }\n return lines.join('\\n');\n }\n const key = em + ',' + font + ',' + text + ',' + letterSpacing;\n let wrappedText = measureCache[key];\n if (!wrappedText) {\n const words = text.split(' ');\n if (words.length > 1) {\n const ctx = getMeasureContext();\n ctx.font = font;\n const oneEm = ctx.measureText('M').width;\n const maxWidth = oneEm * em;\n let line = '';\n const lines = [];\n // Pass 1 - wrap lines to not exceed maxWidth\n for (let i = 0, ii = words.length; i < ii; ++i) {\n const word = words[i];\n const testLine = line + (line ? ' ' : '') + word;\n if (measureText(testLine, letterSpacing) <= maxWidth) {\n line = testLine;\n } else {\n if (line) {\n lines.push(line);\n }\n line = word;\n }\n }\n if (line) {\n lines.push(line);\n }\n // Pass 2 - add lines with a width of less than 30% of maxWidth to the previous or next line\n for (let i = 0, ii = lines.length; i < ii && ii > 1; ++i) {\n const line = lines[i];\n if (measureText(line, letterSpacing) < maxWidth * 0.35) {\n const prevWidth =\n i > 0 ? measureText(lines[i - 1], letterSpacing) : Infinity;\n const nextWidth =\n i < ii - 1 ? measureText(lines[i + 1], letterSpacing) : Infinity;\n lines.splice(i, 1);\n ii -= 1;\n if (prevWidth < nextWidth) {\n lines[i - 1] += ' ' + line;\n i -= 1;\n } else {\n lines[i] = line + ' ' + lines[i];\n }\n }\n }\n // Pass 3 - try to fill 80% of maxWidth for each line\n for (let i = 0, ii = lines.length - 1; i < ii; ++i) {\n const line = lines[i];\n const next = lines[i + 1];\n if (\n measureText(line, letterSpacing) > maxWidth * 0.7 &&\n measureText(next, letterSpacing) < maxWidth * 0.6\n ) {\n const lineWords = line.split(' ');\n const lastWord = lineWords.pop();\n if (measureText(lastWord, letterSpacing) < maxWidth * 0.2) {\n lines[i] = lineWords.join(' ');\n lines[i + 1] = lastWord + ' ' + next;\n }\n ii -= 1;\n }\n }\n wrappedText = lines.join('\\n');\n } else {\n wrappedText = text;\n }\n wrappedText = applyLetterSpacing(wrappedText, letterSpacing);\n measureCache[key] = wrappedText;\n }\n return wrappedText;\n}\n\nconst fontFamilyRegEx = /font-family: ?([^;]*);/;\nconst stripQuotesRegEx = /(\"|')/g;\nlet loadedFontFamilies;\nfunction hasFontFamily(family) {\n if (!loadedFontFamilies) {\n loadedFontFamilies = {};\n const styleSheets = document.styleSheets;\n for (let i = 0, ii = styleSheets.length; i < ii; ++i) {\n const styleSheet = /** @type {CSSStyleSheet} */ (styleSheets[i]);\n try {\n const cssRules = styleSheet.rules || styleSheet.cssRules;\n if (cssRules) {\n for (let j = 0, jj = cssRules.length; j < jj; ++j) {\n const cssRule = cssRules[j];\n if (cssRule.type == 5) {\n const match = cssRule.cssText.match(fontFamilyRegEx);\n loadedFontFamilies[match[1].replace(stripQuotesRegEx, '')] = true;\n }\n }\n }\n } catch (e) {\n // empty catch block\n }\n }\n }\n return family in loadedFontFamilies;\n}\n\nconst processedFontFamilies = {};\n\n/**\n * @param {Array} fonts Fonts.\n * @return {Array} Processed fonts.\n * @private\n */\nexport function getFonts(fonts) {\n const fontsKey = fonts.toString();\n if (fontsKey in processedFontFamilies) {\n return processedFontFamilies[fontsKey];\n }\n const googleFontDescriptions = [];\n for (let i = 0, ii = fonts.length; i < ii; ++i) {\n fonts[i] = fonts[i].replace('Arial Unicode MS', 'Arial');\n const font = fonts[i];\n const cssFont = mb2css(font, 1);\n registerFont(cssFont);\n const parts = cssFont.split(' ');\n googleFontDescriptions.push([\n parts.slice(3).join(' ').replace(/\"/g, ''),\n parts[1],\n parts[0],\n ]);\n }\n for (let i = 0, ii = googleFontDescriptions.length; i < ii; ++i) {\n const googleFontDescription = googleFontDescriptions[i];\n const family = googleFontDescription[0];\n if (!hasFontFamily(family)) {\n if (\n checkedFonts.get(\n `${googleFontDescription[2]}\\n${googleFontDescription[1]} \\n${family}`\n ) !== 100\n ) {\n const fontUrl =\n 'https://fonts.googleapis.com/css?family=' +\n family.replace(/ /g, '+') +\n ':' +\n googleFontDescription[1] +\n googleFontDescription[2];\n if (!document.querySelector('link[href=\"' + fontUrl + '\"]')) {\n const markup = document.createElement('link');\n markup.href = fontUrl;\n markup.rel = 'stylesheet';\n document.head.appendChild(markup);\n }\n }\n }\n }\n processedFontFamilies[fontsKey] = fonts;\n return fonts;\n}\n","/*\nol-mapbox-style - Use Mapbox Style objects with OpenLayers\nCopyright 2016-present ol-mapbox-style contributors\nLicense: https://raw.githubusercontent.com/openlayers/ol-mapbox-style/master/LICENSE\n*/\n\nimport Circle from 'ol/style/Circle.js';\nimport Fill from 'ol/style/Fill.js';\nimport Icon from 'ol/style/Icon.js';\nimport RenderFeature from 'ol/render/Feature.js';\nimport Stroke from 'ol/style/Stroke.js';\nimport Style from 'ol/style/Style.js';\nimport Text from 'ol/style/Text.js';\n\nimport Color from '@mapbox/mapbox-gl-style-spec/util/color.js';\nimport convertFunction from '@mapbox/mapbox-gl-style-spec/function/convert.js';\nimport createFilter from '@mapbox/mapbox-gl-style-spec/feature_filter/index.js';\nimport derefLayers from '@mapbox/mapbox-gl-style-spec/deref.js';\nimport mb2css from 'mapbox-to-css-font';\nimport spec from '@mapbox/mapbox-gl-style-spec/reference/v8.json';\nimport {applyLetterSpacing, wrapText} from './text.js';\nimport {\n createCanvas,\n defaultResolutions,\n deg2rad,\n getZoomForResolution,\n} from './util.js';\nimport {\n createPropertyExpression,\n isExpression,\n} from '@mapbox/mapbox-gl-style-spec/expression/index.js';\nimport {isFunction} from '@mapbox/mapbox-gl-style-spec/function/index.js';\n\n/**\n * @typedef {import(\"ol/layer/Vector\").default} VectorLayer\n * @typedef {import(\"ol/layer/VectorTile\").default} VectorTileLayer\n * @typedef {import(\"ol/style/Style\").StyleFunction} StyleFunction\n */\n\nconst types = {\n 'Point': 1,\n 'MultiPoint': 1,\n 'LineString': 2,\n 'MultiLineString': 2,\n 'Polygon': 3,\n 'MultiPolygon': 3,\n};\nconst anchor = {\n 'center': [0.5, 0.5],\n 'left': [0, 0.5],\n 'right': [1, 0.5],\n 'top': [0.5, 0],\n 'bottom': [0.5, 1],\n 'top-left': [0, 0],\n 'top-right': [1, 0],\n 'bottom-left': [0, 1],\n 'bottom-right': [1, 1],\n};\n\nconst expressionData = function (rawExpression, propertySpec) {\n const compiledExpression = createPropertyExpression(\n rawExpression,\n propertySpec\n );\n if (compiledExpression.result === 'error') {\n throw new Error(\n compiledExpression.value\n .map((err) => `${err.key}: ${err.message}`)\n .join(', ')\n );\n }\n return compiledExpression.value;\n};\n\nconst emptyObj = {};\nconst zoomObj = {zoom: 0};\nlet renderFeatureCoordinates, renderFeature;\n\n/**\n * @private\n * @param {Object} layer Gl object layer.\n * @param {string} layoutOrPaint 'layout' or 'paint'.\n * @param {string} property Feature property.\n * @param {number} zoom Zoom.\n * @param {Object} feature Gl feature.\n * @param {Object} [functionCache] Function cache.\n * @param {Object} [featureState] Feature state.\n * @return {?} Value.\n */\nexport function getValue(\n layer,\n layoutOrPaint,\n property,\n zoom,\n feature,\n functionCache,\n featureState\n) {\n const layerId = layer.id;\n if (!functionCache) {\n functionCache = {};\n console.warn('No functionCache provided to getValue()'); //eslint-disable-line no-console\n }\n if (!functionCache[layerId]) {\n functionCache[layerId] = {};\n }\n const functions = functionCache[layerId];\n if (!functions[property]) {\n let value = (layer[layoutOrPaint] || emptyObj)[property];\n const propertySpec = spec[`${layoutOrPaint}_${layer.type}`][property];\n if (value === undefined) {\n value = propertySpec.default;\n }\n let isExpr = isExpression(value);\n if (!isExpr && isFunction(value)) {\n value = convertFunction(value, propertySpec);\n isExpr = true;\n }\n if (isExpr) {\n const compiledExpression = expressionData(value, propertySpec);\n functions[property] =\n compiledExpression.evaluate.bind(compiledExpression);\n } else {\n if (propertySpec.type == 'color') {\n value = Color.parse(value);\n }\n functions[property] = function () {\n return value;\n };\n }\n }\n zoomObj.zoom = zoom;\n return functions[property](zoomObj, feature, featureState);\n}\n\n/**\n * @private\n * @param {Object} layer Gl object layer.\n * @param {number} zoom Zoom.\n * @param {Object} feature Gl feature.\n * @param {Object} [functionCache] Function cache.\n * @return {\"declutter\"|\"obstacle\"|\"none\"} Value.\n */\nfunction getIconDeclutterMode(layer, zoom, feature, functionCache) {\n const allowOverlap = getValue(\n layer,\n 'layout',\n 'icon-allow-overlap',\n zoom,\n feature,\n functionCache\n );\n if (!allowOverlap) {\n return 'declutter';\n }\n const ignorePlacement = getValue(\n layer,\n 'layout',\n 'icon-ignore-placement',\n zoom,\n feature,\n functionCache\n );\n if (!ignorePlacement) {\n return 'obstacle';\n }\n return 'none';\n}\n\n/**\n * @private\n * @param {string} layerId Layer id.\n * @param {?} filter Filter.\n * @param {Object} feature Feature.\n * @param {number} zoom Zoom.\n * @param {Object} [filterCache] Filter cache.\n * @return {boolean} Filter result.\n */\nfunction evaluateFilter(layerId, filter, feature, zoom, filterCache) {\n if (!filterCache) {\n console.warn('No filterCache provided to evaluateFilter()'); //eslint-disable-line no-console\n }\n if (!(layerId in filterCache)) {\n filterCache[layerId] = createFilter(filter).filter;\n }\n zoomObj.zoom = zoom;\n return filterCache[layerId](zoomObj, feature);\n}\n\nlet renderTransparentEnabled = false;\n\n/**\n * Configure whether features with a transparent style should be rendered. When\n * set to `true`, it will be possible to hit detect content that is not visible,\n * like transparent fills of polygons, using `ol/layer/Layer#getFeatures()` or\n * `ol/Map#getFeaturesAtPixel()`\n * @param {boolean} enabled Rendering of transparent elements is enabled.\n * Default is `false`.\n */\nexport function renderTransparent(enabled) {\n renderTransparentEnabled = enabled;\n}\n\n/**\n * @private\n * @param {?} color Color.\n * @param {number} [opacity] Opacity.\n * @return {string} Color.\n */\nfunction colorWithOpacity(color, opacity) {\n if (color) {\n if (!renderTransparentEnabled && (color.a === 0 || opacity === 0)) {\n return undefined;\n }\n const a = color.a;\n opacity = opacity === undefined ? 1 : opacity;\n return a === 0\n ? 'transparent'\n : 'rgba(' +\n Math.round((color.r * 255) / a) +\n ',' +\n Math.round((color.g * 255) / a) +\n ',' +\n Math.round((color.b * 255) / a) +\n ',' +\n a * opacity +\n ')';\n }\n return color;\n}\n\nconst templateRegEx = /^([^]*)\\{(.*)\\}([^]*)$/;\n\n/**\n * @private\n * @param {string} text Text.\n * @param {Object} properties Properties.\n * @return {string} Text.\n */\nfunction fromTemplate(text, properties) {\n let parts;\n do {\n parts = text.match(templateRegEx);\n if (parts) {\n const value = properties[parts[2]] || '';\n text = parts[1] + value + parts[3];\n }\n } while (parts);\n return text;\n}\n\nlet recordLayer = false;\n\n/**\n * Turns recording of the Mapbox Style's `layer` on and off. When turned on,\n * the layer that a rendered feature belongs to will be set as the feature's\n * `mapbox-layer` property.\n * @param {boolean} record Recording of the style layer is on.\n */\nexport function recordStyleLayer(record = false) {\n recordLayer = record;\n}\n\n/**\n * Creates a style function from the `glStyle` object for all layers that use\n * the specified `source`, which needs to be a `\"type\": \"vector\"` or\n * `\"type\": \"geojson\"` source and applies it to the specified OpenLayers layer.\n *\n * Two additional properties will be set on the provided layer:\n *\n * * `mapbox-source`: The `id` of the Mapbox Style document's source that the\n * OpenLayers layer was created from. Usually `apply()` creates one\n * OpenLayers layer per Mapbox Style source, unless the layer stack has\n * layers from different sources in between.\n * * `mapbox-layers`: The `id`s of the Mapbox Style document's layers that are\n * included in the OpenLayers layer.\n *\n * This function also works in a web worker. In worker mode, the main thread needs\n * to listen to messages from the worker and respond with another message to make\n * sure that sprite image loading works:\n *\n * ```js\n * worker.addEventListener('message', event => {\n * if (event.data.action === 'loadImage') {\n * const image = new Image();\n * image.crossOrigin = 'anonymous';\n * image.addEventListener('load', function() {\n * createImageBitmap(image, 0, 0, image.width, image.height).then(imageBitmap => {\n * worker.postMessage({\n * action: 'imageLoaded',\n * image: imageBitmap,\n * src: event.data.src\n * }, [imageBitmap]);\n * });\n * });\n * image.src = event.data.src;\n * }\n * });\n * ```\n *\n * @param {VectorLayer|VectorTileLayer} olLayer OpenLayers layer to\n * apply the style to. In addition to the style, the layer will get two\n * properties: `mapbox-source` will be the `id` of the `glStyle`'s source used\n * for the layer, and `mapbox-layers` will be an array of the `id`s of the\n * `glStyle`'s layers.\n * @param {string|Object} glStyle Mapbox Style object.\n * @param {string|Array} sourceOrLayers `source` key or an array of layer `id`s\n * from the Mapbox Style object. When a `source` key is provided, all layers for\n * the specified source will be included in the style function. When layer `id`s\n * are provided, they must be from layers that use the same source.\n * @param {Array} resolutions\n * Resolutions for mapping resolution to zoom level.\n * @param {Object} spriteData Sprite data from the url specified in\n * the Mapbox Style object's `sprite` property. Only required if a `sprite`\n * property is specified in the Mapbox Style object.\n * @param {string} spriteImageUrl Sprite image url for the sprite\n * specified in the Mapbox Style object's `sprite` property. Only required if a\n * `sprite` property is specified in the Mapbox Style object.\n * @param {function(Array):Array} getFonts Function that\n * receives a font stack as arguments, and returns a (modified) font stack that\n * is available. Font names are the names used in the Mapbox Style object. If\n * not provided, the font stack will be used as-is. This function can also be\n * used for loading web fonts.\n * @return {StyleFunction} Style function for use in\n * `ol.layer.Vector` or `ol.layer.VectorTile`.\n */\nexport function stylefunction(\n olLayer,\n glStyle,\n sourceOrLayers,\n resolutions = defaultResolutions,\n spriteData = undefined,\n spriteImageUrl = undefined,\n getFonts = undefined\n) {\n if (typeof glStyle == 'string') {\n glStyle = JSON.parse(glStyle);\n }\n if (glStyle.version != 8) {\n throw new Error('glStyle version 8 required.');\n }\n\n let spriteImage, spriteImgSize;\n if (spriteImageUrl) {\n if (typeof Image !== 'undefined') {\n const img = new Image();\n img.crossOrigin = 'anonymous';\n img.onload = function () {\n spriteImage = img;\n spriteImgSize = [img.width, img.height];\n olLayer.changed();\n img.onload = null;\n };\n img.src = spriteImageUrl;\n } else if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) { //eslint-disable-line\n const worker = /** @type {*} */ (self);\n // Main thread needs to handle 'loadImage' and dispatch 'imageLoaded'\n worker.postMessage({\n action: 'loadImage',\n src: spriteImageUrl,\n });\n worker.addEventListener('message', function handler(event) {\n if (\n event.data.action === 'imageLoaded' &&\n event.data.src === spriteImageUrl\n ) {\n spriteImage = event.data.image;\n spriteImgSize = [spriteImage.width, spriteImage.height];\n }\n });\n }\n }\n\n const allLayers = derefLayers(glStyle.layers);\n\n const layersBySourceLayer = {};\n const mapboxLayers = [];\n\n const iconImageCache = {};\n const patternCache = {};\n const functionCache = {};\n const filterCache = {};\n\n let mapboxSource;\n for (let i = 0, ii = allLayers.length; i < ii; ++i) {\n const layer = allLayers[i];\n const layerId = layer.id;\n if (\n (typeof sourceOrLayers == 'string' && layer.source == sourceOrLayers) ||\n sourceOrLayers.indexOf(layerId) !== -1\n ) {\n const sourceLayer = layer['source-layer'];\n if (!mapboxSource) {\n mapboxSource = layer.source;\n const source = glStyle.sources[mapboxSource];\n if (!source) {\n throw new Error(`Source \"${mapboxSource}\" is not defined`);\n }\n const type = source.type;\n if (type !== 'vector' && type !== 'geojson') {\n throw new Error(\n `Source \"${mapboxSource}\" is not of type \"vector\" or \"geojson\", but \"${type}\"`\n );\n }\n } else if (layer.source !== mapboxSource) {\n throw new Error(\n `Layer \"${layerId}\" does not use source \"${mapboxSource}`\n );\n }\n let layers = layersBySourceLayer[sourceLayer];\n if (!layers) {\n layers = [];\n layersBySourceLayer[sourceLayer] = layers;\n }\n layers.push({\n layer: layer,\n index: i,\n });\n mapboxLayers.push(layerId);\n }\n }\n\n const textHalo = new Stroke();\n const textColor = new Fill();\n\n const styles = [];\n\n const styleFunction = function (feature, resolution) {\n const properties = feature.getProperties();\n const layers = layersBySourceLayer[properties.layer];\n if (!layers) {\n return;\n }\n let zoom = resolutions.indexOf(resolution);\n if (zoom == -1) {\n zoom = getZoomForResolution(resolution, resolutions);\n }\n const type = types[feature.getGeometry().getType()];\n const f = {\n properties: properties,\n type: type,\n };\n const featureState = olLayer.get('mapbox-featurestate')[feature.getId()];\n let stylesLength = -1;\n let featureBelongsToLayer;\n for (let i = 0, ii = layers.length; i < ii; ++i) {\n const layerData = layers[i];\n const layer = layerData.layer;\n const layerId = layer.id;\n\n const layout = layer.layout || emptyObj;\n const paint = layer.paint || emptyObj;\n if (\n layout.visibility === 'none' ||\n ('minzoom' in layer && zoom < layer.minzoom) ||\n ('maxzoom' in layer && zoom >= layer.maxzoom)\n ) {\n continue;\n }\n const filter = layer.filter;\n if (!filter || evaluateFilter(layerId, filter, f, zoom, filterCache)) {\n featureBelongsToLayer = layer;\n let color, opacity, fill, stroke, strokeColor, style;\n const index = layerData.index;\n if (\n type == 3 &&\n (layer.type == 'fill' || layer.type == 'fill-extrusion')\n ) {\n opacity = getValue(\n layer,\n 'paint',\n layer.type + '-opacity',\n zoom,\n f,\n functionCache,\n featureState\n );\n if (layer.type + '-pattern' in paint) {\n const fillIcon = getValue(\n layer,\n 'paint',\n layer.type + '-pattern',\n zoom,\n f,\n functionCache,\n featureState\n );\n if (fillIcon) {\n const icon =\n typeof fillIcon === 'string'\n ? fromTemplate(fillIcon, properties)\n : fillIcon.toString();\n if (spriteImage && spriteData && spriteData[icon]) {\n ++stylesLength;\n style = styles[stylesLength];\n if (\n !style ||\n !style.getFill() ||\n style.getStroke() ||\n style.getText()\n ) {\n style = new Style({\n fill: new Fill(),\n });\n styles[stylesLength] = style;\n }\n fill = style.getFill();\n style.setZIndex(index);\n const icon_cache_key = icon + '.' + opacity;\n let pattern = patternCache[icon_cache_key];\n if (!pattern) {\n const spriteImageData = spriteData[icon];\n const canvas = createCanvas(\n spriteImageData.width,\n spriteImageData.height\n );\n const ctx = /** @type {CanvasRenderingContext2D} */ (\n canvas.getContext('2d')\n );\n ctx.globalAlpha = opacity;\n ctx.drawImage(\n spriteImage,\n spriteImageData.x,\n spriteImageData.y,\n spriteImageData.width,\n spriteImageData.height,\n 0,\n 0,\n spriteImageData.width,\n spriteImageData.height\n );\n pattern = ctx.createPattern(canvas, 'repeat');\n patternCache[icon_cache_key] = pattern;\n }\n fill.setColor(pattern);\n }\n }\n } else {\n color = colorWithOpacity(\n getValue(\n layer,\n 'paint',\n layer.type + '-color',\n zoom,\n f,\n functionCache,\n featureState\n ),\n opacity\n );\n if (layer.type + '-outline-color' in paint) {\n strokeColor = colorWithOpacity(\n getValue(\n layer,\n 'paint',\n layer.type + '-outline-color',\n zoom,\n f,\n functionCache,\n featureState\n ),\n opacity\n );\n }\n if (!strokeColor) {\n strokeColor = color;\n }\n if (color || strokeColor) {\n ++stylesLength;\n style = styles[stylesLength];\n if (\n !style ||\n (color && !style.getFill()) ||\n (!color && style.getFill()) ||\n (strokeColor && !style.getStroke()) ||\n (!strokeColor && style.getStroke()) ||\n style.getText()\n ) {\n style = new Style({\n fill: color ? new Fill() : undefined,\n stroke: strokeColor ? new Stroke() : undefined,\n });\n styles[stylesLength] = style;\n }\n if (color) {\n fill = style.getFill();\n fill.setColor(color);\n }\n if (strokeColor) {\n stroke = style.getStroke();\n stroke.setColor(strokeColor);\n stroke.setWidth(0.5);\n }\n style.setZIndex(index);\n }\n }\n }\n if (type != 1 && layer.type == 'line') {\n color =\n !('line-pattern' in paint) && 'line-color' in paint\n ? colorWithOpacity(\n getValue(\n layer,\n 'paint',\n 'line-color',\n zoom,\n f,\n functionCache,\n featureState\n ),\n getValue(\n layer,\n 'paint',\n 'line-opacity',\n zoom,\n f,\n functionCache,\n featureState\n )\n )\n : undefined;\n const width = getValue(\n layer,\n 'paint',\n 'line-width',\n zoom,\n f,\n functionCache,\n featureState\n );\n if (color && width > 0) {\n ++stylesLength;\n style = styles[stylesLength];\n if (\n !style ||\n !style.getStroke() ||\n style.getFill() ||\n style.getText()\n ) {\n style = new Style({\n stroke: new Stroke(),\n });\n styles[stylesLength] = style;\n }\n stroke = style.getStroke();\n stroke.setLineCap(\n getValue(\n layer,\n 'layout',\n 'line-cap',\n zoom,\n f,\n functionCache,\n featureState\n )\n );\n stroke.setLineJoin(\n getValue(\n layer,\n 'layout',\n 'line-join',\n zoom,\n f,\n functionCache,\n featureState\n )\n );\n stroke.setMiterLimit(\n getValue(\n layer,\n 'layout',\n 'line-miter-limit',\n zoom,\n f,\n functionCache,\n featureState\n )\n );\n stroke.setColor(color);\n stroke.setWidth(width);\n stroke.setLineDash(\n paint['line-dasharray']\n ? getValue(\n layer,\n 'paint',\n 'line-dasharray',\n zoom,\n f,\n functionCache,\n featureState\n ).map(function (x) {\n return x * width;\n })\n : null\n );\n style.setZIndex(index);\n }\n }\n\n let hasImage = false;\n let text = null;\n let placementAngle = 0;\n let icon, iconImg, skipLabel;\n if ((type == 1 || type == 2) && 'icon-image' in layout) {\n const iconImage = getValue(\n layer,\n 'layout',\n 'icon-image',\n zoom,\n f,\n functionCache,\n featureState\n );\n if (iconImage) {\n icon =\n typeof iconImage === 'string'\n ? fromTemplate(iconImage, properties)\n : iconImage.toString();\n let styleGeom = undefined;\n if (spriteImage && spriteData && spriteData[icon]) {\n const iconRotationAlignment = getValue(\n layer,\n 'layout',\n 'icon-rotation-alignment',\n zoom,\n f,\n functionCache,\n featureState\n );\n if (type == 2) {\n const geom = feature.getGeometry();\n // ol package and ol-debug.js only\n if (geom.getFlatMidpoint || geom.getFlatMidpoints) {\n const extent = geom.getExtent();\n const size = Math.sqrt(\n Math.max(\n Math.pow((extent[2] - extent[0]) / resolution, 2),\n Math.pow((extent[3] - extent[1]) / resolution, 2)\n )\n );\n if (size > 150) {\n //FIXME Do not hard-code a size of 150\n const midpoint =\n geom.getType() === 'MultiLineString'\n ? geom.getFlatMidpoints()\n : geom.getFlatMidpoint();\n if (!renderFeature) {\n renderFeatureCoordinates = [NaN, NaN];\n renderFeature = new RenderFeature(\n 'Point',\n renderFeatureCoordinates,\n [],\n {},\n null\n );\n }\n styleGeom = renderFeature;\n renderFeatureCoordinates[0] = midpoint[0];\n renderFeatureCoordinates[1] = midpoint[1];\n const placement = getValue(\n layer,\n 'layout',\n 'symbol-placement',\n zoom,\n f,\n functionCache,\n featureState\n );\n if (\n placement === 'line' &&\n iconRotationAlignment === 'map'\n ) {\n const stride = geom.getStride();\n const coordinates = geom.getFlatCoordinates();\n for (\n let i = 0, ii = coordinates.length - stride;\n i < ii;\n i += stride\n ) {\n const x1 = coordinates[i];\n const y1 = coordinates[i + 1];\n const x2 = coordinates[i + stride];\n const y2 = coordinates[i + stride + 1];\n const minX = Math.min(x1, x2);\n const minY = Math.min(y1, y2);\n const maxX = Math.max(x1, x2);\n const maxY = Math.max(y1, y2);\n if (\n midpoint[0] >= minX &&\n midpoint[0] <= maxX &&\n midpoint[1] >= minY &&\n midpoint[1] <= maxY\n ) {\n placementAngle = Math.atan2(y1 - y2, x2 - x1);\n break;\n }\n }\n }\n }\n }\n }\n if (type !== 2 || styleGeom) {\n const iconSize = getValue(\n layer,\n 'layout',\n 'icon-size',\n zoom,\n f,\n functionCache,\n featureState\n );\n const iconColor =\n paint['icon-color'] !== undefined\n ? getValue(\n layer,\n 'paint',\n 'icon-color',\n zoom,\n f,\n functionCache,\n featureState\n )\n : null;\n if (!iconColor || iconColor.a !== 0) {\n let icon_cache_key = icon + '.' + iconSize;\n if (iconColor !== null) {\n icon_cache_key += '.' + iconColor;\n }\n iconImg = iconImageCache[icon_cache_key];\n if (!iconImg) {\n const spriteImageData = spriteData[icon];\n\n const declutterMode = getIconDeclutterMode(\n layer,\n zoom,\n f,\n functionCache\n );\n iconImg = new Icon({\n color: iconColor\n ? [\n iconColor.r * 255,\n iconColor.g * 255,\n iconColor.b * 255,\n iconColor.a,\n ]\n : undefined,\n img: spriteImage,\n imgSize: spriteImgSize,\n size: [spriteImageData.width, spriteImageData.height],\n offset: [spriteImageData.x, spriteImageData.y],\n rotateWithView: iconRotationAlignment === 'map',\n scale: iconSize / spriteImageData.pixelRatio,\n displacement:\n 'icon-offset' in layout\n ? getValue(\n layer,\n 'layout',\n 'icon-offset',\n zoom,\n f,\n functionCache,\n featureState\n ).map((v) => -v * spriteImageData.pixelRatio)\n : undefined,\n declutterMode: declutterMode,\n });\n iconImageCache[icon_cache_key] = iconImg;\n }\n }\n if (iconImg) {\n ++stylesLength;\n style = styles[stylesLength];\n if (\n !style ||\n !style.getImage() ||\n style.getFill() ||\n style.getStroke()\n ) {\n style = new Style();\n styles[stylesLength] = style;\n }\n style.setGeometry(styleGeom);\n iconImg.setRotation(\n placementAngle +\n deg2rad(\n getValue(\n layer,\n 'layout',\n 'icon-rotate',\n zoom,\n f,\n functionCache,\n featureState\n )\n )\n );\n iconImg.setOpacity(\n getValue(\n layer,\n 'paint',\n 'icon-opacity',\n zoom,\n f,\n functionCache,\n featureState\n )\n );\n iconImg.setAnchor(\n anchor[\n getValue(\n layer,\n 'layout',\n 'icon-anchor',\n zoom,\n f,\n functionCache,\n featureState\n )\n ]\n );\n style.setImage(iconImg);\n text = style.getText();\n style.setText(undefined);\n style.setZIndex(index);\n hasImage = true;\n skipLabel = false;\n }\n } else {\n skipLabel = true;\n }\n }\n }\n }\n\n if (type == 1 && layer.type === 'circle') {\n ++stylesLength;\n style = styles[stylesLength];\n if (\n !style ||\n !style.getImage() ||\n style.getFill() ||\n style.getStroke()\n ) {\n style = new Style();\n styles[stylesLength] = style;\n }\n const circleRadius =\n 'circle-radius' in paint\n ? getValue(\n layer,\n 'paint',\n 'circle-radius',\n zoom,\n f,\n functionCache,\n featureState\n )\n : 5;\n const circleStrokeColor = colorWithOpacity(\n getValue(\n layer,\n 'paint',\n 'circle-stroke-color',\n zoom,\n f,\n functionCache,\n featureState\n ),\n getValue(\n layer,\n 'paint',\n 'circle-stroke-opacity',\n zoom,\n f,\n functionCache,\n featureState\n )\n );\n const circleColor = colorWithOpacity(\n getValue(\n layer,\n 'paint',\n 'circle-color',\n zoom,\n f,\n functionCache,\n featureState\n ),\n getValue(\n layer,\n 'paint',\n 'circle-opacity',\n zoom,\n f,\n functionCache,\n featureState\n )\n );\n const circleStrokeWidth = getValue(\n layer,\n 'paint',\n 'circle-stroke-width',\n zoom,\n f,\n functionCache,\n featureState\n );\n const cache_key =\n circleRadius +\n '.' +\n circleStrokeColor +\n '.' +\n circleColor +\n '.' +\n circleStrokeWidth;\n iconImg = iconImageCache[cache_key];\n if (!iconImg) {\n iconImg = new Circle({\n radius: circleRadius,\n stroke:\n circleStrokeColor && circleStrokeWidth > 0\n ? new Stroke({\n width: circleStrokeWidth,\n color: circleStrokeColor,\n })\n : undefined,\n fill: circleColor\n ? new Fill({\n color: circleColor,\n })\n : undefined,\n declutterMode: 'none',\n });\n iconImageCache[cache_key] = iconImg;\n }\n style.setImage(iconImg);\n text = style.getText();\n style.setText(undefined);\n style.setGeometry(undefined);\n style.setZIndex(index);\n hasImage = true;\n }\n\n let label, font, textLineHeight, textSize, letterSpacing, maxTextWidth;\n if ('text-field' in layout) {\n textSize = Math.round(\n getValue(\n layer,\n 'layout',\n 'text-size',\n zoom,\n f,\n functionCache,\n featureState\n )\n );\n const fontArray = getValue(\n layer,\n 'layout',\n 'text-font',\n zoom,\n f,\n functionCache,\n featureState\n );\n textLineHeight = getValue(\n layer,\n 'layout',\n 'text-line-height',\n zoom,\n f,\n functionCache,\n featureState\n );\n font = mb2css(\n getFonts ? getFonts(fontArray) : fontArray,\n textSize,\n textLineHeight\n );\n if (!font.includes('sans-serif')) {\n font += ',sans-serif';\n }\n letterSpacing = getValue(\n layer,\n 'layout',\n 'text-letter-spacing',\n zoom,\n f,\n functionCache,\n featureState\n );\n maxTextWidth = getValue(\n layer,\n 'layout',\n 'text-max-width',\n zoom,\n f,\n functionCache,\n featureState\n );\n const textField = getValue(\n layer,\n 'layout',\n 'text-field',\n zoom,\n f,\n functionCache,\n featureState\n );\n if (typeof textField === 'object' && textField.sections) {\n if (textField.sections.length === 1) {\n label = textField.toString();\n } else {\n label = textField.sections.reduce((acc, chunk, i) => {\n const fonts = chunk.fontStack\n ? chunk.fontStack.split(',')\n : fontArray;\n const chunkFont = mb2css(\n getFonts ? getFonts(fonts) : fonts,\n textSize * (chunk.scale || 1),\n textLineHeight\n );\n let text = chunk.text;\n if (text === '\\n') {\n acc.push('\\n', '');\n return acc;\n }\n if (type == 2) {\n acc.push(applyLetterSpacing(text, letterSpacing), chunkFont);\n return;\n }\n text = wrapText(\n text,\n chunkFont,\n maxTextWidth,\n letterSpacing\n ).split('\\n');\n for (let i = 0, ii = text.length; i < ii; ++i) {\n if (i > 0) {\n acc.push('\\n', '');\n }\n acc.push(text[i], chunkFont);\n }\n return acc;\n }, []);\n }\n } else {\n label = fromTemplate(textField, properties).trim();\n }\n opacity = getValue(\n layer,\n 'paint',\n 'text-opacity',\n zoom,\n f,\n functionCache,\n featureState\n );\n }\n if (label && opacity && !skipLabel) {\n if (!hasImage) {\n ++stylesLength;\n style = styles[stylesLength];\n if (\n !style ||\n !style.getText() ||\n style.getFill() ||\n style.getStroke()\n ) {\n style = new Style();\n styles[stylesLength] = style;\n }\n style.setImage(undefined);\n style.setGeometry(undefined);\n }\n if (!style.getText()) {\n style.setText(\n text ||\n new Text({\n padding: [2, 2, 2, 2],\n })\n );\n }\n text = style.getText();\n const textTransform = layout['text-transform'];\n if (textTransform == 'uppercase') {\n label = Array.isArray(label)\n ? label.map((t, i) => (i % 2 ? t : t.toUpperCase()))\n : label.toUpperCase();\n } else if (textTransform == 'lowercase') {\n label = Array.isArray(label)\n ? label.map((t, i) => (i % 2 ? t : t.toLowerCase()))\n : label.toLowerCase();\n }\n const wrappedLabel = Array.isArray(label)\n ? label\n : type == 2\n ? applyLetterSpacing(label, letterSpacing)\n : wrapText(label, font, maxTextWidth, letterSpacing);\n text.setText(wrappedLabel);\n text.setFont(font);\n text.setRotation(\n deg2rad(\n getValue(\n layer,\n 'layout',\n 'text-rotate',\n zoom,\n f,\n functionCache,\n featureState\n )\n )\n );\n const textAnchor = getValue(\n layer,\n 'layout',\n 'text-anchor',\n zoom,\n f,\n functionCache,\n featureState\n );\n const placement =\n hasImage || type == 1\n ? 'point'\n : getValue(\n layer,\n 'layout',\n 'symbol-placement',\n zoom,\n f,\n functionCache,\n featureState\n );\n text.setPlacement(placement);\n text.setOverflow(placement === 'point');\n let textHaloWidth = getValue(\n layer,\n 'paint',\n 'text-halo-width',\n zoom,\n f,\n functionCache,\n featureState\n );\n const textOffset = getValue(\n layer,\n 'layout',\n 'text-offset',\n zoom,\n f,\n functionCache,\n featureState\n );\n const textTranslate = getValue(\n layer,\n 'paint',\n 'text-translate',\n zoom,\n f,\n functionCache,\n featureState\n );\n // Text offset has to take halo width and line height into account\n let vOffset = 0;\n let hOffset = 0;\n if (placement == 'point') {\n let textAlign = 'center';\n if (textAnchor.indexOf('left') !== -1) {\n textAlign = 'left';\n hOffset = textHaloWidth;\n } else if (textAnchor.indexOf('right') !== -1) {\n textAlign = 'right';\n hOffset = -textHaloWidth;\n }\n text.setTextAlign(textAlign);\n const textRotationAlignment = getValue(\n layer,\n 'layout',\n 'text-rotation-alignment',\n zoom,\n f,\n functionCache,\n featureState\n );\n text.setRotateWithView(textRotationAlignment == 'map');\n } else {\n text.setMaxAngle(\n (deg2rad(\n getValue(\n layer,\n 'layout',\n 'text-max-angle',\n zoom,\n f,\n functionCache,\n featureState\n )\n ) *\n label.length) /\n wrappedLabel.length\n );\n text.setTextAlign();\n text.setRotateWithView(false);\n }\n let textBaseline = 'middle';\n if (textAnchor.indexOf('bottom') == 0) {\n textBaseline = 'bottom';\n vOffset = -textHaloWidth - 0.5 * (textLineHeight - 1) * textSize;\n } else if (textAnchor.indexOf('top') == 0) {\n textBaseline = 'top';\n vOffset = textHaloWidth + 0.5 * (textLineHeight - 1) * textSize;\n }\n text.setTextBaseline(textBaseline);\n text.setOffsetX(\n textOffset[0] * textSize + hOffset + textTranslate[0]\n );\n text.setOffsetY(\n textOffset[1] * textSize + vOffset + textTranslate[1]\n );\n textColor.setColor(\n colorWithOpacity(\n getValue(\n layer,\n 'paint',\n 'text-color',\n zoom,\n f,\n functionCache,\n featureState\n ),\n opacity\n )\n );\n text.setFill(textColor);\n const haloColor = colorWithOpacity(\n getValue(\n layer,\n 'paint',\n 'text-halo-color',\n zoom,\n f,\n functionCache,\n featureState\n ),\n opacity\n );\n if (haloColor) {\n textHalo.setColor(haloColor);\n // spec here : https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-symbol-text-halo-width\n // Halo width must be doubled because it is applied around the center of the text outline\n textHaloWidth *= 2;\n // 1/4 of text size (spec) x 2\n const halfTextSize = 0.5 * textSize;\n textHalo.setWidth(\n textHaloWidth <= halfTextSize ? textHaloWidth : halfTextSize\n );\n text.setStroke(textHalo);\n } else {\n text.setStroke(undefined);\n }\n const textPadding = getValue(\n layer,\n 'layout',\n 'text-padding',\n zoom,\n f,\n functionCache,\n featureState\n );\n const padding = text.getPadding();\n if (textPadding !== padding[0]) {\n padding[0] = textPadding;\n padding[1] = textPadding;\n padding[2] = textPadding;\n padding[3] = textPadding;\n }\n style.setZIndex(index);\n }\n }\n }\n\n if (stylesLength > -1) {\n styles.length = stylesLength + 1;\n if (recordLayer) {\n if (typeof feature.set === 'function') {\n // ol/Feature\n feature.set('mapbox-layer', featureBelongsToLayer);\n } else {\n // ol/render/Feature\n feature.getProperties()['mapbox-layer'] = featureBelongsToLayer;\n }\n }\n return styles;\n }\n };\n\n olLayer.setStyle(styleFunction);\n olLayer.set('mapbox-source', mapboxSource);\n olLayer.set('mapbox-layers', mapboxLayers);\n olLayer.set('mapbox-featurestate', {});\n return styleFunction;\n}\n\nexport {\n colorWithOpacity as _colorWithOpacity,\n evaluateFilter as _evaluateFilter,\n fromTemplate as _fromTemplate,\n getValue as _getValue,\n};\n","/*\nol-mapbox-style - Use Mapbox Style objects with OpenLayers\nCopyright 2016-present ol-mapbox-style contributors\nLicense: https://raw.githubusercontent.com/openlayers/ol-mapbox-style/master/LICENSE\n*/\n\nimport Color from '@mapbox/mapbox-gl-style-spec/util/color.js';\nimport GeoJSON from 'ol/format/GeoJSON.js';\nimport MVT from 'ol/format/MVT.js';\nimport Map from 'ol/Map.js';\nimport TileGrid from 'ol/tilegrid/TileGrid.js';\nimport TileJSON from 'ol/source/TileJSON.js';\nimport TileLayer from 'ol/layer/Tile.js';\nimport VectorLayer from 'ol/layer/Vector.js';\nimport VectorSource from 'ol/source/Vector.js';\nimport VectorTileLayer from 'ol/layer/VectorTile.js';\nimport VectorTileSource, {defaultLoadFunction} from 'ol/source/VectorTile.js';\nimport View from 'ol/View.js';\nimport {\n _colorWithOpacity,\n stylefunction as applyStyleFunction,\n getValue,\n} from './stylefunction.js';\nimport {assign} from 'ol/obj.js';\nimport {createXYZ} from 'ol/tilegrid.js';\nimport {\n defaultResolutions,\n fetchResource,\n getGlStyle,\n getTileJson,\n} from './util.js';\nimport {equivalent, fromLonLat, getUserProjection} from 'ol/proj.js';\nimport {getFonts} from './text.js';\nimport {\n normalizeSourceUrl,\n normalizeSpriteUrl,\n normalizeStyleUrl,\n} from './mapbox.js';\n\n/**\n * @typedef {Object} FeatureIdentifier\n * @property {string|number} id The feature id.\n * @property {string} source The source id.\n */\n\n/**\n * @typedef {Object} Options\n * @property {string} [accessToken] Access token for 'mapbox://' urls.\n * @property {function(string, ResourceType): (Request|void)} [transformRequest]\n * Function for controlling how `ol-mapbox-style` fetches resources. Can be used for modifying\n * the url, adding headers or setting credentials options. Called with the url and the resource\n * type as arguments, this function is supposed to return a `Request` object. Without a return value,\n * the original request will not be modified. For `Tiles` and `GeoJSON` resources, only the `url` of\n * the returned request will be respected.\n * @property {Array} [resolutions] Resolutions for mapping resolution to zoom level.\n * Only needed when working with non-standard tile grids or projections.\n * @property {string} [styleUrl] URL of the Mapbox GL style. Required for styles that were provided\n * as object, when they contain a relative sprite url, or sources referencing data by relative url.\n * @property {string} [accessTokenParam='access_token'] Access token param. For internal use.\n */\n\n/** @typedef {'Style'|'Source'|'Sprite'|'Tiles'|'GeoJSON'} ResourceType */\n/** @typedef {import(\"ol/layer/Layer\").default} Layer */\n/** @typedef {import(\"ol/source/Source\").default} Source */\n\n/**\n * @param {string} styleUrl Style URL.\n * @param {Options} options Options.\n * @return {Options} Completed options with accessToken and accessTokenParam.\n */\nfunction completeOptions(styleUrl, options) {\n if (!options.accessToken) {\n options = assign({}, options);\n const searchParams = new URL(styleUrl).searchParams;\n // The last search parameter is the access token\n searchParams.forEach((value, key) => {\n options.accessToken = value;\n options.accessTokenParam = key;\n });\n }\n return options;\n}\n\n/**\n * Applies a style function to an `ol/layer/VectorTile` or `ol/layer/Vector`\n * with an `ol/source/VectorTile` or an `ol/source/Vector`. If the layer does not have a source\n * yet, it will be created and populated from the information in the `glStyle`.\n *\n * **Example:**\n * ```js\n * import {applyStyle} from 'ol-mapbox-style';\n * import {VectorTile} from 'ol/layer.js';\n *\n * const layer = new VectorTile({declutter: true});\n * applyStyle(layer, 'https://api.maptiler.com/maps/basic/style.json?key=YOUR_OPENMAPTILES_TOKEN');\n * ```\n *\n * The style function will render all layers from the `glStyle` object that use the source\n * of the first layer, the specified `source`, or a subset of layers from the same source. The\n * source needs to be a `\"type\": \"vector\"` or `\"type\": \"geojson\"` source.\n *\n * Two additional properties will be set on the provided layer:\n *\n * * `mapbox-source`: The `id` of the Mapbox Style document's source that the\n * OpenLayers layer was created from. Usually `apply()` creates one\n * OpenLayers layer per Mapbox Style source, unless the layer stack has\n * layers from different sources in between.\n * * `mapbox-layers`: The `id`s of the Mapbox Style document's layers that are\n * included in the OpenLayers layer.\n *\n * @param {VectorTileLayer|VectorLayer} layer OpenLayers layer. When the layer has a source configured,\n * it will be modified to use the configuration from the glStyle's `source`. Options specified on the\n * layer's source will override those from the glStyle's `source`, except for `url`,\n * `tileUrlFunction` and `tileGrid` (exception: when the source projection is not `EPSG:3857`).\n * @param {string|Object} glStyle Mapbox Style object.\n * @param {string|Array} sourceOrLayers `source` key or an array of layer `id`s from the\n * Mapbox Style object. When a `source` key is provided, all layers for the\n * specified source will be included in the style function. When layer `id`s\n * are provided, they must be from layers that use the same source. When not provided or a falsey\n * value, all layers using the first source specified in the glStyle will be rendered.\n * @param {Options|string} optionsOrPath Options. Alternatively the path of the style file\n * (only required when a relative path is used for the `\"sprite\"` property of the style).\n * @param {Array} resolutions Resolutions for mapping resolution to zoom level.\n * Only needed when working with non-standard tile grids or projections.\n * @return {Promise} Promise which will be resolved when the style can be used\n * for rendering.\n */\nexport function applyStyle(\n layer,\n glStyle,\n sourceOrLayers = '',\n optionsOrPath = {},\n resolutions = undefined\n) {\n let styleUrl, sourceId;\n /** @type {Options} */\n let options;\n if (typeof optionsOrPath === 'string') {\n styleUrl = optionsOrPath;\n options = {};\n } else {\n styleUrl = optionsOrPath.styleUrl;\n options = optionsOrPath;\n }\n if (!resolutions) {\n resolutions = options.resolutions;\n }\n if (\n !styleUrl &&\n typeof glStyle === 'string' &&\n !glStyle.trim().startsWith('{')\n ) {\n styleUrl = glStyle;\n }\n if (styleUrl) {\n styleUrl = styleUrl.startsWith('data:')\n ? location.href\n : normalizeStyleUrl(styleUrl, options.accessToken);\n options = completeOptions(styleUrl, options);\n }\n\n return new Promise(function (resolve, reject) {\n // TODO: figure out where best place to check source type is\n // Note that the source arg is an array of gl layer ids and each must be\n // dereferenced to get source type to validate\n getGlStyle(glStyle, options)\n .then(function (glStyle) {\n if (glStyle.version != 8) {\n return reject(new Error('glStyle version 8 required.'));\n }\n if (\n !(layer instanceof VectorLayer || layer instanceof VectorTileLayer)\n ) {\n return reject(\n new Error('Can only apply to VectorLayer or VectorTileLayer')\n );\n }\n\n const type = layer instanceof VectorTileLayer ? 'vector' : 'geojson';\n if (!sourceOrLayers) {\n sourceId = Object.keys(glStyle.sources).find(function (key) {\n return glStyle.sources[key].type === type;\n });\n sourceOrLayers = sourceId;\n } else if (Array.isArray(sourceOrLayers)) {\n sourceId = glStyle.layers.find(function (layer) {\n return layer.id === sourceOrLayers[0];\n }).source;\n } else {\n sourceId = sourceOrLayers;\n }\n if (!sourceId) {\n return reject(new Error(`No ${type} source found in the glStyle.`));\n }\n\n function assignSource() {\n if (layer instanceof VectorTileLayer) {\n return setupVectorSource(\n glStyle.sources[sourceId],\n styleUrl,\n options\n ).then(function (source) {\n const targetSource = layer.getSource();\n if (!targetSource) {\n layer.setSource(source);\n } else if (source !== targetSource) {\n targetSource.setTileUrlFunction(source.getTileUrlFunction());\n //@ts-ignore\n if (!targetSource.format_) {\n //@ts-ignore\n targetSource.format_ = source.format_;\n }\n if (!targetSource.getAttributions()) {\n targetSource.setAttributions(source.getAttributions());\n }\n if (\n targetSource.getTileLoadFunction() === defaultLoadFunction\n ) {\n targetSource.setTileLoadFunction(\n source.getTileLoadFunction()\n );\n }\n if (\n equivalent(\n targetSource.getProjection(),\n source.getProjection()\n )\n ) {\n targetSource.tileGrid = source.getTileGrid();\n }\n }\n if (\n !isFinite(layer.getMaxResolution()) &&\n !isFinite(layer.getMinZoom())\n ) {\n const tileGrid = layer.getSource().getTileGrid();\n layer.setMaxResolution(\n tileGrid.getResolution(tileGrid.getMinZoom())\n );\n }\n });\n } else {\n const glSource = glStyle.sources[sourceId];\n let source = layer.getSource();\n if (!source || source.get('mapbox-source') !== glSource) {\n source = setupGeoJSONSource(glSource, styleUrl, options);\n }\n const targetSource = /** @type {VectorSource} */ (\n layer.getSource()\n );\n if (!targetSource) {\n layer.setSource(source);\n } else if (source !== targetSource) {\n if (!targetSource.getAttributions()) {\n targetSource.setAttributions(source.getAttributions());\n }\n //@ts-ignore\n if (!targetSource.format_) {\n //@ts-ignore\n targetSource.format_ = source.getFormat();\n }\n //@ts-ignore\n targetSource.url_ = source.getUrl();\n }\n return Promise.resolve();\n }\n }\n\n let spriteScale, spriteData, spriteImageUrl, style;\n function onChange() {\n if (!style && (!glStyle.sprite || spriteData)) {\n style = applyStyleFunction(\n layer,\n glStyle,\n sourceOrLayers,\n resolutions,\n spriteData,\n spriteImageUrl,\n getFonts\n );\n if (!layer.getStyle()) {\n reject(new Error(`Nothing to show for source [${sourceId}]`));\n } else {\n assignSource().then(resolve).catch(reject);\n }\n } else if (style) {\n layer.setStyle(style);\n assignSource().then(resolve).catch(reject);\n } else {\n reject(new Error('Something went wrong trying to apply style.'));\n }\n }\n\n if (glStyle.sprite) {\n const sprite = new URL(\n normalizeSpriteUrl(\n glStyle.sprite,\n options.accessToken,\n styleUrl || location.href\n )\n );\n spriteScale = window.devicePixelRatio >= 1.5 ? 0.5 : 1;\n const sizeFactor = spriteScale == 0.5 ? '@2x' : '';\n let spriteUrl =\n sprite.origin +\n sprite.pathname +\n sizeFactor +\n '.json' +\n sprite.search;\n\n new Promise(function (resolve, reject) {\n fetchResource('Sprite', spriteUrl, options)\n .then(resolve)\n .catch(function (error) {\n spriteUrl =\n sprite.origin + sprite.pathname + '.json' + sprite.search;\n fetchResource('Sprite', spriteUrl, options)\n .then(resolve)\n .catch(reject);\n });\n })\n .then(function (spritesJson) {\n if (spritesJson === undefined) {\n reject(new Error('No sprites found.'));\n }\n spriteData = spritesJson;\n spriteImageUrl =\n sprite.origin +\n sprite.pathname +\n sizeFactor +\n '.png' +\n sprite.search;\n onChange();\n })\n .catch(function (err) {\n reject(\n new Error(\n `Sprites cannot be loaded: ${spriteUrl}: ${err.message}`\n )\n );\n });\n } else {\n onChange();\n }\n })\n .catch(reject);\n });\n}\n\nconst emptyObj = {};\n\nfunction setBackground(mapOrLayer, layer) {\n const background = {\n id: layer.id,\n type: layer.type,\n };\n const functionCache = {};\n function updateStyle(resolution) {\n const layout = layer.layout || {};\n const paint = layer.paint || {};\n background['paint'] = paint;\n const zoom =\n typeof mapOrLayer.getSource === 'function'\n ? mapOrLayer.getSource().getTileGrid().getZForResolution(resolution)\n : mapOrLayer.getView().getZoom();\n const element =\n typeof mapOrLayer.getTargetElement === 'function'\n ? mapOrLayer.getTargetElement()\n : undefined;\n let bg, opacity;\n if (paint['background-color'] !== undefined) {\n bg = getValue(\n background,\n 'paint',\n 'background-color',\n zoom,\n emptyObj,\n functionCache\n );\n if (element) {\n element.style.background = Color.parse(bg).toString();\n }\n }\n if (paint['background-opacity'] !== undefined) {\n opacity = getValue(\n background,\n 'paint',\n 'background-opacity',\n zoom,\n emptyObj,\n functionCache\n );\n if (element) {\n element.style.opacity = opacity;\n }\n }\n if (layout.visibility == 'none') {\n if (element) {\n element.style.backgroundColor = '';\n element.style.opacity = '';\n }\n return undefined;\n }\n return _colorWithOpacity(bg, opacity);\n }\n if (typeof mapOrLayer.getTargetElement === 'function') {\n if (mapOrLayer.getTargetElement()) {\n updateStyle();\n }\n mapOrLayer.on(['change:resolution', 'change:target'], updateStyle);\n } else if (typeof mapOrLayer.setBackground === 'function') {\n mapOrLayer.setBackground(updateStyle);\n } else {\n throw new Error('Unable to apply background.');\n }\n}\n\nfunction setFirstBackground(mapOrLayer, glStyle) {\n glStyle.layers.some(function (layer) {\n if (layer.type === 'background') {\n setBackground(mapOrLayer, layer);\n return true;\n }\n });\n}\n\n/**\n * Applies properties of the Mapbox Style's first `background` layer to the\n * provided map or VectorTile layer.\n *\n * **Example:**\n * ```js\n * import {applyBackground} from 'ol-mapbox-style';\n * import {Map} from 'ol';\n *\n * const map = new Map({target: 'map'});\n * applyBackground(map, 'https://api.maptiler.com/maps/basic/style.json?key=YOUR_OPENMAPTILES_TOKEN');\n * ```\n * @param {Map|VectorTileLayer} mapOrLayer OpenLayers Map or VectorTile layer.\n * @param {Object|string} glStyle Mapbox Style object or url.\n * @param {Options} options Options.\n * @return {Promise} Promise that resolves when the background is applied.\n */\nexport function applyBackground(mapOrLayer, glStyle, options = {}) {\n if (typeof glStyle === 'object') {\n setFirstBackground(mapOrLayer, glStyle);\n return Promise.resolve();\n }\n return getGlStyle(glStyle, options).then(function (glStyle) {\n setFirstBackground(mapOrLayer, glStyle);\n });\n}\n\nfunction getSourceIdByRef(layers, ref) {\n let sourceId;\n layers.some(function (layer) {\n if (layer.id == ref) {\n sourceId = layer.source;\n return true;\n }\n });\n return sourceId;\n}\n\nfunction extentFromTileJSON(tileJSON) {\n const bounds = tileJSON.bounds;\n if (bounds) {\n const ll = fromLonLat([bounds[0], bounds[1]]);\n const tr = fromLonLat([bounds[2], bounds[3]]);\n return [ll[0], ll[1], tr[0], tr[1]];\n }\n}\n\n/**\n * Creates an OpenLayers VectorTile source for a gl source entry.\n * @param {Object} glSource \"source\" entry from a Mapbox Style object.\n * @param {string|undefined} styleUrl URL to use for the source. This is expected to be the complete http(s) url,\n * with access key applied.\n * @param {Options} options Options.\n * @return {Promise} Promise resolving to a VectorTile source.\n * @private\n */\nexport function setupVectorSource(glSource, styleUrl, options) {\n return new Promise(function (resolve, reject) {\n getTileJson(glSource, styleUrl, options)\n .then(function (tileJSON) {\n const tileJSONSource = new TileJSON({tileJSON: tileJSON});\n const tileJSONDoc = tileJSONSource.getTileJSON();\n const tileGrid = tileJSONSource.getTileGrid();\n const extent = extentFromTileJSON(tileJSONDoc);\n const minZoom = tileJSONDoc.minzoom || 0;\n const maxZoom = tileJSONDoc.maxzoom || 22;\n const sourceOptions = {\n attributions: tileJSONSource.getAttributions(),\n format: new MVT(),\n tileGrid: new TileGrid({\n origin: tileGrid.getOrigin(0),\n extent: extent || tileGrid.getExtent(),\n minZoom: minZoom,\n resolutions: defaultResolutions.slice(0, maxZoom + 1),\n tileSize: 512,\n }),\n };\n if (Array.isArray(tileJSONDoc.tiles)) {\n sourceOptions.urls = tileJSONDoc.tiles;\n } else {\n sourceOptions.url = tileJSONDoc.tiles;\n }\n if (tileJSON.olSourceOptions) {\n Object.assign(sourceOptions, tileJSON.olSourceOptions);\n }\n resolve(new VectorTileSource(sourceOptions));\n })\n .catch(reject);\n });\n}\n\nfunction setupVectorLayer(glSource, styleUrl, options) {\n const layer = new VectorTileLayer({\n declutter: true,\n visible: false,\n });\n setupVectorSource(glSource, styleUrl, options)\n .then(function (source) {\n source.set('mapbox-source', glSource);\n layer.setSource(source);\n })\n .catch(function (error) {\n layer.setSource(undefined);\n });\n return layer;\n}\n\nfunction setupRasterLayer(glSource, styleUrl, options) {\n const layer = new TileLayer();\n getTileJson(glSource, styleUrl, options)\n .then(function (tileJson) {\n const source = new TileJSON({\n transition: 0,\n crossOrigin: 'anonymous',\n tileJSON: tileJson,\n });\n const extent = extentFromTileJSON(tileJson);\n const tileGrid = source.getTileGrid();\n const tileSize = glSource.tileSize || tileJson.tileSize || 512;\n const minZoom = tileJson.minzoom || 0;\n const maxZoom = tileJson.maxzoom || 22;\n //@ts-ignore\n source.tileGrid = new TileGrid({\n origin: tileGrid.getOrigin(0),\n extent: extent || tileGrid.getExtent(),\n minZoom: minZoom,\n resolutions: createXYZ({\n maxZoom: maxZoom,\n tileSize: tileSize,\n }).getResolutions(),\n tileSize: tileSize,\n });\n const getTileUrl = source.getTileUrlFunction();\n source.setTileUrlFunction(function (tileCoord, pixelRatio, projection) {\n let src = getTileUrl(tileCoord, pixelRatio, projection);\n if (src.indexOf('{bbox-epsg-3857}') != -1) {\n const bbox = source.getTileGrid().getTileCoordExtent(tileCoord);\n src = src.replace('{bbox-epsg-3857}', bbox.toString());\n }\n return src;\n });\n source.set('mapbox-source', glSource);\n layer.setSource(source);\n })\n .catch(function (error) {\n layer.setSource(undefined);\n });\n return layer;\n}\n\nconst geoJsonFormat = new GeoJSON();\n/**\n * @param {Object} glSource glStyle source.\n * @param {string} styleUrl Style URL.\n * @param {Options} options Options.\n * @return {VectorSource} Configured vector source.\n */\nfunction setupGeoJSONSource(glSource, styleUrl, options) {\n const data = glSource.data;\n const sourceOptions = {};\n if (typeof data == 'string') {\n let geoJsonUrl = normalizeSourceUrl(\n data,\n options.accessToken,\n options.accessTokenParam || 'access_token',\n styleUrl || location.href\n );\n if (options.transformRequest) {\n const transformed = options.transformRequest(geoJsonUrl, 'GeoJSON');\n if (transformed instanceof Request) {\n geoJsonUrl = encodeURI(transformed.url);\n }\n }\n sourceOptions.url = geoJsonUrl;\n } else {\n sourceOptions.features = geoJsonFormat.readFeatures(data, {\n featureProjection: getUserProjection() || 'EPSG:3857',\n });\n }\n const source = new VectorSource(\n assign(\n {\n attributions: glSource.attribution,\n format: geoJsonFormat,\n },\n sourceOptions\n )\n );\n source.set('mapbox-source', glSource);\n return source;\n}\n\nfunction setupGeoJSONLayer(glSource, styleUrl, options) {\n return new VectorLayer({\n declutter: true,\n source: setupGeoJSONSource(glSource, styleUrl, options),\n visible: false,\n });\n}\n\nfunction updateRasterLayerProperties(glLayer, layer, view, functionCache) {\n const zoom = view.getZoom();\n const opacity = getValue(\n glLayer,\n 'paint',\n 'raster-opacity',\n zoom,\n emptyObj,\n functionCache\n );\n layer.setOpacity(opacity);\n}\n\nfunction processStyle(glStyle, map, styleUrl, options) {\n const promises = [];\n let view = map.getView();\n if (!view.isDef() && !view.getRotation() && !view.getResolutions()) {\n view = new View(\n assign(view.getProperties(), {\n maxResolution: defaultResolutions[0],\n })\n );\n map.setView(view);\n }\n\n if ('center' in glStyle && !view.getCenter()) {\n view.setCenter(fromLonLat(glStyle.center));\n }\n if ('zoom' in glStyle && view.getZoom() === undefined) {\n view.setResolution(defaultResolutions[0] / Math.pow(2, glStyle.zoom));\n }\n if (!view.getCenter() || view.getZoom() === undefined) {\n view.fit(view.getProjection().getExtent(), {\n nearest: true,\n size: map.getSize(),\n });\n }\n\n const glLayers = glStyle.layers;\n let layerIds = [];\n\n let glLayer, glSource, glSourceId, id, layer;\n for (let i = 0, ii = glLayers.length; i < ii; ++i) {\n glLayer = glLayers[i];\n const type = glLayer.type;\n if (type == 'heatmap' || type == 'hillshade') {\n //FIXME Unsupported layer type\n throw new Error(`${type} layers are not supported`);\n } else if (type == 'background') {\n setBackground(map, glLayer);\n } else {\n id = glLayer.source || getSourceIdByRef(glLayers, glLayer.ref);\n // this technique assumes gl layers will be in a particular order\n if (id != glSourceId) {\n if (layerIds.length) {\n promises.push(\n finalizeLayer(layer, layerIds, glStyle, styleUrl, map, options)\n );\n layerIds = [];\n }\n glSource = glStyle.sources[id];\n if (glSource.type == 'vector') {\n layer = setupVectorLayer(glSource, styleUrl, options);\n } else if (glSource.type == 'raster') {\n layer = setupRasterLayer(glSource, styleUrl, options);\n layer.setVisible(\n glLayer.layout ? glLayer.layout.visibility !== 'none' : true\n );\n const functionCache = {};\n view.on(\n 'change:resolution',\n updateRasterLayerProperties.bind(\n this,\n glLayer,\n layer,\n view,\n functionCache\n )\n );\n updateRasterLayerProperties(glLayer, layer, view, functionCache);\n } else if (glSource.type == 'geojson') {\n layer = setupGeoJSONLayer(glSource, styleUrl, options);\n }\n glSourceId = id;\n if (layer) {\n layer.set('mapbox-source', glSourceId);\n }\n }\n layerIds.push(glLayer.id);\n }\n }\n promises.push(\n finalizeLayer(layer, layerIds, glStyle, styleUrl, map, options)\n );\n map.set('mapbox-style', glStyle);\n return Promise.all(promises);\n}\n\n/**\n * Loads and applies a Mapbox Style object into an OpenLayers Map. This includes\n * the map background, the layers, the center and the zoom.\n *\n * **Example:**\n * ```js\n * import apply from 'ol-mapbox-style';\n *\n * apply('map', 'mapbox://styles/mapbox/bright-v9', {accessToken: 'YOUR_MAPBOX_TOKEN'});\n * ```\n *\n * The center and zoom will only be set if present in the Mapbox Style document,\n * and if not already set on the OpenLayers map.\n *\n * Layers will be added to the OpenLayers map, without affecting any layers that\n * might already be set on the map.\n *\n * Layers added by `apply()` will have two additional properties:\n *\n * * `mapbox-source`: The `id` of the Mapbox Style document's source that the\n * OpenLayers layer was created from. Usually `apply()` creates one\n * OpenLayers layer per Mapbox Style source, unless the layer stack has\n * layers from different sources in between.\n * * `mapbox-layers`: The `id`s of the Mapbox Style document's layers that are\n * included in the OpenLayers layer.\n *\n * This function sets an additional `mapbox-style` property on the OpenLayers\n * map instance, which holds the Mapbox Style object.\n *\n * @param {Map|HTMLElement|string} map Either an existing OpenLayers Map\n * instance, or a HTML element, or the id of a HTML element that will be the\n * target of a new OpenLayers Map.\n * @param {string|Object} style JSON style object or style url pointing to a\n * Mapbox Style object. When using Mapbox APIs, the url is the `styleUrl`\n * shown in Mapbox Studio's \"share\" panel. In addition, the `accessToken` option\n * (see below) must be set.\n * When passed as JSON style object, all OpenLayers layers created by `apply()`\n * will be immediately available, but they may not have a source yet (i.e. when\n * they are defined by a TileJSON url in the Mapbox Style document). When passed\n * as style url, layers will be added to the map when the Mapbox Style document\n * is loaded and parsed.\n * @param {Options} options Options.\n * @return {Promise} A promise that resolves after all layers have been added to\n * the OpenLayers Map instance, their sources set, and their styles applied. The\n * `resolve` callback will be called with the OpenLayers Map instance as\n * argument.\n */\nexport function apply(map, style, options = {}) {\n let promise;\n\n if (typeof map === 'string' || map instanceof HTMLElement) {\n map = new Map({\n target: map,\n });\n }\n\n if (typeof style === 'string') {\n const styleUrl = style.startsWith('data:')\n ? location.href\n : normalizeStyleUrl(style, options.accessToken);\n options = completeOptions(styleUrl, options);\n\n promise = new Promise(function (resolve, reject) {\n getGlStyle(style, options)\n .then(function (glStyle) {\n processStyle(glStyle, map, styleUrl, options)\n .then(function () {\n resolve(map);\n })\n .catch(reject);\n })\n .catch(function (err) {\n reject(new Error(`Could not load ${style}: ${err.message}`));\n });\n });\n } else {\n promise = new Promise(function (resolve, reject) {\n processStyle(\n style,\n map,\n !options.styleUrl || options.styleUrl.startsWith('data:')\n ? location.href\n : normalizeStyleUrl(options.styleUrl, options.accessToken),\n options\n )\n .then(function () {\n resolve(map);\n })\n .catch(reject);\n });\n }\n\n return promise;\n}\n\n/**\n * If layerIds is not empty, applies the style specified in glStyle to the layer,\n * and adds the layer to the map.\n *\n * The layer may not yet have a source when the function is called. If so, the style\n * is applied to the layer via a once listener on the 'change:source' event.\n *\n * @param {Layer} layer An OpenLayers layer instance.\n * @param {Array} layerIds Array containing layer ids of already-processed layers.\n * @param {Object} glStyle Style as a JSON object.\n * @param {string|undefined} styleUrl The original style URL. Only required\n * when a relative path is used with the `\"sprite\"` property of the style.\n * @param {Map} map OpenLayers Map.\n * @param {Options} options Options.\n * @return {Promise} Returns a promise that resolves after the source has\n * been set on the specified layer, and the style has been applied.\n * @private\n */\nfunction finalizeLayer(layer, layerIds, glStyle, styleUrl, map, options = {}) {\n let minZoom = 24;\n let maxZoom = 0;\n const glLayers = glStyle.layers;\n for (let i = 0, ii = glLayers.length; i < ii; ++i) {\n const glLayer = glLayers[i];\n if (layerIds.indexOf(glLayer.id) !== -1) {\n minZoom = Math.min('minzoom' in glLayer ? glLayer.minzoom : 0, minZoom);\n maxZoom = Math.max('maxzoom' in glLayer ? glLayer.maxzoom : 24, maxZoom);\n }\n }\n return new Promise(function (resolve, reject) {\n const setStyle = function () {\n const source = layer.getSource();\n if (!source || source.getState() === 'error') {\n reject(\n new Error(\n 'Error accessing data for source ' + layer.get('mapbox-source')\n )\n );\n return;\n }\n if ('getTileGrid' in source) {\n const tileGrid =\n /** @type {import(\"ol/source/Tile.js\").default|import(\"ol/source/VectorTile.js\").default} */ (\n source\n ).getTileGrid();\n if (tileGrid) {\n const sourceMinZoom = tileGrid.getMinZoom();\n if (minZoom > 0 || sourceMinZoom > 0) {\n layer.setMaxResolution(\n Math.min(\n defaultResolutions[minZoom],\n tileGrid.getResolution(sourceMinZoom)\n ) + 1e-9\n );\n }\n if (maxZoom < 24) {\n layer.setMinResolution(defaultResolutions[maxZoom] + 1e-9);\n }\n }\n }\n if (\n source instanceof VectorSource ||\n source instanceof VectorTileSource\n ) {\n applyStyle(\n /** @type {import(\"ol/layer/Vector\").default|import(\"ol/layer/VectorTile\").default} */ (\n layer\n ),\n glStyle,\n layerIds,\n assign({styleUrl: styleUrl}, options)\n )\n .then(function () {\n layer.setVisible(true);\n resolve();\n })\n .catch(reject);\n } else {\n resolve();\n }\n };\n\n layer.set('mapbox-layers', layerIds);\n if (map.getLayers().getArray().indexOf(layer) === -1) {\n map.addLayer(layer);\n }\n\n if (layer.getSource()) {\n setStyle();\n } else {\n layer.once('change:source', setStyle);\n }\n });\n}\n\n/**\n * Get the OpenLayers layer instance that contains the provided Mapbox Style\n * `layer`. Note that multiple Mapbox Style layers are combined in a single\n * OpenLayers layer instance when they use the same Mapbox Style `source`.\n * @param {Map} map OpenLayers Map.\n * @param {string} layerId Mapbox Style layer id.\n * @return {Layer} OpenLayers layer instance.\n */\nexport function getLayer(map, layerId) {\n const layers = map.getLayers().getArray();\n for (let i = 0, ii = layers.length; i < ii; ++i) {\n const mapboxLayers = layers[i].get('mapbox-layers');\n if (mapboxLayers && mapboxLayers.indexOf(layerId) !== -1) {\n return /** @type {Layer} */ (layers[i]);\n }\n }\n}\n\n/**\n * Get the OpenLayers layer instances for the provided Mapbox Style `source`.\n * @param {Map} map OpenLayers Map.\n * @param {string} sourceId Mapbox Style source id.\n * @return {Array} OpenLayers layer instances.\n */\nexport function getLayers(map, sourceId) {\n const result = [];\n const layers = map.getAllLayers();\n for (let i = 0, ii = layers.length; i < ii; ++i) {\n if (layers[i].get('mapbox-source') === sourceId) {\n result.push(/** @type {Layer} */ (layers[i]));\n }\n }\n return result;\n}\n\n/**\n * Get the OpenLayers source instance for the provided Mapbox Style `source`.\n * @param {Map} map OpenLayers Map.\n * @param {string} sourceId Mapbox Style source id.\n * @return {Source} OpenLayers source instance.\n */\nexport function getSource(map, sourceId) {\n const layers = map.getLayers().getArray();\n for (let i = 0, ii = layers.length; i < ii; ++i) {\n const source = /** @type {Layer} */ (layers[i]).getSource();\n if (layers[i].get('mapbox-source') === sourceId) {\n return source;\n }\n }\n}\n\n/**\n * Sets or removes a feature state. The feature state is taken into account for styling,\n * just like the feature's properties, and can be used e.g. to conditionally render selected\n * features differently.\n *\n * The feature state will be stored on the OpenLayers layer matching the feature identifier, in the\n * `mapbox-featurestate` property.\n * @param {Map|VectorLayer|VectorTileLayer} mapOrLayer OpenLayers Map or layer to set the feature\n * state on.\n * @param {FeatureIdentifier} feature Feature identifier.\n * @param {Object|null} state Feature state. Set to `null` to remove the feature state.\n */\nexport function setFeatureState(mapOrLayer, feature, state) {\n const layers =\n 'getLayers' in mapOrLayer\n ? getLayers(mapOrLayer, feature.source)\n : [mapOrLayer];\n for (let i = 0, ii = layers.length; i < ii; ++i) {\n const featureState = layers[i].get('mapbox-featurestate');\n if (featureState) {\n if (state) {\n featureState[feature.id] = state;\n } else {\n delete featureState[feature.id];\n }\n layers[i].changed();\n } else {\n throw new Error(`Map or layer for source \"${feature.source}\" not found.`);\n }\n }\n}\n\n/**\n * Sets or removes a feature state. The feature state is taken into account for styling,\n * just like the feature's properties, and can be used e.g. to conditionally render selected\n * features differently.\n * @param {Map|VectorLayer|VectorTileLayer} mapOrLayer Map or layer to set the feature state on.\n * @param {FeatureIdentifier} feature Feature identifier.\n * @return {Object|null} Feature state or `null` when no feature state is set for the given\n * feature identifier.\n */\nexport function getFeatureState(mapOrLayer, feature) {\n const layers =\n 'getLayers' in mapOrLayer\n ? getLayers(mapOrLayer, feature.source)\n : [mapOrLayer];\n for (let i = 0, ii = layers.length; i < ii; ++i) {\n const featureState = layers[i].get('mapbox-featurestate');\n if (featureState && featureState[feature.id]) {\n return featureState[feature.id];\n }\n }\n return null;\n}\n\nexport {finalizeLayer as _finalizeLayer};\n",null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"import $ol$AssertionError from './ol/AssertionError.js';\nimport {CollectionEvent as _ol_Collection$CollectionEvent} from './ol/Collection.js';\nimport $ol$Collection from './ol/Collection.js';\nimport $ol$DataTile from './ol/DataTile.js';\nimport $ol$Disposable from './ol/Disposable.js';\nimport $ol$Feature from './ol/Feature.js';\nimport {createStyleFunction as _ol_Feature$createStyleFunction} from './ol/Feature.js';\nimport $ol$Geolocation from './ol/Geolocation.js';\nimport $ol$Image from './ol/Image.js';\nimport {listenImage as _ol_Image$listenImage} from './ol/Image.js';\nimport $ol$ImageBase from './ol/ImageBase.js';\nimport $ol$ImageCanvas from './ol/ImageCanvas.js';\nimport $ol$ImageTile from './ol/ImageTile.js';\nimport $ol$Kinetic from './ol/Kinetic.js';\nimport $ol$Map from './ol/Map.js';\nimport $ol$MapBrowserEvent from './ol/MapBrowserEvent.js';\nimport $ol$MapBrowserEventHandler from './ol/MapBrowserEventHandler.js';\nimport $ol$MapEvent from './ol/MapEvent.js';\nimport {ObjectEvent as _ol_Object$ObjectEvent} from './ol/Object.js';\nimport $ol$Object from './ol/Object.js';\nimport $ol$Observable from './ol/Observable.js';\nimport {unByKey as _ol_Observable$unByKey} from './ol/Observable.js';\nimport $ol$Overlay from './ol/Overlay.js';\nimport $ol$PluggableMap from './ol/PluggableMap.js';\nimport $ol$Tile from './ol/Tile.js';\nimport $ol$TileCache from './ol/TileCache.js';\nimport $ol$TileQueue from './ol/TileQueue.js';\nimport {getTilePriority as _ol_TileQueue$getTilePriority} from './ol/TileQueue.js';\nimport $ol$TileRange from './ol/TileRange.js';\nimport {createOrUpdate as _ol_TileRange$createOrUpdate} from './ol/TileRange.js';\nimport $ol$VectorRenderTile from './ol/VectorRenderTile.js';\nimport $ol$VectorTile from './ol/VectorTile.js';\nimport $ol$View from './ol/View.js';\nimport {createCenterConstraint as _ol_View$createCenterConstraint} from './ol/View.js';\nimport {createResolutionConstraint as _ol_View$createResolutionConstraint} from './ol/View.js';\nimport {createRotationConstraint as _ol_View$createRotationConstraint} from './ol/View.js';\nimport {isNoopAnimation as _ol_View$isNoopAnimation} from './ol/View.js';\nimport {binarySearch as _ol_array$binarySearch} from './ol/array.js';\nimport {numberSafeCompareFunction as _ol_array$numberSafeCompareFunction} from './ol/array.js';\nimport {includes as _ol_array$includes} from './ol/array.js';\nimport {linearFindNearest as _ol_array$linearFindNearest} from './ol/array.js';\nimport {reverseSubArray as _ol_array$reverseSubArray} from './ol/array.js';\nimport {extend as _ol_array$extend} from './ol/array.js';\nimport {remove as _ol_array$remove} from './ol/array.js';\nimport {find as _ol_array$find} from './ol/array.js';\nimport {equals as _ol_array$equals} from './ol/array.js';\nimport {stableSort as _ol_array$stableSort} from './ol/array.js';\nimport {findIndex as _ol_array$findIndex} from './ol/array.js';\nimport {isSorted as _ol_array$isSorted} from './ol/array.js';\nimport {assert as _ol_asserts$assert} from './ol/asserts.js';\nimport {createExtent as _ol_centerconstraint$createExtent} from './ol/centerconstraint.js';\nimport {none as _ol_centerconstraint$none} from './ol/centerconstraint.js';\nimport {asString as _ol_color$asString} from './ol/color.js';\nimport {fromString as _ol_color$fromString} from './ol/color.js';\nimport {asArray as _ol_color$asArray} from './ol/color.js';\nimport {normalize as _ol_color$normalize} from './ol/color.js';\nimport {toString as _ol_color$toString} from './ol/color.js';\nimport {isStringColor as _ol_color$isStringColor} from './ol/color.js';\nimport {asColorLike as _ol_colorlike$asColorLike} from './ol/colorlike.js';\nimport {defaults as _ol_control$defaults} from './ol/control.js';\nimport {add as _ol_coordinate$add} from './ol/coordinate.js';\nimport {closestOnCircle as _ol_coordinate$closestOnCircle} from './ol/coordinate.js';\nimport {closestOnSegment as _ol_coordinate$closestOnSegment} from './ol/coordinate.js';\nimport {createStringXY as _ol_coordinate$createStringXY} from './ol/coordinate.js';\nimport {degreesToStringHDMS as _ol_coordinate$degreesToStringHDMS} from './ol/coordinate.js';\nimport {format as _ol_coordinate$format} from './ol/coordinate.js';\nimport {equals as _ol_coordinate$equals} from './ol/coordinate.js';\nimport {rotate as _ol_coordinate$rotate} from './ol/coordinate.js';\nimport {scale as _ol_coordinate$scale} from './ol/coordinate.js';\nimport {squaredDistance as _ol_coordinate$squaredDistance} from './ol/coordinate.js';\nimport {distance as _ol_coordinate$distance} from './ol/coordinate.js';\nimport {squaredDistanceToSegment as _ol_coordinate$squaredDistanceToSegment} from './ol/coordinate.js';\nimport {toStringHDMS as _ol_coordinate$toStringHDMS} from './ol/coordinate.js';\nimport {toStringXY as _ol_coordinate$toStringXY} from './ol/coordinate.js';\nimport {wrapX as _ol_coordinate$wrapX} from './ol/coordinate.js';\nimport {getWorldsAway as _ol_coordinate$getWorldsAway} from './ol/coordinate.js';\nimport {CLASS_HIDDEN as _ol_css$CLASS_HIDDEN} from './ol/css.js';\nimport {CLASS_SELECTABLE as _ol_css$CLASS_SELECTABLE} from './ol/css.js';\nimport {CLASS_UNSELECTABLE as _ol_css$CLASS_UNSELECTABLE} from './ol/css.js';\nimport {CLASS_UNSUPPORTED as _ol_css$CLASS_UNSUPPORTED} from './ol/css.js';\nimport {CLASS_CONTROL as _ol_css$CLASS_CONTROL} from './ol/css.js';\nimport {CLASS_COLLAPSED as _ol_css$CLASS_COLLAPSED} from './ol/css.js';\nimport {getFontParameters as _ol_css$getFontParameters} from './ol/css.js';\nimport {createCanvasContext2D as _ol_dom$createCanvasContext2D} from './ol/dom.js';\nimport {releaseCanvas as _ol_dom$releaseCanvas} from './ol/dom.js';\nimport {outerWidth as _ol_dom$outerWidth} from './ol/dom.js';\nimport {outerHeight as _ol_dom$outerHeight} from './ol/dom.js';\nimport {replaceNode as _ol_dom$replaceNode} from './ol/dom.js';\nimport {removeNode as _ol_dom$removeNode} from './ol/dom.js';\nimport {removeChildren as _ol_dom$removeChildren} from './ol/dom.js';\nimport {replaceChildren as _ol_dom$replaceChildren} from './ol/dom.js';\nimport {easeIn as _ol_easing$easeIn} from './ol/easing.js';\nimport {easeOut as _ol_easing$easeOut} from './ol/easing.js';\nimport {inAndOut as _ol_easing$inAndOut} from './ol/easing.js';\nimport {linear as _ol_easing$linear} from './ol/easing.js';\nimport {upAndDown as _ol_easing$upAndDown} from './ol/easing.js';\nimport {listen as _ol_events$listen} from './ol/events.js';\nimport {listenOnce as _ol_events$listenOnce} from './ol/events.js';\nimport {unlistenByKey as _ol_events$unlistenByKey} from './ol/events.js';\nimport {boundingExtent as _ol_extent$boundingExtent} from './ol/extent.js';\nimport {buffer as _ol_extent$buffer} from './ol/extent.js';\nimport {clone as _ol_extent$clone} from './ol/extent.js';\nimport {closestSquaredDistanceXY as _ol_extent$closestSquaredDistanceXY} from './ol/extent.js';\nimport {containsCoordinate as _ol_extent$containsCoordinate} from './ol/extent.js';\nimport {containsExtent as _ol_extent$containsExtent} from './ol/extent.js';\nimport {containsXY as _ol_extent$containsXY} from './ol/extent.js';\nimport {coordinateRelationship as _ol_extent$coordinateRelationship} from './ol/extent.js';\nimport {createEmpty as _ol_extent$createEmpty} from './ol/extent.js';\nimport {createOrUpdate as _ol_extent$createOrUpdate} from './ol/extent.js';\nimport {createOrUpdateEmpty as _ol_extent$createOrUpdateEmpty} from './ol/extent.js';\nimport {createOrUpdateFromCoordinate as _ol_extent$createOrUpdateFromCoordinate} from './ol/extent.js';\nimport {createOrUpdateFromCoordinates as _ol_extent$createOrUpdateFromCoordinates} from './ol/extent.js';\nimport {createOrUpdateFromFlatCoordinates as _ol_extent$createOrUpdateFromFlatCoordinates} from './ol/extent.js';\nimport {createOrUpdateFromRings as _ol_extent$createOrUpdateFromRings} from './ol/extent.js';\nimport {equals as _ol_extent$equals} from './ol/extent.js';\nimport {approximatelyEquals as _ol_extent$approximatelyEquals} from './ol/extent.js';\nimport {extend as _ol_extent$extend} from './ol/extent.js';\nimport {extendCoordinate as _ol_extent$extendCoordinate} from './ol/extent.js';\nimport {extendCoordinates as _ol_extent$extendCoordinates} from './ol/extent.js';\nimport {extendFlatCoordinates as _ol_extent$extendFlatCoordinates} from './ol/extent.js';\nimport {extendRings as _ol_extent$extendRings} from './ol/extent.js';\nimport {extendXY as _ol_extent$extendXY} from './ol/extent.js';\nimport {forEachCorner as _ol_extent$forEachCorner} from './ol/extent.js';\nimport {getArea as _ol_extent$getArea} from './ol/extent.js';\nimport {getBottomLeft as _ol_extent$getBottomLeft} from './ol/extent.js';\nimport {getBottomRight as _ol_extent$getBottomRight} from './ol/extent.js';\nimport {getCenter as _ol_extent$getCenter} from './ol/extent.js';\nimport {getCorner as _ol_extent$getCorner} from './ol/extent.js';\nimport {getEnlargedArea as _ol_extent$getEnlargedArea} from './ol/extent.js';\nimport {getForViewAndSize as _ol_extent$getForViewAndSize} from './ol/extent.js';\nimport {getRotatedViewport as _ol_extent$getRotatedViewport} from './ol/extent.js';\nimport {getHeight as _ol_extent$getHeight} from './ol/extent.js';\nimport {getIntersectionArea as _ol_extent$getIntersectionArea} from './ol/extent.js';\nimport {getIntersection as _ol_extent$getIntersection} from './ol/extent.js';\nimport {getMargin as _ol_extent$getMargin} from './ol/extent.js';\nimport {getSize as _ol_extent$getSize} from './ol/extent.js';\nimport {getTopLeft as _ol_extent$getTopLeft} from './ol/extent.js';\nimport {getTopRight as _ol_extent$getTopRight} from './ol/extent.js';\nimport {getWidth as _ol_extent$getWidth} from './ol/extent.js';\nimport {intersects as _ol_extent$intersects} from './ol/extent.js';\nimport {isEmpty as _ol_extent$isEmpty} from './ol/extent.js';\nimport {returnOrUpdate as _ol_extent$returnOrUpdate} from './ol/extent.js';\nimport {scaleFromCenter as _ol_extent$scaleFromCenter} from './ol/extent.js';\nimport {intersectsSegment as _ol_extent$intersectsSegment} from './ol/extent.js';\nimport {applyTransform as _ol_extent$applyTransform} from './ol/extent.js';\nimport {wrapX as _ol_extent$wrapX} from './ol/extent.js';\nimport {wrapAndSliceX as _ol_extent$wrapAndSliceX} from './ol/extent.js';\nimport {loadFeaturesXhr as _ol_featureloader$loadFeaturesXhr} from './ol/featureloader.js';\nimport {xhr as _ol_featureloader$xhr} from './ol/featureloader.js';\nimport {setWithCredentials as _ol_featureloader$setWithCredentials} from './ol/featureloader.js';\nimport {TRUE as _ol_functions$TRUE} from './ol/functions.js';\nimport {FALSE as _ol_functions$FALSE} from './ol/functions.js';\nimport {VOID as _ol_functions$VOID} from './ol/functions.js';\nimport {memoizeOne as _ol_functions$memoizeOne} from './ol/functions.js';\nimport {toPromise as _ol_functions$toPromise} from './ol/functions.js';\nimport {FIREFOX as _ol_has$FIREFOX} from './ol/has.js';\nimport {SAFARI as _ol_has$SAFARI} from './ol/has.js';\nimport {SAFARI_BUG_237906 as _ol_has$SAFARI_BUG_237906} from './ol/has.js';\nimport {WEBKIT as _ol_has$WEBKIT} from './ol/has.js';\nimport {MAC as _ol_has$MAC} from './ol/has.js';\nimport {DEVICE_PIXEL_RATIO as _ol_has$DEVICE_PIXEL_RATIO} from './ol/has.js';\nimport {WORKER_OFFSCREEN_CANVAS as _ol_has$WORKER_OFFSCREEN_CANVAS} from './ol/has.js';\nimport {IMAGE_DECODE as _ol_has$IMAGE_DECODE} from './ol/has.js';\nimport {PASSIVE_EVENT_LISTENERS as _ol_has$PASSIVE_EVENT_LISTENERS} from './ol/has.js';\nimport {defaults as _ol_interaction$defaults} from './ol/interaction.js';\nimport {all as _ol_loadingstrategy$all} from './ol/loadingstrategy.js';\nimport {bbox as _ol_loadingstrategy$bbox} from './ol/loadingstrategy.js';\nimport {tile as _ol_loadingstrategy$tile} from './ol/loadingstrategy.js';\nimport {clamp as _ol_math$clamp} from './ol/math.js';\nimport {cosh as _ol_math$cosh} from './ol/math.js';\nimport {log2 as _ol_math$log2} from './ol/math.js';\nimport {squaredSegmentDistance as _ol_math$squaredSegmentDistance} from './ol/math.js';\nimport {squaredDistance as _ol_math$squaredDistance} from './ol/math.js';\nimport {solveLinearSystem as _ol_math$solveLinearSystem} from './ol/math.js';\nimport {toDegrees as _ol_math$toDegrees} from './ol/math.js';\nimport {toRadians as _ol_math$toRadians} from './ol/math.js';\nimport {modulo as _ol_math$modulo} from './ol/math.js';\nimport {lerp as _ol_math$lerp} from './ol/math.js';\nimport {toFixed as _ol_math$toFixed} from './ol/math.js';\nimport {round as _ol_math$round} from './ol/math.js';\nimport {floor as _ol_math$floor} from './ol/math.js';\nimport {ceil as _ol_math$ceil} from './ol/math.js';\nimport {jsonp as _ol_net$jsonp} from './ol/net.js';\nimport {ResponseError as _ol_net$ResponseError} from './ol/net.js';\nimport {ClientError as _ol_net$ClientError} from './ol/net.js';\nimport {getJSON as _ol_net$getJSON} from './ol/net.js';\nimport {resolveUrl as _ol_net$resolveUrl} from './ol/net.js';\nimport {overrideXHR as _ol_net$overrideXHR} from './ol/net.js';\nimport {restoreXHR as _ol_net$restoreXHR} from './ol/net.js';\nimport {assign as _ol_obj$assign} from './ol/obj.js';\nimport {clear as _ol_obj$clear} from './ol/obj.js';\nimport {getValues as _ol_obj$getValues} from './ol/obj.js';\nimport {isEmpty as _ol_obj$isEmpty} from './ol/obj.js';\nimport {disableCoordinateWarning as _ol_proj$disableCoordinateWarning} from './ol/proj.js';\nimport {cloneTransform as _ol_proj$cloneTransform} from './ol/proj.js';\nimport {identityTransform as _ol_proj$identityTransform} from './ol/proj.js';\nimport {addProjection as _ol_proj$addProjection} from './ol/proj.js';\nimport {addProjections as _ol_proj$addProjections} from './ol/proj.js';\nimport {get as _ol_proj$get} from './ol/proj.js';\nimport {getPointResolution as _ol_proj$getPointResolution} from './ol/proj.js';\nimport {addEquivalentProjections as _ol_proj$addEquivalentProjections} from './ol/proj.js';\nimport {addEquivalentTransforms as _ol_proj$addEquivalentTransforms} from './ol/proj.js';\nimport {clearAllProjections as _ol_proj$clearAllProjections} from './ol/proj.js';\nimport {createProjection as _ol_proj$createProjection} from './ol/proj.js';\nimport {createTransformFromCoordinateTransform as _ol_proj$createTransformFromCoordinateTransform} from './ol/proj.js';\nimport {addCoordinateTransforms as _ol_proj$addCoordinateTransforms} from './ol/proj.js';\nimport {fromLonLat as _ol_proj$fromLonLat} from './ol/proj.js';\nimport {toLonLat as _ol_proj$toLonLat} from './ol/proj.js';\nimport {equivalent as _ol_proj$equivalent} from './ol/proj.js';\nimport {getTransformFromProjections as _ol_proj$getTransformFromProjections} from './ol/proj.js';\nimport {getTransform as _ol_proj$getTransform} from './ol/proj.js';\nimport {transform as _ol_proj$transform} from './ol/proj.js';\nimport {transformExtent as _ol_proj$transformExtent} from './ol/proj.js';\nimport {transformWithProjections as _ol_proj$transformWithProjections} from './ol/proj.js';\nimport {setUserProjection as _ol_proj$setUserProjection} from './ol/proj.js';\nimport {clearUserProjection as _ol_proj$clearUserProjection} from './ol/proj.js';\nimport {getUserProjection as _ol_proj$getUserProjection} from './ol/proj.js';\nimport {useGeographic as _ol_proj$useGeographic} from './ol/proj.js';\nimport {toUserCoordinate as _ol_proj$toUserCoordinate} from './ol/proj.js';\nimport {fromUserCoordinate as _ol_proj$fromUserCoordinate} from './ol/proj.js';\nimport {toUserExtent as _ol_proj$toUserExtent} from './ol/proj.js';\nimport {fromUserExtent as _ol_proj$fromUserExtent} from './ol/proj.js';\nimport {toUserResolution as _ol_proj$toUserResolution} from './ol/proj.js';\nimport {fromUserResolution as _ol_proj$fromUserResolution} from './ol/proj.js';\nimport {createSafeCoordinateTransform as _ol_proj$createSafeCoordinateTransform} from './ol/proj.js';\nimport {addCommon as _ol_proj$addCommon} from './ol/proj.js';\nimport {toContext as _ol_render$toContext} from './ol/render.js';\nimport {getVectorContext as _ol_render$getVectorContext} from './ol/render.js';\nimport {getRenderPixel as _ol_render$getRenderPixel} from './ol/render.js';\nimport {canvasPool as _ol_reproj$canvasPool} from './ol/reproj.js';\nimport {calculateSourceResolution as _ol_reproj$calculateSourceResolution} from './ol/reproj.js';\nimport {calculateSourceExtentResolution as _ol_reproj$calculateSourceExtentResolution} from './ol/reproj.js';\nimport {render as _ol_reproj$render} from './ol/reproj.js';\nimport {createSnapToResolutions as _ol_resolutionconstraint$createSnapToResolutions} from './ol/resolutionconstraint.js';\nimport {createSnapToPower as _ol_resolutionconstraint$createSnapToPower} from './ol/resolutionconstraint.js';\nimport {createMinMaxResolution as _ol_resolutionconstraint$createMinMaxResolution} from './ol/resolutionconstraint.js';\nimport {disable as _ol_rotationconstraint$disable} from './ol/rotationconstraint.js';\nimport {none as _ol_rotationconstraint$none} from './ol/rotationconstraint.js';\nimport {createSnapToN as _ol_rotationconstraint$createSnapToN} from './ol/rotationconstraint.js';\nimport {createSnapToZero as _ol_rotationconstraint$createSnapToZero} from './ol/rotationconstraint.js';\nimport {buffer as _ol_size$buffer} from './ol/size.js';\nimport {hasArea as _ol_size$hasArea} from './ol/size.js';\nimport {scale as _ol_size$scale} from './ol/size.js';\nimport {toSize as _ol_size$toSize} from './ol/size.js';\nimport {sourcesFromTileGrid as _ol_source$sourcesFromTileGrid} from './ol/source.js';\nimport {DEFAULT_RADIUS as _ol_sphere$DEFAULT_RADIUS} from './ol/sphere.js';\nimport {getDistance as _ol_sphere$getDistance} from './ol/sphere.js';\nimport {getLength as _ol_sphere$getLength} from './ol/sphere.js';\nimport {getArea as _ol_sphere$getArea} from './ol/sphere.js';\nimport {offset as _ol_sphere$offset} from './ol/sphere.js';\nimport {padNumber as _ol_string$padNumber} from './ol/string.js';\nimport {compareVersions as _ol_string$compareVersions} from './ol/string.js';\nimport {createOrUpdate as _ol_tilecoord$createOrUpdate} from './ol/tilecoord.js';\nimport {getKeyZXY as _ol_tilecoord$getKeyZXY} from './ol/tilecoord.js';\nimport {getKey as _ol_tilecoord$getKey} from './ol/tilecoord.js';\nimport {getCacheKeyForTileKey as _ol_tilecoord$getCacheKeyForTileKey} from './ol/tilecoord.js';\nimport {fromKey as _ol_tilecoord$fromKey} from './ol/tilecoord.js';\nimport {hash as _ol_tilecoord$hash} from './ol/tilecoord.js';\nimport {withinExtentAndZ as _ol_tilecoord$withinExtentAndZ} from './ol/tilecoord.js';\nimport {getForProjection as _ol_tilegrid$getForProjection} from './ol/tilegrid.js';\nimport {wrapX as _ol_tilegrid$wrapX} from './ol/tilegrid.js';\nimport {createForExtent as _ol_tilegrid$createForExtent} from './ol/tilegrid.js';\nimport {createXYZ as _ol_tilegrid$createXYZ} from './ol/tilegrid.js';\nimport {createForProjection as _ol_tilegrid$createForProjection} from './ol/tilegrid.js';\nimport {extentFromProjection as _ol_tilegrid$extentFromProjection} from './ol/tilegrid.js';\nimport {createFromTemplate as _ol_tileurlfunction$createFromTemplate} from './ol/tileurlfunction.js';\nimport {createFromTemplates as _ol_tileurlfunction$createFromTemplates} from './ol/tileurlfunction.js';\nimport {createFromTileUrlFunctions as _ol_tileurlfunction$createFromTileUrlFunctions} from './ol/tileurlfunction.js';\nimport {nullTileUrlFunction as _ol_tileurlfunction$nullTileUrlFunction} from './ol/tileurlfunction.js';\nimport {expandUrl as _ol_tileurlfunction$expandUrl} from './ol/tileurlfunction.js';\nimport {create as _ol_transform$create} from './ol/transform.js';\nimport {reset as _ol_transform$reset} from './ol/transform.js';\nimport {multiply as _ol_transform$multiply} from './ol/transform.js';\nimport {set as _ol_transform$set} from './ol/transform.js';\nimport {setFromArray as _ol_transform$setFromArray} from './ol/transform.js';\nimport {apply as _ol_transform$apply} from './ol/transform.js';\nimport {rotate as _ol_transform$rotate} from './ol/transform.js';\nimport {scale as _ol_transform$scale} from './ol/transform.js';\nimport {makeScale as _ol_transform$makeScale} from './ol/transform.js';\nimport {translate as _ol_transform$translate} from './ol/transform.js';\nimport {compose as _ol_transform$compose} from './ol/transform.js';\nimport {composeCssTransform as _ol_transform$composeCssTransform} from './ol/transform.js';\nimport {invert as _ol_transform$invert} from './ol/transform.js';\nimport {makeInverse as _ol_transform$makeInverse} from './ol/transform.js';\nimport {determinant as _ol_transform$determinant} from './ol/transform.js';\nimport {toString as _ol_transform$toString} from './ol/transform.js';\nimport {appendParams as _ol_uri$appendParams} from './ol/uri.js';\nimport {abstract as _ol_util$abstract} from './ol/util.js';\nimport {getUid as _ol_util$getUid} from './ol/util.js';\nimport {VERSION as _ol_util$VERSION} from './ol/util.js';\nimport {ARRAY_BUFFER as _ol_webgl$ARRAY_BUFFER} from './ol/webgl.js';\nimport {ELEMENT_ARRAY_BUFFER as _ol_webgl$ELEMENT_ARRAY_BUFFER} from './ol/webgl.js';\nimport {STREAM_DRAW as _ol_webgl$STREAM_DRAW} from './ol/webgl.js';\nimport {STATIC_DRAW as _ol_webgl$STATIC_DRAW} from './ol/webgl.js';\nimport {DYNAMIC_DRAW as _ol_webgl$DYNAMIC_DRAW} from './ol/webgl.js';\nimport {UNSIGNED_BYTE as _ol_webgl$UNSIGNED_BYTE} from './ol/webgl.js';\nimport {UNSIGNED_SHORT as _ol_webgl$UNSIGNED_SHORT} from './ol/webgl.js';\nimport {UNSIGNED_INT as _ol_webgl$UNSIGNED_INT} from './ol/webgl.js';\nimport {FLOAT as _ol_webgl$FLOAT} from './ol/webgl.js';\nimport {getContext as _ol_webgl$getContext} from './ol/webgl.js';\nimport {getSupportedExtensions as _ol_webgl$getSupportedExtensions} from './ol/webgl.js';\nimport {XML_SCHEMA_INSTANCE_URI as _ol_xml$XML_SCHEMA_INSTANCE_URI} from './ol/xml.js';\nimport {createElementNS as _ol_xml$createElementNS} from './ol/xml.js';\nimport {getAllTextContent as _ol_xml$getAllTextContent} from './ol/xml.js';\nimport {getAllTextContent_ as _ol_xml$getAllTextContent_} from './ol/xml.js';\nimport {isDocument as _ol_xml$isDocument} from './ol/xml.js';\nimport {getAttributeNS as _ol_xml$getAttributeNS} from './ol/xml.js';\nimport {parse as _ol_xml$parse} from './ol/xml.js';\nimport {makeArrayExtender as _ol_xml$makeArrayExtender} from './ol/xml.js';\nimport {makeArrayPusher as _ol_xml$makeArrayPusher} from './ol/xml.js';\nimport {makeReplacer as _ol_xml$makeReplacer} from './ol/xml.js';\nimport {makeObjectPropertyPusher as _ol_xml$makeObjectPropertyPusher} from './ol/xml.js';\nimport {makeObjectPropertySetter as _ol_xml$makeObjectPropertySetter} from './ol/xml.js';\nimport {makeChildAppender as _ol_xml$makeChildAppender} from './ol/xml.js';\nimport {makeArraySerializer as _ol_xml$makeArraySerializer} from './ol/xml.js';\nimport {makeSimpleNodeFactory as _ol_xml$makeSimpleNodeFactory} from './ol/xml.js';\nimport {OBJECT_PROPERTY_NODE_FACTORY as _ol_xml$OBJECT_PROPERTY_NODE_FACTORY} from './ol/xml.js';\nimport {makeSequence as _ol_xml$makeSequence} from './ol/xml.js';\nimport {makeStructureNS as _ol_xml$makeStructureNS} from './ol/xml.js';\nimport {parseNode as _ol_xml$parseNode} from './ol/xml.js';\nimport {pushParseAndPop as _ol_xml$pushParseAndPop} from './ol/xml.js';\nimport {serialize as _ol_xml$serialize} from './ol/xml.js';\nimport {pushSerializeAndPop as _ol_xml$pushSerializeAndPop} from './ol/xml.js';\nimport {registerXMLSerializer as _ol_xml$registerXMLSerializer} from './ol/xml.js';\nimport {getXMLSerializer as _ol_xml$getXMLSerializer} from './ol/xml.js';\nimport {registerDocument as _ol_xml$registerDocument} from './ol/xml.js';\nimport {getDocument as _ol_xml$getDocument} from './ol/xml.js';\nimport $ol$webgl$Buffer from './ol/webgl/Buffer.js';\nimport {getArrayClassForType as _ol_webgl_Buffer$getArrayClassForType} from './ol/webgl/Buffer.js';\nimport $ol$webgl$Helper from './ol/webgl/Helper.js';\nimport {computeAttributesStride as _ol_webgl_Helper$computeAttributesStride} from './ol/webgl/Helper.js';\nimport $ol$webgl$PaletteTexture from './ol/webgl/PaletteTexture.js';\nimport $ol$webgl$PostProcessingPass from './ol/webgl/PostProcessingPass.js';\nimport $ol$webgl$RenderTarget from './ol/webgl/RenderTarget.js';\nimport {ShaderBuilder as _ol_webgl_ShaderBuilder$ShaderBuilder} from './ol/webgl/ShaderBuilder.js';\nimport {parseLiteralStyle as _ol_webgl_ShaderBuilder$parseLiteralStyle} from './ol/webgl/ShaderBuilder.js';\nimport $ol$webgl$TileTexture from './ol/webgl/TileTexture.js';\nimport {create as _ol_vec_mat4$create} from './ol/vec/mat4.js';\nimport {fromTransform as _ol_vec_mat4$fromTransform} from './ol/vec/mat4.js';\nimport $ol$tilegrid$TileGrid from './ol/tilegrid/TileGrid.js';\nimport $ol$tilegrid$WMTS from './ol/tilegrid/WMTS.js';\nimport {createFromCapabilitiesMatrixSet as _ol_tilegrid_WMTS$createFromCapabilitiesMatrixSet} from './ol/tilegrid/WMTS.js';\nimport {DEFAULT_MAX_ZOOM as _ol_tilegrid_common$DEFAULT_MAX_ZOOM} from './ol/tilegrid/common.js';\nimport {DEFAULT_TILE_SIZE as _ol_tilegrid_common$DEFAULT_TILE_SIZE} from './ol/tilegrid/common.js';\nimport $ol$style$Circle from './ol/style/Circle.js';\nimport $ol$style$Fill from './ol/style/Fill.js';\nimport $ol$style$Icon from './ol/style/Icon.js';\nimport $ol$style$IconImage from './ol/style/IconImage.js';\nimport {get as _ol_style_IconImage$get} from './ol/style/IconImage.js';\nimport $ol$style$IconImageCache from './ol/style/IconImageCache.js';\nimport {shared as _ol_style_IconImageCache$shared} from './ol/style/IconImageCache.js';\nimport $ol$style$Image from './ol/style/Image.js';\nimport $ol$style$RegularShape from './ol/style/RegularShape.js';\nimport $ol$style$Stroke from './ol/style/Stroke.js';\nimport $ol$style$Style from './ol/style/Style.js';\nimport {toFunction as _ol_style_Style$toFunction} from './ol/style/Style.js';\nimport {createDefaultStyle as _ol_style_Style$createDefaultStyle} from './ol/style/Style.js';\nimport {createEditingStyle as _ol_style_Style$createEditingStyle} from './ol/style/Style.js';\nimport $ol$style$Text from './ol/style/Text.js';\nimport {Operators as _ol_style_expressions$Operators} from './ol/style/expressions.js';\nimport {getValueType as _ol_style_expressions$getValueType} from './ol/style/expressions.js';\nimport {isTypeUnique as _ol_style_expressions$isTypeUnique} from './ol/style/expressions.js';\nimport {numberToGlsl as _ol_style_expressions$numberToGlsl} from './ol/style/expressions.js';\nimport {arrayToGlsl as _ol_style_expressions$arrayToGlsl} from './ol/style/expressions.js';\nimport {colorToGlsl as _ol_style_expressions$colorToGlsl} from './ol/style/expressions.js';\nimport {getStringNumberEquivalent as _ol_style_expressions$getStringNumberEquivalent} from './ol/style/expressions.js';\nimport {stringToGlsl as _ol_style_expressions$stringToGlsl} from './ol/style/expressions.js';\nimport {expressionToGlsl as _ol_style_expressions$expressionToGlsl} from './ol/style/expressions.js';\nimport {uniformNameForVariable as _ol_style_expressions$uniformNameForVariable} from './ol/style/expressions.js';\nimport {PALETTE_TEXTURE_ARRAY as _ol_style_expressions$PALETTE_TEXTURE_ARRAY} from './ol/style/expressions.js';\nimport $ol$structs$LRUCache from './ol/structs/LRUCache.js';\nimport $ol$structs$LinkedList from './ol/structs/LinkedList.js';\nimport {DROP as _ol_structs_PriorityQueue$DROP} from './ol/structs/PriorityQueue.js';\nimport $ol$structs$PriorityQueue from './ol/structs/PriorityQueue.js';\nimport $ol$structs$RBush from './ol/structs/RBush.js';\nimport {quadKey as _ol_source_BingMaps$quadKey} from './ol/source/BingMaps.js';\nimport $ol$source$BingMaps from './ol/source/BingMaps.js';\nimport $ol$source$CartoDB from './ol/source/CartoDB.js';\nimport $ol$source$Cluster from './ol/source/Cluster.js';\nimport $ol$source$DataTile from './ol/source/DataTile.js';\nimport $ol$source$GeoTIFF from './ol/source/GeoTIFF.js';\nimport $ol$source$IIIF from './ol/source/IIIF.js';\nimport {ImageSourceEvent as _ol_source_Image$ImageSourceEvent} from './ol/source/Image.js';\nimport $ol$source$Image from './ol/source/Image.js';\nimport {defaultImageLoadFunction as _ol_source_Image$defaultImageLoadFunction} from './ol/source/Image.js';\nimport $ol$source$ImageArcGISRest from './ol/source/ImageArcGISRest.js';\nimport $ol$source$ImageCanvas from './ol/source/ImageCanvas.js';\nimport $ol$source$ImageMapGuide from './ol/source/ImageMapGuide.js';\nimport $ol$source$ImageStatic from './ol/source/ImageStatic.js';\nimport $ol$source$ImageWMS from './ol/source/ImageWMS.js';\nimport $ol$source$OGCMapTile from './ol/source/OGCMapTile.js';\nimport $ol$source$OGCVectorTile from './ol/source/OGCVectorTile.js';\nimport {ATTRIBUTION as _ol_source_OSM$ATTRIBUTION} from './ol/source/OSM.js';\nimport $ol$source$OSM from './ol/source/OSM.js';\nimport {newImageData as _ol_source_Raster$newImageData} from './ol/source/Raster.js';\nimport {Processor as _ol_source_Raster$Processor} from './ol/source/Raster.js';\nimport {RasterSourceEvent as _ol_source_Raster$RasterSourceEvent} from './ol/source/Raster.js';\nimport $ol$source$Raster from './ol/source/Raster.js';\nimport $ol$source$Source from './ol/source/Source.js';\nimport $ol$source$Stamen from './ol/source/Stamen.js';\nimport $ol$source$Tile from './ol/source/Tile.js';\nimport {TileSourceEvent as _ol_source_Tile$TileSourceEvent} from './ol/source/Tile.js';\nimport $ol$source$TileArcGISRest from './ol/source/TileArcGISRest.js';\nimport $ol$source$TileDebug from './ol/source/TileDebug.js';\nimport $ol$source$TileImage from './ol/source/TileImage.js';\nimport $ol$source$TileJSON from './ol/source/TileJSON.js';\nimport $ol$source$TileWMS from './ol/source/TileWMS.js';\nimport {CustomTile as _ol_source_UTFGrid$CustomTile} from './ol/source/UTFGrid.js';\nimport $ol$source$UTFGrid from './ol/source/UTFGrid.js';\nimport $ol$source$UrlTile from './ol/source/UrlTile.js';\nimport {VectorSourceEvent as _ol_source_Vector$VectorSourceEvent} from './ol/source/Vector.js';\nimport $ol$source$Vector from './ol/source/Vector.js';\nimport $ol$source$VectorTile from './ol/source/VectorTile.js';\nimport {defaultLoadFunction as _ol_source_VectorTile$defaultLoadFunction} from './ol/source/VectorTile.js';\nimport $ol$source$WMTS from './ol/source/WMTS.js';\nimport {optionsFromCapabilities as _ol_source_WMTS$optionsFromCapabilities} from './ol/source/WMTS.js';\nimport $ol$source$XYZ from './ol/source/XYZ.js';\nimport {CustomTile as _ol_source_Zoomify$CustomTile} from './ol/source/Zoomify.js';\nimport $ol$source$Zoomify from './ol/source/Zoomify.js';\nimport {DEFAULT_WMS_VERSION as _ol_source_common$DEFAULT_WMS_VERSION} from './ol/source/common.js';\nimport {getMapTileUrlTemplate as _ol_source_ogcTileUtil$getMapTileUrlTemplate} from './ol/source/ogcTileUtil.js';\nimport {getVectorTileUrlTemplate as _ol_source_ogcTileUtil$getVectorTileUrlTemplate} from './ol/source/ogcTileUtil.js';\nimport {getTileSetInfo as _ol_source_ogcTileUtil$getTileSetInfo} from './ol/source/ogcTileUtil.js';\nimport {DEFAULT_VERSION as _ol_source_wms$DEFAULT_VERSION} from './ol/source/wms.js';\nimport $ol$reproj$Image from './ol/reproj/Image.js';\nimport $ol$reproj$Tile from './ol/reproj/Tile.js';\nimport $ol$reproj$Triangulation from './ol/reproj/Triangulation.js';\nimport {ERROR_THRESHOLD as _ol_reproj_common$ERROR_THRESHOLD} from './ol/reproj/common.js';\nimport {ENABLE_RASTER_REPROJECTION as _ol_reproj_common$ENABLE_RASTER_REPROJECTION} from './ol/reproj/common.js';\nimport $ol$renderer$Composite from './ol/renderer/Composite.js';\nimport $ol$renderer$Layer from './ol/renderer/Layer.js';\nimport $ol$renderer$Map from './ol/renderer/Map.js';\nimport {defaultOrder as _ol_renderer_vector$defaultOrder} from './ol/renderer/vector.js';\nimport {getSquaredTolerance as _ol_renderer_vector$getSquaredTolerance} from './ol/renderer/vector.js';\nimport {getTolerance as _ol_renderer_vector$getTolerance} from './ol/renderer/vector.js';\nimport {renderFeature as _ol_renderer_vector$renderFeature} from './ol/renderer/vector.js';\nimport $ol$renderer$webgl$Layer from './ol/renderer/webgl/Layer.js';\nimport {writePointFeatureToBuffers as _ol_renderer_webgl_Layer$writePointFeatureToBuffers} from './ol/renderer/webgl/Layer.js';\nimport {getBlankImageData as _ol_renderer_webgl_Layer$getBlankImageData} from './ol/renderer/webgl/Layer.js';\nimport {colorEncodeId as _ol_renderer_webgl_Layer$colorEncodeId} from './ol/renderer/webgl/Layer.js';\nimport {colorDecodeId as _ol_renderer_webgl_Layer$colorDecodeId} from './ol/renderer/webgl/Layer.js';\nimport $ol$renderer$webgl$PointsLayer from './ol/renderer/webgl/PointsLayer.js';\nimport {Uniforms as _ol_renderer_webgl_TileLayer$Uniforms} from './ol/renderer/webgl/TileLayer.js';\nimport {Attributes as _ol_renderer_webgl_TileLayer$Attributes} from './ol/renderer/webgl/TileLayer.js';\nimport $ol$renderer$webgl$TileLayer from './ol/renderer/webgl/TileLayer.js';\nimport $ol$renderer$canvas$ImageLayer from './ol/renderer/canvas/ImageLayer.js';\nimport {canvasPool as _ol_renderer_canvas_Layer$canvasPool} from './ol/renderer/canvas/Layer.js';\nimport $ol$renderer$canvas$Layer from './ol/renderer/canvas/Layer.js';\nimport $ol$renderer$canvas$TileLayer from './ol/renderer/canvas/TileLayer.js';\nimport $ol$renderer$canvas$VectorImageLayer from './ol/renderer/canvas/VectorImageLayer.js';\nimport $ol$renderer$canvas$VectorLayer from './ol/renderer/canvas/VectorLayer.js';\nimport $ol$renderer$canvas$VectorTileLayer from './ol/renderer/canvas/VectorTileLayer.js';\nimport {IMAGE_SMOOTHING_DISABLED as _ol_renderer_canvas_common$IMAGE_SMOOTHING_DISABLED} from './ol/renderer/canvas/common.js';\nimport {IMAGE_SMOOTHING_ENABLED as _ol_renderer_canvas_common$IMAGE_SMOOTHING_ENABLED} from './ol/renderer/canvas/common.js';\nimport $ol$render$Box from './ol/render/Box.js';\nimport $ol$render$Event from './ol/render/Event.js';\nimport $ol$render$Feature from './ol/render/Feature.js';\nimport {toGeometry as _ol_render_Feature$toGeometry} from './ol/render/Feature.js';\nimport {toFeature as _ol_render_Feature$toFeature} from './ol/render/Feature.js';\nimport $ol$render$VectorContext from './ol/render/VectorContext.js';\nimport {defaultFont as _ol_render_canvas$defaultFont} from './ol/render/canvas.js';\nimport {defaultFillStyle as _ol_render_canvas$defaultFillStyle} from './ol/render/canvas.js';\nimport {defaultLineCap as _ol_render_canvas$defaultLineCap} from './ol/render/canvas.js';\nimport {defaultLineDash as _ol_render_canvas$defaultLineDash} from './ol/render/canvas.js';\nimport {defaultLineDashOffset as _ol_render_canvas$defaultLineDashOffset} from './ol/render/canvas.js';\nimport {defaultLineJoin as _ol_render_canvas$defaultLineJoin} from './ol/render/canvas.js';\nimport {defaultMiterLimit as _ol_render_canvas$defaultMiterLimit} from './ol/render/canvas.js';\nimport {defaultStrokeStyle as _ol_render_canvas$defaultStrokeStyle} from './ol/render/canvas.js';\nimport {defaultTextAlign as _ol_render_canvas$defaultTextAlign} from './ol/render/canvas.js';\nimport {defaultTextBaseline as _ol_render_canvas$defaultTextBaseline} from './ol/render/canvas.js';\nimport {defaultPadding as _ol_render_canvas$defaultPadding} from './ol/render/canvas.js';\nimport {defaultLineWidth as _ol_render_canvas$defaultLineWidth} from './ol/render/canvas.js';\nimport {checkedFonts as _ol_render_canvas$checkedFonts} from './ol/render/canvas.js';\nimport {labelCache as _ol_render_canvas$labelCache} from './ol/render/canvas.js';\nimport {textHeights as _ol_render_canvas$textHeights} from './ol/render/canvas.js';\nimport {registerFont as _ol_render_canvas$registerFont} from './ol/render/canvas.js';\nimport {measureTextHeight as _ol_render_canvas$measureTextHeight} from './ol/render/canvas.js';\nimport {measureTextWidth as _ol_render_canvas$measureTextWidth} from './ol/render/canvas.js';\nimport {measureAndCacheTextWidth as _ol_render_canvas$measureAndCacheTextWidth} from './ol/render/canvas.js';\nimport {getTextDimensions as _ol_render_canvas$getTextDimensions} from './ol/render/canvas.js';\nimport {rotateAtOffset as _ol_render_canvas$rotateAtOffset} from './ol/render/canvas.js';\nimport {drawImageOrLabel as _ol_render_canvas$drawImageOrLabel} from './ol/render/canvas.js';\nimport $ol$render$canvas$Builder from './ol/render/canvas/Builder.js';\nimport $ol$render$canvas$BuilderGroup from './ol/render/canvas/BuilderGroup.js';\nimport $ol$render$canvas$Executor from './ol/render/canvas/Executor.js';\nimport $ol$render$canvas$ExecutorGroup from './ol/render/canvas/ExecutorGroup.js';\nimport {getPixelIndexArray as _ol_render_canvas_ExecutorGroup$getPixelIndexArray} from './ol/render/canvas/ExecutorGroup.js';\nimport $ol$render$canvas$ImageBuilder from './ol/render/canvas/ImageBuilder.js';\nimport $ol$render$canvas$Immediate from './ol/render/canvas/Immediate.js';\nimport {fillInstruction as _ol_render_canvas_Instruction$fillInstruction} from './ol/render/canvas/Instruction.js';\nimport {strokeInstruction as _ol_render_canvas_Instruction$strokeInstruction} from './ol/render/canvas/Instruction.js';\nimport {beginPathInstruction as _ol_render_canvas_Instruction$beginPathInstruction} from './ol/render/canvas/Instruction.js';\nimport {closePathInstruction as _ol_render_canvas_Instruction$closePathInstruction} from './ol/render/canvas/Instruction.js';\nimport $ol$render$canvas$LineStringBuilder from './ol/render/canvas/LineStringBuilder.js';\nimport $ol$render$canvas$PolygonBuilder from './ol/render/canvas/PolygonBuilder.js';\nimport $ol$render$canvas$TextBuilder from './ol/render/canvas/TextBuilder.js';\nimport {HIT_DETECT_RESOLUTION as _ol_render_canvas_hitdetect$HIT_DETECT_RESOLUTION} from './ol/render/canvas/hitdetect.js';\nimport {createHitDetectionImageData as _ol_render_canvas_hitdetect$createHitDetectionImageData} from './ol/render/canvas/hitdetect.js';\nimport {hitDetect as _ol_render_canvas_hitdetect$hitDetect} from './ol/render/canvas/hitdetect.js';\nimport $ol$proj$Projection from './ol/proj/Projection.js';\nimport {fromCode as _ol_proj_Units$fromCode} from './ol/proj/Units.js';\nimport {METERS_PER_UNIT as _ol_proj_Units$METERS_PER_UNIT} from './ol/proj/Units.js';\nimport {RADIUS as _ol_proj_epsg3857$RADIUS} from './ol/proj/epsg3857.js';\nimport {HALF_SIZE as _ol_proj_epsg3857$HALF_SIZE} from './ol/proj/epsg3857.js';\nimport {EXTENT as _ol_proj_epsg3857$EXTENT} from './ol/proj/epsg3857.js';\nimport {WORLD_EXTENT as _ol_proj_epsg3857$WORLD_EXTENT} from './ol/proj/epsg3857.js';\nimport {MAX_SAFE_Y as _ol_proj_epsg3857$MAX_SAFE_Y} from './ol/proj/epsg3857.js';\nimport {PROJECTIONS as _ol_proj_epsg3857$PROJECTIONS} from './ol/proj/epsg3857.js';\nimport {fromEPSG4326 as _ol_proj_epsg3857$fromEPSG4326} from './ol/proj/epsg3857.js';\nimport {toEPSG4326 as _ol_proj_epsg3857$toEPSG4326} from './ol/proj/epsg3857.js';\nimport {RADIUS as _ol_proj_epsg4326$RADIUS} from './ol/proj/epsg4326.js';\nimport {EXTENT as _ol_proj_epsg4326$EXTENT} from './ol/proj/epsg4326.js';\nimport {METERS_PER_UNIT as _ol_proj_epsg4326$METERS_PER_UNIT} from './ol/proj/epsg4326.js';\nimport {PROJECTIONS as _ol_proj_epsg4326$PROJECTIONS} from './ol/proj/epsg4326.js';\nimport {register as _ol_proj_proj4$register} from './ol/proj/proj4.js';\nimport {clear as _ol_proj_projections$clear} from './ol/proj/projections.js';\nimport {get as _ol_proj_projections$get} from './ol/proj/projections.js';\nimport {add as _ol_proj_projections$add} from './ol/proj/projections.js';\nimport {clear as _ol_proj_transforms$clear} from './ol/proj/transforms.js';\nimport {add as _ol_proj_transforms$add} from './ol/proj/transforms.js';\nimport {remove as _ol_proj_transforms$remove} from './ol/proj/transforms.js';\nimport {get as _ol_proj_transforms$get} from './ol/proj/transforms.js';\nimport $ol$layer$Base from './ol/layer/Base.js';\nimport $ol$layer$BaseImage from './ol/layer/BaseImage.js';\nimport $ol$layer$BaseTile from './ol/layer/BaseTile.js';\nimport $ol$layer$BaseVector from './ol/layer/BaseVector.js';\nimport $ol$layer$Graticule from './ol/layer/Graticule.js';\nimport {GroupEvent as _ol_layer_Group$GroupEvent} from './ol/layer/Group.js';\nimport $ol$layer$Group from './ol/layer/Group.js';\nimport $ol$layer$Heatmap from './ol/layer/Heatmap.js';\nimport $ol$layer$Image from './ol/layer/Image.js';\nimport $ol$layer$Layer from './ol/layer/Layer.js';\nimport {inView as _ol_layer_Layer$inView} from './ol/layer/Layer.js';\nimport $ol$layer$MapboxVector from './ol/layer/MapboxVector.js';\nimport $ol$layer$Tile from './ol/layer/Tile.js';\nimport $ol$layer$Vector from './ol/layer/Vector.js';\nimport $ol$layer$VectorImage from './ol/layer/VectorImage.js';\nimport $ol$layer$VectorTile from './ol/layer/VectorTile.js';\nimport $ol$layer$WebGLPoints from './ol/layer/WebGLPoints.js';\nimport $ol$layer$WebGLTile from './ol/layer/WebGLTile.js';\nimport $ol$interaction$DoubleClickZoom from './ol/interaction/DoubleClickZoom.js';\nimport {DragAndDropEvent as _ol_interaction_DragAndDrop$DragAndDropEvent} from './ol/interaction/DragAndDrop.js';\nimport $ol$interaction$DragAndDrop from './ol/interaction/DragAndDrop.js';\nimport {DragBoxEvent as _ol_interaction_DragBox$DragBoxEvent} from './ol/interaction/DragBox.js';\nimport $ol$interaction$DragBox from './ol/interaction/DragBox.js';\nimport $ol$interaction$DragPan from './ol/interaction/DragPan.js';\nimport $ol$interaction$DragRotate from './ol/interaction/DragRotate.js';\nimport $ol$interaction$DragRotateAndZoom from './ol/interaction/DragRotateAndZoom.js';\nimport $ol$interaction$DragZoom from './ol/interaction/DragZoom.js';\nimport {DrawEvent as _ol_interaction_Draw$DrawEvent} from './ol/interaction/Draw.js';\nimport $ol$interaction$Draw from './ol/interaction/Draw.js';\nimport {createRegularPolygon as _ol_interaction_Draw$createRegularPolygon} from './ol/interaction/Draw.js';\nimport {createBox as _ol_interaction_Draw$createBox} from './ol/interaction/Draw.js';\nimport {ExtentEvent as _ol_interaction_Extent$ExtentEvent} from './ol/interaction/Extent.js';\nimport $ol$interaction$Extent from './ol/interaction/Extent.js';\nimport $ol$interaction$Interaction from './ol/interaction/Interaction.js';\nimport {pan as _ol_interaction_Interaction$pan} from './ol/interaction/Interaction.js';\nimport {zoomByDelta as _ol_interaction_Interaction$zoomByDelta} from './ol/interaction/Interaction.js';\nimport $ol$interaction$KeyboardPan from './ol/interaction/KeyboardPan.js';\nimport $ol$interaction$KeyboardZoom from './ol/interaction/KeyboardZoom.js';\nimport $ol$interaction$Link from './ol/interaction/Link.js';\nimport {ModifyEvent as _ol_interaction_Modify$ModifyEvent} from './ol/interaction/Modify.js';\nimport $ol$interaction$Modify from './ol/interaction/Modify.js';\nimport $ol$interaction$MouseWheelZoom from './ol/interaction/MouseWheelZoom.js';\nimport $ol$interaction$PinchRotate from './ol/interaction/PinchRotate.js';\nimport $ol$interaction$PinchZoom from './ol/interaction/PinchZoom.js';\nimport $ol$interaction$Pointer from './ol/interaction/Pointer.js';\nimport {centroid as _ol_interaction_Pointer$centroid} from './ol/interaction/Pointer.js';\nimport {SelectEvent as _ol_interaction_Select$SelectEvent} from './ol/interaction/Select.js';\nimport $ol$interaction$Select from './ol/interaction/Select.js';\nimport $ol$interaction$Snap from './ol/interaction/Snap.js';\nimport {TranslateEvent as _ol_interaction_Translate$TranslateEvent} from './ol/interaction/Translate.js';\nimport $ol$interaction$Translate from './ol/interaction/Translate.js';\nimport $ol$geom$Circle from './ol/geom/Circle.js';\nimport $ol$geom$Geometry from './ol/geom/Geometry.js';\nimport $ol$geom$GeometryCollection from './ol/geom/GeometryCollection.js';\nimport $ol$geom$LineString from './ol/geom/LineString.js';\nimport $ol$geom$LinearRing from './ol/geom/LinearRing.js';\nimport $ol$geom$MultiLineString from './ol/geom/MultiLineString.js';\nimport $ol$geom$MultiPoint from './ol/geom/MultiPoint.js';\nimport $ol$geom$MultiPolygon from './ol/geom/MultiPolygon.js';\nimport $ol$geom$Point from './ol/geom/Point.js';\nimport $ol$geom$Polygon from './ol/geom/Polygon.js';\nimport {circular as _ol_geom_Polygon$circular} from './ol/geom/Polygon.js';\nimport {fromExtent as _ol_geom_Polygon$fromExtent} from './ol/geom/Polygon.js';\nimport {fromCircle as _ol_geom_Polygon$fromCircle} from './ol/geom/Polygon.js';\nimport {makeRegular as _ol_geom_Polygon$makeRegular} from './ol/geom/Polygon.js';\nimport $ol$geom$SimpleGeometry from './ol/geom/SimpleGeometry.js';\nimport {getStrideForLayout as _ol_geom_SimpleGeometry$getStrideForLayout} from './ol/geom/SimpleGeometry.js';\nimport {transformGeom2D as _ol_geom_SimpleGeometry$transformGeom2D} from './ol/geom/SimpleGeometry.js';\nimport {linearRing as _ol_geom_flat_area$linearRing} from './ol/geom/flat/area.js';\nimport {linearRings as _ol_geom_flat_area$linearRings} from './ol/geom/flat/area.js';\nimport {linearRingss as _ol_geom_flat_area$linearRingss} from './ol/geom/flat/area.js';\nimport {linearRingss as _ol_geom_flat_center$linearRingss} from './ol/geom/flat/center.js';\nimport {maxSquaredDelta as _ol_geom_flat_closest$maxSquaredDelta} from './ol/geom/flat/closest.js';\nimport {arrayMaxSquaredDelta as _ol_geom_flat_closest$arrayMaxSquaredDelta} from './ol/geom/flat/closest.js';\nimport {multiArrayMaxSquaredDelta as _ol_geom_flat_closest$multiArrayMaxSquaredDelta} from './ol/geom/flat/closest.js';\nimport {assignClosestPoint as _ol_geom_flat_closest$assignClosestPoint} from './ol/geom/flat/closest.js';\nimport {assignClosestArrayPoint as _ol_geom_flat_closest$assignClosestArrayPoint} from './ol/geom/flat/closest.js';\nimport {assignClosestMultiArrayPoint as _ol_geom_flat_closest$assignClosestMultiArrayPoint} from './ol/geom/flat/closest.js';\nimport {linearRingContainsExtent as _ol_geom_flat_contains$linearRingContainsExtent} from './ol/geom/flat/contains.js';\nimport {linearRingContainsXY as _ol_geom_flat_contains$linearRingContainsXY} from './ol/geom/flat/contains.js';\nimport {linearRingsContainsXY as _ol_geom_flat_contains$linearRingsContainsXY} from './ol/geom/flat/contains.js';\nimport {linearRingssContainsXY as _ol_geom_flat_contains$linearRingssContainsXY} from './ol/geom/flat/contains.js';\nimport {deflateCoordinate as _ol_geom_flat_deflate$deflateCoordinate} from './ol/geom/flat/deflate.js';\nimport {deflateCoordinates as _ol_geom_flat_deflate$deflateCoordinates} from './ol/geom/flat/deflate.js';\nimport {deflateCoordinatesArray as _ol_geom_flat_deflate$deflateCoordinatesArray} from './ol/geom/flat/deflate.js';\nimport {deflateMultiCoordinatesArray as _ol_geom_flat_deflate$deflateMultiCoordinatesArray} from './ol/geom/flat/deflate.js';\nimport {flipXY as _ol_geom_flat_flip$flipXY} from './ol/geom/flat/flip.js';\nimport {greatCircleArc as _ol_geom_flat_geodesic$greatCircleArc} from './ol/geom/flat/geodesic.js';\nimport {meridian as _ol_geom_flat_geodesic$meridian} from './ol/geom/flat/geodesic.js';\nimport {parallel as _ol_geom_flat_geodesic$parallel} from './ol/geom/flat/geodesic.js';\nimport {inflateCoordinates as _ol_geom_flat_inflate$inflateCoordinates} from './ol/geom/flat/inflate.js';\nimport {inflateCoordinatesArray as _ol_geom_flat_inflate$inflateCoordinatesArray} from './ol/geom/flat/inflate.js';\nimport {inflateMultiCoordinatesArray as _ol_geom_flat_inflate$inflateMultiCoordinatesArray} from './ol/geom/flat/inflate.js';\nimport {getInteriorPointOfArray as _ol_geom_flat_interiorpoint$getInteriorPointOfArray} from './ol/geom/flat/interiorpoint.js';\nimport {getInteriorPointsOfMultiArray as _ol_geom_flat_interiorpoint$getInteriorPointsOfMultiArray} from './ol/geom/flat/interiorpoint.js';\nimport {interpolatePoint as _ol_geom_flat_interpolate$interpolatePoint} from './ol/geom/flat/interpolate.js';\nimport {lineStringCoordinateAtM as _ol_geom_flat_interpolate$lineStringCoordinateAtM} from './ol/geom/flat/interpolate.js';\nimport {lineStringsCoordinateAtM as _ol_geom_flat_interpolate$lineStringsCoordinateAtM} from './ol/geom/flat/interpolate.js';\nimport {intersectsLineString as _ol_geom_flat_intersectsextent$intersectsLineString} from './ol/geom/flat/intersectsextent.js';\nimport {intersectsLineStringArray as _ol_geom_flat_intersectsextent$intersectsLineStringArray} from './ol/geom/flat/intersectsextent.js';\nimport {intersectsLinearRing as _ol_geom_flat_intersectsextent$intersectsLinearRing} from './ol/geom/flat/intersectsextent.js';\nimport {intersectsLinearRingArray as _ol_geom_flat_intersectsextent$intersectsLinearRingArray} from './ol/geom/flat/intersectsextent.js';\nimport {intersectsLinearRingMultiArray as _ol_geom_flat_intersectsextent$intersectsLinearRingMultiArray} from './ol/geom/flat/intersectsextent.js';\nimport {lineStringLength as _ol_geom_flat_length$lineStringLength} from './ol/geom/flat/length.js';\nimport {linearRingLength as _ol_geom_flat_length$linearRingLength} from './ol/geom/flat/length.js';\nimport {linearRingIsClockwise as _ol_geom_flat_orient$linearRingIsClockwise} from './ol/geom/flat/orient.js';\nimport {linearRingsAreOriented as _ol_geom_flat_orient$linearRingsAreOriented} from './ol/geom/flat/orient.js';\nimport {linearRingssAreOriented as _ol_geom_flat_orient$linearRingssAreOriented} from './ol/geom/flat/orient.js';\nimport {orientLinearRings as _ol_geom_flat_orient$orientLinearRings} from './ol/geom/flat/orient.js';\nimport {orientLinearRingsArray as _ol_geom_flat_orient$orientLinearRingsArray} from './ol/geom/flat/orient.js';\nimport {inflateEnds as _ol_geom_flat_orient$inflateEnds} from './ol/geom/flat/orient.js';\nimport {coordinates as _ol_geom_flat_reverse$coordinates} from './ol/geom/flat/reverse.js';\nimport {forEach as _ol_geom_flat_segments$forEach} from './ol/geom/flat/segments.js';\nimport {simplifyLineString as _ol_geom_flat_simplify$simplifyLineString} from './ol/geom/flat/simplify.js';\nimport {douglasPeucker as _ol_geom_flat_simplify$douglasPeucker} from './ol/geom/flat/simplify.js';\nimport {douglasPeuckerArray as _ol_geom_flat_simplify$douglasPeuckerArray} from './ol/geom/flat/simplify.js';\nimport {douglasPeuckerMultiArray as _ol_geom_flat_simplify$douglasPeuckerMultiArray} from './ol/geom/flat/simplify.js';\nimport {radialDistance as _ol_geom_flat_simplify$radialDistance} from './ol/geom/flat/simplify.js';\nimport {snap as _ol_geom_flat_simplify$snap} from './ol/geom/flat/simplify.js';\nimport {quantize as _ol_geom_flat_simplify$quantize} from './ol/geom/flat/simplify.js';\nimport {quantizeArray as _ol_geom_flat_simplify$quantizeArray} from './ol/geom/flat/simplify.js';\nimport {quantizeMultiArray as _ol_geom_flat_simplify$quantizeMultiArray} from './ol/geom/flat/simplify.js';\nimport {matchingChunk as _ol_geom_flat_straightchunk$matchingChunk} from './ol/geom/flat/straightchunk.js';\nimport {drawTextOnPath as _ol_geom_flat_textpath$drawTextOnPath} from './ol/geom/flat/textpath.js';\nimport {lineStringIsClosed as _ol_geom_flat_topology$lineStringIsClosed} from './ol/geom/flat/topology.js';\nimport {transform2D as _ol_geom_flat_transform$transform2D} from './ol/geom/flat/transform.js';\nimport {rotate as _ol_geom_flat_transform$rotate} from './ol/geom/flat/transform.js';\nimport {scale as _ol_geom_flat_transform$scale} from './ol/geom/flat/transform.js';\nimport {translate as _ol_geom_flat_transform$translate} from './ol/geom/flat/transform.js';\nimport $ol$format$EsriJSON from './ol/format/EsriJSON.js';\nimport $ol$format$Feature from './ol/format/Feature.js';\nimport {transformGeometryWithOptions as _ol_format_Feature$transformGeometryWithOptions} from './ol/format/Feature.js';\nimport {transformExtentWithOptions as _ol_format_Feature$transformExtentWithOptions} from './ol/format/Feature.js';\nimport $ol$format$GML from './ol/format/GML.js';\nimport $ol$format$GML2 from './ol/format/GML2.js';\nimport $ol$format$GML3 from './ol/format/GML3.js';\nimport $ol$format$GML32 from './ol/format/GML32.js';\nimport {GMLNS as _ol_format_GMLBase$GMLNS} from './ol/format/GMLBase.js';\nimport $ol$format$GMLBase from './ol/format/GMLBase.js';\nimport $ol$format$GPX from './ol/format/GPX.js';\nimport $ol$format$GeoJSON from './ol/format/GeoJSON.js';\nimport $ol$format$IGC from './ol/format/IGC.js';\nimport $ol$format$IIIFInfo from './ol/format/IIIFInfo.js';\nimport $ol$format$JSONFeature from './ol/format/JSONFeature.js';\nimport {getDefaultFillStyle as _ol_format_KML$getDefaultFillStyle} from './ol/format/KML.js';\nimport {getDefaultImageStyle as _ol_format_KML$getDefaultImageStyle} from './ol/format/KML.js';\nimport {getDefaultStrokeStyle as _ol_format_KML$getDefaultStrokeStyle} from './ol/format/KML.js';\nimport {getDefaultTextStyle as _ol_format_KML$getDefaultTextStyle} from './ol/format/KML.js';\nimport {getDefaultStyle as _ol_format_KML$getDefaultStyle} from './ol/format/KML.js';\nimport {getDefaultStyleArray as _ol_format_KML$getDefaultStyleArray} from './ol/format/KML.js';\nimport $ol$format$KML from './ol/format/KML.js';\nimport {readFlatCoordinates as _ol_format_KML$readFlatCoordinates} from './ol/format/KML.js';\nimport $ol$format$MVT from './ol/format/MVT.js';\nimport $ol$format$OSMXML from './ol/format/OSMXML.js';\nimport $ol$format$OWS from './ol/format/OWS.js';\nimport $ol$format$Polyline from './ol/format/Polyline.js';\nimport {encodeDeltas as _ol_format_Polyline$encodeDeltas} from './ol/format/Polyline.js';\nimport {decodeDeltas as _ol_format_Polyline$decodeDeltas} from './ol/format/Polyline.js';\nimport {encodeFloats as _ol_format_Polyline$encodeFloats} from './ol/format/Polyline.js';\nimport {decodeFloats as _ol_format_Polyline$decodeFloats} from './ol/format/Polyline.js';\nimport {encodeSignedIntegers as _ol_format_Polyline$encodeSignedIntegers} from './ol/format/Polyline.js';\nimport {decodeSignedIntegers as _ol_format_Polyline$decodeSignedIntegers} from './ol/format/Polyline.js';\nimport {encodeUnsignedIntegers as _ol_format_Polyline$encodeUnsignedIntegers} from './ol/format/Polyline.js';\nimport {decodeUnsignedIntegers as _ol_format_Polyline$decodeUnsignedIntegers} from './ol/format/Polyline.js';\nimport {encodeUnsignedInteger as _ol_format_Polyline$encodeUnsignedInteger} from './ol/format/Polyline.js';\nimport $ol$format$TextFeature from './ol/format/TextFeature.js';\nimport $ol$format$TopoJSON from './ol/format/TopoJSON.js';\nimport $ol$format$WFS from './ol/format/WFS.js';\nimport {writeFilter as _ol_format_WFS$writeFilter} from './ol/format/WFS.js';\nimport $ol$format$WKB from './ol/format/WKB.js';\nimport $ol$format$WKT from './ol/format/WKT.js';\nimport $ol$format$WMSCapabilities from './ol/format/WMSCapabilities.js';\nimport $ol$format$WMSGetFeatureInfo from './ol/format/WMSGetFeatureInfo.js';\nimport $ol$format$WMTSCapabilities from './ol/format/WMTSCapabilities.js';\nimport $ol$format$XML from './ol/format/XML.js';\nimport $ol$format$XMLFeature from './ol/format/XMLFeature.js';\nimport {and as _ol_format_filter$and} from './ol/format/filter.js';\nimport {or as _ol_format_filter$or} from './ol/format/filter.js';\nimport {not as _ol_format_filter$not} from './ol/format/filter.js';\nimport {bbox as _ol_format_filter$bbox} from './ol/format/filter.js';\nimport {contains as _ol_format_filter$contains} from './ol/format/filter.js';\nimport {intersects as _ol_format_filter$intersects} from './ol/format/filter.js';\nimport {disjoint as _ol_format_filter$disjoint} from './ol/format/filter.js';\nimport {within as _ol_format_filter$within} from './ol/format/filter.js';\nimport {dwithin as _ol_format_filter$dwithin} from './ol/format/filter.js';\nimport {equalTo as _ol_format_filter$equalTo} from './ol/format/filter.js';\nimport {notEqualTo as _ol_format_filter$notEqualTo} from './ol/format/filter.js';\nimport {lessThan as _ol_format_filter$lessThan} from './ol/format/filter.js';\nimport {lessThanOrEqualTo as _ol_format_filter$lessThanOrEqualTo} from './ol/format/filter.js';\nimport {greaterThan as _ol_format_filter$greaterThan} from './ol/format/filter.js';\nimport {greaterThanOrEqualTo as _ol_format_filter$greaterThanOrEqualTo} from './ol/format/filter.js';\nimport {isNull as _ol_format_filter$isNull} from './ol/format/filter.js';\nimport {between as _ol_format_filter$between} from './ol/format/filter.js';\nimport {like as _ol_format_filter$like} from './ol/format/filter.js';\nimport {during as _ol_format_filter$during} from './ol/format/filter.js';\nimport {resourceId as _ol_format_filter$resourceId} from './ol/format/filter.js';\nimport {readHref as _ol_format_xlink$readHref} from './ol/format/xlink.js';\nimport {readBoolean as _ol_format_xsd$readBoolean} from './ol/format/xsd.js';\nimport {readBooleanString as _ol_format_xsd$readBooleanString} from './ol/format/xsd.js';\nimport {readDateTime as _ol_format_xsd$readDateTime} from './ol/format/xsd.js';\nimport {readDecimal as _ol_format_xsd$readDecimal} from './ol/format/xsd.js';\nimport {readDecimalString as _ol_format_xsd$readDecimalString} from './ol/format/xsd.js';\nimport {readPositiveInteger as _ol_format_xsd$readPositiveInteger} from './ol/format/xsd.js';\nimport {readNonNegativeIntegerString as _ol_format_xsd$readNonNegativeIntegerString} from './ol/format/xsd.js';\nimport {readString as _ol_format_xsd$readString} from './ol/format/xsd.js';\nimport {writeBooleanTextNode as _ol_format_xsd$writeBooleanTextNode} from './ol/format/xsd.js';\nimport {writeCDATASection as _ol_format_xsd$writeCDATASection} from './ol/format/xsd.js';\nimport {writeDateTimeTextNode as _ol_format_xsd$writeDateTimeTextNode} from './ol/format/xsd.js';\nimport {writeDecimalTextNode as _ol_format_xsd$writeDecimalTextNode} from './ol/format/xsd.js';\nimport {writeNonNegativeIntegerTextNode as _ol_format_xsd$writeNonNegativeIntegerTextNode} from './ol/format/xsd.js';\nimport {writeStringTextNode as _ol_format_xsd$writeStringTextNode} from './ol/format/xsd.js';\nimport $ol$format$filter$And from './ol/format/filter/And.js';\nimport $ol$format$filter$Bbox from './ol/format/filter/Bbox.js';\nimport $ol$format$filter$Comparison from './ol/format/filter/Comparison.js';\nimport $ol$format$filter$ComparisonBinary from './ol/format/filter/ComparisonBinary.js';\nimport $ol$format$filter$Contains from './ol/format/filter/Contains.js';\nimport $ol$format$filter$DWithin from './ol/format/filter/DWithin.js';\nimport $ol$format$filter$Disjoint from './ol/format/filter/Disjoint.js';\nimport $ol$format$filter$During from './ol/format/filter/During.js';\nimport $ol$format$filter$EqualTo from './ol/format/filter/EqualTo.js';\nimport $ol$format$filter$Filter from './ol/format/filter/Filter.js';\nimport $ol$format$filter$GreaterThan from './ol/format/filter/GreaterThan.js';\nimport $ol$format$filter$GreaterThanOrEqualTo from './ol/format/filter/GreaterThanOrEqualTo.js';\nimport $ol$format$filter$Intersects from './ol/format/filter/Intersects.js';\nimport $ol$format$filter$IsBetween from './ol/format/filter/IsBetween.js';\nimport $ol$format$filter$IsLike from './ol/format/filter/IsLike.js';\nimport $ol$format$filter$IsNull from './ol/format/filter/IsNull.js';\nimport $ol$format$filter$LessThan from './ol/format/filter/LessThan.js';\nimport $ol$format$filter$LessThanOrEqualTo from './ol/format/filter/LessThanOrEqualTo.js';\nimport $ol$format$filter$LogicalNary from './ol/format/filter/LogicalNary.js';\nimport $ol$format$filter$Not from './ol/format/filter/Not.js';\nimport $ol$format$filter$NotEqualTo from './ol/format/filter/NotEqualTo.js';\nimport $ol$format$filter$Or from './ol/format/filter/Or.js';\nimport $ol$format$filter$ResourceId from './ol/format/filter/ResourceId.js';\nimport $ol$format$filter$Spatial from './ol/format/filter/Spatial.js';\nimport $ol$format$filter$Within from './ol/format/filter/Within.js';\nimport $ol$events$Event from './ol/events/Event.js';\nimport {stopPropagation as _ol_events_Event$stopPropagation} from './ol/events/Event.js';\nimport {preventDefault as _ol_events_Event$preventDefault} from './ol/events/Event.js';\nimport $ol$events$Target from './ol/events/Target.js';\nimport {all as _ol_events_condition$all} from './ol/events/condition.js';\nimport {altKeyOnly as _ol_events_condition$altKeyOnly} from './ol/events/condition.js';\nimport {altShiftKeysOnly as _ol_events_condition$altShiftKeysOnly} from './ol/events/condition.js';\nimport {focus as _ol_events_condition$focus} from './ol/events/condition.js';\nimport {focusWithTabindex as _ol_events_condition$focusWithTabindex} from './ol/events/condition.js';\nimport {always as _ol_events_condition$always} from './ol/events/condition.js';\nimport {click as _ol_events_condition$click} from './ol/events/condition.js';\nimport {mouseActionButton as _ol_events_condition$mouseActionButton} from './ol/events/condition.js';\nimport {never as _ol_events_condition$never} from './ol/events/condition.js';\nimport {pointerMove as _ol_events_condition$pointerMove} from './ol/events/condition.js';\nimport {singleClick as _ol_events_condition$singleClick} from './ol/events/condition.js';\nimport {doubleClick as _ol_events_condition$doubleClick} from './ol/events/condition.js';\nimport {noModifierKeys as _ol_events_condition$noModifierKeys} from './ol/events/condition.js';\nimport {platformModifierKeyOnly as _ol_events_condition$platformModifierKeyOnly} from './ol/events/condition.js';\nimport {shiftKeyOnly as _ol_events_condition$shiftKeyOnly} from './ol/events/condition.js';\nimport {targetNotEditable as _ol_events_condition$targetNotEditable} from './ol/events/condition.js';\nimport {mouseOnly as _ol_events_condition$mouseOnly} from './ol/events/condition.js';\nimport {touchOnly as _ol_events_condition$touchOnly} from './ol/events/condition.js';\nimport {penOnly as _ol_events_condition$penOnly} from './ol/events/condition.js';\nimport {primaryAction as _ol_events_condition$primaryAction} from './ol/events/condition.js';\nimport $ol$control$Attribution from './ol/control/Attribution.js';\nimport $ol$control$Control from './ol/control/Control.js';\nimport $ol$control$FullScreen from './ol/control/FullScreen.js';\nimport $ol$control$MousePosition from './ol/control/MousePosition.js';\nimport $ol$control$OverviewMap from './ol/control/OverviewMap.js';\nimport $ol$control$Rotate from './ol/control/Rotate.js';\nimport $ol$control$ScaleLine from './ol/control/ScaleLine.js';\nimport $ol$control$Zoom from './ol/control/Zoom.js';\nimport $ol$control$ZoomSlider from './ol/control/ZoomSlider.js';\nimport $ol$control$ZoomToExtent from './ol/control/ZoomToExtent.js';\n\nvar ol = {};\nol.AssertionError = $ol$AssertionError;\nol.Collection = $ol$Collection;\nol.Collection.CollectionEvent = _ol_Collection$CollectionEvent;\nol.DataTile = $ol$DataTile;\nol.Disposable = $ol$Disposable;\nol.Feature = $ol$Feature;\nol.Feature.createStyleFunction = _ol_Feature$createStyleFunction;\nol.Geolocation = $ol$Geolocation;\nol.Image = $ol$Image;\nol.Image.listenImage = _ol_Image$listenImage;\nol.ImageBase = $ol$ImageBase;\nol.ImageCanvas = $ol$ImageCanvas;\nol.ImageTile = $ol$ImageTile;\nol.Kinetic = $ol$Kinetic;\nol.Map = $ol$Map;\nol.MapBrowserEvent = $ol$MapBrowserEvent;\nol.MapBrowserEventHandler = $ol$MapBrowserEventHandler;\nol.MapEvent = $ol$MapEvent;\nol.Object = $ol$Object;\nol.Object.ObjectEvent = _ol_Object$ObjectEvent;\nol.Observable = $ol$Observable;\nol.Observable.unByKey = _ol_Observable$unByKey;\nol.Overlay = $ol$Overlay;\nol.PluggableMap = $ol$PluggableMap;\nol.Tile = $ol$Tile;\nol.TileCache = $ol$TileCache;\nol.TileQueue = $ol$TileQueue;\nol.TileQueue.getTilePriority = _ol_TileQueue$getTilePriority;\nol.TileRange = $ol$TileRange;\nol.TileRange.createOrUpdate = _ol_TileRange$createOrUpdate;\nol.VectorRenderTile = $ol$VectorRenderTile;\nol.VectorTile = $ol$VectorTile;\nol.View = $ol$View;\nol.View.createCenterConstraint = _ol_View$createCenterConstraint;\nol.View.createResolutionConstraint = _ol_View$createResolutionConstraint;\nol.View.createRotationConstraint = _ol_View$createRotationConstraint;\nol.View.isNoopAnimation = _ol_View$isNoopAnimation;\nol.array = {};\nol.array.binarySearch = _ol_array$binarySearch;\nol.array.equals = _ol_array$equals;\nol.array.extend = _ol_array$extend;\nol.array.find = _ol_array$find;\nol.array.findIndex = _ol_array$findIndex;\nol.array.includes = _ol_array$includes;\nol.array.isSorted = _ol_array$isSorted;\nol.array.linearFindNearest = _ol_array$linearFindNearest;\nol.array.numberSafeCompareFunction = _ol_array$numberSafeCompareFunction;\nol.array.remove = _ol_array$remove;\nol.array.reverseSubArray = _ol_array$reverseSubArray;\nol.array.stableSort = _ol_array$stableSort;\nol.asserts = {};\nol.asserts.assert = _ol_asserts$assert;\nol.centerconstraint = {};\nol.centerconstraint.createExtent = _ol_centerconstraint$createExtent;\nol.centerconstraint.none = _ol_centerconstraint$none;\nol.color = {};\nol.color.asArray = _ol_color$asArray;\nol.color.asString = _ol_color$asString;\nol.color.fromString = _ol_color$fromString;\nol.color.isStringColor = _ol_color$isStringColor;\nol.color.normalize = _ol_color$normalize;\nol.color.toString = _ol_color$toString;\nol.colorlike = {};\nol.colorlike.asColorLike = _ol_colorlike$asColorLike;\nol.control = {};\nol.control.Attribution = $ol$control$Attribution;\nol.control.Control = $ol$control$Control;\nol.control.FullScreen = $ol$control$FullScreen;\nol.control.MousePosition = $ol$control$MousePosition;\nol.control.OverviewMap = $ol$control$OverviewMap;\nol.control.Rotate = $ol$control$Rotate;\nol.control.ScaleLine = $ol$control$ScaleLine;\nol.control.Zoom = $ol$control$Zoom;\nol.control.ZoomSlider = $ol$control$ZoomSlider;\nol.control.ZoomToExtent = $ol$control$ZoomToExtent;\nol.control.defaults = _ol_control$defaults;\nol.coordinate = {};\nol.coordinate.add = _ol_coordinate$add;\nol.coordinate.closestOnCircle = _ol_coordinate$closestOnCircle;\nol.coordinate.closestOnSegment = _ol_coordinate$closestOnSegment;\nol.coordinate.createStringXY = _ol_coordinate$createStringXY;\nol.coordinate.degreesToStringHDMS = _ol_coordinate$degreesToStringHDMS;\nol.coordinate.distance = _ol_coordinate$distance;\nol.coordinate.equals = _ol_coordinate$equals;\nol.coordinate.format = _ol_coordinate$format;\nol.coordinate.getWorldsAway = _ol_coordinate$getWorldsAway;\nol.coordinate.rotate = _ol_coordinate$rotate;\nol.coordinate.scale = _ol_coordinate$scale;\nol.coordinate.squaredDistance = _ol_coordinate$squaredDistance;\nol.coordinate.squaredDistanceToSegment = _ol_coordinate$squaredDistanceToSegment;\nol.coordinate.toStringHDMS = _ol_coordinate$toStringHDMS;\nol.coordinate.toStringXY = _ol_coordinate$toStringXY;\nol.coordinate.wrapX = _ol_coordinate$wrapX;\nol.css = {};\nol.css.CLASS_COLLAPSED = _ol_css$CLASS_COLLAPSED;\nol.css.CLASS_CONTROL = _ol_css$CLASS_CONTROL;\nol.css.CLASS_HIDDEN = _ol_css$CLASS_HIDDEN;\nol.css.CLASS_SELECTABLE = _ol_css$CLASS_SELECTABLE;\nol.css.CLASS_UNSELECTABLE = _ol_css$CLASS_UNSELECTABLE;\nol.css.CLASS_UNSUPPORTED = _ol_css$CLASS_UNSUPPORTED;\nol.css.getFontParameters = _ol_css$getFontParameters;\nol.dom = {};\nol.dom.createCanvasContext2D = _ol_dom$createCanvasContext2D;\nol.dom.outerHeight = _ol_dom$outerHeight;\nol.dom.outerWidth = _ol_dom$outerWidth;\nol.dom.releaseCanvas = _ol_dom$releaseCanvas;\nol.dom.removeChildren = _ol_dom$removeChildren;\nol.dom.removeNode = _ol_dom$removeNode;\nol.dom.replaceChildren = _ol_dom$replaceChildren;\nol.dom.replaceNode = _ol_dom$replaceNode;\nol.easing = {};\nol.easing.easeIn = _ol_easing$easeIn;\nol.easing.easeOut = _ol_easing$easeOut;\nol.easing.inAndOut = _ol_easing$inAndOut;\nol.easing.linear = _ol_easing$linear;\nol.easing.upAndDown = _ol_easing$upAndDown;\nol.events = {};\nol.events.Event = $ol$events$Event;\nol.events.Event.preventDefault = _ol_events_Event$preventDefault;\nol.events.Event.stopPropagation = _ol_events_Event$stopPropagation;\nol.events.Target = $ol$events$Target;\nol.events.condition = {};\nol.events.condition.all = _ol_events_condition$all;\nol.events.condition.altKeyOnly = _ol_events_condition$altKeyOnly;\nol.events.condition.altShiftKeysOnly = _ol_events_condition$altShiftKeysOnly;\nol.events.condition.always = _ol_events_condition$always;\nol.events.condition.click = _ol_events_condition$click;\nol.events.condition.doubleClick = _ol_events_condition$doubleClick;\nol.events.condition.focus = _ol_events_condition$focus;\nol.events.condition.focusWithTabindex = _ol_events_condition$focusWithTabindex;\nol.events.condition.mouseActionButton = _ol_events_condition$mouseActionButton;\nol.events.condition.mouseOnly = _ol_events_condition$mouseOnly;\nol.events.condition.never = _ol_events_condition$never;\nol.events.condition.noModifierKeys = _ol_events_condition$noModifierKeys;\nol.events.condition.penOnly = _ol_events_condition$penOnly;\nol.events.condition.platformModifierKeyOnly = _ol_events_condition$platformModifierKeyOnly;\nol.events.condition.pointerMove = _ol_events_condition$pointerMove;\nol.events.condition.primaryAction = _ol_events_condition$primaryAction;\nol.events.condition.shiftKeyOnly = _ol_events_condition$shiftKeyOnly;\nol.events.condition.singleClick = _ol_events_condition$singleClick;\nol.events.condition.targetNotEditable = _ol_events_condition$targetNotEditable;\nol.events.condition.touchOnly = _ol_events_condition$touchOnly;\nol.events.listen = _ol_events$listen;\nol.events.listenOnce = _ol_events$listenOnce;\nol.events.unlistenByKey = _ol_events$unlistenByKey;\nol.extent = {};\nol.extent.applyTransform = _ol_extent$applyTransform;\nol.extent.approximatelyEquals = _ol_extent$approximatelyEquals;\nol.extent.boundingExtent = _ol_extent$boundingExtent;\nol.extent.buffer = _ol_extent$buffer;\nol.extent.clone = _ol_extent$clone;\nol.extent.closestSquaredDistanceXY = _ol_extent$closestSquaredDistanceXY;\nol.extent.containsCoordinate = _ol_extent$containsCoordinate;\nol.extent.containsExtent = _ol_extent$containsExtent;\nol.extent.containsXY = _ol_extent$containsXY;\nol.extent.coordinateRelationship = _ol_extent$coordinateRelationship;\nol.extent.createEmpty = _ol_extent$createEmpty;\nol.extent.createOrUpdate = _ol_extent$createOrUpdate;\nol.extent.createOrUpdateEmpty = _ol_extent$createOrUpdateEmpty;\nol.extent.createOrUpdateFromCoordinate = _ol_extent$createOrUpdateFromCoordinate;\nol.extent.createOrUpdateFromCoordinates = _ol_extent$createOrUpdateFromCoordinates;\nol.extent.createOrUpdateFromFlatCoordinates = _ol_extent$createOrUpdateFromFlatCoordinates;\nol.extent.createOrUpdateFromRings = _ol_extent$createOrUpdateFromRings;\nol.extent.equals = _ol_extent$equals;\nol.extent.extend = _ol_extent$extend;\nol.extent.extendCoordinate = _ol_extent$extendCoordinate;\nol.extent.extendCoordinates = _ol_extent$extendCoordinates;\nol.extent.extendFlatCoordinates = _ol_extent$extendFlatCoordinates;\nol.extent.extendRings = _ol_extent$extendRings;\nol.extent.extendXY = _ol_extent$extendXY;\nol.extent.forEachCorner = _ol_extent$forEachCorner;\nol.extent.getArea = _ol_extent$getArea;\nol.extent.getBottomLeft = _ol_extent$getBottomLeft;\nol.extent.getBottomRight = _ol_extent$getBottomRight;\nol.extent.getCenter = _ol_extent$getCenter;\nol.extent.getCorner = _ol_extent$getCorner;\nol.extent.getEnlargedArea = _ol_extent$getEnlargedArea;\nol.extent.getForViewAndSize = _ol_extent$getForViewAndSize;\nol.extent.getHeight = _ol_extent$getHeight;\nol.extent.getIntersection = _ol_extent$getIntersection;\nol.extent.getIntersectionArea = _ol_extent$getIntersectionArea;\nol.extent.getMargin = _ol_extent$getMargin;\nol.extent.getRotatedViewport = _ol_extent$getRotatedViewport;\nol.extent.getSize = _ol_extent$getSize;\nol.extent.getTopLeft = _ol_extent$getTopLeft;\nol.extent.getTopRight = _ol_extent$getTopRight;\nol.extent.getWidth = _ol_extent$getWidth;\nol.extent.intersects = _ol_extent$intersects;\nol.extent.intersectsSegment = _ol_extent$intersectsSegment;\nol.extent.isEmpty = _ol_extent$isEmpty;\nol.extent.returnOrUpdate = _ol_extent$returnOrUpdate;\nol.extent.scaleFromCenter = _ol_extent$scaleFromCenter;\nol.extent.wrapAndSliceX = _ol_extent$wrapAndSliceX;\nol.extent.wrapX = _ol_extent$wrapX;\nol.featureloader = {};\nol.featureloader.loadFeaturesXhr = _ol_featureloader$loadFeaturesXhr;\nol.featureloader.setWithCredentials = _ol_featureloader$setWithCredentials;\nol.featureloader.xhr = _ol_featureloader$xhr;\nol.format = {};\nol.format.EsriJSON = $ol$format$EsriJSON;\nol.format.Feature = $ol$format$Feature;\nol.format.Feature.transformExtentWithOptions = _ol_format_Feature$transformExtentWithOptions;\nol.format.Feature.transformGeometryWithOptions = _ol_format_Feature$transformGeometryWithOptions;\nol.format.GML = $ol$format$GML;\nol.format.GML2 = $ol$format$GML2;\nol.format.GML3 = $ol$format$GML3;\nol.format.GML32 = $ol$format$GML32;\nol.format.GMLBase = $ol$format$GMLBase;\nol.format.GMLBase.GMLNS = _ol_format_GMLBase$GMLNS;\nol.format.GPX = $ol$format$GPX;\nol.format.GeoJSON = $ol$format$GeoJSON;\nol.format.IGC = $ol$format$IGC;\nol.format.IIIFInfo = $ol$format$IIIFInfo;\nol.format.JSONFeature = $ol$format$JSONFeature;\nol.format.KML = $ol$format$KML;\nol.format.KML.getDefaultFillStyle = _ol_format_KML$getDefaultFillStyle;\nol.format.KML.getDefaultImageStyle = _ol_format_KML$getDefaultImageStyle;\nol.format.KML.getDefaultStrokeStyle = _ol_format_KML$getDefaultStrokeStyle;\nol.format.KML.getDefaultStyle = _ol_format_KML$getDefaultStyle;\nol.format.KML.getDefaultStyleArray = _ol_format_KML$getDefaultStyleArray;\nol.format.KML.getDefaultTextStyle = _ol_format_KML$getDefaultTextStyle;\nol.format.KML.readFlatCoordinates = _ol_format_KML$readFlatCoordinates;\nol.format.MVT = $ol$format$MVT;\nol.format.OSMXML = $ol$format$OSMXML;\nol.format.OWS = $ol$format$OWS;\nol.format.Polyline = $ol$format$Polyline;\nol.format.Polyline.decodeDeltas = _ol_format_Polyline$decodeDeltas;\nol.format.Polyline.decodeFloats = _ol_format_Polyline$decodeFloats;\nol.format.Polyline.decodeSignedIntegers = _ol_format_Polyline$decodeSignedIntegers;\nol.format.Polyline.decodeUnsignedIntegers = _ol_format_Polyline$decodeUnsignedIntegers;\nol.format.Polyline.encodeDeltas = _ol_format_Polyline$encodeDeltas;\nol.format.Polyline.encodeFloats = _ol_format_Polyline$encodeFloats;\nol.format.Polyline.encodeSignedIntegers = _ol_format_Polyline$encodeSignedIntegers;\nol.format.Polyline.encodeUnsignedInteger = _ol_format_Polyline$encodeUnsignedInteger;\nol.format.Polyline.encodeUnsignedIntegers = _ol_format_Polyline$encodeUnsignedIntegers;\nol.format.TextFeature = $ol$format$TextFeature;\nol.format.TopoJSON = $ol$format$TopoJSON;\nol.format.WFS = $ol$format$WFS;\nol.format.WFS.writeFilter = _ol_format_WFS$writeFilter;\nol.format.WKB = $ol$format$WKB;\nol.format.WKT = $ol$format$WKT;\nol.format.WMSCapabilities = $ol$format$WMSCapabilities;\nol.format.WMSGetFeatureInfo = $ol$format$WMSGetFeatureInfo;\nol.format.WMTSCapabilities = $ol$format$WMTSCapabilities;\nol.format.XML = $ol$format$XML;\nol.format.XMLFeature = $ol$format$XMLFeature;\nol.format.filter = {};\nol.format.filter.And = $ol$format$filter$And;\nol.format.filter.Bbox = $ol$format$filter$Bbox;\nol.format.filter.Comparison = $ol$format$filter$Comparison;\nol.format.filter.ComparisonBinary = $ol$format$filter$ComparisonBinary;\nol.format.filter.Contains = $ol$format$filter$Contains;\nol.format.filter.DWithin = $ol$format$filter$DWithin;\nol.format.filter.Disjoint = $ol$format$filter$Disjoint;\nol.format.filter.During = $ol$format$filter$During;\nol.format.filter.EqualTo = $ol$format$filter$EqualTo;\nol.format.filter.Filter = $ol$format$filter$Filter;\nol.format.filter.GreaterThan = $ol$format$filter$GreaterThan;\nol.format.filter.GreaterThanOrEqualTo = $ol$format$filter$GreaterThanOrEqualTo;\nol.format.filter.Intersects = $ol$format$filter$Intersects;\nol.format.filter.IsBetween = $ol$format$filter$IsBetween;\nol.format.filter.IsLike = $ol$format$filter$IsLike;\nol.format.filter.IsNull = $ol$format$filter$IsNull;\nol.format.filter.LessThan = $ol$format$filter$LessThan;\nol.format.filter.LessThanOrEqualTo = $ol$format$filter$LessThanOrEqualTo;\nol.format.filter.LogicalNary = $ol$format$filter$LogicalNary;\nol.format.filter.Not = $ol$format$filter$Not;\nol.format.filter.NotEqualTo = $ol$format$filter$NotEqualTo;\nol.format.filter.Or = $ol$format$filter$Or;\nol.format.filter.ResourceId = $ol$format$filter$ResourceId;\nol.format.filter.Spatial = $ol$format$filter$Spatial;\nol.format.filter.Within = $ol$format$filter$Within;\nol.format.filter.and = _ol_format_filter$and;\nol.format.filter.bbox = _ol_format_filter$bbox;\nol.format.filter.between = _ol_format_filter$between;\nol.format.filter.contains = _ol_format_filter$contains;\nol.format.filter.disjoint = _ol_format_filter$disjoint;\nol.format.filter.during = _ol_format_filter$during;\nol.format.filter.dwithin = _ol_format_filter$dwithin;\nol.format.filter.equalTo = _ol_format_filter$equalTo;\nol.format.filter.greaterThan = _ol_format_filter$greaterThan;\nol.format.filter.greaterThanOrEqualTo = _ol_format_filter$greaterThanOrEqualTo;\nol.format.filter.intersects = _ol_format_filter$intersects;\nol.format.filter.isNull = _ol_format_filter$isNull;\nol.format.filter.lessThan = _ol_format_filter$lessThan;\nol.format.filter.lessThanOrEqualTo = _ol_format_filter$lessThanOrEqualTo;\nol.format.filter.like = _ol_format_filter$like;\nol.format.filter.not = _ol_format_filter$not;\nol.format.filter.notEqualTo = _ol_format_filter$notEqualTo;\nol.format.filter.or = _ol_format_filter$or;\nol.format.filter.resourceId = _ol_format_filter$resourceId;\nol.format.filter.within = _ol_format_filter$within;\nol.format.xlink = {};\nol.format.xlink.readHref = _ol_format_xlink$readHref;\nol.format.xsd = {};\nol.format.xsd.readBoolean = _ol_format_xsd$readBoolean;\nol.format.xsd.readBooleanString = _ol_format_xsd$readBooleanString;\nol.format.xsd.readDateTime = _ol_format_xsd$readDateTime;\nol.format.xsd.readDecimal = _ol_format_xsd$readDecimal;\nol.format.xsd.readDecimalString = _ol_format_xsd$readDecimalString;\nol.format.xsd.readNonNegativeIntegerString = _ol_format_xsd$readNonNegativeIntegerString;\nol.format.xsd.readPositiveInteger = _ol_format_xsd$readPositiveInteger;\nol.format.xsd.readString = _ol_format_xsd$readString;\nol.format.xsd.writeBooleanTextNode = _ol_format_xsd$writeBooleanTextNode;\nol.format.xsd.writeCDATASection = _ol_format_xsd$writeCDATASection;\nol.format.xsd.writeDateTimeTextNode = _ol_format_xsd$writeDateTimeTextNode;\nol.format.xsd.writeDecimalTextNode = _ol_format_xsd$writeDecimalTextNode;\nol.format.xsd.writeNonNegativeIntegerTextNode = _ol_format_xsd$writeNonNegativeIntegerTextNode;\nol.format.xsd.writeStringTextNode = _ol_format_xsd$writeStringTextNode;\nol.functions = {};\nol.functions.FALSE = _ol_functions$FALSE;\nol.functions.TRUE = _ol_functions$TRUE;\nol.functions.VOID = _ol_functions$VOID;\nol.functions.memoizeOne = _ol_functions$memoizeOne;\nol.functions.toPromise = _ol_functions$toPromise;\nol.geom = {};\nol.geom.Circle = $ol$geom$Circle;\nol.geom.Geometry = $ol$geom$Geometry;\nol.geom.GeometryCollection = $ol$geom$GeometryCollection;\nol.geom.LineString = $ol$geom$LineString;\nol.geom.LinearRing = $ol$geom$LinearRing;\nol.geom.MultiLineString = $ol$geom$MultiLineString;\nol.geom.MultiPoint = $ol$geom$MultiPoint;\nol.geom.MultiPolygon = $ol$geom$MultiPolygon;\nol.geom.Point = $ol$geom$Point;\nol.geom.Polygon = $ol$geom$Polygon;\nol.geom.Polygon.circular = _ol_geom_Polygon$circular;\nol.geom.Polygon.fromCircle = _ol_geom_Polygon$fromCircle;\nol.geom.Polygon.fromExtent = _ol_geom_Polygon$fromExtent;\nol.geom.Polygon.makeRegular = _ol_geom_Polygon$makeRegular;\nol.geom.SimpleGeometry = $ol$geom$SimpleGeometry;\nol.geom.SimpleGeometry.getStrideForLayout = _ol_geom_SimpleGeometry$getStrideForLayout;\nol.geom.SimpleGeometry.transformGeom2D = _ol_geom_SimpleGeometry$transformGeom2D;\nol.geom.flat = {};\nol.geom.flat.area = {};\nol.geom.flat.area.linearRing = _ol_geom_flat_area$linearRing;\nol.geom.flat.area.linearRings = _ol_geom_flat_area$linearRings;\nol.geom.flat.area.linearRingss = _ol_geom_flat_area$linearRingss;\nol.geom.flat.center = {};\nol.geom.flat.center.linearRingss = _ol_geom_flat_center$linearRingss;\nol.geom.flat.closest = {};\nol.geom.flat.closest.arrayMaxSquaredDelta = _ol_geom_flat_closest$arrayMaxSquaredDelta;\nol.geom.flat.closest.assignClosestArrayPoint = _ol_geom_flat_closest$assignClosestArrayPoint;\nol.geom.flat.closest.assignClosestMultiArrayPoint = _ol_geom_flat_closest$assignClosestMultiArrayPoint;\nol.geom.flat.closest.assignClosestPoint = _ol_geom_flat_closest$assignClosestPoint;\nol.geom.flat.closest.maxSquaredDelta = _ol_geom_flat_closest$maxSquaredDelta;\nol.geom.flat.closest.multiArrayMaxSquaredDelta = _ol_geom_flat_closest$multiArrayMaxSquaredDelta;\nol.geom.flat.contains = {};\nol.geom.flat.contains.linearRingContainsExtent = _ol_geom_flat_contains$linearRingContainsExtent;\nol.geom.flat.contains.linearRingContainsXY = _ol_geom_flat_contains$linearRingContainsXY;\nol.geom.flat.contains.linearRingsContainsXY = _ol_geom_flat_contains$linearRingsContainsXY;\nol.geom.flat.contains.linearRingssContainsXY = _ol_geom_flat_contains$linearRingssContainsXY;\nol.geom.flat.deflate = {};\nol.geom.flat.deflate.deflateCoordinate = _ol_geom_flat_deflate$deflateCoordinate;\nol.geom.flat.deflate.deflateCoordinates = _ol_geom_flat_deflate$deflateCoordinates;\nol.geom.flat.deflate.deflateCoordinatesArray = _ol_geom_flat_deflate$deflateCoordinatesArray;\nol.geom.flat.deflate.deflateMultiCoordinatesArray = _ol_geom_flat_deflate$deflateMultiCoordinatesArray;\nol.geom.flat.flip = {};\nol.geom.flat.flip.flipXY = _ol_geom_flat_flip$flipXY;\nol.geom.flat.geodesic = {};\nol.geom.flat.geodesic.greatCircleArc = _ol_geom_flat_geodesic$greatCircleArc;\nol.geom.flat.geodesic.meridian = _ol_geom_flat_geodesic$meridian;\nol.geom.flat.geodesic.parallel = _ol_geom_flat_geodesic$parallel;\nol.geom.flat.inflate = {};\nol.geom.flat.inflate.inflateCoordinates = _ol_geom_flat_inflate$inflateCoordinates;\nol.geom.flat.inflate.inflateCoordinatesArray = _ol_geom_flat_inflate$inflateCoordinatesArray;\nol.geom.flat.inflate.inflateMultiCoordinatesArray = _ol_geom_flat_inflate$inflateMultiCoordinatesArray;\nol.geom.flat.interiorpoint = {};\nol.geom.flat.interiorpoint.getInteriorPointOfArray = _ol_geom_flat_interiorpoint$getInteriorPointOfArray;\nol.geom.flat.interiorpoint.getInteriorPointsOfMultiArray = _ol_geom_flat_interiorpoint$getInteriorPointsOfMultiArray;\nol.geom.flat.interpolate = {};\nol.geom.flat.interpolate.interpolatePoint = _ol_geom_flat_interpolate$interpolatePoint;\nol.geom.flat.interpolate.lineStringCoordinateAtM = _ol_geom_flat_interpolate$lineStringCoordinateAtM;\nol.geom.flat.interpolate.lineStringsCoordinateAtM = _ol_geom_flat_interpolate$lineStringsCoordinateAtM;\nol.geom.flat.intersectsextent = {};\nol.geom.flat.intersectsextent.intersectsLineString = _ol_geom_flat_intersectsextent$intersectsLineString;\nol.geom.flat.intersectsextent.intersectsLineStringArray = _ol_geom_flat_intersectsextent$intersectsLineStringArray;\nol.geom.flat.intersectsextent.intersectsLinearRing = _ol_geom_flat_intersectsextent$intersectsLinearRing;\nol.geom.flat.intersectsextent.intersectsLinearRingArray = _ol_geom_flat_intersectsextent$intersectsLinearRingArray;\nol.geom.flat.intersectsextent.intersectsLinearRingMultiArray = _ol_geom_flat_intersectsextent$intersectsLinearRingMultiArray;\nol.geom.flat.length = {};\nol.geom.flat.length.lineStringLength = _ol_geom_flat_length$lineStringLength;\nol.geom.flat.length.linearRingLength = _ol_geom_flat_length$linearRingLength;\nol.geom.flat.orient = {};\nol.geom.flat.orient.inflateEnds = _ol_geom_flat_orient$inflateEnds;\nol.geom.flat.orient.linearRingIsClockwise = _ol_geom_flat_orient$linearRingIsClockwise;\nol.geom.flat.orient.linearRingsAreOriented = _ol_geom_flat_orient$linearRingsAreOriented;\nol.geom.flat.orient.linearRingssAreOriented = _ol_geom_flat_orient$linearRingssAreOriented;\nol.geom.flat.orient.orientLinearRings = _ol_geom_flat_orient$orientLinearRings;\nol.geom.flat.orient.orientLinearRingsArray = _ol_geom_flat_orient$orientLinearRingsArray;\nol.geom.flat.reverse = {};\nol.geom.flat.reverse.coordinates = _ol_geom_flat_reverse$coordinates;\nol.geom.flat.segments = {};\nol.geom.flat.segments.forEach = _ol_geom_flat_segments$forEach;\nol.geom.flat.simplify = {};\nol.geom.flat.simplify.douglasPeucker = _ol_geom_flat_simplify$douglasPeucker;\nol.geom.flat.simplify.douglasPeuckerArray = _ol_geom_flat_simplify$douglasPeuckerArray;\nol.geom.flat.simplify.douglasPeuckerMultiArray = _ol_geom_flat_simplify$douglasPeuckerMultiArray;\nol.geom.flat.simplify.quantize = _ol_geom_flat_simplify$quantize;\nol.geom.flat.simplify.quantizeArray = _ol_geom_flat_simplify$quantizeArray;\nol.geom.flat.simplify.quantizeMultiArray = _ol_geom_flat_simplify$quantizeMultiArray;\nol.geom.flat.simplify.radialDistance = _ol_geom_flat_simplify$radialDistance;\nol.geom.flat.simplify.simplifyLineString = _ol_geom_flat_simplify$simplifyLineString;\nol.geom.flat.simplify.snap = _ol_geom_flat_simplify$snap;\nol.geom.flat.straightchunk = {};\nol.geom.flat.straightchunk.matchingChunk = _ol_geom_flat_straightchunk$matchingChunk;\nol.geom.flat.textpath = {};\nol.geom.flat.textpath.drawTextOnPath = _ol_geom_flat_textpath$drawTextOnPath;\nol.geom.flat.topology = {};\nol.geom.flat.topology.lineStringIsClosed = _ol_geom_flat_topology$lineStringIsClosed;\nol.geom.flat.transform = {};\nol.geom.flat.transform.rotate = _ol_geom_flat_transform$rotate;\nol.geom.flat.transform.scale = _ol_geom_flat_transform$scale;\nol.geom.flat.transform.transform2D = _ol_geom_flat_transform$transform2D;\nol.geom.flat.transform.translate = _ol_geom_flat_transform$translate;\nol.has = {};\nol.has.DEVICE_PIXEL_RATIO = _ol_has$DEVICE_PIXEL_RATIO;\nol.has.FIREFOX = _ol_has$FIREFOX;\nol.has.IMAGE_DECODE = _ol_has$IMAGE_DECODE;\nol.has.MAC = _ol_has$MAC;\nol.has.PASSIVE_EVENT_LISTENERS = _ol_has$PASSIVE_EVENT_LISTENERS;\nol.has.SAFARI = _ol_has$SAFARI;\nol.has.SAFARI_BUG_237906 = _ol_has$SAFARI_BUG_237906;\nol.has.WEBKIT = _ol_has$WEBKIT;\nol.has.WORKER_OFFSCREEN_CANVAS = _ol_has$WORKER_OFFSCREEN_CANVAS;\nol.interaction = {};\nol.interaction.DoubleClickZoom = $ol$interaction$DoubleClickZoom;\nol.interaction.DragAndDrop = $ol$interaction$DragAndDrop;\nol.interaction.DragAndDrop.DragAndDropEvent = _ol_interaction_DragAndDrop$DragAndDropEvent;\nol.interaction.DragBox = $ol$interaction$DragBox;\nol.interaction.DragBox.DragBoxEvent = _ol_interaction_DragBox$DragBoxEvent;\nol.interaction.DragPan = $ol$interaction$DragPan;\nol.interaction.DragRotate = $ol$interaction$DragRotate;\nol.interaction.DragRotateAndZoom = $ol$interaction$DragRotateAndZoom;\nol.interaction.DragZoom = $ol$interaction$DragZoom;\nol.interaction.Draw = $ol$interaction$Draw;\nol.interaction.Draw.DrawEvent = _ol_interaction_Draw$DrawEvent;\nol.interaction.Draw.createBox = _ol_interaction_Draw$createBox;\nol.interaction.Draw.createRegularPolygon = _ol_interaction_Draw$createRegularPolygon;\nol.interaction.Extent = $ol$interaction$Extent;\nol.interaction.Extent.ExtentEvent = _ol_interaction_Extent$ExtentEvent;\nol.interaction.Interaction = $ol$interaction$Interaction;\nol.interaction.Interaction.pan = _ol_interaction_Interaction$pan;\nol.interaction.Interaction.zoomByDelta = _ol_interaction_Interaction$zoomByDelta;\nol.interaction.KeyboardPan = $ol$interaction$KeyboardPan;\nol.interaction.KeyboardZoom = $ol$interaction$KeyboardZoom;\nol.interaction.Link = $ol$interaction$Link;\nol.interaction.Modify = $ol$interaction$Modify;\nol.interaction.Modify.ModifyEvent = _ol_interaction_Modify$ModifyEvent;\nol.interaction.MouseWheelZoom = $ol$interaction$MouseWheelZoom;\nol.interaction.PinchRotate = $ol$interaction$PinchRotate;\nol.interaction.PinchZoom = $ol$interaction$PinchZoom;\nol.interaction.Pointer = $ol$interaction$Pointer;\nol.interaction.Pointer.centroid = _ol_interaction_Pointer$centroid;\nol.interaction.Select = $ol$interaction$Select;\nol.interaction.Select.SelectEvent = _ol_interaction_Select$SelectEvent;\nol.interaction.Snap = $ol$interaction$Snap;\nol.interaction.Translate = $ol$interaction$Translate;\nol.interaction.Translate.TranslateEvent = _ol_interaction_Translate$TranslateEvent;\nol.interaction.defaults = _ol_interaction$defaults;\nol.layer = {};\nol.layer.Base = $ol$layer$Base;\nol.layer.BaseImage = $ol$layer$BaseImage;\nol.layer.BaseTile = $ol$layer$BaseTile;\nol.layer.BaseVector = $ol$layer$BaseVector;\nol.layer.Graticule = $ol$layer$Graticule;\nol.layer.Group = $ol$layer$Group;\nol.layer.Group.GroupEvent = _ol_layer_Group$GroupEvent;\nol.layer.Heatmap = $ol$layer$Heatmap;\nol.layer.Image = $ol$layer$Image;\nol.layer.Layer = $ol$layer$Layer;\nol.layer.Layer.inView = _ol_layer_Layer$inView;\nol.layer.MapboxVector = $ol$layer$MapboxVector;\nol.layer.Tile = $ol$layer$Tile;\nol.layer.Vector = $ol$layer$Vector;\nol.layer.VectorImage = $ol$layer$VectorImage;\nol.layer.VectorTile = $ol$layer$VectorTile;\nol.layer.WebGLPoints = $ol$layer$WebGLPoints;\nol.layer.WebGLTile = $ol$layer$WebGLTile;\nol.loadingstrategy = {};\nol.loadingstrategy.all = _ol_loadingstrategy$all;\nol.loadingstrategy.bbox = _ol_loadingstrategy$bbox;\nol.loadingstrategy.tile = _ol_loadingstrategy$tile;\nol.math = {};\nol.math.ceil = _ol_math$ceil;\nol.math.clamp = _ol_math$clamp;\nol.math.cosh = _ol_math$cosh;\nol.math.floor = _ol_math$floor;\nol.math.lerp = _ol_math$lerp;\nol.math.log2 = _ol_math$log2;\nol.math.modulo = _ol_math$modulo;\nol.math.round = _ol_math$round;\nol.math.solveLinearSystem = _ol_math$solveLinearSystem;\nol.math.squaredDistance = _ol_math$squaredDistance;\nol.math.squaredSegmentDistance = _ol_math$squaredSegmentDistance;\nol.math.toDegrees = _ol_math$toDegrees;\nol.math.toFixed = _ol_math$toFixed;\nol.math.toRadians = _ol_math$toRadians;\nol.net = {};\nol.net.ClientError = _ol_net$ClientError;\nol.net.ResponseError = _ol_net$ResponseError;\nol.net.getJSON = _ol_net$getJSON;\nol.net.jsonp = _ol_net$jsonp;\nol.net.overrideXHR = _ol_net$overrideXHR;\nol.net.resolveUrl = _ol_net$resolveUrl;\nol.net.restoreXHR = _ol_net$restoreXHR;\nol.obj = {};\nol.obj.assign = _ol_obj$assign;\nol.obj.clear = _ol_obj$clear;\nol.obj.getValues = _ol_obj$getValues;\nol.obj.isEmpty = _ol_obj$isEmpty;\nol.proj = {};\nol.proj.Projection = $ol$proj$Projection;\nol.proj.Units = {};\nol.proj.Units.METERS_PER_UNIT = _ol_proj_Units$METERS_PER_UNIT;\nol.proj.Units.fromCode = _ol_proj_Units$fromCode;\nol.proj.addCommon = _ol_proj$addCommon;\nol.proj.addCoordinateTransforms = _ol_proj$addCoordinateTransforms;\nol.proj.addEquivalentProjections = _ol_proj$addEquivalentProjections;\nol.proj.addEquivalentTransforms = _ol_proj$addEquivalentTransforms;\nol.proj.addProjection = _ol_proj$addProjection;\nol.proj.addProjections = _ol_proj$addProjections;\nol.proj.clearAllProjections = _ol_proj$clearAllProjections;\nol.proj.clearUserProjection = _ol_proj$clearUserProjection;\nol.proj.cloneTransform = _ol_proj$cloneTransform;\nol.proj.createProjection = _ol_proj$createProjection;\nol.proj.createSafeCoordinateTransform = _ol_proj$createSafeCoordinateTransform;\nol.proj.createTransformFromCoordinateTransform = _ol_proj$createTransformFromCoordinateTransform;\nol.proj.disableCoordinateWarning = _ol_proj$disableCoordinateWarning;\nol.proj.epsg3857 = {};\nol.proj.epsg3857.EXTENT = _ol_proj_epsg3857$EXTENT;\nol.proj.epsg3857.HALF_SIZE = _ol_proj_epsg3857$HALF_SIZE;\nol.proj.epsg3857.MAX_SAFE_Y = _ol_proj_epsg3857$MAX_SAFE_Y;\nol.proj.epsg3857.PROJECTIONS = _ol_proj_epsg3857$PROJECTIONS;\nol.proj.epsg3857.RADIUS = _ol_proj_epsg3857$RADIUS;\nol.proj.epsg3857.WORLD_EXTENT = _ol_proj_epsg3857$WORLD_EXTENT;\nol.proj.epsg3857.fromEPSG4326 = _ol_proj_epsg3857$fromEPSG4326;\nol.proj.epsg3857.toEPSG4326 = _ol_proj_epsg3857$toEPSG4326;\nol.proj.epsg4326 = {};\nol.proj.epsg4326.EXTENT = _ol_proj_epsg4326$EXTENT;\nol.proj.epsg4326.METERS_PER_UNIT = _ol_proj_epsg4326$METERS_PER_UNIT;\nol.proj.epsg4326.PROJECTIONS = _ol_proj_epsg4326$PROJECTIONS;\nol.proj.epsg4326.RADIUS = _ol_proj_epsg4326$RADIUS;\nol.proj.equivalent = _ol_proj$equivalent;\nol.proj.fromLonLat = _ol_proj$fromLonLat;\nol.proj.fromUserCoordinate = _ol_proj$fromUserCoordinate;\nol.proj.fromUserExtent = _ol_proj$fromUserExtent;\nol.proj.fromUserResolution = _ol_proj$fromUserResolution;\nol.proj.get = _ol_proj$get;\nol.proj.getPointResolution = _ol_proj$getPointResolution;\nol.proj.getTransform = _ol_proj$getTransform;\nol.proj.getTransformFromProjections = _ol_proj$getTransformFromProjections;\nol.proj.getUserProjection = _ol_proj$getUserProjection;\nol.proj.identityTransform = _ol_proj$identityTransform;\nol.proj.proj4 = {};\nol.proj.proj4.register = _ol_proj_proj4$register;\nol.proj.projections = {};\nol.proj.projections.add = _ol_proj_projections$add;\nol.proj.projections.clear = _ol_proj_projections$clear;\nol.proj.projections.get = _ol_proj_projections$get;\nol.proj.setUserProjection = _ol_proj$setUserProjection;\nol.proj.toLonLat = _ol_proj$toLonLat;\nol.proj.toUserCoordinate = _ol_proj$toUserCoordinate;\nol.proj.toUserExtent = _ol_proj$toUserExtent;\nol.proj.toUserResolution = _ol_proj$toUserResolution;\nol.proj.transform = _ol_proj$transform;\nol.proj.transformExtent = _ol_proj$transformExtent;\nol.proj.transformWithProjections = _ol_proj$transformWithProjections;\nol.proj.transforms = {};\nol.proj.transforms.add = _ol_proj_transforms$add;\nol.proj.transforms.clear = _ol_proj_transforms$clear;\nol.proj.transforms.get = _ol_proj_transforms$get;\nol.proj.transforms.remove = _ol_proj_transforms$remove;\nol.proj.useGeographic = _ol_proj$useGeographic;\nol.render = {};\nol.render.Box = $ol$render$Box;\nol.render.Event = $ol$render$Event;\nol.render.Feature = $ol$render$Feature;\nol.render.Feature.toFeature = _ol_render_Feature$toFeature;\nol.render.Feature.toGeometry = _ol_render_Feature$toGeometry;\nol.render.VectorContext = $ol$render$VectorContext;\nol.render.canvas = {};\nol.render.canvas.Builder = $ol$render$canvas$Builder;\nol.render.canvas.BuilderGroup = $ol$render$canvas$BuilderGroup;\nol.render.canvas.Executor = $ol$render$canvas$Executor;\nol.render.canvas.ExecutorGroup = $ol$render$canvas$ExecutorGroup;\nol.render.canvas.ExecutorGroup.getPixelIndexArray = _ol_render_canvas_ExecutorGroup$getPixelIndexArray;\nol.render.canvas.ImageBuilder = $ol$render$canvas$ImageBuilder;\nol.render.canvas.Immediate = $ol$render$canvas$Immediate;\nol.render.canvas.Instruction = {};\nol.render.canvas.Instruction.beginPathInstruction = _ol_render_canvas_Instruction$beginPathInstruction;\nol.render.canvas.Instruction.closePathInstruction = _ol_render_canvas_Instruction$closePathInstruction;\nol.render.canvas.Instruction.fillInstruction = _ol_render_canvas_Instruction$fillInstruction;\nol.render.canvas.Instruction.strokeInstruction = _ol_render_canvas_Instruction$strokeInstruction;\nol.render.canvas.LineStringBuilder = $ol$render$canvas$LineStringBuilder;\nol.render.canvas.PolygonBuilder = $ol$render$canvas$PolygonBuilder;\nol.render.canvas.TextBuilder = $ol$render$canvas$TextBuilder;\nol.render.canvas.checkedFonts = _ol_render_canvas$checkedFonts;\nol.render.canvas.defaultFillStyle = _ol_render_canvas$defaultFillStyle;\nol.render.canvas.defaultFont = _ol_render_canvas$defaultFont;\nol.render.canvas.defaultLineCap = _ol_render_canvas$defaultLineCap;\nol.render.canvas.defaultLineDash = _ol_render_canvas$defaultLineDash;\nol.render.canvas.defaultLineDashOffset = _ol_render_canvas$defaultLineDashOffset;\nol.render.canvas.defaultLineJoin = _ol_render_canvas$defaultLineJoin;\nol.render.canvas.defaultLineWidth = _ol_render_canvas$defaultLineWidth;\nol.render.canvas.defaultMiterLimit = _ol_render_canvas$defaultMiterLimit;\nol.render.canvas.defaultPadding = _ol_render_canvas$defaultPadding;\nol.render.canvas.defaultStrokeStyle = _ol_render_canvas$defaultStrokeStyle;\nol.render.canvas.defaultTextAlign = _ol_render_canvas$defaultTextAlign;\nol.render.canvas.defaultTextBaseline = _ol_render_canvas$defaultTextBaseline;\nol.render.canvas.drawImageOrLabel = _ol_render_canvas$drawImageOrLabel;\nol.render.canvas.getTextDimensions = _ol_render_canvas$getTextDimensions;\nol.render.canvas.hitdetect = {};\nol.render.canvas.hitdetect.HIT_DETECT_RESOLUTION = _ol_render_canvas_hitdetect$HIT_DETECT_RESOLUTION;\nol.render.canvas.hitdetect.createHitDetectionImageData = _ol_render_canvas_hitdetect$createHitDetectionImageData;\nol.render.canvas.hitdetect.hitDetect = _ol_render_canvas_hitdetect$hitDetect;\nol.render.canvas.labelCache = _ol_render_canvas$labelCache;\nol.render.canvas.measureAndCacheTextWidth = _ol_render_canvas$measureAndCacheTextWidth;\nol.render.canvas.measureTextHeight = _ol_render_canvas$measureTextHeight;\nol.render.canvas.measureTextWidth = _ol_render_canvas$measureTextWidth;\nol.render.canvas.registerFont = _ol_render_canvas$registerFont;\nol.render.canvas.rotateAtOffset = _ol_render_canvas$rotateAtOffset;\nol.render.canvas.textHeights = _ol_render_canvas$textHeights;\nol.render.getRenderPixel = _ol_render$getRenderPixel;\nol.render.getVectorContext = _ol_render$getVectorContext;\nol.render.toContext = _ol_render$toContext;\nol.renderer = {};\nol.renderer.Composite = $ol$renderer$Composite;\nol.renderer.Layer = $ol$renderer$Layer;\nol.renderer.Map = $ol$renderer$Map;\nol.renderer.canvas = {};\nol.renderer.canvas.ImageLayer = $ol$renderer$canvas$ImageLayer;\nol.renderer.canvas.Layer = $ol$renderer$canvas$Layer;\nol.renderer.canvas.Layer.canvasPool = _ol_renderer_canvas_Layer$canvasPool;\nol.renderer.canvas.TileLayer = $ol$renderer$canvas$TileLayer;\nol.renderer.canvas.VectorImageLayer = $ol$renderer$canvas$VectorImageLayer;\nol.renderer.canvas.VectorLayer = $ol$renderer$canvas$VectorLayer;\nol.renderer.canvas.VectorTileLayer = $ol$renderer$canvas$VectorTileLayer;\nol.renderer.canvas.common = {};\nol.renderer.canvas.common.IMAGE_SMOOTHING_DISABLED = _ol_renderer_canvas_common$IMAGE_SMOOTHING_DISABLED;\nol.renderer.canvas.common.IMAGE_SMOOTHING_ENABLED = _ol_renderer_canvas_common$IMAGE_SMOOTHING_ENABLED;\nol.renderer.vector = {};\nol.renderer.vector.defaultOrder = _ol_renderer_vector$defaultOrder;\nol.renderer.vector.getSquaredTolerance = _ol_renderer_vector$getSquaredTolerance;\nol.renderer.vector.getTolerance = _ol_renderer_vector$getTolerance;\nol.renderer.vector.renderFeature = _ol_renderer_vector$renderFeature;\nol.renderer.webgl = {};\nol.renderer.webgl.Layer = $ol$renderer$webgl$Layer;\nol.renderer.webgl.Layer.colorDecodeId = _ol_renderer_webgl_Layer$colorDecodeId;\nol.renderer.webgl.Layer.colorEncodeId = _ol_renderer_webgl_Layer$colorEncodeId;\nol.renderer.webgl.Layer.getBlankImageData = _ol_renderer_webgl_Layer$getBlankImageData;\nol.renderer.webgl.Layer.writePointFeatureToBuffers = _ol_renderer_webgl_Layer$writePointFeatureToBuffers;\nol.renderer.webgl.PointsLayer = $ol$renderer$webgl$PointsLayer;\nol.renderer.webgl.TileLayer = $ol$renderer$webgl$TileLayer;\nol.renderer.webgl.TileLayer.Attributes = _ol_renderer_webgl_TileLayer$Attributes;\nol.renderer.webgl.TileLayer.Uniforms = _ol_renderer_webgl_TileLayer$Uniforms;\nol.reproj = {};\nol.reproj.Image = $ol$reproj$Image;\nol.reproj.Tile = $ol$reproj$Tile;\nol.reproj.Triangulation = $ol$reproj$Triangulation;\nol.reproj.calculateSourceExtentResolution = _ol_reproj$calculateSourceExtentResolution;\nol.reproj.calculateSourceResolution = _ol_reproj$calculateSourceResolution;\nol.reproj.canvasPool = _ol_reproj$canvasPool;\nol.reproj.common = {};\nol.reproj.common.ENABLE_RASTER_REPROJECTION = _ol_reproj_common$ENABLE_RASTER_REPROJECTION;\nol.reproj.common.ERROR_THRESHOLD = _ol_reproj_common$ERROR_THRESHOLD;\nol.reproj.render = _ol_reproj$render;\nol.resolutionconstraint = {};\nol.resolutionconstraint.createMinMaxResolution = _ol_resolutionconstraint$createMinMaxResolution;\nol.resolutionconstraint.createSnapToPower = _ol_resolutionconstraint$createSnapToPower;\nol.resolutionconstraint.createSnapToResolutions = _ol_resolutionconstraint$createSnapToResolutions;\nol.rotationconstraint = {};\nol.rotationconstraint.createSnapToN = _ol_rotationconstraint$createSnapToN;\nol.rotationconstraint.createSnapToZero = _ol_rotationconstraint$createSnapToZero;\nol.rotationconstraint.disable = _ol_rotationconstraint$disable;\nol.rotationconstraint.none = _ol_rotationconstraint$none;\nol.size = {};\nol.size.buffer = _ol_size$buffer;\nol.size.hasArea = _ol_size$hasArea;\nol.size.scale = _ol_size$scale;\nol.size.toSize = _ol_size$toSize;\nol.source = {};\nol.source.BingMaps = $ol$source$BingMaps;\nol.source.BingMaps.quadKey = _ol_source_BingMaps$quadKey;\nol.source.CartoDB = $ol$source$CartoDB;\nol.source.Cluster = $ol$source$Cluster;\nol.source.DataTile = $ol$source$DataTile;\nol.source.GeoTIFF = $ol$source$GeoTIFF;\nol.source.IIIF = $ol$source$IIIF;\nol.source.Image = $ol$source$Image;\nol.source.Image.ImageSourceEvent = _ol_source_Image$ImageSourceEvent;\nol.source.Image.defaultImageLoadFunction = _ol_source_Image$defaultImageLoadFunction;\nol.source.ImageArcGISRest = $ol$source$ImageArcGISRest;\nol.source.ImageCanvas = $ol$source$ImageCanvas;\nol.source.ImageMapGuide = $ol$source$ImageMapGuide;\nol.source.ImageStatic = $ol$source$ImageStatic;\nol.source.ImageWMS = $ol$source$ImageWMS;\nol.source.OGCMapTile = $ol$source$OGCMapTile;\nol.source.OGCVectorTile = $ol$source$OGCVectorTile;\nol.source.OSM = $ol$source$OSM;\nol.source.OSM.ATTRIBUTION = _ol_source_OSM$ATTRIBUTION;\nol.source.Raster = $ol$source$Raster;\nol.source.Raster.Processor = _ol_source_Raster$Processor;\nol.source.Raster.RasterSourceEvent = _ol_source_Raster$RasterSourceEvent;\nol.source.Raster.newImageData = _ol_source_Raster$newImageData;\nol.source.Source = $ol$source$Source;\nol.source.Stamen = $ol$source$Stamen;\nol.source.Tile = $ol$source$Tile;\nol.source.Tile.TileSourceEvent = _ol_source_Tile$TileSourceEvent;\nol.source.TileArcGISRest = $ol$source$TileArcGISRest;\nol.source.TileDebug = $ol$source$TileDebug;\nol.source.TileImage = $ol$source$TileImage;\nol.source.TileJSON = $ol$source$TileJSON;\nol.source.TileWMS = $ol$source$TileWMS;\nol.source.UTFGrid = $ol$source$UTFGrid;\nol.source.UTFGrid.CustomTile = _ol_source_UTFGrid$CustomTile;\nol.source.UrlTile = $ol$source$UrlTile;\nol.source.Vector = $ol$source$Vector;\nol.source.Vector.VectorSourceEvent = _ol_source_Vector$VectorSourceEvent;\nol.source.VectorTile = $ol$source$VectorTile;\nol.source.VectorTile.defaultLoadFunction = _ol_source_VectorTile$defaultLoadFunction;\nol.source.WMTS = $ol$source$WMTS;\nol.source.WMTS.optionsFromCapabilities = _ol_source_WMTS$optionsFromCapabilities;\nol.source.XYZ = $ol$source$XYZ;\nol.source.Zoomify = $ol$source$Zoomify;\nol.source.Zoomify.CustomTile = _ol_source_Zoomify$CustomTile;\nol.source.common = {};\nol.source.common.DEFAULT_WMS_VERSION = _ol_source_common$DEFAULT_WMS_VERSION;\nol.source.ogcTileUtil = {};\nol.source.ogcTileUtil.getMapTileUrlTemplate = _ol_source_ogcTileUtil$getMapTileUrlTemplate;\nol.source.ogcTileUtil.getTileSetInfo = _ol_source_ogcTileUtil$getTileSetInfo;\nol.source.ogcTileUtil.getVectorTileUrlTemplate = _ol_source_ogcTileUtil$getVectorTileUrlTemplate;\nol.source.sourcesFromTileGrid = _ol_source$sourcesFromTileGrid;\nol.source.wms = {};\nol.source.wms.DEFAULT_VERSION = _ol_source_wms$DEFAULT_VERSION;\nol.sphere = {};\nol.sphere.DEFAULT_RADIUS = _ol_sphere$DEFAULT_RADIUS;\nol.sphere.getArea = _ol_sphere$getArea;\nol.sphere.getDistance = _ol_sphere$getDistance;\nol.sphere.getLength = _ol_sphere$getLength;\nol.sphere.offset = _ol_sphere$offset;\nol.string = {};\nol.string.compareVersions = _ol_string$compareVersions;\nol.string.padNumber = _ol_string$padNumber;\nol.structs = {};\nol.structs.LRUCache = $ol$structs$LRUCache;\nol.structs.LinkedList = $ol$structs$LinkedList;\nol.structs.PriorityQueue = $ol$structs$PriorityQueue;\nol.structs.PriorityQueue.DROP = _ol_structs_PriorityQueue$DROP;\nol.structs.RBush = $ol$structs$RBush;\nol.style = {};\nol.style.Circle = $ol$style$Circle;\nol.style.Fill = $ol$style$Fill;\nol.style.Icon = $ol$style$Icon;\nol.style.IconImage = $ol$style$IconImage;\nol.style.IconImage.get = _ol_style_IconImage$get;\nol.style.IconImageCache = $ol$style$IconImageCache;\nol.style.IconImageCache.shared = _ol_style_IconImageCache$shared;\nol.style.Image = $ol$style$Image;\nol.style.RegularShape = $ol$style$RegularShape;\nol.style.Stroke = $ol$style$Stroke;\nol.style.Style = $ol$style$Style;\nol.style.Style.createDefaultStyle = _ol_style_Style$createDefaultStyle;\nol.style.Style.createEditingStyle = _ol_style_Style$createEditingStyle;\nol.style.Style.toFunction = _ol_style_Style$toFunction;\nol.style.Text = $ol$style$Text;\nol.style.expressions = {};\nol.style.expressions.Operators = _ol_style_expressions$Operators;\nol.style.expressions.PALETTE_TEXTURE_ARRAY = _ol_style_expressions$PALETTE_TEXTURE_ARRAY;\nol.style.expressions.arrayToGlsl = _ol_style_expressions$arrayToGlsl;\nol.style.expressions.colorToGlsl = _ol_style_expressions$colorToGlsl;\nol.style.expressions.expressionToGlsl = _ol_style_expressions$expressionToGlsl;\nol.style.expressions.getStringNumberEquivalent = _ol_style_expressions$getStringNumberEquivalent;\nol.style.expressions.getValueType = _ol_style_expressions$getValueType;\nol.style.expressions.isTypeUnique = _ol_style_expressions$isTypeUnique;\nol.style.expressions.numberToGlsl = _ol_style_expressions$numberToGlsl;\nol.style.expressions.stringToGlsl = _ol_style_expressions$stringToGlsl;\nol.style.expressions.uniformNameForVariable = _ol_style_expressions$uniformNameForVariable;\nol.tilecoord = {};\nol.tilecoord.createOrUpdate = _ol_tilecoord$createOrUpdate;\nol.tilecoord.fromKey = _ol_tilecoord$fromKey;\nol.tilecoord.getCacheKeyForTileKey = _ol_tilecoord$getCacheKeyForTileKey;\nol.tilecoord.getKey = _ol_tilecoord$getKey;\nol.tilecoord.getKeyZXY = _ol_tilecoord$getKeyZXY;\nol.tilecoord.hash = _ol_tilecoord$hash;\nol.tilecoord.withinExtentAndZ = _ol_tilecoord$withinExtentAndZ;\nol.tilegrid = {};\nol.tilegrid.TileGrid = $ol$tilegrid$TileGrid;\nol.tilegrid.WMTS = $ol$tilegrid$WMTS;\nol.tilegrid.WMTS.createFromCapabilitiesMatrixSet = _ol_tilegrid_WMTS$createFromCapabilitiesMatrixSet;\nol.tilegrid.common = {};\nol.tilegrid.common.DEFAULT_MAX_ZOOM = _ol_tilegrid_common$DEFAULT_MAX_ZOOM;\nol.tilegrid.common.DEFAULT_TILE_SIZE = _ol_tilegrid_common$DEFAULT_TILE_SIZE;\nol.tilegrid.createForExtent = _ol_tilegrid$createForExtent;\nol.tilegrid.createForProjection = _ol_tilegrid$createForProjection;\nol.tilegrid.createXYZ = _ol_tilegrid$createXYZ;\nol.tilegrid.extentFromProjection = _ol_tilegrid$extentFromProjection;\nol.tilegrid.getForProjection = _ol_tilegrid$getForProjection;\nol.tilegrid.wrapX = _ol_tilegrid$wrapX;\nol.tileurlfunction = {};\nol.tileurlfunction.createFromTemplate = _ol_tileurlfunction$createFromTemplate;\nol.tileurlfunction.createFromTemplates = _ol_tileurlfunction$createFromTemplates;\nol.tileurlfunction.createFromTileUrlFunctions = _ol_tileurlfunction$createFromTileUrlFunctions;\nol.tileurlfunction.expandUrl = _ol_tileurlfunction$expandUrl;\nol.tileurlfunction.nullTileUrlFunction = _ol_tileurlfunction$nullTileUrlFunction;\nol.transform = {};\nol.transform.apply = _ol_transform$apply;\nol.transform.compose = _ol_transform$compose;\nol.transform.composeCssTransform = _ol_transform$composeCssTransform;\nol.transform.create = _ol_transform$create;\nol.transform.determinant = _ol_transform$determinant;\nol.transform.invert = _ol_transform$invert;\nol.transform.makeInverse = _ol_transform$makeInverse;\nol.transform.makeScale = _ol_transform$makeScale;\nol.transform.multiply = _ol_transform$multiply;\nol.transform.reset = _ol_transform$reset;\nol.transform.rotate = _ol_transform$rotate;\nol.transform.scale = _ol_transform$scale;\nol.transform.set = _ol_transform$set;\nol.transform.setFromArray = _ol_transform$setFromArray;\nol.transform.toString = _ol_transform$toString;\nol.transform.translate = _ol_transform$translate;\nol.uri = {};\nol.uri.appendParams = _ol_uri$appendParams;\nol.util = {};\nol.util.VERSION = _ol_util$VERSION;\nol.util.abstract = _ol_util$abstract;\nol.util.getUid = _ol_util$getUid;\nol.vec = {};\nol.vec.mat4 = {};\nol.vec.mat4.create = _ol_vec_mat4$create;\nol.vec.mat4.fromTransform = _ol_vec_mat4$fromTransform;\nol.webgl = {};\nol.webgl.ARRAY_BUFFER = _ol_webgl$ARRAY_BUFFER;\nol.webgl.Buffer = $ol$webgl$Buffer;\nol.webgl.Buffer.getArrayClassForType = _ol_webgl_Buffer$getArrayClassForType;\nol.webgl.DYNAMIC_DRAW = _ol_webgl$DYNAMIC_DRAW;\nol.webgl.ELEMENT_ARRAY_BUFFER = _ol_webgl$ELEMENT_ARRAY_BUFFER;\nol.webgl.FLOAT = _ol_webgl$FLOAT;\nol.webgl.Helper = $ol$webgl$Helper;\nol.webgl.Helper.computeAttributesStride = _ol_webgl_Helper$computeAttributesStride;\nol.webgl.PaletteTexture = $ol$webgl$PaletteTexture;\nol.webgl.PostProcessingPass = $ol$webgl$PostProcessingPass;\nol.webgl.RenderTarget = $ol$webgl$RenderTarget;\nol.webgl.STATIC_DRAW = _ol_webgl$STATIC_DRAW;\nol.webgl.STREAM_DRAW = _ol_webgl$STREAM_DRAW;\nol.webgl.ShaderBuilder = {};\nol.webgl.ShaderBuilder.ShaderBuilder = _ol_webgl_ShaderBuilder$ShaderBuilder;\nol.webgl.ShaderBuilder.parseLiteralStyle = _ol_webgl_ShaderBuilder$parseLiteralStyle;\nol.webgl.TileTexture = $ol$webgl$TileTexture;\nol.webgl.UNSIGNED_BYTE = _ol_webgl$UNSIGNED_BYTE;\nol.webgl.UNSIGNED_INT = _ol_webgl$UNSIGNED_INT;\nol.webgl.UNSIGNED_SHORT = _ol_webgl$UNSIGNED_SHORT;\nol.webgl.getContext = _ol_webgl$getContext;\nol.webgl.getSupportedExtensions = _ol_webgl$getSupportedExtensions;\nol.xml = {};\nol.xml.OBJECT_PROPERTY_NODE_FACTORY = _ol_xml$OBJECT_PROPERTY_NODE_FACTORY;\nol.xml.XML_SCHEMA_INSTANCE_URI = _ol_xml$XML_SCHEMA_INSTANCE_URI;\nol.xml.createElementNS = _ol_xml$createElementNS;\nol.xml.getAllTextContent = _ol_xml$getAllTextContent;\nol.xml.getAllTextContent_ = _ol_xml$getAllTextContent_;\nol.xml.getAttributeNS = _ol_xml$getAttributeNS;\nol.xml.getDocument = _ol_xml$getDocument;\nol.xml.getXMLSerializer = _ol_xml$getXMLSerializer;\nol.xml.isDocument = _ol_xml$isDocument;\nol.xml.makeArrayExtender = _ol_xml$makeArrayExtender;\nol.xml.makeArrayPusher = _ol_xml$makeArrayPusher;\nol.xml.makeArraySerializer = _ol_xml$makeArraySerializer;\nol.xml.makeChildAppender = _ol_xml$makeChildAppender;\nol.xml.makeObjectPropertyPusher = _ol_xml$makeObjectPropertyPusher;\nol.xml.makeObjectPropertySetter = _ol_xml$makeObjectPropertySetter;\nol.xml.makeReplacer = _ol_xml$makeReplacer;\nol.xml.makeSequence = _ol_xml$makeSequence;\nol.xml.makeSimpleNodeFactory = _ol_xml$makeSimpleNodeFactory;\nol.xml.makeStructureNS = _ol_xml$makeStructureNS;\nol.xml.parse = _ol_xml$parse;\nol.xml.parseNode = _ol_xml$parseNode;\nol.xml.pushParseAndPop = _ol_xml$pushParseAndPop;\nol.xml.pushSerializeAndPop = _ol_xml$pushSerializeAndPop;\nol.xml.registerDocument = _ol_xml$registerDocument;\nol.xml.registerXMLSerializer = _ol_xml$registerXMLSerializer;\nol.xml.serialize = _ol_xml$serialize;\n\nexport default ol;",null,null,null,"export const fieldTagNames = {\n // TIFF Baseline\n 0x013B: 'Artist',\n 0x0102: 'BitsPerSample',\n 0x0109: 'CellLength',\n 0x0108: 'CellWidth',\n 0x0140: 'ColorMap',\n 0x0103: 'Compression',\n 0x8298: 'Copyright',\n 0x0132: 'DateTime',\n 0x0152: 'ExtraSamples',\n 0x010A: 'FillOrder',\n 0x0121: 'FreeByteCounts',\n 0x0120: 'FreeOffsets',\n 0x0123: 'GrayResponseCurve',\n 0x0122: 'GrayResponseUnit',\n 0x013C: 'HostComputer',\n 0x010E: 'ImageDescription',\n 0x0101: 'ImageLength',\n 0x0100: 'ImageWidth',\n 0x010F: 'Make',\n 0x0119: 'MaxSampleValue',\n 0x0118: 'MinSampleValue',\n 0x0110: 'Model',\n 0x00FE: 'NewSubfileType',\n 0x0112: 'Orientation',\n 0x0106: 'PhotometricInterpretation',\n 0x011C: 'PlanarConfiguration',\n 0x0128: 'ResolutionUnit',\n 0x0116: 'RowsPerStrip',\n 0x0115: 'SamplesPerPixel',\n 0x0131: 'Software',\n 0x0117: 'StripByteCounts',\n 0x0111: 'StripOffsets',\n 0x00FF: 'SubfileType',\n 0x0107: 'Threshholding',\n 0x011A: 'XResolution',\n 0x011B: 'YResolution',\n\n // TIFF Extended\n 0x0146: 'BadFaxLines',\n 0x0147: 'CleanFaxData',\n 0x0157: 'ClipPath',\n 0x0148: 'ConsecutiveBadFaxLines',\n 0x01B1: 'Decode',\n 0x01B2: 'DefaultImageColor',\n 0x010D: 'DocumentName',\n 0x0150: 'DotRange',\n 0x0141: 'HalftoneHints',\n 0x015A: 'Indexed',\n 0x015B: 'JPEGTables',\n 0x011D: 'PageName',\n 0x0129: 'PageNumber',\n 0x013D: 'Predictor',\n 0x013F: 'PrimaryChromaticities',\n 0x0214: 'ReferenceBlackWhite',\n 0x0153: 'SampleFormat',\n 0x0154: 'SMinSampleValue',\n 0x0155: 'SMaxSampleValue',\n 0x022F: 'StripRowCounts',\n 0x014A: 'SubIFDs',\n 0x0124: 'T4Options',\n 0x0125: 'T6Options',\n 0x0145: 'TileByteCounts',\n 0x0143: 'TileLength',\n 0x0144: 'TileOffsets',\n 0x0142: 'TileWidth',\n 0x012D: 'TransferFunction',\n 0x013E: 'WhitePoint',\n 0x0158: 'XClipPathUnits',\n 0x011E: 'XPosition',\n 0x0211: 'YCbCrCoefficients',\n 0x0213: 'YCbCrPositioning',\n 0x0212: 'YCbCrSubSampling',\n 0x0159: 'YClipPathUnits',\n 0x011F: 'YPosition',\n\n // EXIF\n 0x9202: 'ApertureValue',\n 0xA001: 'ColorSpace',\n 0x9004: 'DateTimeDigitized',\n 0x9003: 'DateTimeOriginal',\n 0x8769: 'Exif IFD',\n 0x9000: 'ExifVersion',\n 0x829A: 'ExposureTime',\n 0xA300: 'FileSource',\n 0x9209: 'Flash',\n 0xA000: 'FlashpixVersion',\n 0x829D: 'FNumber',\n 0xA420: 'ImageUniqueID',\n 0x9208: 'LightSource',\n 0x927C: 'MakerNote',\n 0x9201: 'ShutterSpeedValue',\n 0x9286: 'UserComment',\n\n // IPTC\n 0x83BB: 'IPTC',\n\n // ICC\n 0x8773: 'ICC Profile',\n\n // XMP\n 0x02BC: 'XMP',\n\n // GDAL\n 0xA480: 'GDAL_METADATA',\n 0xA481: 'GDAL_NODATA',\n\n // Photoshop\n 0x8649: 'Photoshop',\n\n // GeoTiff\n 0x830E: 'ModelPixelScale',\n 0x8482: 'ModelTiepoint',\n 0x85D8: 'ModelTransformation',\n 0x87AF: 'GeoKeyDirectory',\n 0x87B0: 'GeoDoubleParams',\n 0x87B1: 'GeoAsciiParams',\n\n // LERC\n 0xC5F2: 'LercParameters',\n};\n\nexport const fieldTags = {};\nfor (const key in fieldTagNames) {\n if (fieldTagNames.hasOwnProperty(key)) {\n fieldTags[fieldTagNames[key]] = parseInt(key, 10);\n }\n}\n\nexport const fieldTagTypes = {\n 256: 'SHORT',\n 257: 'SHORT',\n 258: 'SHORT',\n 259: 'SHORT',\n 262: 'SHORT',\n 273: 'LONG',\n 274: 'SHORT',\n 277: 'SHORT',\n 278: 'LONG',\n 279: 'LONG',\n 282: 'RATIONAL',\n 283: 'RATIONAL',\n 284: 'SHORT',\n 286: 'SHORT',\n 287: 'RATIONAL',\n 296: 'SHORT',\n 297: 'SHORT',\n 305: 'ASCII',\n 306: 'ASCII',\n 338: 'SHORT',\n 339: 'SHORT',\n 513: 'LONG',\n 514: 'LONG',\n 1024: 'SHORT',\n 1025: 'SHORT',\n 2048: 'SHORT',\n 2049: 'ASCII',\n 3072: 'SHORT',\n 3073: 'ASCII',\n 33550: 'DOUBLE',\n 33922: 'DOUBLE',\n 34665: 'LONG',\n 34735: 'SHORT',\n 34737: 'ASCII',\n 42113: 'ASCII',\n};\n\nexport const arrayFields = [\n fieldTags.BitsPerSample,\n fieldTags.ExtraSamples,\n fieldTags.SampleFormat,\n fieldTags.StripByteCounts,\n fieldTags.StripOffsets,\n fieldTags.StripRowCounts,\n fieldTags.TileByteCounts,\n fieldTags.TileOffsets,\n fieldTags.SubIFDs,\n];\n\nexport const fieldTypeNames = {\n 0x0001: 'BYTE',\n 0x0002: 'ASCII',\n 0x0003: 'SHORT',\n 0x0004: 'LONG',\n 0x0005: 'RATIONAL',\n 0x0006: 'SBYTE',\n 0x0007: 'UNDEFINED',\n 0x0008: 'SSHORT',\n 0x0009: 'SLONG',\n 0x000A: 'SRATIONAL',\n 0x000B: 'FLOAT',\n 0x000C: 'DOUBLE',\n // IFD offset, suggested by https://owl.phy.queensu.ca/~phil/exiftool/standards.html\n 0x000D: 'IFD',\n // introduced by BigTIFF\n 0x0010: 'LONG8',\n 0x0011: 'SLONG8',\n 0x0012: 'IFD8',\n};\n\nexport const fieldTypes = {};\nfor (const key in fieldTypeNames) {\n if (fieldTypeNames.hasOwnProperty(key)) {\n fieldTypes[fieldTypeNames[key]] = parseInt(key, 10);\n }\n}\n\nexport const photometricInterpretations = {\n WhiteIsZero: 0,\n BlackIsZero: 1,\n RGB: 2,\n Palette: 3,\n TransparencyMask: 4,\n CMYK: 5,\n YCbCr: 6,\n\n CIELab: 8,\n ICCLab: 9,\n};\n\nexport const ExtraSamplesValues = {\n Unspecified: 0,\n Assocalpha: 1,\n Unassalpha: 2,\n};\n\nexport const LercParameters = {\n Version: 0,\n AddCompression: 1,\n};\n\nexport const LercAddCompression = {\n None: 0,\n Deflate: 1,\n};\n\nexport const geoKeyNames = {\n 1024: 'GTModelTypeGeoKey',\n 1025: 'GTRasterTypeGeoKey',\n 1026: 'GTCitationGeoKey',\n 2048: 'GeographicTypeGeoKey',\n 2049: 'GeogCitationGeoKey',\n 2050: 'GeogGeodeticDatumGeoKey',\n 2051: 'GeogPrimeMeridianGeoKey',\n 2052: 'GeogLinearUnitsGeoKey',\n 2053: 'GeogLinearUnitSizeGeoKey',\n 2054: 'GeogAngularUnitsGeoKey',\n 2055: 'GeogAngularUnitSizeGeoKey',\n 2056: 'GeogEllipsoidGeoKey',\n 2057: 'GeogSemiMajorAxisGeoKey',\n 2058: 'GeogSemiMinorAxisGeoKey',\n 2059: 'GeogInvFlatteningGeoKey',\n 2060: 'GeogAzimuthUnitsGeoKey',\n 2061: 'GeogPrimeMeridianLongGeoKey',\n 2062: 'GeogTOWGS84GeoKey',\n 3072: 'ProjectedCSTypeGeoKey',\n 3073: 'PCSCitationGeoKey',\n 3074: 'ProjectionGeoKey',\n 3075: 'ProjCoordTransGeoKey',\n 3076: 'ProjLinearUnitsGeoKey',\n 3077: 'ProjLinearUnitSizeGeoKey',\n 3078: 'ProjStdParallel1GeoKey',\n 3079: 'ProjStdParallel2GeoKey',\n 3080: 'ProjNatOriginLongGeoKey',\n 3081: 'ProjNatOriginLatGeoKey',\n 3082: 'ProjFalseEastingGeoKey',\n 3083: 'ProjFalseNorthingGeoKey',\n 3084: 'ProjFalseOriginLongGeoKey',\n 3085: 'ProjFalseOriginLatGeoKey',\n 3086: 'ProjFalseOriginEastingGeoKey',\n 3087: 'ProjFalseOriginNorthingGeoKey',\n 3088: 'ProjCenterLongGeoKey',\n 3089: 'ProjCenterLatGeoKey',\n 3090: 'ProjCenterEastingGeoKey',\n 3091: 'ProjCenterNorthingGeoKey',\n 3092: 'ProjScaleAtNatOriginGeoKey',\n 3093: 'ProjScaleAtCenterGeoKey',\n 3094: 'ProjAzimuthAngleGeoKey',\n 3095: 'ProjStraightVertPoleLongGeoKey',\n 3096: 'ProjRectifiedGridAngleGeoKey',\n 4096: 'VerticalCSTypeGeoKey',\n 4097: 'VerticalCitationGeoKey',\n 4098: 'VerticalDatumGeoKey',\n 4099: 'VerticalUnitsGeoKey',\n};\n\nexport const geoKeys = {};\nfor (const key in geoKeyNames) {\n if (geoKeyNames.hasOwnProperty(key)) {\n geoKeys[geoKeyNames[key]] = parseInt(key, 10);\n }\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = function(chunkId) {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce(function(promises, key) {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks\n__webpack_require__.u = function(chunkId) {\n\t// return url for filenames based on template\n\treturn \"\" + chunkId + \".ol.js\";\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","var scriptUrl;\nif (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + \"\";\nvar document = __webpack_require__.g.document;\nif (!scriptUrl && document) {\n\tif (document.currentScript)\n\t\tscriptUrl = document.currentScript.src\n\tif (!scriptUrl) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tif(scripts.length) scriptUrl = scripts[scripts.length - 1].src\n\t}\n}\n// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration\n// or pass an empty string (\"\") and set the __webpack_public_path__ variable from your code to use your own logic.\nif (!scriptUrl) throw new Error(\"Automatic publicPath is not supported in this browser\");\nscriptUrl = scriptUrl.replace(/#.*$/, \"\").replace(/\\?.*$/, \"\").replace(/\\/[^\\/]+$/, \"/\");\n__webpack_require__.p = scriptUrl;","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t179: 0\n};\n\n__webpack_require__.f.j = function(chunkId, promises) {\n\t\t// JSONP chunk loading for javascript\n\t\tvar installedChunkData = __webpack_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined;\n\t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n\t\t\t// a Promise means \"currently loading\".\n\t\t\tif(installedChunkData) {\n\t\t\t\tpromises.push(installedChunkData[2]);\n\t\t\t} else {\n\t\t\t\tif(true) { // all chunks have JS\n\t\t\t\t\t// setup Promise in chunk cache\n\t\t\t\t\tvar promise = new Promise(function(resolve, reject) { installedChunkData = installedChunks[chunkId] = [resolve, reject]; });\n\t\t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n\t\t\t\t\t// start chunk loading\n\t\t\t\t\tvar url = __webpack_require__.p + __webpack_require__.u(chunkId);\n\t\t\t\t\t// create error before stack unwound to get useful stacktrace later\n\t\t\t\t\tvar error = new Error();\n\t\t\t\t\tvar loadingEnded = function(event) {\n\t\t\t\t\t\tif(__webpack_require__.o(installedChunks, chunkId)) {\n\t\t\t\t\t\t\tinstalledChunkData = installedChunks[chunkId];\n\t\t\t\t\t\t\tif(installedChunkData !== 0) installedChunks[chunkId] = undefined;\n\t\t\t\t\t\t\tif(installedChunkData) {\n\t\t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n\t\t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n\t\t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n\t\t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n\t\t\t\t\t\t\t\terror.type = errorType;\n\t\t\t\t\t\t\t\terror.request = realSrc;\n\t\t\t\t\t\t\t\tinstalledChunkData[1](error);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\t__webpack_require__.l(url, loadingEnded, \"chunk-\" + chunkId, chunkId);\n\t\t\t\t} else installedChunks[chunkId] = 0;\n\t\t\t}\n\t\t}\n};\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n// no on chunks loaded\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkol\"] = self[\"webpackChunkol\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module is referenced by other modules so it can't be inlined\n__webpack_require__(760);\nvar __webpack_exports__ = __webpack_require__(429);\n"],"names":["root","factory","exports","module","define","amd","self","inProgress","read","buffer","offset","isLE","mLen","nBytes","e","m","eLen","eMax","eBias","nBits","i","d","s","NaN","Infinity","Math","pow","write","value","c","rt","abs","isNaN","floor","log","LN2","Yallist","require","MAX","Symbol","LENGTH","LENGTH_CALCULATOR","ALLOW_STALE","MAX_AGE","DISPOSE","NO_DISPOSE_ON_SET","LRU_LIST","CACHE","UPDATE_AGE_ON_GET","naiveLength","get","key","doUse","node","hit","isStale","del","now","Date","unshiftNode","maxAge","diff","trim","walker","tail","prev","length","delete","removeNode","Entry","constructor","this","forEachStep","fn","thisp","undefined","call","options","max","TypeError","lc","stale","dispose","noDisposeOnSet","updateAgeOnGet","reset","mL","allowStale","mA","lC","forEach","rforEach","head","next","keys","toArray","map","k","values","Map","dump","v","filter","h","dumpLru","set","len","has","item","unshift","peek","pop","load","arr","l","expiresAt","prune","Pbf","ieee754","buf","ArrayBuffer","isView","Uint8Array","pos","type","Varint","Fixed64","Bytes","Fixed32","SHIFT_LEFT_32","SHIFT_RIGHT_32","utf8TextDecoder","TextDecoder","readPackedEnd","pbf","readVarint","toNum","low","high","isSigned","makeRoomForExtraLength","startPos","extraLen","realloc","writePackedVarint","writeVarint","writePackedSVarint","writeSVarint","writePackedFloat","writeFloat","writePackedDouble","writeDouble","writePackedBoolean","writeBoolean","writePackedFixed32","writeFixed32","writePackedSFixed32","writeSFixed32","writePackedFixed64","writeFixed64","writePackedSFixed64","writeSFixed64","readUInt32","writeInt32","val","readInt32","prototype","destroy","readFields","readField","result","end","tag","skip","readMessage","readFixed32","readSFixed32","readFixed64","readSFixed64","readFloat","readDouble","b","p","Error","readVarintRemainder","readVarint64","readSVarint","num","readBoolean","Boolean","readString","decode","subarray","readUtf8TextDecoder","str","b1","b2","b3","b0","bytesPerSequence","String","fromCharCode","readUtf8","readBytes","readPackedVarint","push","readPackedSVarint","readPackedBoolean","readPackedFloat","readPackedDouble","readPackedFixed32","readPackedSFixed32","readPackedFixed64","readPackedSFixed64","writeTag","min","finish","writeBigVarintLow","lsb","writeBigVarintHigh","writeBigVarint","writeString","lead","charCodeAt","writeUtf8","writeBytes","writeRawMessage","obj","writeMessage","writeBytesField","writeFixed32Field","writeSFixed32Field","writeFixed64Field","writeSFixed64Field","writeVarintField","writeSVarintField","writeStringField","writeFloatField","writeDoubleField","writeBooleanField","t","r","a","n","o","f","exp","u","sqrt","x","_maxEntries","_minEntries","ceil","clear","indexOf","children","minX","minY","maxX","maxY","leaf","height","all","_all","data","search","toBBox","collides","insert","_build","slice","_splitRoot","_insert","remove","splice","_condense","compareMinX","compareMinY","toJSON","fromJSON","apply","_chooseSubtree","_split","_adjustParentBBoxes","_chooseSplitAxis","_chooseSplitIndex","M","_allDistMargin","sort","runtime","Op","Object","hasOwn","hasOwnProperty","$Symbol","iteratorSymbol","iterator","asyncIteratorSymbol","asyncIterator","toStringTagSymbol","toStringTag","defineProperty","enumerable","configurable","writable","err","wrap","innerFn","outerFn","tryLocsList","protoGenerator","Generator","generator","create","context","Context","_invoke","state","GenStateSuspendedStart","method","arg","GenStateExecuting","GenStateCompleted","doneResult","delegate","delegateResult","maybeInvokeDelegate","ContinueSentinel","sent","_sent","dispatchException","abrupt","record","tryCatch","done","GenStateSuspendedYield","makeInvokeMethod","GeneratorFunction","GeneratorFunctionPrototype","IteratorPrototype","getProto","getPrototypeOf","NativeIteratorPrototype","Gp","defineIteratorMethods","AsyncIterator","PromiseImpl","invoke","resolve","reject","__await","then","unwrapped","error","previousPromise","callInvokeWithMethodAndArg","info","resultName","nextLoc","pushTryEntry","locs","entry","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","resetTryEntry","completion","iterable","iteratorMethod","displayName","isGeneratorFunction","genFun","ctor","name","mark","setPrototypeOf","__proto__","awrap","async","Promise","iter","object","reverse","skipTempReset","charAt","stop","rootRecord","rval","exception","handle","loc","caught","hasCatch","hasFinally","finallyEntry","complete","thrown","delegateYield","regeneratorRuntime","accidentalStrictMode","globalThis","Function","indexOfMatch","xml","tagName","debug","startIndex","console","start","afterStart","relativeEnd","selfClosing","outer","inner","lastIndexOf","findTagByName","tags","attributeName","pattern","match","RegExp","exec","index","list","arguments","inserted","Node","pushNode","res","shift","forEachReverse","getReverse","mapReverse","reduce","initial","acc","reduceReverse","Array","toArrayReverse","from","to","ret","sliceReverse","deleteCount","er","abstract","uidCounter_","getUid","ol_uid","VERSION","code","message","_super","_this","__extends","stopPropagation","evt","propagationStopped","defaultPrevented","target","BaseEvent","disposed","Disposable","disposeInternal","binarySearch","haystack","needle","opt_comparator","mid","cmp","comparator","numberSafeCompareFunction","found","includes","linearFindNearest","direction","reverseSubArray","begin","tmp","extend","extension","isArray","find","func","equals","arr1","arr2","len1","findIndex","every","el","idx","isSorted","opt_func","opt_strict","compare","currentVal","TRUE","FALSE","VOID","memoizeOne","lastResult","lastArgs","lastThis","called","nextArgs","arrayEquals","toPromise","getter","promiseGetter","assign","var_sources","output","ii","source","property","getValues","isEmpty","opt_target","eventTarget_","pendingRemovals_","dispatching_","listeners_","Target","listener","listeners","listenersForType","event","isString","Event","propagate","dispatching","pendingRemovals","handleEvent","pr","removeEventListener","opt_type","listen","opt_this","opt_once","bind","originalListener_1","eventsKey","addEventListener","listenOnce","unlistenByKey","on","onInternal","once","onceInternal","un","unInternal","revision_","Observable","dispatchEvent","EventType","ol_key","unByKey","EventTarget","oldValue","opt_values","values_","setProperties","BaseObject","eventType","hasListener","ObjectEvent","ObjectEventType","opt_silent","notify","Property","opt_element","opt_index","element","opt_array","opt_options","unique_","unique","array_","assertUnique_","updateLength_","Collection","getLength","array","elem","CollectionEvent","CollectionEventType","removeAt","insertAt","j","opt_except","AssertionError","easeIn","easeOut","inAndOut","linear","tileCoord","interimTile","transition_","transition","transitionStarts_","interpolate","Tile","tile","getState","TileState","changed","id","time","delta","loader_","loader","data_","error_","size_","size","DataTile","catch","assert","assertion","errorCode","createStyleFunction","styles_1","getZIndex","opt_geometryOrProperties","id_","geometryName_","style_","styleFunction_","geometryChangeKey_","addChangeListener","handleGeometryChanged_","getSimplifiedGeometry","geometry","setGeometry","properties","Feature","clone","hasProperties","getProperties","setGeometryName","getGeometryName","getGeometry","style","getStyle","setStyle","handleGeometryChange_","opt_style","removeChangeListener","Units","RADIANS","DEGREES","FEET","METERS","PIXELS","TILE_PIXELS","USFEET","unitByCode","fromCode","METERS_PER_UNIT","PI","transformStringDiv","ua","navigator","userAgent","toLowerCase","FIREFOX","SAFARI","SAFARI_BUG_237906","WEBKIT","MAC","DEVICE_PIXEL_RATIO","devicePixelRatio","WORKER_OFFSCREEN_CANVAS","WorkerGlobalScope","OffscreenCanvas","IMAGE_DECODE","Image","PASSIVE_EVENT_LISTENERS","passive","window","tmp_","transform","multiply","transform1","transform2","a1","c1","d1","e1","f1","a2","c2","d2","e2","f2","setFromArray","coordinate","y","rotate","angle","cos","sin","scale","makeScale","translate","dx","dy","compose","dx1","dy1","sx","sy","dx2","dy2","makeInverse","det","determinant","mat","toString","transformString","join","document","createElement","boundingExtent","coordinates","extent","createEmpty","extendCoordinate","opt_extent","closestSquaredDistanceXY","containsCoordinate","containsXY","containsExtent","extent1","extent2","coordinateRelationship","relationship","Relationship","createOrUpdate","createOrUpdateEmpty","createOrUpdateFromCoordinate","createOrUpdateFromFlatCoordinates","flatCoordinates","stride","extendFlatCoordinates","approximatelyEquals","tolerance","extendCoordinates","extendXY","extendRings","rings","forEachCorner","callback","getBottomLeft","getBottomRight","getTopRight","getTopLeft","getArea","area","getWidth","getHeight","getCenter","getCorner","corner","getForViewAndSize","center","resolution","rotation","getRotatedViewport","x0","y0","x1","y1","x2","y2","x3","y3","cosRotation","sinRotation","xCos","xSin","yCos","ySin","getIntersection","intersection","intersects","returnOrUpdate","scaleFromCenter","deltaX","deltaY","intersectsSegment","startRel","endRel","startX","startY","endX","endY","slope","applyTransform","transformFn","opt_stops","width","xs","ys","_boundingExtentXYs","wrapX","projection","projectionExtent","getExtent","canWrapX","worldWidth","wrapAndSliceX","isFinite","code_","units_","units","extent_","worldExtent_","worldExtent","axisOrientation_","axisOrientation","global_","global","canWrapX_","getPointResolutionFunc_","getPointResolution","defaultTileGrid_","metersPerUnit_","metersPerUnit","Projection","tileGrid","clamp","cosh","log2","LOG2E","squaredSegmentDistance","squaredDistance","solveLinearSystem","maxRow","maxEl","absValue","coef","toDegrees","angleInRadians","toRadians","angleInDegrees","modulo","lerp","toFixed","decimals","factor","round","RADIUS","HALF_SIZE","EXTENT","WORLD_EXTENT","MAX_SAFE_Y","tan","point","PROJECTIONS","EPSG3857Projection","fromEPSG4326","input","opt_output","opt_dimension","dimension","toEPSG4326","atan","opt_axisOrientation","EPSG4326Projection","cache","replace","add","transforms","destination","sourceCode","getCode","destinationCode","padNumber","number","opt_precision","numberString","decimal","compareVersions","v1","v2","s1","split","s2","n1","parseInt","n2","closestOnCircle","circle","getRadius","closestOnSegment","segment","along","degreesToStringHDMS","hemispheres","degrees","opt_fractionDigits","normalizedDegrees","dflPrecision","precision","deg","sec","format","template","coordinate1","coordinate2","cosAngle","sinAngle","coord1","coord2","distance","squaredDistanceToSegment","toStringXY","worldsAway","getWorldsAway","opt_sourceExtentWidth","sourceExtentWidth","DEFAULT_RADIUS","getDistance","opt_radius","radius","lat1","lat2","deltaLatBy2","deltaLonBy2","atan2","getLengthInternal","getAreaInternal","bearing","lon1","dByR","lat","asin","showCoordinateWarning","disableCoordinateWarning","opt_disable","cloneTransform","identityTransform","addProjection","addProj","addTransformFunc","addProjections","projections","projectionLike","getProj","opt_units","pointResolution","getPointResolutionFunc","getUnits","getMetersPerUnit","toEPSG4326_1","getTransformFromProjections","vertices","addEquivalentProjections","addEquivalentTransforms","projections1","projections2","forwardTransform","inverseTransform","projection1","projection2","createProjection","defaultCode","createTransformFromCoordinateTransform","coordTransform","pointLength","jj","addCoordinateTransforms","forward","inverse","sourceProj","destProj","fromLonLat","opt_projection","equivalent","equalUnits","sourceProjection","destinationProjection","transformFunc","getTransformFunc","getTransform","transformExtent","userProjection","setUserProjection","getUserProjection","toUserCoordinate","fromUserCoordinate","destProjection","warn","toUserExtent","fromUserExtent","toUserResolution","sourceUnits","userUnits","fromUserResolution","createSafeCoordinateTransform","coord","transformed","sourceExtent","addCommon","EPSG3857_PROJECTIONS","EPSG4326_PROJECTIONS","transform2D","opt_dest","dest","anchor","anchorX","anchorY","tmpTransform","extentRevision_","simplifiedGeometryMaxMinSquaredTolerance","simplifiedGeometryRevision","simplifyTransformedInternal","revision","squaredTolerance","opt_transform","Geometry","getRevision","closestPoint","minSquaredDistance","getClosestPoint","opt_closestPoint","closestPointXY","computeExtent","opt_sy","opt_anchor","getProjection","inCoordinates","outCoordinates","pixelExtent","projectedExtent","getWorldExtent","composeTransform","getStrideForLayout","layout","GeometryLayout","transformGeom2D","simpleGeometry","getFlatCoordinates","getStride","SimpleGeometry","simplifiedGeometry","getSimplifiedGeometryInternal","opt_layout","nesting","getLayoutForStride","assignClosest","offset1","offset2","maxSquaredDelta","squaredDelta","squaredDx","arrayMaxSquaredDelta","ends","multiArrayMaxSquaredDelta","endss","assignClosestPoint","maxDelta","isRing","opt_tmpPoint","tmpPoint","assignClosestArrayPoint","assignClosestMultiArrayPoint","deflateCoordinate","deflateCoordinates","deflateCoordinatesArray","coordinatess","opt_ends","deflateMultiCoordinatesArray","coordinatesss","opt_endss","douglasPeucker","simplifiedFlatCoordinates","simplifiedOffset","markers","stack","last","first","maxSquaredDistance","squaredDistance_1","douglasPeuckerArray","simplifiedEnds","radialDistance","snap","quantize","quantizeArray","quantizeMultiArray","simplifiedEndss","inflateCoordinates","opt_coordinates","inflateCoordinatesArray","opt_coordinatess","inflateMultiCoordinatesArray","opt_coordinatesss","linearRing","twiceArea","linearRings","linearRingss","maxDelta_","maxDeltaRevision_","setCoordinates","setFlatCoordinates","LinearRing","linearRingArea","setLayout","Point","applyProperties","linearRingContainsExtent","linearRingContainsXY","wn","linearRingsContainsXY","linearRingssContainsXY","getInteriorPointOfArray","flatCenters","flatCentersOffset","intersections","rr","pointX","maxSegmentLength","segmentLength","getInteriorPointsOfMultiArray","interiorPoints","intersectsLineString","coordinatesExtent","forEachSegment","point1","point2","intersectsLineStringArray","intersectsLinearRing","intersectsLinearRingArray","intersectsLinearRingMultiArray","linearRingIsClockwise","edge","linearRingsAreOriented","opt_right","right","isClockwise","linearRingssAreOriented","orientLinearRings","reverseCoordinates","orientLinearRingsArray","inflateEnds","prevEndIndex","ends_","flatInteriorPointRevision_","flatInteriorPoint_","orientedRevision_","orientedFlatCoordinates_","Polygon","polygon","getOrientedFlatCoordinates","linearRingsArea","flatCenter","getFlatInteriorPoint","circular","opt_n","opt_sphereRadius","sphereOffset","fromExtent","fromCircle","opt_sides","opt_angle","sides","getLayout","arrayLength","makeRegular","startAngle","position_","transform_","watchId_","handleProjectionChanged_","handleTrackingChanged_","setProjection","trackingOptions","setTrackingOptions","setTracking","tracking","Geolocation","getTracking","geolocation","watchPosition","positionChange_","positionError_","getTrackingOptions","clearWatch","position","coords","accuracy","altitude","altitudeAccuracy","heading","longitude","latitude","projectedPosition","speed","circularPolygon","GeolocationError","pixelRatio","pixelRatio_","ImageBase","listenImage","image","loadHandler","errorHandler","img","listening","decoding","loaded","listenerKeys","src","crossOrigin","imageLoadFunction","ImageState","src_","image_","unlisten_","imageLoadFunction_","ImageWrapper","unlistenImage_","handleImageLoad_","handleImageError_","canvas","opt_loader","canvas_","ImageCanvas","handleLoad_","createCanvasContext2D","opt_width","opt_height","opt_canvasPool","opt_Context2DSettings","getContext","releaseCanvas","clearRect","outerWidth","offsetWidth","getComputedStyle","marginLeft","marginRight","outerHeight","offsetHeight","marginTop","marginBottom","replaceNode","newNode","oldNode","parent","parentNode","replaceChild","removeChild","removeChildren","lastChild","replaceChildren","oldChildren","childNodes","oldChild","newChild","insertBefore","appendChild","tileLoadFunction","crossOrigin_","tileLoadFunction_","ImageTile","ctx","fillStyle","fillRect","naturalWidth","naturalHeight","decay","minVelocity","delay","decay_","minVelocity_","delay_","points_","angle_","initialVelocity_","Kinetic","lastIndex","firstIndex","duration","HEX_COLOR_RE_","NAMED_COLOR_RE_","asString","color","fromNamed","body","rgb","fromString","cacheSize","g","hasAlpha","substr","normalize","Number","fromStringInternal_","asArray","isStringColor","test","cache_","cacheSize_","maxCacheSize_","IconImageCache","canExpireCache","iconImage","getKey","maxCacheSize","expire","shared","background_","background","LayerProperty","opacity","visible","zIndex","maxResolution","minResolution","minZoom","maxZoom","className_","className","state_","BaseLayer","opt_managed","layer","managed","getOpacity","getVisible","getMaxResolution","getMinResolution","getMinZoom","getMaxZoom","opt_states","opt_background","zindex","inView","layerState","viewState","zoom","baseOptions","mapPrecomposeKey_","mapRenderKey_","sourceChangeKey_","renderer_","rendered","render","setMap","handleSourcePropertyChange_","setSource","Layer","states","getLayerState","getSource","handleSourceChange_","pixel","getFeatures","getData","frameState","layerRenderer","getRenderer","prepareFrame","renderFrame","unrender","RenderEventType","layerStatesArray","some","arrayLayerState","createRenderer","expireIconCache","iconImageCache","map_","MapRenderer","coordinateToPixelTransform","pixelToCoordinateTransform","hitTolerance","checkWrapped","thisArg","layerFilter","thisArg2","forEachFeatureAtCoordinate","feature","translatedCoordinate","offsets","layerStates","numLayers","matches","tmpCoord","hasRenderer","getWrapX","callback_1","order","distanceSq","postRenderFunctions","opt_inversePixelTransform","opt_frameState","opt_context","inversePixelTransform","CLASS_HIDDEN","CLASS_SELECTABLE","CLASS_UNSELECTABLE","CLASS_UNSUPPORTED","CLASS_CONTROL","CLASS_COLLAPSED","fontRegEx","fontRegExMatchIndex","getFontParameters","fontSpec","lineHeight","weight","variant","families","family","defaultFont","defaultFillStyle","defaultLineCap","defaultLineDash","defaultLineJoin","defaultMiterLimit","defaultStrokeStyle","defaultTextAlign","defaultTextBaseline","defaultPadding","checkedFonts","labelCache","setSize","measureFont","measureElement","measureContext","textHeights","registerFont","interval","referenceWidth","referenceFonts","text","isAvailable","fontStyle","fontWeight","fontFamily","available","referenceFont","measureTextWidth","check","fonts","getKeys","font","clearInterval","setInterval","measureTextHeight","metrics","measureText","actualBoundingBoxAscent","actualBoundingBoxDescent","innerHTML","minHeight","maxHeight","padding","border","display","left","measureAndCacheTextWidth","curr","getTextDimensions","baseStyle","chunks","widths","heights","lineWidths","lineWidth","currentWidth","currentHeight","drawImageOrLabel","labelOrImage","originX","originY","w","save","globalAlpha","setTransform","contextInstructions","label","executeLabelInstructions","drawImage","restore","fontChangeListenerKey_","redrawText","element_","container","getViewport","firstChild","children_","renderedVisible_","CompositeMapRenderer","getMap","event_1","RenderEvent","calculateMatrices2D","dispatchRenderEvent","declutterLayers","previousElement","layerIndex","sourceState","getSourceState","renderDeclutter","scheduleExpireIconCache","getDataAtPixel","layers","layersListenerKeys_","listenerKeys_","handleLayersChanged_","getArray","setLayers","LayerGroup","getLayers","handleLayersAdd_","handleLayersRemove_","layersArray","registerLayerListeners_","GroupEvent","handleLayerChange_","handleLayerGroupAdd_","handleLayerGroupRemove_","collectionEvent","collection","currentLayers","getLayersArray","getLayerStatesArray","ownLayerState","defaultZIndex","originalEvent","opt_dragging","opt_activePointers","pixel_","coordinate_","dragging","activePointers","MapBrowserEvent","getEventPixel","getCoordinateFromPixel","preventDefault","MapEvent","SINGLECLICK","CLICK","DBLCLICK","POINTERDRAG","POINTERMOVE","POINTERDOWN","POINTERUP","POINTEROVER","POINTEROUT","POINTERENTER","POINTERLEAVE","POINTERCANCEL","moveTolerance","clickTimeoutId_","emulateClicks_","dragging_","dragListenerKeys_","moveTolerance_","down_","activePointers_","trackedTouches_","pointerdownListenerKey_","PointerEventType","handlePointerDown_","originalPointerMoveEvent_","relayedListenerKey_","relayMoveEvent_","boundHandleTouchMove_","handleTouchMove_","MapBrowserEventHandler","pointerEvent","newEvent","MapBrowserEventType","clearTimeout","setTimeout","pointerId","updateActivePointers_","isMouseActionButton_","emulateClick_","button","doc","getOwnerDocument","handlePointerMove_","handlePointerUp_","getRootNode","isMoving_","cancelable","clientX","clientY","DROP","priorityFunction","keyFunction","priorityFunction_","keyFunction_","elements_","priorities_","queuedElements_","PriorityQueue","elements","priorities","siftUp_","elementKey","priority","siftDown_","isKeyQueued","count","lIndex","getLeftChildIndex_","rIndex","getRightChildIndex_","smallerChildIndex","parentIndex","getParentIndex_","heapify_","tilePriorityFunction","tileChangeCallback","boundHandleTileChange_","handleTileChange","tileChangeCallback_","tilesLoading_","tilesLoadingKeys_","TileQueue","added","enqueue","tileKey","maxTotalLoading","maxNewLoads","newLoads","getCount","dequeue","getTilePriority","tileSourceKey","tileCenter","tileResolution","wantedTiles","CENTER","RESOLUTION","ROTATION","DEFAULT_TILE_SIZE","createExtent","onlyCenter","smooth","opt_isMoving","opt_centerShift","viewWidth","viewHeight","shiftX","shiftY","ratio","none","getViewportClampedResolution","maxExtent","viewportSize","showFullExtent","xResolution","yResolution","getSmoothClampedResolution","createSnapToResolutions","resolutions","opt_smooth","opt_maxExtent","opt_showFullExtent","cappedMaxRes","capped","z","createSnapToPower","power","opt_minResolution","minZoomLevel","cappedZoomLevel","zoomLevel","createMinMaxResolution","disable","createSnapToN","theta","createSnapToZero","opt_tolerance","animationCallback","returnValue","createCenterConstraint","smoothExtentConstraint","constrainOnlyCenter","multiWorld","isGlobal","centerNone","createResolutionConstraint","resolutionConstraint","zoomFactor","smoothResolutionConstraint","projExtent","constrainResolution","defaultMaxResolution","defaultMinResolution","defaultMaxZoom","constraint","createRotationConstraint","enableRotation","constrainRotation","rotationNone","isNoopAnimation","animation","sourceCenter","targetCenter","coordinatesEqual","sourceResolution","targetResolution","sourceRotation","targetRotation","calculateCenterOn","rotX","rotY","hints_","animations_","updateAnimationKey_","projection_","viewportSize_","targetCenter_","targetResolution_","targetRotation_","nextCenter_","nextResolution_","nextRotation_","cancelAnchor_","applyOptions_","View","ViewProperty","resolutionConstraintInfo","maxResolution_","minResolution_","zoomFactor_","resolutions_","padding_","minZoom_","centerConstraint","rotationConstraint","constraints_","setRotation","setCenterInternal","setResolution","setZoom","oldPadding","newPadding","getResolution","offsetX","offsetY","newOptions","getZoom","getCenterInternal","getRotation","var_args","isDef","getAnimating","resolveConstraints","args","animateInternal","animationCount","series","easing","getResolutionForZoom","setHint","ViewHint","updateAnimations_","cancelAnimationFrame","more","seriesComplete","elapsed","fraction","progress","getViewportSize_","constrainedResolution","calculateCenterZoom","applyTargetState_","constrainedRotation","calculateCenterRotate","requestAnimationFrame","currentCenter","rotateCoordinate","addCoordinate","currentResolution","opt_rotation","opt_size","opt_hints","calculateExtentInternal","getViewportSizeMinusPadding_","getZoomForResolution","getUpdatedOptions_","enabled","getResolutionForExtentInternal","opt_power","getConstrainedResolution","logPower","reducedSize","nextCenter","nextResolution","nextRotation","nearest","baseLevel","geometryOrExtent","polygonFromExtent","getType","fitInternal","minRotX","minRotY","maxRotX","maxRotY","rotatedExtent","rotatedExtentForGeometry","centerRot","centerX","centerY","getConstrainedCenter","centerOnInternal","centerShift","shiftedCenter","deltaCoordinates","setCenter","adjustResolutionInternal","isMoving","getInteracting","newResolution","adjustResolution","adjustRotationInternal","newRotation","hint","opt_doNotCancelAnims","opt_forceMoving","newCenter","calculateCenterShift","cancelAnimations","opt_duration","opt_resolutionDirection","endInteractionInternal","opt_targetResolution","targetZoom","opt_direction","targetRes","hasArea","toSize","removeLayerMapProperty","setMapInternal","setLayerMapProperty","optionsInternal","keyboardEventTarget","getElementById","controls","interactions","overlays","layerGroup","MapProperty","view","createOptionsInternal","renderComplete_","loaded_","boundHandleBrowserEvent_","handleBrowserEvent","maxTilesLoading_","maxTilesLoading","postRenderTimeoutHandle_","animationDelayKey_","animationDelay_","renderFrame_","coordinateToPixelTransform_","pixelToCoordinateTransform_","frameIndex_","frameState_","previousExtent_","viewPropertyListenerKey_","viewChangeListenerKey_","layerGroupPropertyListenerKeys_","viewport_","overflow","overlayContainer_","pointerEvents","overlayContainerStopEvent_","mapBrowserEventHandler_","keyboardEventTarget_","targetChangeHandlerKeys_","overlays_","overlayIdIndex_","postRenderFunctions_","tileQueue_","handleTileChange_","handleLayerGroupChanged_","handleViewChanged_","handleSizeChanged_","handleTargetChanged_","viewOptions","setView","addOverlayInternal_","getId","control","interaction","PluggableMap","getControls","getInteractions","getLayerGroup","overlay","getOverlays","setTarget","getCoordinateFromPixelInternal","features","forEachFeatureAtPixel","addLayersFrom","forEachLayerAtPixel","hasFeatureAtCoordinate","viewportPosition","getBoundingClientRect","eventPosition","changedTouches","top","getTarget","getView","group","renderer","ready","loading","viewCoordinate","getPixelFromCoordinateInternal","targetElement","getTargetElement","ownerDocument","browserEvent","mapBrowserEvent","handleMapBrowserEvent","rootNode","contains","documentElement","interactionsArray","getActive","tileQueue","hints","viewHints","lowOnFrameBudget","getTilesLoading","reprioritize","loadMoreTiles","animate","MapEventType","defaultView","updateSize","updateViewportSize_","handleViewPropertyChanged_","handleLayerAdd_","handleLayerRemove_","handleFontsChanged","getSize","previousFrameState","getHints","declutterTree","usedTiles","mapId","renderTargets","nextExtent","getLoadingOrNotReady","handlePostRender","oldLayerGroup","computedStyle","parseFloat","getClientRects","setViewportSize","target_","Control","getOverlayContainerStopEvent","mapEvent","ulElement_","collapsed_","collapsed","userCollapsed_","overrideCollapsible_","collapsible","collapsible_","tipLabel","expandClassName","collapseLabel","collapseClassName","collapseLabel_","textContent","label_","activeLabel","toggleButton_","setAttribute","title","handleClick_","cssClasses","renderedAttributions_","Attribution","lookup","visibleAttributions","attributionGetter","getAttributions","attributions","getAttributionsCollapsible","setCollapsible","collectSourceAttributions_","handleToggle_","classList","toggle","updateElement_","compassClassName","callResetNorth_","resetNorth","duration_","autoHide_","autoHide","rotation_","Rotate","resetNorth_","zoomInClassName","zoomOutClassName","zoomInLabel","zoomOutLabel","zoomInTipLabel","zoomOutTipLabel","inElement","createTextNode","outElement","Zoom","zoomByDelta_","currentZoom","newZoom","getConstrainedZoom","defaults","zoomOptions","rotateOptions","attribution","attributionOptions","pan","zoomByDelta","setActive","Interaction","InteractionProperty","active","delta_","DoubleClickZoom","stopEvent","shiftKey","centroid","handleDownEvent","handleDragEvent","handleMoveEvent","handleUpEvent","stopDown","handlingDownUpSequence","targetPointers","PointerInteraction","updateTrackedPointers_","handledUp","handled","conditions","pass","altKeyOnly","altKey","metaKey","ctrlKey","altShiftKeysOnly","focus","activeElement","focusWithTabindex","hasAttribute","always","mouseActionButton","never","singleClick","noModifierKeys","shiftKeyOnly","targetNotEditable","isContentEditable","mouseOnly","pointerType","primaryAction","isPrimary","kinetic_","kinetic","lastCentroid","lastPointersCount_","panning_","condition","condition_","onFocusOnly","noKinetic_","DragPan","beginInteraction","centroidFromPointers","update","scaleCoordinate","adjustCenterInternal","getAngle","centerpx","endInteraction","lastAngle_","DragRotate","getConstraints","geometry_","startPixel_","endPixel_","RenderBox","startPixel","endPixel","px","getOverlayContainer","createOrUpdateGeometry","render_","DragBoxEventType","box_","minArea_","minArea","onBoxEnd","boxEndCondition_","boxEndCondition","defaultBoxEndCondition","DragBox","setPixels","DragBoxEvent","completeBox","out_","out","DragZoom","defaultCondition_","pixelDelta_","pixelDelta","KeyboardPan","keyEvent","keyCode","KeyCode","mapUnitsDelta","KeyboardZoom","charCode","Mode","totalDelta_","lastDelta_","timeout_","timeout","useAnchor_","useAnchor","constrainResolution_","lastAnchor_","startTime_","timeoutId_","mode_","trackpadEventGap_","trackpadTimeoutId_","deltaPerZoom_","MouseWheelZoom","wheelEvent","deltaMode","WheelEvent","DOM_DELTA_PIXEL","DOM_DELTA_LINE","getConstrainResolution","endInteraction_","adjustZoom","timeLeft","handleWheelZoom_","pointerOptions","anchor_","rotating_","rotationDelta_","threshold_","threshold","PinchRotate","rotationDelta","touch0","touch1","lastDistance_","lastScaleDelta_","PinchZoom","scaleDelta","altShiftDragRotate","doubleClickZoom","zoomDelta","zoomDuration","dragPan","pinchRotate","pinchZoom","keyboard","mouseWheelZoom","shiftDragZoom","defaultControls","defaultInteractions","insertFirst","autoPan","autoPanAnimation","margin","autoPanMargin","mapPostrenderListenerKey","handleElementChanged","handleMapChanged","handleOffsetChanged","handlePositionChanged","handlePositioningChanged","setElement","setOffset","setPositioning","positioning","setPosition","Overlay","getElement","updatePixelPosition","performAutoPan","panIntoView","opt_panIntoViewOptions","mapRect","getRect","overlayRect","panIntoViewOptions","myMargin","offsetLeft","offsetRight","offsetTop","offsetBottom","centerPx","newCenterPx","panOptions","box","pageXOffset","pageYOffset","getPosition","isRendered","getPixelFromCoordinate","mapSize","updateRenderedPosition","setVisible","getOffset","getPositioning","posX","posY","concat","msTransform","opt_highWaterMark","highWaterMark","count_","entries_","oldest_","newest_","LRUCache","keep","value_","key_","newer","older","containsKey","opt_tileCoord","getKeyZXY","getCacheKeyForTileKey","substring","fromKey","hash","withinExtentAndZ","tileRange","getFullTileRange","TileCache","peekLast","release","peekFirstKey","TileRange","canvasPool","urlTileCoord","getSourceTiles","context_","executorGroups","declutterExecutorGroups","loadingSourceTiles","hitDetectionImageData","replayState_","sourceTiles","errorTileKeys","wantedResolution","wrappedTileCoord","VectorRenderTile","hasContext","dirty","renderedRenderOrder","renderedResolution","renderedRevision","renderedTileResolution","renderedTileRevision","renderedTileZ","format_","features_","url_","VectorTile","setState","dataProjection","setFeatures","asColorLike","withCredentials","loadFeaturesXhr","url","success","failure","xhr","XMLHttpRequest","open","responseType","onload","status","responseText","responseXML","DOMParser","parseFromString","response","readFeatures","featureProjection","readProjection","onerror","send","addFeatures","jsonp","opt_errback","opt_callbackParam","script","cleanup","timer","originalXHR","client","getJSON","JSON","parse","ResponseError","ClientError","setRequestHeader","resolveUrl","base","URL","href","VectorContext","hitDetectionRenderer","circleGeometry","geometryCollectionGeometry","lineStringGeometry","multiLineStringGeometry","multiPointGeometry","multiPolygonGeometry","pointGeometry","polygonGeometry","strokeStyle","imageStyle","opt_declutterImageWithText","textStyle","viewRotation","opt_squaredTolerance","opt_userTransform","viewRotation_","squaredTolerance_","userTransform_","contextFillState_","contextStrokeState_","contextTextState_","fillState_","strokeState_","imageAnchorX_","imageAnchorY_","imageHeight_","imageOpacity_","imageOriginX_","imageOriginY_","imageRotateWithView_","imageRotation_","imageScale_","imageWidth_","text_","textOffsetX_","textOffsetY_","textRotateWithView_","textRotation_","textScale_","textFillState_","textStrokeState_","textState_","pixelCoordinates_","tmpLocalTransform_","CanvasImmediateRenderer","pixelCoordinates","localTransform","alpha","setContextFillState_","setContextStrokeState_","setContextTextState_","strokeText","fillText","close","moveTo","lineTo","closePath","moveToLineTo_","beginPath","arc","fill","stroke","drawText_","setFillStrokeStyle","getFill","getStroke","setImageStyle","getImage","setTextStyle","getText","drawPoint","drawLineString","drawPolygon","drawMultiPoint","drawMultiLineString","drawMultiPolygon","drawGeometryCollection","drawCircle","getGeometryFunction","drawGeometry","geometries","getGeometriesArray","simplifyTransformed","drawImages_","flatMidpoint","getFlatMidpoint","geometryExtent","getEnds","flatMidpoints","getFlatMidpoints","drawRings_","flatInteriorPoint","getEndss","flatInteriorPoints","getFlatInteriorPoints","fillState","contextFillState","strokeState","contextStrokeState","lineCap","setLineDash","lineDash","lineDashOffset","lineJoin","miterLimit","textState","contextTextState","textAlign","textBaseline","fillStyleColor","getColor","strokeStyleColor","strokeStyleLineCap","getLineCap","strokeStyleLineDash","getLineDash","strokeStyleLineDashOffset","getLineDashOffset","strokeStyleLineJoin","getLineJoin","strokeStyleWidth","strokeStyleMiterLimit","getMiterLimit","imageSize","imageAnchor","getAnchor","imageOrigin","getOrigin","getRotateWithView","getScaleArray","textFillStyle","textFillStyleColor","textStrokeStyle","textStrokeStyleColor","textStrokeStyleLineCap","textStrokeStyleLineDash","textStrokeStyleLineDashOffset","textStrokeStyleLineJoin","textStrokeStyleWidth","textStrokeStyleMiterLimit","textFont","getFont","textOffsetX","getOffsetX","textOffsetY","getOffsetY","textRotateWithView","textRotation","textScale","textText","textTextAlign","getTextAlign","textTextBaseline","getTextBaseline","GEOMETRY_RENDERERS","builderGroup","opt_declutterBuilderGroup","declutterImageWithText","getImageState","imageBuilderGroup","declutterMode","getDeclutterMode","imageReplay_1","getBuilder","imageReplay","textBuilderGroup","textReplay","drawText","lineStringReplay","polygonReplay","imageReplay_2","replayGroup","geometryRenderer","circleReplay","defaultOrder","feature1","feature2","getSquaredTolerance","getTolerance","renderFeature","imageState","unlistenImageChange","listenImageChange","renderGeometry","renderFeatureInternal","drawCustom","getHitDetectionRenderer","getGeometries","getVectorContext","CanvasRenderingContext2D","userTransform","canvasPixelRatio","multiplyTransform","brokenDiagonalRendering_","IMAGE_SMOOTHING_DISABLED","imageSmoothingEnabled","msImageSmoothingEnabled","IMAGE_SMOOTHING_ENABLED","drawTestTriangle","u1","u2","clip","verifyBrokenDiagonalRendering","calculateSourceResolution","targetProj","targetMetersPerUnit","sourceMetersPerUnit","compensationFactor","calculateSourceExtentResolution","targetExtent","triangulation","sources","gutter","opt_renderEdges","opt_interpolate","pixelRound","globalCompositeOperation","sourceDataExtent","canvasWidthInUnits","canvasHeightInUnits","stitchContext","stitchScale","xPos","yPos","srcWidth","srcHeight","targetTopLeft","getTriangles","triangle","u0","v0","sourceNumericalShiftX","sourceNumericalShiftY","affineCoefs","getImageData","isBrokenDiagonalRendering","ud","vd","step","steps","tmpTileCoord","origins","origin_","origin","origins_","tileSizes_","tileSizes","tileSize_","tileSize","fullTileRanges_","tmpSize_","tmpExtent_","sizes","restrictedTileRange","getTileRangeForExtentAndZ","calculateTileRanges_","TileGrid","opt_tileRange","tileCoordExtent","getTileCoordExtent","createOrUpdateTileRange","tileCoordZ","tileCoordX","tileCoordY","getTileSize","getTileCoordForXYAndZ_","getTileCoordForXYAndResolution_","reverseIntersectionPolicy","getZForResolution","createOrUpdateTileCoord","viewport","fullTileRanges","getForProjection","getDefaultTileGrid","createForProjection","setDefaultTileGrid","getTileCoordCenter","extentFromProjection","getTileCoordForCoordAndZ","createForExtent","opt_maxZoom","opt_tileSize","opt_corner","resolutionsFromExtent","createXYZ","xyzOptions","gridOptions","opt_maxResolution","half","createFromTemplate","zRegEx","xRegEx","yRegEx","dashYRegEx","range","createFromTemplates","templates","tileUrlFunctions","createFromTileUrlFunctions","tileCoordHash","nullTileUrlFunction","expandUrl","urls","startCharCode","stopCharCode","stop_1","appendParams","uri","params","keyParams","encodeURIComponent","qs","supportedExtensions","ARRAY_BUFFER","ELEMENT_ARRAY_BUFFER","STATIC_DRAW","DYNAMIC_DRAW","FLOAT","CONTEXT_IDS","opt_attributes","attributes","preserveDrawingBuffer","antialias","XML_SCHEMA_INSTANCE_URI","createElementNS","namespaceURI","qualifiedName","getDocument","getAllTextContent","normalizeWhitespace","getAllTextContent_","accumulator","nodeType","CDATA_SECTION_NODE","TEXT_NODE","nodeValue","nextSibling","isDocument","getAttributeNS","makeArrayExtender","valueReader","objectStack","makeArrayPusher","makeReplacer","makeObjectPropertyPusher","opt_property","localName","makeObjectPropertySetter","makeChildAppender","nodeWriter","makeArraySerializer","serializersNS","nodeFactory","serializers","makeSimpleNodeFactory","serialize","opt_nodeName","opt_namespaceURI","fixedNodeName","nodeName","OBJECT_PROPERTY_NODE_FACTORY","makeSequence","orderedKeys","sequence","makeStructureNS","namespaceURIs","structure","opt_structureNS","structureNS","parseNode","parsersNS","firstElementChild","nextElementSibling","parsers","parser","pushParseAndPop","opt_keys","pushSerializeAndPop","xmlSerializer_","getXMLSerializer","XMLSerializer","document_","implementation","createDocument","BufferUsage","getArrayClassForType","Float32Array","Uint32Array","opt_usage","usage","WebGLArrayBuffer","arrayClass","gl_","webGlContext","gl","scaleRatio_","scaleRatio","renderTargetTexture_","createTexture","renderTargetTextureSize_","frameBuffer_","createFramebuffer","vertexShader","createShader","VERTEX_SHADER","shaderSource","compileShader","fragmentShader","FRAGMENT_SHADER","renderTargetProgram_","createProgram","attachShader","linkProgram","renderTargetVerticesBuffer_","createBuffer","bindBuffer","bufferData","renderTargetAttribLocation_","getAttribLocation","renderTargetUniformLocation_","getUniformLocation","renderTargetOpacityLocation_","renderTargetTextureLocation_","uniforms_","uniforms","location","WebGLPostProcessingPass","getGL","textureSize","drawingBufferWidth","drawingBufferHeight","bindFramebuffer","FRAMEBUFFER","getFrameBuffer","internalFormat","RGBA","UNSIGNED_BYTE","bindTexture","TEXTURE_2D","texImage2D","texParameteri","TEXTURE_MIN_FILTER","LINEAR","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","framebufferTexture2D","COLOR_ATTACHMENT0","nextPass","preCompose","postCompose","activeTexture","TEXTURE0","canvasId","getContextAttributes","clearColor","COLOR_BUFFER_BIT","enable","BLEND","blendFunc","ONE","ONE_MINUS_SRC_ALPHA","useProgram","enableVertexAttribArray","vertexAttribPointer","uniform2f","uniform1i","uniform1f","applyUniforms","drawArrays","TRIANGLES","textureSlot","uniform","HTMLCanvasElement","ImageData","texture","uniform3f","uniform4f","fromTransform","mat4","DefaultUniform","AttributeType","UNSIGNED_SHORT","UNSIGNED_INT","canvasCache","getSharedCanvasCacheKey","uniqueCanvasCacheKeyCount","computeAttributesStride","attr","getByteSizeFromType","BYTES_PER_ELEMENT","Uint16Array","boundHandleWebGLContextLost_","handleWebGLContextLost","boundHandleWebGLContextRestored_","handleWebGLContextRestored","canvasCacheKey_","canvasCacheKey","cacheItem","users","getCanvas","bufferCache_","extensionCache_","currentProgram_","ContextEventType","offsetRotateMatrix_","offsetScaleMatrix_","tmpMat4_","uniformLocations_","attribLocations_","setUniforms","postProcessPasses_","postProcesses","shaderCompileErrors_","WebGLHelper","name_1","getExtension","bufferKey","bufferCache","webGlBuffer","getUsage","bufferCacheEntry","isContextLost","deleteBuffer","loseContext","opt_disableAlphaBlend","init","ZERO","applyFrameState","renderTarget","getFramebuffer","getTexture","elementType","numItems","offsetInBytes","drawElements","offsetScaleMatrix","resetTransform","scaleTransform","offsetRotateMatrix","rotateTransform","setUniformMatrixValue","setUniformFloatValue","HTMLImageElement","prevValue","program","shader","fragmentShaderSource","vertexShaderSource","getShaderParameter","COMPILE_STATUS","getShaderInfoLog","deleteShader","getProgramParameter","LINK_STATUS","uniform4fv","uniformMatrix4fv","attribName","getAttributeLocation","enableAttributeArray_","opt_data","opt_texture","texture_","PaletteTexture","NEAREST","TEXTURE_MAG_FILTER","tmpArray4","helper","helper_","framebuffer_","dataCacheDirty_","updateSize_","WebGLRenderTarget","readPixels","readAll","ENABLE_RASTER_REPROJECTION","maxSourceExtent","errorThreshold","opt_destinationResolution","sourceProj_","targetProj_","transformInvCache","transformInv","transformInv_","maxSourceExtent_","errorThresholdSquared_","triangles_","wrapsXInSource_","canWrapXInSource_","sourceWorldWidth_","targetWorldWidth_","destinationTopLeft","destinationTopRight","destinationBottomRight","destinationBottomLeft","sourceTopLeft","sourceTopRight","sourceBottomRight","sourceBottomLeft","maxSubdivision","addQuad_","leftBound_1","newTriangle","Triangulation","aSrc","bSrc","cSrc","dSrc","sourceQuadExtent","sourceCoverageX","sourceWorldWidth","wrapsX","needsSubdivision","isNotFinite","centerSrc","bc","bcSrc","da","daSrc","ab","abSrc","cd","cdSrc","addTriangle_","sourceTileGrid","targetTileGrid","getTileFunction","opt_errorThreshold","renderEdges_","gutter_","sourceTileGrid_","targetTileGrid_","wrappedTileCoord_","sourceTiles_","sourcesListenerKeys_","sourceZ_","maxTargetExtent","limitedTargetExtent","sourceProjExtent","errorThresholdInPixels","triangulation_","calculateSourceExtent","sourceRange","srcX","srcY","ReprojTile","renderReprojected","leftToLoad_1","sourceListenKey_1","unlistenSources_","reproject_","bindAndConfigure","resampleFilter","uploadDataTexture","bandCount","textureType","canInterpolate","bytesPerRow","byteLength","unpackAlignment","LUMINANCE","LUMINANCE_ALPHA","RGB","oldUnpackAlignment","getParameter","UNPACK_ALIGNMENT","pixelStorei","pixelContext","textures","renderSize_","grid","fromArray","flushBufferData","setTile","TileTexture","uploadTile_","uploadImageTexture","sourceTileSize","pixelSize","isFloat","pixelCount","DataType","bytesPerElement","textureCount","textureDataArrays","textureIndex","dataIndex","rowOffset","colCount","rowIndex","colIndex","dataValue","pixelIndex","bandIndex","textureData","deleteTexture","renderCol","renderRow","renderWidth","renderHeight","sourceSize","sourceWidthWithoutGutter_1","sourceHeightWithoutGutter_1","sourceWidth_1","sourceHeight_1","sourceCol_1","sourceRow_1","data_1","DataView","bytesPerPixel","offset_1","sourceWidthWithoutGutter","sourceHeightWithoutGutter","sourceCol","sourceRow","boundHandleImageChange_","handleImageChange_","layer_","declutterExecutorGroup","LayerRenderer","tiles","loadedTileCallback","forEachLoadedTile","renderIfReadyAndVisible","getLayer","WebGLWorkerMessageType","inversePixelTransform_","pixelContext_","postProcesses_","removeHelper","dispatchPreComposeEvent","dispatchPostComposeEvent","WebGLLayerRenderer","event_2","getRenderSource","incrementGroup","groupNumber","layerClassName","getClassName","canvasCacheKeyMatches","afterHelperCreated","prepareFrameInternal","event_3","dispatchRenderEvent_","renderPixel","layerExtent","pixelCanvas","tmpArray_","bufferPositions_","vertexPosition","indexPosition","writePointVertex","colorEncodeId","radix","divide","colorDecodeId","mult","Uniforms","TILE_TEXTURE_ARRAY","TILE_TRANSFORM","TRANSITION_ALPHA","DEPTH","TEXTURE_PIXEL_WIDTH","TEXTURE_PIXEL_HEIGHT","TEXTURE_RESOLUTION","TEXTURE_ORIGIN_X","TEXTURE_ORIGIN_Y","RENDER_EXTENT","ZOOM","Attributes","TEXTURE_COORD","attributeDescriptions","empty","depthForZ","addTileTextureToLookup","tileTexturesByZ","tileTexture","getRenderExtent","gridExtent","getTileGridForProjection","getCacheKey","getTileCoordKey","tileLayer","renderComplete","tileTransform_","tempMat4_","tempTileRange_","tempTileCoord_","createTileCoord","tempSize_","program_","vertexShader_","fragmentShader_","indices_","tileTextureCache_","paletteTextures_","paletteTextures","WebGLTileLayerRenderer","getProgram","tileState","useInterimTilesOnError","getUseInterimTilesOnError","initialZ","tileSource","getGutterForProjection","tileTextureCache","minZ","getPreload","cacheKey","getTile","isDrawableTile_","getInterimTile","tileQueueKey","preRender","zDirection","targetZ","enqueueTiles","alphaLookup","uid","blend","tileTextures","getAlpha","endTransition","tileCoordKey","findAltTiles_","parentZ","prepareDraw","zs","tileZ","tileOrigin","tileWidthWithGutter","tileHeightWithGutter","aspectRatio","centerI","centerJ","tileScale","depth","tileTextures_1","tileCenterI","tileCenterJ","translateTransform","mat4FromTransform","enableAttributes","textureProperty","uniformName","paletteIndex","paletteTexture","gutterExtent","setUniformFloatVec4","finalizeDraw","expireCache","postRender","getSources","col","row","getPixelData","altZ","getTileRangeForTileCoordAndZ","covered","deleteProgram","ValueTypes","Operators","getValueType","stringify","valueArr","operator","getReturnType","isTypeUnique","valueType","numberToGlsl","arrayToGlsl","colorToGlsl","getStringNumberEquivalent","string","stringLiteralsMap","stringToGlsl","expressionToGlsl","typeHint","toGlsl","assertNumber","assertNumbers","assertString","assertBoolean","assertArgsCount","assertArgsMinCount","assertArgsMaxCount","assertArgsEven","assertUniqueInferredType","types","uniformNameForVariable","variableName","inFragmentShader","variables","PALETTE_TEXTURE_ARRAY","colors","numColors","palette","candidate","length_1","paletteName","GET_BAND_VALUE_FUNC","getEqualOperator","getDecisionOperator","band","functions","ifBlocks","colorIndex","textureName","bandExpression","xOffsetExpression","yOffsetExpression","parsedArgs","opt_typeHint","interpolation","outputType","exponent","stop1","output1","stop2","output2","fallback","assertArgsOdd","varyings","sizeExpression","rotationExpression","offsetExpression","colorExpression","texCoordExpression","discardExpression","rotateWithView","ShaderBuilder","expression","forHitDetection","offsetMatrix","attribute","varying","hitDetectionBypass","parseLiteralStyle","symbStyle","symbol","texCoord","textureCoord","vertContext","parsedSize","parsedOffset","parsedTexCoord","parsedRotation","fragContext","parsedColor","parsedOpacity","opacityFilter","visibleSize","symbolType","st","builder","setSizeExpression","setRotationExpression","setSymbolOffsetExpression","setTextureCoordinateExpression","setSymbolRotateWithView","setColorExpression","parsedFilter","setFragmentDiscardExpression","varName","addUniform","getColorExpression","attrName","addVarying","addAttribute","props","matrixIds_","matrixIds","WMTSTileGrid","createFromCapabilitiesMatrixSet","matrixSet","opt_matrixLimits","matrixLimits","switchOriginXY","getAxisOrientation","elt","elt_ml","tileWidth","tileHeight","opacity_","rotateWithView_","scale_","scaleArray_","displacement_","displacement","declutterMode_","ImageStyle","getScale","getDisplacement","hitDetectionCanvas_","fill_","points","radius_","radius1","radius2_","radius2","stroke_","renderOptions_","RegularShape","getPoints","getRadius2","setOpacity","createHitDetectionCanvas_","renderOptions","draw_","strokeWidth","r1","r2","miterRatio","bevelAdd","aa","dd","innerMiterRatio","innerLength","calculateLineJoinSize_","maxRadius","createRenderOptions","createPath_","drawHitDetectionCanvas_","angle0","radiusC","CircleStyle","color_","Fill","taintedTestContext","hitDetectionImage_","imageState_","tainted_","IconImage","dispatchChangeEvent_","replaceColor_","isTainted_","imgData","putImageData","normalizedAnchor_","anchorOrigin_","anchorOrigin","IconOrigin","anchorXUnits_","anchorXUnits","IconAnchorUnits","anchorYUnits_","anchorYUnits","imgSize_","imgSize","iconImage_","getIconImage","offset_","offsetOrigin_","offsetOrigin","Icon","getSrc","getPixelRatio","getHitDetectionImage","iconImageSize","lineCap_","lineDash_","lineDashOffset_","lineJoin_","miterLimit_","width_","Stroke","geometryFunction_","defaultGeometryFunction","hitDetectionRenderer_","zIndex_","Style","toFunction","styleFunction","defaultStyles","createDefaultStyle","createEditingStyle","styles","white","blue","font_","textAlign_","justify_","justify","textBaseline_","maxAngle_","maxAngle","placement_","placement","TextPlacement","overflow_","offsetX_","offsetY_","backgroundFill_","backgroundFill","backgroundStroke_","backgroundStroke","Text","getPlacement","getMaxAngle","getOverflow","getJustify","getBackgroundFill","getBackgroundStroke","getPadding","opt_circular","first_","last_","head_","circular_","length_","LinkedList","opt_maxEntries","rbush_","RBush_","items_","RBush","extents","items","bbox","forEach_","getAll","getInExtent","rbush","adaptAttributions","attributionLike","attributions_","attributionsCollapsible_","attributionsCollapsible","wrapX_","interpolate_","viewResolver","viewRejector","viewPromise_","Source","opaque_","opaque","tilePixelRatio_","tilePixelRatio","tileCache","tmpSize","tileOptions","TileSource","getTileCacheForProjection","getResolutions","getTilePixelRatio","scaleSize","refresh","tileCount","generateTileUrlFunction_","tileUrlFunction","UrlTile","setUrls","setUrl","tileLoadingKeys_","TileEventType","TileSourceEvent","pruneExceptNewestZ","setKey","setTileUrlFunction","defaultTileLoadFunction","imageTile","imageSmoothing","tileClass","tileCacheForProjection","tileGridForProjection","reprojectionErrorThreshold_","reprojectionErrorThreshold","renderReprojectionEdges_","TileImage","usedTileCache","getGutter","getInterpolate","getOpaque","thisProj","projKey","getTileCoordForTileUrlFunction","tileUrl","newTile","getTileInternal","refreshInterimChain","createTile_","tilegrid","proj","quadKey","digits","mask","hidpi","hidpi_","culture_","culture","maxZoom_","apiKey_","imagerySet_","imagerySet","requestJSONP","handleImageryMetadataResponse","BingMaps","statusCode","statusDescription","authenticationResultCode","resourceSets","resources","resource","zoomMax","imageWidth","imageHeight","zoomMin","imageUrlSubdomains","subdomain","quadKeyTileCoord","imageUrl","imageryProviders","transform_1","setAttributions","getTileGrid","imageryProvider","intersecting","coverageAreas","coverageArea","XYZ","account_","account","mapId_","config_","config","templateCache_","initializeMap_","CartoDB","paramHash","applyTemplate_","mapUrl","handleInitResponse_","handleInitError_","tilesUrl","cdn_url","https","layergroupid","opt_feature","opt_features","overlaps_","overlaps","strategy_","strategy","allStrategy","useSpatialIndex","featuresRtree_","loadedExtentsRtree_","loadingExtentsCount_","nullGeometryFeatures_","idIndex_","uidIndex_","featureChangeKeys_","featuresCollection_","addFeaturesInternal","bindFeaturesCollection_","VectorSource","addFeatureInternal","featureKey","addToIndex_","setupChangeEvents_","VectorSourceEvent","VectorEventType","handleFeatureChange_","valid","newFeatures","geometryFeatures","length_2","length_3","modifyingCollection","addFeature","removeFeature","opt_fast","featureId","removeAndIgnoreReturn","removeFeatureInternal","clearEvent","forEachFeatureInExtent","intersectsCoordinate","forEachInExtent","intersectsExtent","forEachFeatureAtCoordinateDirect","anExtent","opt_filter","closestFeature","previousMinSquaredDistance","minDistance","sid","removeFromIdIndex_","loadedExtentsRtree","extentsToLoad","extentToLoad","this_1","featureChangeKeys","removed","setLoader","interpolationRatio","geometryFunction","createCustomCluster_","createCluster","boundRefresh_","updateDistance","Cluster","loadFeatures","cluster","mapDistance","clustered","getCoordinates","neighbors","getFeaturesInExtent","neighbor","geometry_1","searchCenter","renderTileSize","DataTileSource","sourceLoader","floatView","uint32View","baseTable","shiftTable","mantissaTable","exponentTable","offsetTable","convertToNumber","float16bits","TypedArrayPrototype","Reflect","getTypedArrayPrototypeSybolToStringTag","getOwnPropertyDescriptor","isTypedArray","isDataView","getFloat16","dataView","byteOffset","opts","getUint16","registry","addDecoder","cases","importFn","getDecoder","fileDirectory","Compression","copyNewSize","samplesPerPixel","resampleNearest","valueArrays","inWidth","inHeight","outWidth","outHeight","relX","relY","newArray","cy","cx","resampleBilinear","rawY","yl","yh","rawX","tx","xl","xh","ll","hl","lh","hh","resampleNearestInterleaved","valueArray","samples","resampleBilinearInterleaved","sum","arrayForType","bitsPerSample","Int8Array","Int16Array","Int32Array","Float64Array","default","geoKeys","littleEndian","isTiled","StripOffsets","planarConfiguration","PlanarConfiguration","getFileDirectory","getGeoKeys","ImageWidth","ImageLength","getSamplesPerPixel","SamplesPerPixel","getTileWidth","TileWidth","getTileHeight","TileLength","RowsPerStrip","getBlockWidth","getBlockHeight","getBytesPerPixel","bytes","BitsPerSample","getSampleByteSize","RangeError","getReaderForSample","sampleIndex","SampleFormat","getUint8","getUint32","getInt8","getInt16","getInt32","getFloat32","getFloat64","getSampleFormat","getBitsPerSample","getArrayForSample","sample","poolOrDecoder","signal","numTilesPerRow","numTilesPerCol","byteCount","TileOffsets","TileByteCounts","StripByteCounts","fetch","request","sampleFormat","needsNormalization","inBuffer","samplesToTransfer","outArray","bitMask","repeat","pixelBitSkip","bitsPerLine","lineBitOffset","pixelBitOffset","bitOffset","outIndex","innerBitOffset","raw","normalizeArray","imageWindow","interleave","resampleMethod","minXTile","maxXTile","minYTile","maxYTile","windowWidth","srcSampleOffsets","sampleReaders","promises","yTile","xTile","si","promise","getTileOrStrip","blockHeight","firstLine","firstCol","lastLine","lastCol","reader","ymax","xmax","pixelOffset","windowCoordinate","resampled","resampleInterleaved","resample","wnd","pool","fillValue","numPixels","_readRaster","enableAlpha","pi","PhotometricInterpretation","photometricInterpretations","ExtraSamples","ExtraSamplesValues","readRasters","subOptions","raster","rgbRaster","fromWhiteIsZero","fromBlackIsZero","colorMap","greenOffset","blueOffset","mapIndex","fromPalette","ColorMap","cmykRaster","fromCMYK","yCbCrRaster","Uint8ClampedArray","cb","cr","fromYCbCr","cieLabRaster","fromCIELab","red","green","getTiePoints","ModelTiepoint","tiePoints","getGDALMetadata","metadata","GDAL_METADATA","findTagsByName","getAttribute","getGDALNoData","GDAL_NODATA","modelTransformation","ModelTransformation","referenceImage","modelPixelScale","ModelPixelScale","refResX","refResY","refResZ","pixelIsArea","GTRasterTypeGeoKey","getBoundingBox","DataView64","arrayBuffer","_dataView","getUint64","combined","isSafeInteger","getInt64","isNegative","carrying","byte","DataSlice","sliceOffset","bigTiff","_sliceOffset","_littleEndian","_bigTiff","covers","sliceTop","readUint8","readInt8","readUint16","readInt16","readUint32","readFloat32","readFloat64","readUint64","readInt64","readOffset","CRLFCRLF","itemsToObject","fromEntries","parseHeaders","line","kv","parseContentRange","rawContentRange","total","BaseSource","slices","fetchSlice","zip","A","B","AbortError","super","captureStackTrace","CustomAggregateError","errors","AggregateError","Block","BlockGroup","blockIds","BlockedSource","blockSize","blockCache","blockRequests","blockIdsToFetch","Set","fileSize","cachedBlocks","missingBlockIds","current","blockId","milliseconds","wait","fetchBlocks","block","cachedBlock","results","allSettled","retriedBlockRequests","rejected","reason","aborted","requiredBlocks","readSliceData","groups","groupBlocks","groupRequests","groupIndex","blockRequest","blockOffset","sortedBlockIds","lastBlockId","blocks","blockIdLow","blockIdHigh","sliceData","sliceView","topDelta","usedBlockLength","blockInnerOffset","rangeInnerOffset","blockView","BaseResponse","getHeader","headerName","BaseClient","headers","credentials","FetchResponse","FetchClient","XHRResponse","getResponseHeader","XHRClient","constructRequest","entries","onabort","abort","HttpResponse","dataPromise","HttpClient","parsedUrl","urlMod","httpApi","protocol","http","resolveData","chunk","Buffer","RemoteSource","maxRanges","allowFullFile","_fileSize","fetchSlices","Range","ok","rawContentType","rawParams","param","parseContentType","byteRanges","responseArrayBuffer","boundary","decoder","startBoundary","endBoundary","startsWith","innerText","endOfHeaders","startOfData","parseByteRanges","others","maybeWrapInBlockedSource","makeFetchSource","blockOptions","makeXHRSource","makeHttpSource","makeRemoteSource","forceXHR","clientOptions","FileReaderSource","file","blob","FileReader","readAsArrayBuffer","getFieldTypeLength","fieldType","fieldTypes","dataSlice","readMethod","fieldTypeLength","ImageFileDirectory","geoKeyDirectory","nextIFDByteOffset","GeoTIFFImageIndexError","GeoTIFFBase","resX","resY","firstImage","usedImage","imageCount","getImageCount","imgBBox","oX","oY","rX","rY","usedBBox","allImages","SubfileType","subfileType","NewSubfileType","newSubfileType","imgResX","imgResY","imageResX","imageResY","GeoTIFF","firstIFDOffset","ifdRequests","ghostValues","fallbackSize","entrySize","offsetSize","getSlice","numDirEntries","byteSize","entryCount","fieldTag","typeCount","fieldValues","valueOffset","actualOffset","arrayFields","fieldTagNames","rawGeoKeyDirectory","GeoKeyDirectory","geoKeyNames","parseGeoKeyDirectory","parseFileDirectoryAt","requestIFD","previousIfd","ifd","GeoTIFFImage","hasNext","detectionString","heuristicAreaSize","metadataSize","fullString","headerData","BOM","magicNumber","MultiGeoTIFF","mainFile","overviewFiles","imageFiles","fileDirectoriesPerFile","fileDirectoriesPerFileParsing","requests","parseFileDirectoriesPerFile","visited","relativeIndex","imageFile","imageCounts","ifds","fromBlob","fromSource","defaultPoolSize","hardwareConcurrency","workerPool","createWorker","workers","_awaitingDecoder","messageId","worker","idle","random","onMessage","decoded","postMessage","terminate","STATISTICS_MAXIMUM","STATISTICS_MINIMUM","_","ImageHeight","ProjectedCSTypeGeoKey","getCachedProjection","unitsFromCode","ProjLinearUnitsGeoKey","GeographicTypeGeoKey","GeogAngularUnitsGeoKey","getImagesForTIFF","tiff","getImagesForSource","tiffFromBlob","overviews","mainUrl","overviewUrls","tiffFromUrls","tiffFromUrl","assertEqual","expected","got","rejector","getMinForDataType","getMaxForDataType","sourceInfo_","numSources","sourceOptions_","sourceOptions","sourceImagery_","resolutionFactors_","samplesPerPixel_","nodataValues_","metadata_","normalize_","addAlpha_","readMethod_","convertToRGB","configure_","GeoTIFFSource","commonRenderTileSizes","commonSourceTileSizes","nodataValues","sourceCount","sourceIndex","images","sourceOrigin","sourceTileSizes","renderTileSizes","sourceResolutions","imageIndex","nodataValue","wantedSamples","bands","level","imageResolutions","resolutionFactor_1","scaledSourceResolutions","sourceImagery","firstSource","nodata","additionalBands","setTileSizes","loadTile_","addAlpha","sourceInfo","resolutionFactor","this_2","pixelBounds","bandNumber","Pool","dataLength","sourceSamples","transparent","gain","bias","stats","sourceValue","nodataIsNaN","TierSizeCalculation","zoomifyImage_","CustomTile","tierSizeCalculation","tierSizeInTiles","tileSizeForTierSizeCalculation","tileCountUpToTier","tileIndex","localContext_1","ZoomifyTileClass","testTileUrl","getTileCoordForCoordAndResolution","Versions","IIIF_PROFILE_VALUES","supports","formats","qualities","COMPLIANCE_VERSION1","COMPLIANCE_VERSION2","COMPLIANCE_VERSION3","versionFunctions","iiifInfo","levelProfile","getComplianceLevelSupportedFeatures","imageInfo","scale_factors","tile_width","tile_height","additionalProfile","profile","profileSupports","profileFormats","profileQualities","scaleFactors","extraFormats","__spreadArray","preferredFormat","preferredFormats","extraFeatures","extraQualities","setImageInfo","IIIFInfo","getComplianceLevelEntryFromProfile","identifier","version","getImageApiVersion","complianceLevel","getComplianceLevelFromProfile","opt_preferredOptions","imageOptions","quality","formatPercentage","percentage","toLocaleString","maximumFractionDigits","baseUrl","supportsListedSizes","supportsListedTiles","isInteger","supportsArbitraryTiling","maxScaleFactor","ignoredSizesIndex","IiifTileClass","regionParam","sizeParam","tileX","tileY","regionX","regionY","regionW","regionH","sizeW","sizeH","regionWidth","regionHeight","getImageFunction","sourceImage","sourcePixelRatio","targetExtent_","sourceImage_","sourcePixelRatio_","sourceListenerKey_","ReprojImage","unlistenSource_","ImageSourceEventType","defaultImageLoadFunction","reprojectedImage_","reprojectedRevision_","ImageSource","getImageInternal","ImageSourceEvent","params_","imageSize_","renderedRevision_","ratio_","ImageArcGISRest","findNearestResolution","halfWidth","halfHeight","imageResolution","getRequestUrl_","handleImageChange","srid","modifiedUrl","canvasFunction_","canvasFunction","ImageCanvasSource","canvasElement","displayDpi_","displayDpi","useOverlay_","useOverlay","ImageMapGuide","getUrl","dpi","mcsW","mcsH","devW","devH","mpp","baseParams","imageExtent_","imageExtent","Static","extentWidth","extentHeight","targetWidth","targetHeight","setImage","DEFAULT_VERSION","GETFEATUREINFO_IMAGE_SIZE","v13_","updateV13_","serverType_","serverType","ImageWMS","projectionObj","sourceProjectionObj","LAYERS","mpu","viewExtent","requestExtent","knownMapMediaTypes","knownVectorMediaTypes","getMapTileUrlTemplate","links","mediaType","tileUrlTemplate","fallbackUrlTemplate","link","rel","getVectorTileUrlTemplate","supportedMediaTypes","hrefLookup","supportedMediaType","parseTileMatrixSet","tileMatrixSet","tileMatrixSetLimits","crs","backwards","matrices","tileMatrices","matrixLookup","matrix","limitLookup","limit","tileMatrix","origin_1","pointOfOrigin","cellSize","matrixWidth","matrixHeight","tileMapWidth","minTileCol","maxTileCol","tileMapHeight","cornerOfOrigin","minTileRow","maxTileRow","intersectExtents","urlTemplate","urlFunction","upsideDown","localContext","tileCol","tileRow","getTileSetInfo","tileSet","dataType","tileMatrixSetLink","tileMatrixSetDefinition","parseTileSetMetadata","handleTileSetInfo_","handleError_","OGCMapTile","tileSetInfo","defaultLoadFunction","sourceTileCache","tileGrids_","sourceTile","tileFeatures","usedSourceTiles","bufferExtent","sourceTileGrid_1","sourceZ","forEachTileCoord","sourceTileCoord","sourceTileState","listenChange_1","sourceTileKey","coordKey","tileExtent","sourceTileGrid_2","DEFAULT_MAX_ZOOM","updateCacheSize","getFormat","onLoad","onError","OGCVectorTile","ATTRIBUTION","tempTransform","pixelTransform","containerReused","CanvasLayerRenderer","getBackground","opt_backgroundColor","backgroundColor","transformOrigin","topLeft","topRight","bottomRight","bottomLeft","inverted","imageLayer","CanvasImageLayerRenderer","viewResolution","imageSource","renderedExtent","loadImage","imageMapWidth","imageMapHeight","imagePixelRatio","viewCenter","canvasTransform","toTransformString","useContainer","clipped","clipUnrotated","dw","dh","previousAlpha","ImageLayer","BaseImageLayer","preload","setPreload","setUseInterimTilesOnError","BaseTileLayer","TileProperty","extentChanged","renderedExtent_","renderedPixelRatio","renderedProjection","renderedTiles","newTiles_","tmpExtent","tmpTileRange_","CanvasTileLayerRenderer","isDrawableTile","sourceRevision","canvasExtent","tilesToDrawByZ","findLoadedTiles","createLoadedTileFinder","tmpTileRange","tileCoordIntersectsViewport","inTransition","childTileRange","getTileCoordChildTileRange","forEachTileCoordParentTileRange","canvasScale","clips","clipZs","currentClip","currentZ","currentTilePixelSize","getTilePixelSize","currentScale","dx_1","dy_1","originTileCoord","originTileExtent","tileGutter","tilesToDraw","xIndex","nextX","yIndex","nextY","contextSaved","i_1","drawTileImage","updateUsedTiles","manageTilePyramid","scheduleExpireCache","getTileImage","alphaChanged","postRenderFunction","opt_tileCallback","useTile","TileLayer","hasImageData","newImageData","imageData","createImageData","createMinion","operation","workerHasImageData","newWorkerImageData","buffers","meta","imageOps","numBuffers","numBytes","arrays","pixels","lines","lib","Worker","Blob","createObjectURL","threads","_imageOps","_onWorkerMessage","minion","terminated","createFauxWorker","_workers","_queue","_maxQueueLength","queue","_running","_dataLookup","_job","Processor","inputs","_enqueue","_dispatch","job","_resolveJob","RasterEventType","RasterOperationType","processor_","operationType_","operationType","threads_","layers_","createLayer","createLayers","requestedFrameState_","renderedImageCanvas_","iMax","sourceOrLayer","sourceAttribution","setOperation","RasterSource","opt_lib","allSourcesReady_","updateFrameState_","processSources_","imageDatas","RasterSourceEvent","process","onWorkerComplete_","sharedContext","layerOrSource","ATTRIBUTIONS","OSM_ATTRIBUTION","LayerConfig","ProviderConfig","provider","providerConfig","layerConfig","getKeyForParams_","TileArcGISRest","getTileCoord","strokeRect","tileJSON_","handleTileJSONResponse","handleTileJSONError","onXHRLoad_","onXHRError_","tileJSON","TileJSON","epsg4326Projection","attributionExtent_1","TileWMS","bufferSize","preemptive","preemptive_","grid_","keys_","jsonp_","xRelative","yRelative","opt_request","loadInternal_","json","tileUrlFunction_","template_","UTFGrid","forDataAtCoordinate","grids","requestEncoding","version_","dimensions_","dimensions","matrixSet_","requestEncoding_","getKeyForDimensions_","createFromWMTSTemplate","WMTS","getMatrixId","renderBuffer","updateWhileAnimating","updateWhileInteracting","declutter_","declutter","renderBuffer_","updateWhileAnimating_","updateWhileInteracting_","BaseVectorLayer","renderOrder","toStyleFunction","projectionMatrixTransform","sourceRevision_","verticesBuffer_","hitVerticesBuffer_","indicesBuffer_","hitDetectionEnabled_","hitFragmentShader","hitVertexShader","hitVertexShader_","hitFragmentShader_","hitProgram_","customAttributes","hitDetectionAttributes","currentTransform_","renderTransform_","invertRenderTransform_","renderInstructions_","hitRenderInstructions_","hitRenderTarget_","generateBuffersRun_","worker_","createWebGLWorker","received","projectionTransform","hitDetection","fromArrayBuffer","vertexBuffer","indexBuffer","makeInverseTransform","renderInstructions","generateBuffersRun","featureCache_","featureCount_","sourceListenKeys_","handleSourceFeatureAdded_","handleSourceFeatureChanged_","handleSourceFeatureDelete_","handleSourceFeatureClear_","forEachFeature","WebGLPointsLayerRenderer","endWorld","startWorld","world","renderCount","makeProjectionTransform","renderHitDetection","clearCachedData","vectorSource","viewNotMoving","sourceChanged","BaseVector","getRenderBuffer","rebuildBuffers_","featureCache","totalInstructionsCount","totalHitInstructionsCount","hitColor","tmpCoords","tmpColor","renderIndex","hitIndex","featureUid","customAttributesCount","hitMessage","readPixel","getFeatureByUid","prepareDrawToRenderTarget","Instruction","BEGIN_GEOMETRY","BEGIN_PATH","CIRCLE","CLOSE_PATH","CUSTOM","DRAW_CHARS","DRAW_IMAGE","END_GEOMETRY","FILL","MOVE_TO_LINE_TO","SET_FILL_STYLE","SET_STROKE_STYLE","STROKE","fillInstruction","strokeInstruction","beginPathInstruction","closePathInstruction","maxLineWidth","beginGeometryInstruction1_","beginGeometryInstruction2_","bufferedMaxExtent_","instructions","tmpCoordinate_","hitDetectionInstructions","CanvasBuilder","dashArray","dash","getBufferedMaxExtent","myEnd","closed","skipFirst","lastRel","nextRel","lastXCoord","lastYCoord","nextCoord","skipped","builderEnds","builderEnd","appendFlatLineCoordinates","beginGeometry","builderEndss","builderBegin","myEnds","drawCustomCoordinates_","CanvasInstruction","appendFlatPointCoordinates","endGeometry","instruction","createStroke","applyPixelRatio","createFill","currentFillStyle","applyStroke","currentStrokeStyle","currentLineCap","currentLineDash","currentLineDashOffset","currentLineJoin","currentLineWidth","currentMiterLimit","endGeometryInstruction","imagePixelRatio_","anchorX_","anchorY_","height_","originX_","originY_","declutterImageWithText_","CanvasImageBuilder","myBegin","reverseHitDetectionInstructions","opt_sharedData","CanvasLineStringBuilder","moveToLineToInstruction","updateStrokeStyle","drawFlatCoordinates_","lastStroke","CanvasPolygonBuilder","numEnds","setFillStrokeStyles_","circleInstruction","drawFlatCoordinatess_","updateFillStyle","matchingChunk","m12","m23","x12","y12","x23","y23","chunkStart","chunkEnd","chunkM","acos","TEXT_ALIGN","labels_","fillStates","strokeStates","textStates","textKey_","fillKey_","strokeKey_","CanvasTextBuilder","geometryType","geometryWidths","beg_1","saveTextStates_","p0","p1","p2","p3","pixelRatio_1","flatOffset","flatEnd","oo","drawChars_","strokeKey","textKey","fillKey","baseline","BATCH_CONSTRUCTORS","PolygonBuilder","Builder","ImageBuilder","LineStringBuilder","TextBuilder","tolerance_","maxExtent_","resolution_","buildersByZIndex_","BuilderGroup","builderInstructions","zKey","builders","builderKey","builderInstruction","builderType","zIndexKey","replays","replay","Constructor","drawTextOnPath","startM","segmentM","advance","beginX","beginY","startOffset","startLength","endM","flat","previousAngle","singleSegment","iStart","charLength","chars","lineStringLength","p4","getDeclutterBox","replayImageOrLabelArgs","declutterBox","rtlRegEx","horizontalTextAlign","align","createTextChunks","alignFill_","coordinateCache_","renderedTransform_","widths_","Executor","textIsArray","OffscreenCanvasRenderingContext2D","previousFont","leftRight","strokeInstructions","fillInstructions","lineOffset","widthHeightIndex","lineWidthIndex","text_1","fillStrokeArgs","setStrokeStyle_","sheetWidth","sheetHeight","snapToPixel","fillStroke","boxW","boxH","boxX","boxY","drawImageX","drawImageY","drawImageW","drawImageH","contextScale","imageOrLabel","strokePadding","replayTextBackground_","repeatSize","createLabel","opt_featureCallback","opt_hitExtent","opt_declutterTree","transformSetFromArray","prevX","prevY","roundX","roundY","currentGeometry","pendingFill","pendingStroke","lastFillInstruction","lastStrokeInstruction","coordinateCache","viewRotationFromTransform","batchSize","labelWithAnchor","drawLabelWithPointPlacement_","widthIndex","calculateImageOrLabelDimensions_","imageArgs","imageDeclutterBox","replayImageOrLabel_","measurePixelRatio","pixelRatioScale","cachedWidths","pathLength","textLength","parts","drawChars","cc","part","ii_1","execute_","ORDER","allInstructions","opt_renderBuffer","executorsByZIndex_","hitDetectionContext_","hitDetectionTransform_","createExecutors_","ExecutorGroup","flatClipCoords","getClipCoords","executors","instructionByZindex","candidates","declutteredFeatures","contextSize","newContext","hitExtent","indexes","getPixelIndexArray","featureCallback","result_1","executor","executeHitDetection","opt_builderTypes","builderTypes","execute","circlePixelIndexArrayCache","maxDistanceSq","distances","HIT_DETECT_RESOLUTION","createHitDetectionImageData","featureCount","indexFactor","featuresByZIndex","featureStyleFunction","getStyleFunction","originalStyle","setColor","setText","getImageSize","imgContext","byGeometryType","zIndexKeys","geomAndStyle","kk","hitDetect","resultFeatures","vectorLayer","boundHandleStyleImageChange_","handleStyleImageChange_","animatingOrInteracting_","hitDetectionImageData_","renderedFeatures_","renderedResolution_","wrappedRenderedExtent_","renderedRotation_","renderedCenter_","renderedProjection_","renderedRenderOrder_","replayGroup_","replayGroupChanged","clipping","compositionContext_","CanvasVectorLayerRenderer","executorGroup","getRenderTransform","compositionContext","setupCompositionContext_","renderWorlds","releaseCompositionContext_","transformToString","animating","interacting","getUpdateWhileAnimating","getUpdateWhileInteracting","frameStateExtent","vectorLayerRevision","vectorLayerRenderBuffer","vectorLayerRenderOrder","getRenderOrder","defaultRenderOrder","loadExtents","wrapCoordinateX","loadExtent","wrapExtentX","declutterBuilderGroup","CanvasBuilderGroup","getRenderTolerance","getDeclutter","userExtent_1","getSquaredRenderTolerance","userExtent","replayGroupInstructions","getOverlaps","vectorRenderer_","layerImageRatio_","getImageRatio","coordinateToVectorPixelTransform_","renderedPixelToCoordinateTransform_","CanvasVectorImageLayerRenderer","vectorPixel","vectorRenderer","imageLayerState","imageFrameState_1","emptyImage_1","image_1","IMAGE_REPLAYS","VECTOR_REPLAYS","renderedLayerRevision_","tmpTransform_","CanvasVectorTileLayerRenderer","updateExecutorGroup_","tileImageNeedsRender_","hifi","prepareTile","getRenderMode","VectorTileRenderType","renderTileImage_","layerRevision","builderState","getReplayState","layerUid","tt","sourceTileExtent","sharedExtent","builderExtent","bufferedExtent","executorGroupInstructions","replayExtent","renderingReplayGroup","CanvasExecutorGroup","extent_1","tilePixel","getTileRenderTransform","worldOffset","renderMode","replayTypes","hasExecutors","replayState","renderPixelRatio","renderScale","pixelScale","MultiPoint","multiPoint","interpolatePoint","cumulativeLengths","lineStringCoordinateAtM","extrapolate","lo","hi","m0","lineStringsCoordinateAtM","flatMidpoint_","flatMidpointRevision_","LineString","lineString","opt_extrapolate","getCoordinateAt","lineStrings","MultiLineString","multiLineString","midpoints","endss_","flatInteriorPointsRevision_","flatInteriorPoints_","polygons","MultiPolygon","newEndss","multiPolygon","linearRingssArea","linearRingssCenter","prevEnds","lastEnds","type_","flatCoordinates_","flatMidpoints_","properties_","RenderFeature","midpoint","toGeometry","VectorLayer","geoM","fracA","fracB","fracM","geoA","geoB","geoStack","fractionStack","fractions","maxIterations","meridian","lon","frac","parallel","lon2","DEFAULT_STROKE_STYLE","INTERVALS","maxLines","targetSize","showLabels","lonLabelFormatter","latLabelFormatter","lonLabelPosition","latLabelPosition","lonLabelStyle","latLabelStyle","intervals","maxLat_","maxLon_","minLat_","minLon_","maxX_","maxY_","minX_","minY_","targetSize_","maxLines_","meridians_","parallels_","strokeStyle_","fromLonLatTransform_","toLonLatTransform_","projectionCenterLonLat_","bottomLeft_","bottomRight_","topLeft_","topRight_","meridiansLabels_","parallelsLabels_","lonLabelFormatter_","latLabelFormatter_","lonLabelPosition_","latLabelPosition_","lonLabelStyleBase_","lonLabelStyle_","latLabelStyleBase_","latLabelStyle_","drawLabels_","intervals_","loaderFunction","strategyFunction","featurePool_","lineStyle_","loadedExtent_","setRenderOrder","Graticule","realWorldExtent","removeLoadedExtent","renderExtent","equivalentProjection","updateProjectionInfo_","createGraticule_","featuresColl","getFeaturesCollection","poolIndex","minLat","maxLat","getMeridian_","geom","minLon","maxLon","getParallel_","rotationCenter","rotationExtent","unrotatedWidth","unrotatedHeight","labelsAtStart","vectorContext","textPoint","getMeridianPoint_","drawFeature","getParallelPoint_","getInterval_","validCenterP","centerLonLat","cnt","centerLon","centerLat","validExtentP","validExtent","addMeridian_","addParallel_","clampedLat","bottom","clampedBottom","clampedTop","clampedLeft","clampedRight","toLonLatTransform","split_1","lonLatCoordinates","worldExtentP","DEFAULT_GRADIENT","gradient","blur","gradient_","handleGradientChanged_","setGradient","setBlur","setRadius","weightFunction_","Heatmap","createLinearGradient","addColorStop","createGradient","getGradient","u_size","u_blurSlope","u_gradientTexture","u_opacity","defaultFeatureProjection","FeatureFormat","setWorldExtent","adaptOptions","transformGeometryWithOptions","power_1","transformExtentWithOptions","layersPBFReader","layerPBFReader","featurePBFReader","readRawFeature","featureClass_","featureClass","geometryName","layerName_","layerName","idProperty_","idProperty","MVT","cmd","coordsLen","currentEnd","cmdLen","rawFeature","readRawGeometry_","getGeometryType","setId","PBF","pbfLayers","pbfLayer","setExtent","createFeature_","renderMode_","setBackground","VectorTileLayer","cloneGeometries","clonedGeometries","opt_geometries","geometries_","changeEventsKeys_","listenGeometriesChange_","GeometryCollection","geometryCollection","setGeometries","geometriesArray","getGeometriesArrayRecursive","simplifiedGeometries","simplified","simplifiedGeometryCollection","setGeometriesArray","unlistenGeometriesChange_","getObject","JSONFeature","readFeatureFromObject","getReadOptions","readFeaturesFromObject","readGeometryFromObject","readProjectionFromObject","writeFeatureObject","writeFeaturesObject","writeGeometryObject","readGeometry","readPointGeometry","readLineStringGeometry","readPolygonGeometry","readMultiPointGeometry","readMultiLineStringGeometry","readMultiPolygonGeometry","readGeometryCollectionGeometry","writeGeometry","geoJSON","writePointGeometry","writeLineStringGeometry","rightHanded","writePolygonGeometry","writeMultiPointGeometry","writeMultiLineStringGeometry","writeMultiPolygonGeometry","writeGeometryCollectionGeometry","extractGeometryName_","extractGeometryName","GeoJSON","geoJSONFeature","geoJSONFeatures","objects","kCSSColorTable","clamp_css_byte","clamp_css_float","parse_css_int","parse_css_float","css_hue_to_rgb","m1","m2","css_str","iv","op","ep","fname","Color","convertLiteral","convertFunction","parameters","propertySpec","let","stops","const","convertIdentityFunction","zoomAndFeatureDependent","featureDependent","zoomDependent","tokens","convertTokenString","featureFunctionParameters","featureFunctionStops","zoomStops","getFunctionType","getInterpolateOperator","appendStopPair","convertPropertyFunction","fixupDegenerateStepCurve","convertZoomAndPropertyFunction","isStep","convertZoomFunction","colorSpace","getFallback","defaultValue","curve","interpolated","re","literal","rgba","parseCSSColor","black","ParsingError","Scope","bindings","NullType","kind","NumberType","StringType","BooleanType","ColorType","ObjectType","ValueType","CollatorType","FormattedType","ResolvedImageType","itemType","N","valueMemberTypes","checkSubtype","memberType","isValidType","provided","allowedTypes","isValidNativeType","Collator","caseSensitive","diacriticSensitive","locale","sensitivity","collator","Intl","lhs","rhs","resolvedLocale","resolvedOptions","FormattedSection","fontStack","textColor","Formatted","sections","unformatted","section","serialized","ResolvedImage","validateRGBA","isValue","mixed","typeOf","Literal","expectedType","evaluate","eachChild","outputDefined","RuntimeError","boolean","Assertion","parsed","FormatExpression","firstArg","nextTokenMayBeObject","lastExpression","content","evaluatedContent","ImageExpression","evaluatedImageName","availableImages","Coercion","parseColor","valueToString","child","geometryTypes","EvaluationContext","globals","featureState","formattedSection","_parseColorCache","canonical","featureTileCoord","featureDistanceData","canonicalID","distanceFromCenter","dX","dY","cached","CompoundExpression","_evaluate","definition","definitions","availableOverloads","overloads","signature","signatureContext","ParsingContext","path","scope","argParseFailed","signatures","stringifySignature","actualTypes","register","CollatorExpression","updateBBox","boxWithinBox","bbox1","bbox2","getTileCoordinates","lng","tilesAtZoom","onBoundary","rayIntersect","pointWithinPolygon","inside","ring","len2","pointWithinPolygons","twoSided","q1","q2","det1","det2","lineIntersectPolygon","vectorP","vectorQ","lineStringWithinPolygon","lineStringWithinPolygons","getTilePolygon","getTilePolygons","updatePoint","polyBBox","worldSize","halfWorldSize","getTilePoints","pointBBox","shifts","tilePoints","getTileLines","lineBBox","tileLines","tileLine","resetBBox","Within","geojson","isFeatureConstant","isStateConstant","isGlobalPropertyConstant","tilePolygon","tilePolygons","pointsWithinPolygons","linesWithinPolygons","Var","boundExpression","isConstant","isTypeAnnotation","childrenConstant","findStopLessThanOrEqualTo","currentValue","nextValue","lowerIndex","upperIndex","currentIndex","expr","_parse","annotate","typeAnnotation","Expr","actual","ec","Step","labels","outputs","labelKey","valueKey","stopCount","UnitBezier","p1x","p1y","p2x","p2y","bx","ax","by","ay","sampleCurveX","sampleCurveY","sampleCurveDerivativeX","solveCurveX","epsilon","t0","t1","t2","solve","Xn","Zn","deg2rad","rad2deg","xyz2lab","lab2xyz","xyz2rgb","rgb2xyz","rgbToLab","rgbColor","labToRgb","labColor","interpolateHue","lab","interpolateNumber","hcl","hclColor","Interpolate","exponentialInterpolation","lowerValue","upperValue","difference","interpolationFactor","lower","upper","controlPoints","rest","outputLower","outputUpper","Coalesce","needsAnnotation","argCount","Let","binding","At","In","IndexOf","fromIndex","Match","inputType","otherwise","labelContext","MAX_SAFE_INTEGER","groupedByOutput","outputLookup","sortedLabels","outputIndex","coerceLabel","Case","branches","Slice","beginIndex","endIndex","isComparableType","eqCollate","makeComparison","compareBasic","compareWithCollator","isOrderComparison","hasUntypedArgument","Comparison","lt","Equals","NotEquals","LessThan","GreaterThan","LessThanOrEqual","GreaterThanOrEqual","NumberFormat","currency","minFractionDigits","maxFractionDigits","minimumFractionDigits","Length","expressions","varargs","isFunction","ref","typeToString","pitch","heatmapDensity","lineProgress","skyRadialProgress","accumulated","E","LN10","isSupportedScript","toUpperCase","StyleExpression","_warningHistory","_evaluator","_defaultValue","spec","getDefaultValue","_enumValues","createExpression","enum","formatted","resolvedImage","getExpectedType","evaluateWithoutErrorHandling","ZoomConstantExpression","_styleExpression","isStateDependent","ZoomDependentExpression","interpolationType","createPropertyExpression","supportsPropertyExpression","isZoomConstant","supportsZoomExpression","zoomCurve","findZoomCurve","supportsInterpolation","childResult","deepUnbundle","unbundledValue","valueOf","unbundle","isExpressionFilter","createFilter","layerType","needGeometry","needFeature","convertFilter","filterExp","staticFilter","isDynamicFilter","unionDynamicBranches","collapseDynamicBooleanExpressions","extractStaticFilter","filterSpec","latest","compiledStaticFilter","filterFunc","globalProperties","dynamicFilterFunc","compiledDynamicFilter","dynamicFilter","geometryNeeded","dynamicConditionExpressions","collapsedExpression","subExpression","isBranchingDynamically","filters","convertComparisonOp","convertNegation","convertInOp","convertHasOp","deref","refProperties","fontWeights","thin","hairline","light","book","regular","normal","plain","roman","standard","medium","bold","heavy","fat","poster","sp","italicRE","fontCache","cssData","fontFamilies","maybeWeight","previousPart","mapboxBaseUrl","getMapboxPath","normalizeStyleUrl","token","mapboxPath","decodeURI","normalizeSourceUrl","tokenParam","styleUrl","urlObject","searchParams","defaultResolutions","createCanvas","pendingRequests","fetchResource","resourceType","transformRequest","Request","pendingRequest","getGlStyle","glStyleOrUrl","accessToken","glStyle","tilejsonCache","getTileJson","glSource","normalizedSourceUrl","accessTokenParam","tileJson","normalizedTileUrl","transformedRequest","hairSpacePool","applyLetterSpacing","letterSpacing","textWithLetterSpacing","joinSpaceString","getMeasureContext","measureCache","wrapText","em","hardLines","wrappedText","words","maxWidth","word","testLine","prevWidth","nextWidth","lineWords","lastWord","loadedFontFamilies","fontFamilyRegEx","stripQuotesRegEx","hasFontFamily","styleSheets","styleSheet","cssRules","rules","cssRule","cssText","processedFontFamilies","getFonts","fontsKey","googleFontDescriptions","cssFont","mb2css","googleFontDescription","fontUrl","querySelector","markup","renderFeatureCoordinates","emptyObj","zoomObj","getValue","layoutOrPaint","functionCache","layerId","isExpr","compiledExpression","rawExpression","expressionData","getIconDeclutterMode","evaluateFilter","filterCache","renderTransparentEnabled","colorWithOpacity","templateRegEx","fromTemplate","recordLayer","stylefunction","olLayer","sourceOrLayers","spriteData","spriteImageUrl","spriteImage","spriteImgSize","action","mapboxSource","allLayers","derefLayers","layersBySourceLayer","mapboxLayers","patternCache","sourceLayer","textHalo","featureBelongsToLayer","stylesLength","layerData","paint","visibility","minzoom","maxzoom","strokeColor","fillIcon","icon","setZIndex","icon_cache_key","spriteImageData","createPattern","setWidth","setLineCap","setLineJoin","setMiterLimit","hasImage","placementAngle","iconImg","skipLabel","styleGeom","iconRotationAlignment","iconSize","iconColor","setAnchor","circleRadius","circleStrokeColor","circleColor","circleStrokeWidth","cache_key","Circle","textLineHeight","textSize","maxTextWidth","fontArray","textField","chunkFont","textTransform","wrappedLabel","setFont","textAnchor","setPlacement","setOverflow","textHaloWidth","textOffset","textTranslate","vOffset","hOffset","setTextAlign","textRotationAlignment","setRotateWithView","setMaxAngle","setTextBaseline","setOffsetX","setOffsetY","setFill","haloColor","halfTextSize","setStroke","textPadding","completeOptions","applyStyle","optionsOrPath","sourceId","assignSource","setupVectorSource","targetSource","getTileUrlFunction","getTileLoadFunction","setTileLoadFunction","setMaxResolution","setupGeoJSONSource","onChange","sprite","applyStyleFunction","normalizeSpriteUrl","sizeFactor","spriteUrl","pathname","spritesJson","mapOrLayer","updateStyle","bg","_colorWithOpacity","setFirstBackground","extentFromTileJSON","bounds","tr","tileJSONSource","tileJSONDoc","getTileJSON","olSourceOptions","VectorTileSource","geoJsonFormat","geoJsonUrl","encodeURI","ErrorEvent","applyBackground","imageRatio","imageRatio_","VectorImageLayer","parseResult_","styleVariables_","hitDetectionDisabled_","disableHitDetection","WebGLPointsLayer","getSymbolVertexShader","getSymbolFragmentShader","parseStyle","pipeline","contrast","exposure","saturation","gamma","brightness","numVariables","uniformDeclarations","functionDefintions","sources_","renderedSource_","handleSourceUpdate_","WebGLTileLayer","parsedStyle","getSourceBandCount_","onChange_1","renderSources","altSources","DragAndDropEventType","readAsBuffer_","formats_","formatConstructors","dropListenKeys_","source_","DragAndDrop","tryReadFeatures_","DragAndDropEvent","dropArea","handleDrop","handleStop","registerListeners_","unregisterListeners_","files","dataTransfer","handleResult_","readAsText","dropEffect","lastMagnitude_","DragRotateAndZoom","magnitude","angleDelta","setCenterAndRadius","getRadiusSquared_","DrawEventType","shouldHandle_","downPx_","downTimeout_","lastDragTime_","pointerType_","freehand_","snapTolerance_","snapTolerance","getMode","stopClick_","stopClick","minPoints_","minPoints","maxPoints_","maxPoints","finishCondition_","finishCondition","geometryLayout_","geometryLayout","Constructor_1","mode_1","squaredLength","squaredCoordinateDistance","dragVertexDelay_","dragVertexDelay","finishCoordinate_","sketchFeature_","sketchPoint_","sketchCoords_","sketchLine_","sketchLineCoords_","squaredClickTolerance_","clickTolerance","overlay_","freehandCondition_","freehand","freehandCondition","updateState_","Draw","move","addToDrawing_","getPointerCount","startDrawing_","startingToDraw","finishDrawing","atFinish_","abortDrawing","downPx","clickPx","modifyDrawing_","createOrUpdateSketchPoint_","at","potentiallyDone","potentiallyFinishCoordinates","mode","sketchCoords","finishCoordinate","finishPixel","updateSketchFeatures_","getLinearRing","sketchLineGeom","DrawEvent","createOrUpdateCustomSketchLine_","sketchFeature","abortDrawing_","newDrawing","ending","sketchFeatures","overlaySource","ExtentEventType","getDefaultPointerStyleFunction","getPointHandler","fixedPoint","getEdgeHandler","fixedP1","fixedP2","pointerHandler_","pixelTolerance_","pixelTolerance","snappedToVertex_","extentFeature_","vertexFeature_","extentOverlay_","boxStyle","vertexOverlay_","pointerStyle","Extent","pixelCoordinate","getExtentInternal","segments","getSegments","closestSegment","vertex","vertexPixel","coordinateDistance","pixel1","pixel2","squaredDist1","squaredDist2","dist","snapToVertex_","createOrUpdatePointerFeature_","extentFeature","vertexFeature","getOpposingPoint","x_","y_","createOrUpdateExtentFeature_","ExtentEvent","readNumber","writeNumber","to5","differentNumber","animationOptions","prefix","animationOptions_","replace_","prefix_","initial_","Link","getParamName_","oldMap","updateUrl_","handleChangeLayerGroup_","delete_","history","replaceState","updateView","viewProperties","get_","getAllLayers","layersParam","visibilities","set_","pushState","tempExtent","tempSegment","ModifyEventType","compareIndexes","projectedDistanceToSegmentDataSquared","pointCoordinates","segmentData","distanceToCenterSquared","distanceToCircumference","closestOnSegmentData","boundHandleFeatureChange_","defaultDeleteCondition_","deleteCondition_","deleteCondition","insertVertexCondition_","insertVertexCondition","vertexSegments_","lastPixel_","ignoreNextSingleClick_","featuresBeingModified_","rBush_","changingFeature_","dragSegments_","SEGMENT_WRITERS_","writePointGeometry_","writeLineStringGeometry_","writePolygonGeometry_","writeMultiPointGeometry_","writeMultiLineStringGeometry_","writeMultiPolygonGeometry_","writeCircleGeometry_","writeGeometryCollectionGeometry_","hitDetection_","handleSourceAdd_","handleSourceRemove_","addFeature_","handleFeatureAdd_","handleFeatureRemove_","lastPointerEvent_","snapToPointer_","snapToPointer","Modify","writer","handlePointerAtPixel_","ss","ModifyEvent","removeFeatureSegmentData_","rBush","nodesToRemove","nodeToRemove","removeFeature_","centerSegmentData","circumferenceSegmentData","featureSegments","removePoint","willModifyFeatures_","dragSegment","setGeometryCoordinates_","createOrUpdateVertexFeature_","insertVertices","vertexExtent","segmentDataMatches","componentSegments","segmentDataMatch","insertVertex_","opt_coordinate","nodes","hitPointGeometry","vertexSegments","geometryUid","rTree","updateSegmentIndices_","newSegmentData","newSegmentData2","removeVertex_","component","newIndex","dragSegments","segmentsByFeature","deleted","SelectEventType","selected","deselected","originalFeatureStyles","boundAddFeature_","boundRemoveFeature_","addCondition_","addCondition","removeCondition_","removeCondition","toggleCondition_","toggleCondition","multi_","multi","filter_","hitTolerance_","layers_1","layerFilter_","featureLayerAssociation_","Select","restorePreviousStyle_","applySelectedStyle_","hasFeature","addFeatureLayerAssociation_","removeFeatureLayerAssociation_","SelectEvent","getFeatureFromEvent","vertex_","edge_","featuresListenerKeys_","featureChangeListenerKeys_","indexedFeaturesExtents_","pendingFeatures_","GEOMETRY_SEGMENTERS_","segmentPointGeometry_","segmentLineStringGeometry_","segmentPolygonGeometry_","segmentMultiPointGeometry_","segmentMultiLineStringGeometry_","segmentMultiPolygonGeometry_","segmentGeometryCollectionGeometry_","segmentCircleGeometry_","Snap","opt_listen","feature_uid","segmenter","segmentsData","snapTo","updateFeature_","featuresToUpdate","opt_unlisten","unregister","nodesToRemove_1","currentMap","getFeatures_","forEachFeatureRemove_","forEachFeatureAdd_","segmentsLength","closestVertex","projectedCoordinate","squaredPixelTolerance","getResult","tempVertexCoord","segmentStart","segmentEnd","TranslateEventType","startCoordinate","lastCoordinate_","startCoordinate_","lastFeature_","handleActiveChanged_","Translate","featuresAtPixel_","TranslateEvent","newCoordinate","deltaX_1","deltaY_1","flipXY","opt_destOffset","destOffset","GEOMETRY_READERS","getGeometryLayout","paths","GEOMETRY_WRITERS","esriJSON","hasZM","getHasZM","hasZ","hasM","esriJSONPolygon","flatRing","outerRings","holes","hole","matched","outerRing","convertRings","_a","_b","geometryReader","geometryWriter","EsriJSON","opt_idField","esriJSONFeature","esriJSONFeatures","objectIdFieldName","wkid","XMLFeature","readFeatureFromDocument","readFeatureFromNode","readFeaturesFromDocument","readFeaturesFromNode","ELEMENT_NODE","readGeometryFromDocument","readGeometryFromNode","readProjectionFromDocument","readProjectionFromNode","writeFeatureNode","serializeToString","writeFeaturesNode","writeGeometryNode","GMLNS","ONLY_WHITESPACE_RE","featureType","featureNS","srsName","schemaLocation","FEATURE_COLLECTION_PARSERS","namespace","readFeaturesInternal","GMLBase","ft","ns","featureTypes","readFeatureElement","GEOMETRY_PARSERS","readGeometryOrExtent","asFeature","readExtentElement","readGeometryElement","readFeatureElementInternal","_content_","fid","readFlatCoordinatesFromNode","MULTIPOINT_PARSERS","MULTILINESTRING_PARSERS","MULTIPOLYGON_PARSERS","POINTMEMBER_PARSERS","LINESTRINGMEMBER_PARSERS","POLYGONMEMBER_PARSERS","GEOMETRY_FLAT_COORDINATES_PARSERS","flatLinearRings","FLAT_LINEAR_RINGS_PARSERS","pointMemberParser","lineStringMemberParser","polygonMemberParser","readLineString","readPolygon","RING_PARSERS","readFlatLinearRing","readBooleanString","readDateTime","dateTime","readDecimal","readDecimalString","readPositiveInteger","readNonNegativeIntegerString","writeBooleanTextNode","bool","writeStringTextNode","writeCDATASection","createCDATASection","writeDateTimeTextNode","date","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","getUTCSeconds","writeDecimalTextNode","toPrecision","writeNonNegativeIntegerTextNode","nonNegativeInteger","MULTIGEOMETRY_TO_MEMBER_NODENAME","GML2","containerSrs","coordsGroups","BOX_PARSERS_","flatLinearRing","multiSurface","surface","multiCurve","writeGeometryElement","createCoordinatesNode_","writeCoordinates_","writeCurveSegments_","GEOMETRY_NODE_FACTORY_","writeCurveOrLineString","getLineStrings","LINESTRINGORCURVEMEMBER_SERIALIZERS","MULTIGEOMETRY_MEMBER_NODE_FACTORY_","GEOMETRY_SERIALIZERS","getCoords_","getLinearRings","RING_SERIALIZERS","RING_NODE_FACTORY_","patches","writeSurfacePatches_","exteriorWritten","writeSurfaceOrPolygon","writeLinearRing","opt_srsName","opt_hasZ","POINTMEMBER_SERIALIZERS","writePoint","getPolygons","SURFACEORPOLYGONMEMBER_SERIALIZERS","ENVELOPE_SERIALIZERS","readFlatCoordinates","innerBoundaryIsParser","outerBoundaryIsParser","readBox","writeMultiCurveOrLineString","writeMultiPoint","writeMultiSurfaceOrPolygon","writeEnvelope","writeLineStringOrCurveMember","writeRing","writePointMember","writeSurfaceOrPolygonMember","surface_","curve_","multiCurve_","multiSurface_","GML3","MULTICURVE_PARSERS","MULTISURFACE_PARSERS","CURVEMEMBER_PARSERS","SURFACEMEMBER_PARSERS","PATCHES_PARSERS","SEGMENTS_PARSERS","SURFACE_PARSERS","CURVE_PARSERS","ENVELOPE_PARSERS","contextDimension","dim","srsDimension","writePos_","posList","writePosList_","writeFeatureElement","setAttributeNS","writeFeatureMembers_","readFlatPos","readFlatPosList","interiorParser","exteriorParser","readSurface","readMultiSurface","readCurve","readMultiCurve","readEnvelope","curveMemberParser","surfaceMemberParser","readPatch","readSegment","readPolygonPatch","readLineStringSegment","readFlatCurveRing","writeFeatures","GML","GML32","NAMESPACE_URIS","FEATURE_READER","readRte","readTrk","readWpt","GPX_PARSERS","LINK_PARSERS","GPX_SERIALIZERS","RTE_SEQUENCE","RTE_SERIALIZERS","TRK_SEQUENCE","TRK_SERIALIZERS","writeWptType","readExtensions_","readExtensions","GPX","extensionsNode","featureReader","handleReadExtensions_","gpx","GPX_NODE_FACTORY","RTE_PARSERS","parseLink","parseExtensions","RTEPT_PARSERS","rteValues","layoutOptions","appendCoordinate","TRK_PARSERS","TRKSEG_PARSERS","TRKPT_PARSERS","trkValues","WPT_PARSERS","LINK_SEQUENCE","LINK_SERIALIZERS","writeLink","RTEPT_TYPE_SEQUENCE","TRKSEG_SERIALIZERS","TRKSEG_NODE_FACTORY","WPT_TYPE_SEQUENCE","WPT_TYPE_SERIALIZERS","GEOMETRY_TYPE_TO_NODENAME","applyLayoutOptions","DEFAULT_COLOR","DEFAULT_IMAGE_STYLE_ANCHOR","DEFAULT_IMAGE_STYLE_ANCHOR_X_UNITS","DEFAULT_IMAGE_STYLE_ANCHOR_Y_UNITS","DEFAULT_IMAGE_STYLE_SIZE","DEFAULT_IMAGE_STYLE_SRC","TextFeature","readFeatureFromText","readFeaturesFromText","readGeometryFromText","readProjectionFromText","writeFeatureText","writeFeaturesText","writeGeometryText","IGCZ","B_RECORD_RE","H_RECORD_RE","HFDTE_RECORD_RE","NEWLINE_RE","altitudeMode_","altitudeMode","IGC","year","month","day","lastDateTime","hour","minute","second","UTC","GX_NAMESPACE_URIS","ICON_ANCHOR_UNITS_MAP","PLACEMARK_PARSERS","extendedDataParser","regionParser","readMultiGeometry","readLinearRing","readPoint","readStyle","styleMapValue","readStyleMapValue","placemarkObject","readStyleURL","GX_MULTITRACK_GEOMETRY_PARSERS","readGxTrack","NETWORK_LINK_PARSERS","readURI","REGION_PARSERS","LAT_LON_ALT_BOX_PARSERS","regionObject","LOD_PARSERS","lodObject","KML_SEQUENCE","KML_SERIALIZERS","DOCUMENT_SERIALIZERS","DOCUMENT_NODE_FACTORY","writePlacemark","DEFAULT_FILL_STYLE","DEFAULT_NO_IMAGE_STYLE","DEFAULT_IMAGE_STYLE","DEFAULT_TEXT_STROKE_STYLE","DEFAULT_TEXT_STYLE","DEFAULT_STYLE","TEXTAREA","DEFAULT_STYLE_ARRAY","scaleForSize","defaultIconUrlFunction","defaultStyle_","defaultStyle","extractStyles_","extractStyles","writeStyles_","writeStyles","sharedStyles_","showPointNames_","showPointNames","iconUrlFunction_","iconUrlFunction","KML","readDocumentOrFolder_","readPlacemark_","readSharedStyle_","readSharedStyleMap_","sharedStyles","drawName","multiGeometryPoints","featureStyle","findStyle","nameStyle","foundStyle","imageScale","setScale","createNameStyleFunction","createFeatureStyleFunction","styleUri","baseURI","fs","readNameFromDocument","readNameFromNode","name_2","networkLinks","readNetworkLinksFromDocument","readNetworkLinksFromNode","regions","readRegionFromDocument","readRegionFromNode","kml","xmlnsUri","styleValue","readColor","hexColor","readScale","STYLE_MAP_PARSERS","pairObject","PAIR_PARSERS","ICON_STYLE_PARSERS","iconObject","ICON_PARSERS","xunits","yunits","LABEL_STYLE_PARSERS","LINE_STYLE_PARSERS","POLY_STYLE_PARSERS","FLAT_LINEAR_RING_PARSERS","GX_TRACK_PARSERS","whens","when","gxTrackObject","EXTRUDE_AND_ALTITUDE_MODE_PARSERS","MULTI_GEOMETRY_PARSERS","multiGeometry","homogeneous","setCommonGeometryProperties","innerBoundaryFlatLinearRings","INNER_BOUNDARY_IS_PARSERS","OUTER_BOUNDARY_IS_PARSERS","STYLE_PARSERS","styleObject","IconObject","drawIcon","hotSpot","imageStyle_1","imageScale_1","listener_1","imageSize_1","resizeScale","outline","hasExtrude","hasTessellate","hasAltitudeMode","extrudes","tessellates","altitudeModes","DATA_PARSERS","EXTENDED_DATA_PARSERS","featureObject","SCHEMA_DATA_PARSERS","writeColorTextNode","abgr","hex","EXTENDEDDATA_NODE_SERIALIZERS","pair","DATA_NODE_FACTORY","ICON_SEQUENCE","ICON_SERIALIZERS","GX_NODE_FACTORY","ICON_STYLE_SEQUENCE","ICON_STYLE_SERIALIZERS","vec2","writeScaleTextNode","LABEL_STYLE_SEQUENCE","LABEL_STYLE_SERIALIZERS","LINE_STYLE_SEQUENCE","LINE_STYLE_SERIALIZERS","GEOMETRY_NODE_FACTORY","POINT_NODE_FACTORY","LINE_STRING_NODE_FACTORY","LINEAR_RING_NODE_FACTORY","POLYGON_NODE_FACTORY","MULTI_GEOMETRY_SERIALIZERS","writePrimitiveGeometry","writePolygon","writeMultiGeometry","BOUNDARY_IS_SERIALIZERS","writeBoundaryIs","PLACEMARK_SERIALIZERS","namesAndValues","names","pointStyles","lineStyles","polyStyles","STYLE_SEQUENCE","STYLE_SERIALIZERS","PLACEMARK_SEQUENCE","EXTENDEDDATA_NODE_FACTORY","styleArray","PRIMITIVE_GEOMETRY_SEQUENCE","PRIMITIVE_GEOMETRY_SERIALIZERS","POLY_STYLE_SEQUENCE","POLYGON_SERIALIZERS","INNER_BOUNDARY_NODE_FACTORY","OUTER_BOUNDARY_NODE_FACTORY","POLY_STYLE_SERIALIZERS","iconProperties","WAY_PARSERS","ndrefs","readTag","PARSERS","NODE_PARSERS","ways","OSMXML","XML","readFromDocument","readFromNode","readHref","SERVICE_IDENTIFICATION_PARSERS","SERVICE_PROVIDER_PARSERS","OPERATIONS_METADATA_PARSERS","OWS","owsObject","ADDRESS_PARSERS","ALLOWED_VALUES_PARSERS","CONSTRAINT_PARSERS","CONTACT_INFO_PARSERS","PHONE_PARSERS","DCP_PARSERS","HTTP_PARSERS","REQUEST_METHOD_PARSERS","OPERATION_PARSERS","SERVICE_CONTACT_PARSERS","encodeDeltas","numbers","opt_factor","lastNumbers","encodeFloats","decodeDeltas","encoded","decodeFloats","encodeSignedIntegers","decodeSignedIntegers","encodeUnsignedIntegers","decodeUnsignedIntegers","encodeUnsignedInteger","factor_","Polyline","TopoJSON","topoJSONTopology","arcs","transformArc","transformArcs","topoJSONFeatures","objectName","readFeaturesFromGeometryCollection","readFeatureFromGeometry","transformVertex","concatenateArcs","polyArray","ringCoords","indices","tagName_","Filter","LogicalNary","Spatial","unit","propertyName","opt_matchCase","matchCase","ComparisonBinary","lowerBoundary","upperBoundary","opt_wildCard","opt_singleChar","opt_escapeChar","wildCard","singleChar","escapeChar","rid","and","And","Bbox","TRANSACTION_SUMMARY_PARSERS","TRANSACTION_RESPONSE_PARSERS","readTransactionSummary","readInsertResults","QUERY_SERIALIZERS","TRANSACTION_SERIALIZERS","writeFeature","writeUpdate","writeDelete","writeProperty","writeNative","FEATURE_PREFIX","XMLNS","OGCNS","WFSNS","FESNS","SCHEMA_LOCATIONS","GML_FORMATS","featureType_","featureNS_","gmlFormat_","gmlFormat","schemaLocation_","WFS","readTransactionResponseFromDocument","readTransactionResponseFromNode","readFeatureCollectionMetadataFromDocument","readFeatureCollectionMetadataFromNode","outputFormat","maxFeatures","resultType","viewParams","featurePrefix","propertyNames","combineBboxAndFilter","writeGetFeature","completeFilter","bboxFilter","bboxFilterFn","andFilterFn","inserts","updates","deletes","baseObj","gmlOptions","gmlVersion","createTransactionRequest","serializeTransactionRequest","nativeElements","OGC_FID_PARSERS","fidParser","INSERT_RESULTS_PARSERS","writeOgcFidFilter","getTypeName","typeName","nativeElement","vendorId","safeToIgnore","GETFEATURE_SERIALIZERS","writeQuery","writeDuringFilter","writeLogicalFilter","writeNotFilter","writeBboxFilter","writeSpatialFilter","writeDWithinFilter","writeComparisonFilter","writeIsNullFilter","writeIsBetweenFilter","writeIsLikeFilter","typeNameAttr","getFilterNS","writeFilterCondition","getTagName","writePropertyName","writeExpression","timePeriod","writeTimeInstant","writeLiteral","timeInstant","timePosition","WKBGeometryType","view_","pos_","initialized_","isLittleEndian_","hasZ_","hasM_","srid_","layout_","WkbReader","isLittleEndian","numPoints","numRings","expectedTypeId","wkbType","wkbTypeThousandth","hasSRID","typeId","readMultiPoint","readMultiLineString","readMultiPolygon","readGeometryCollection","readWkbPayload","readWkbHeader","readWkbCollection","readWkbBlock","isEWKB_","ewkb","writeQueue_","nodata_","X","Y","Z","WkbWriter","coordsObj","axis","_i","writeUint32","writeLineString","writeUint8","writeWkbHeader","geoms","findMinimumLayout","wkblut","geomType","writeMultiLineString","writeMultiPolygon","writeGeometryCollection","setUint8","setUint32","setFloat64","getDataView","decodeHexString","splitCollection","viewCache_","hex_","littleEndian_","ewkb_","nodataZ_","nodataZ","nodataM_","nodataM","WKB","getSrid","getBuffer","encodeHexString","GeometryConstructor","EMPTY","TokenType","wktTypeLookup","wkt","index_","Lexer","opt_decimal","nextChar_","isNumeric_","readNumber_","isAlpha_","readText_","isWhiteSpace_","nextToken","scientificNotation","lexer","lexer_","token_","Parser","isMatch","isTokenType","consume_","parseGeometry_","dimToken","dimInfo","formatErrorMessage_","parsePoint_","parsePointList_","parseLineStringTextList_","parsePointTextList_","parsePolygonTextList_","parsePointText_","parseLineStringText_","parsePolygonText_","parseGeometryLayout_","isEmptyGeometry_","parseGeometryCollectionText_","parseMultiPointText_","parseMultiLineStringText_","parseMultiPolygonText_","splitCollection_","WKT","parse_","encode","encodePointGeometry","encodeLineStringGeometry","encodePolygonGeometry","GeometryEncoder","components","enc","geometryEncoder","wktType","encodeGeometryLayout","SERVICE_PARSERS","CAPABILITY_PARSERS","REQUEST_PARSERS","EXCEPTION_PARSERS","layerObject","LAYER_PARSERS","readLayer","WMSCapabilities","wmsCapabilityObject","readKeywordList","CONTACT_INFORMATION_PARSERS","CONTACT_PERSON_PARSERS","CONTACT_ADDRESS_PARSERS","geographicBoundingBox","EX_GEOGRAPHIC_BOUNDING_BOX_PARSERS","westBoundLongitude","southBoundLatitude","eastBoundLongitude","northBoundLatitude","ATTRIBUTION_PARSERS","authorityObject","readFormatOnlineresource","metadataObject","readSizedFormatOnlineresource","readOperationType","OPERATIONTYPE_PARSERS","DCPTYPE_PARSERS","FORMAT_ONLINERESOURCE_PARSERS","KEYWORDLIST_PARSERS","parentLayerObject","queryable","cascaded","noSubsets","fixedWidth","fixedHeight","childValue","parentValue","formatOnlineresource","WMSGetFeatureInfo","layerElement","layerFeatures","gmlFeatures","readFeatures_","OWS_NAMESPACE_URIS","CONTENTS_PARSERS","owsParser_","WMTSCapabilities","WMTSCapabilityObject","TMS_PARSERS","isDefault","TMS_LINKS_PARSERS","DIMENSION_PARSERS","readBoundingBox","legend","TMS_LIMITS_LIST_PARSERS","TMS_LIMITS_PARSERS","WGS84_BBOX_READERS","readCoordinates","TM_PARSERS","events","FullScreenEventType","isFullScreenSupported","requestFullscreen","fullscreenEnabled","isFullScreen","fullscreenElement","requestFullScreen","isInFullscreen_","boundHandleMapTargetChange_","handleMapTargetChange_","cssClassName_","documentListeners_","activeClassName_","activeClassName","inactiveClassName_","inactiveClassName","labelNode_","labelActive","labelActiveNode_","button_","setClassName_","FullScreen","handleFullScreen_","exitFullscreen","exitFullScreen","requestFullScreenWithKeys","wasInFullscreen","fullscreen","_c","_d","handleFullScreenChange_","PROJECTION","COORDINATE_FORMAT","coordinateFormat","setCoordinateFormat","renderOnMouseOut","placeholder","undefinedHTML","placeholder_","renderOnMouseOut_","renderedHTML_","mapProjection_","MousePosition","updateHTML_","handleMouseMove","handleMouseOut","html","getCoordinateFormat","MAX_RATIO","MIN_RATIO","ControlledMap","boundHandleRotationChanged_","handleRotationChanged_","viewExtent_","ovmapDiv_","ovmap_","ovmap","addLayer","boxSizing","boxOverlay_","addOverlay","overlayBox","mousePosition","getEventCoordinateInternal","endMoving","OverviewMap","oldView","unbindView_","handleMapPropertyChange_","bindView_","resetExtent_","updateBoxAfterOvmapIsRendered_","newView","equalsExtent","ovmapSize","ovextent","topLeftPixel","bottomRightPixel","boxWidth","boxHeight","ovmapWidth","ovmapHeight","recenter_","ovview","ovresolution","ovmapPostrenderKey_","updateBox_","validateExtent_","UNITS_PROP","LEADING_DIGITS","DEFAULT_DPI","bar","innerElement_","viewState_","minWidth_","minWidth","maxWidth_","renderedWidth_","handleUnitsChanged_","setUnits","scaleBar_","scaleBarSteps_","scaleBarText_","dpi_","ScaleLine","pointResolutionUnits","ProjUnits","nominalCount","suffix","metersPerDegree","decimalCount","previousCount","previousWidth","previousDecimalCount","createScaleBar","mapScale","getScaleForResolution","scaleSteps","stepWidth","createMarker","createStepText","isLast","lengthString","Direction","currentResolution_","direction_","heightLimit_","widthLimit_","startX_","startY_","thumbSize_","sliderInitialized_","thumbElement","containerElement","handleDraggerStart_","handleDraggerDrag_","handleDraggerEnd_","handleContainerClick_","ZoomSlider","containerWidth","containerHeight","containerStyle","thumb","thumbStyle","thumbWidth","thumbHeight","relativePosition","getRelativePosition_","getResolutionForPosition_","drag","getPositionForResolution_","getResolutionForValueFunction","getValueForResolutionFunction","initSlider_","setThumbPosition_","ZoomToExtent","handleZoomToExtent","ol","$ol$AssertionError","$ol$Collection","_ol_Collection$CollectionEvent","$ol$DataTile","$ol$Disposable","$ol$Feature","_ol_Feature$createStyleFunction","$ol$Geolocation","$ol$Image","_ol_Image$listenImage","$ol$ImageBase","$ol$ImageCanvas","$ol$ImageTile","$ol$Kinetic","$ol$Map","$ol$MapBrowserEvent","$ol$MapBrowserEventHandler","$ol$MapEvent","$ol$Object","_ol_Object$ObjectEvent","$ol$Observable","_ol_Observable$unByKey","$ol$Overlay","$ol$PluggableMap","$ol$Tile","$ol$TileCache","$ol$TileQueue","_ol_TileQueue$getTilePriority","$ol$TileRange","_ol_TileRange$createOrUpdate","$ol$VectorRenderTile","$ol$VectorTile","$ol$View","_ol_View$createCenterConstraint","_ol_View$createResolutionConstraint","_ol_View$createRotationConstraint","_ol_View$isNoopAnimation","_ol_array$binarySearch","_ol_array$equals","_ol_array$extend","_ol_array$find","_ol_array$findIndex","_ol_array$includes","_ol_array$isSorted","_ol_array$linearFindNearest","_ol_array$numberSafeCompareFunction","_ol_array$reverseSubArray","stableSort","compareFnc","asserts","_ol_asserts$assert","centerconstraint","_ol_centerconstraint$createExtent","_ol_centerconstraint$none","_ol_color$asArray","_ol_color$asString","_ol_color$fromString","_ol_color$isStringColor","_ol_color$normalize","_ol_color$toString","colorlike","_ol_colorlike$asColorLike","$ol$control$Attribution","$ol$control$Control","$ol$control$FullScreen","$ol$control$MousePosition","$ol$control$OverviewMap","$ol$control$Rotate","$ol$control$ScaleLine","$ol$control$Zoom","$ol$control$ZoomSlider","$ol$control$ZoomToExtent","_ol_control$defaults","_ol_coordinate$add","_ol_coordinate$closestOnCircle","_ol_coordinate$closestOnSegment","createStringXY","_ol_coordinate$degreesToStringHDMS","_ol_coordinate$distance","_ol_coordinate$equals","_ol_coordinate$format","_ol_coordinate$getWorldsAway","_ol_coordinate$rotate","_ol_coordinate$scale","_ol_coordinate$squaredDistance","_ol_coordinate$squaredDistanceToSegment","toStringHDMS","_ol_coordinate$toStringXY","_ol_coordinate$wrapX","css","_ol_css$CLASS_COLLAPSED","_ol_css$CLASS_CONTROL","_ol_css$CLASS_HIDDEN","_ol_css$CLASS_SELECTABLE","_ol_css$CLASS_UNSELECTABLE","_ol_css$CLASS_UNSUPPORTED","_ol_css$getFontParameters","dom","_ol_dom$createCanvasContext2D","_ol_dom$outerHeight","_ol_dom$outerWidth","_ol_dom$releaseCanvas","_ol_dom$removeChildren","_ol_dom$removeNode","_ol_dom$replaceChildren","_ol_dom$replaceNode","_ol_easing$easeIn","_ol_easing$easeOut","_ol_easing$inAndOut","_ol_easing$linear","upAndDown","$ol$events$Event","_ol_events_Event$stopPropagation","$ol$events$Target","_ol_events_condition$all","_ol_events_condition$altKeyOnly","_ol_events_condition$altShiftKeysOnly","_ol_events_condition$always","click","doubleClick","_ol_events_condition$focus","_ol_events_condition$focusWithTabindex","_ol_events_condition$mouseActionButton","_ol_events_condition$mouseOnly","_ol_events_condition$never","_ol_events_condition$noModifierKeys","penOnly","pointerEvt","platformModifierKeyOnly","pointerMove","_ol_events_condition$primaryAction","_ol_events_condition$shiftKeyOnly","_ol_events_condition$singleClick","_ol_events_condition$targetNotEditable","touchOnly","_ol_events$listen","_ol_events$listenOnce","_ol_events$unlistenByKey","_ol_extent$applyTransform","_ol_extent$approximatelyEquals","_ol_extent$boundingExtent","_ol_extent$buffer","_ol_extent$clone","_ol_extent$closestSquaredDistanceXY","_ol_extent$containsCoordinate","_ol_extent$containsExtent","_ol_extent$containsXY","_ol_extent$coordinateRelationship","_ol_extent$createEmpty","_ol_extent$createOrUpdate","_ol_extent$createOrUpdateEmpty","_ol_extent$createOrUpdateFromCoordinate","createOrUpdateFromCoordinates","_ol_extent$createOrUpdateFromFlatCoordinates","createOrUpdateFromRings","_ol_extent$equals","_ol_extent$extend","_ol_extent$extendCoordinate","_ol_extent$extendCoordinates","_ol_extent$extendFlatCoordinates","_ol_extent$extendRings","_ol_extent$extendXY","_ol_extent$forEachCorner","_ol_extent$getArea","_ol_extent$getBottomLeft","_ol_extent$getBottomRight","_ol_extent$getCenter","_ol_extent$getCorner","getEnlargedArea","_ol_extent$getForViewAndSize","_ol_extent$getHeight","_ol_extent$getIntersection","getIntersectionArea","getMargin","_ol_extent$getRotatedViewport","_ol_extent$getTopLeft","_ol_extent$getTopRight","_ol_extent$getWidth","_ol_extent$intersects","_ol_extent$intersectsSegment","_ol_extent$isEmpty","_ol_extent$returnOrUpdate","_ol_extent$scaleFromCenter","_ol_extent$wrapAndSliceX","_ol_extent$wrapX","featureloader","_ol_featureloader$loadFeaturesXhr","setWithCredentials","xhrWithCredentials","_ol_featureloader$xhr","$ol$format$EsriJSON","$ol$format$Feature","_ol_format_Feature$transformExtentWithOptions","_ol_format_Feature$transformGeometryWithOptions","$ol$format$GML","$ol$format$GML2","$ol$format$GML3","$ol$format$GML32","$ol$format$GMLBase","_ol_format_GMLBase$GMLNS","$ol$format$GPX","$ol$format$GeoJSON","$ol$format$IGC","$ol$format$IIIFInfo","$ol$format$JSONFeature","$ol$format$KML","getDefaultFillStyle","getDefaultImageStyle","getDefaultStrokeStyle","getDefaultStyle","getDefaultStyleArray","getDefaultTextStyle","_ol_format_KML$readFlatCoordinates","$ol$format$MVT","$ol$format$OSMXML","$ol$format$OWS","$ol$format$Polyline","_ol_format_Polyline$decodeDeltas","_ol_format_Polyline$decodeFloats","_ol_format_Polyline$decodeSignedIntegers","_ol_format_Polyline$decodeUnsignedIntegers","_ol_format_Polyline$encodeDeltas","_ol_format_Polyline$encodeFloats","_ol_format_Polyline$encodeSignedIntegers","_ol_format_Polyline$encodeUnsignedInteger","_ol_format_Polyline$encodeUnsignedIntegers","$ol$format$TextFeature","$ol$format$TopoJSON","$ol$format$WFS","writeFilter","opt_version","$ol$format$WKB","$ol$format$WKT","$ol$format$WMSCapabilities","$ol$format$WMSGetFeatureInfo","$ol$format$WMTSCapabilities","$ol$format$XML","$ol$format$XMLFeature","$ol$format$filter$And","$ol$format$filter$Bbox","$ol$format$filter$Comparison","$ol$format$filter$ComparisonBinary","Contains","$ol$format$filter$Contains","DWithin","$ol$format$filter$DWithin","Disjoint","$ol$format$filter$Disjoint","During","$ol$format$filter$During","EqualTo","$ol$format$filter$EqualTo","$ol$format$filter$Filter","$ol$format$filter$GreaterThan","GreaterThanOrEqualTo","$ol$format$filter$GreaterThanOrEqualTo","Intersects","$ol$format$filter$Intersects","IsBetween","$ol$format$filter$IsBetween","IsLike","$ol$format$filter$IsLike","IsNull","$ol$format$filter$IsNull","$ol$format$filter$LessThan","LessThanOrEqualTo","$ol$format$filter$LessThanOrEqualTo","$ol$format$filter$LogicalNary","Not","$ol$format$filter$Not","NotEqualTo","$ol$format$filter$NotEqualTo","Or","$ol$format$filter$Or","ResourceId","$ol$format$filter$ResourceId","$ol$format$filter$Spatial","$ol$format$filter$Within","_ol_format_filter$and","_ol_format_filter$bbox","between","disjoint","during","dwithin","equalTo","greaterThan","greaterThanOrEqualTo","isNull","lessThan","lessThanOrEqualTo","like","not","notEqualTo","or","resourceId","within","xlink","_ol_format_xlink$readHref","xsd","_ol_format_xsd$readBoolean","_ol_format_xsd$readBooleanString","_ol_format_xsd$readDateTime","_ol_format_xsd$readDecimal","_ol_format_xsd$readDecimalString","_ol_format_xsd$readNonNegativeIntegerString","_ol_format_xsd$readPositiveInteger","_ol_format_xsd$readString","_ol_format_xsd$writeBooleanTextNode","_ol_format_xsd$writeCDATASection","_ol_format_xsd$writeDateTimeTextNode","_ol_format_xsd$writeDecimalTextNode","_ol_format_xsd$writeNonNegativeIntegerTextNode","_ol_format_xsd$writeStringTextNode","_ol_functions$FALSE","_ol_functions$TRUE","_ol_functions$VOID","_ol_functions$memoizeOne","_ol_functions$toPromise","$ol$geom$Circle","$ol$geom$Geometry","$ol$geom$GeometryCollection","$ol$geom$LineString","$ol$geom$LinearRing","$ol$geom$MultiLineString","$ol$geom$MultiPoint","$ol$geom$MultiPolygon","$ol$geom$Point","$ol$geom$Polygon","_ol_geom_Polygon$circular","_ol_geom_Polygon$fromCircle","_ol_geom_Polygon$fromExtent","_ol_geom_Polygon$makeRegular","$ol$geom$SimpleGeometry","_ol_geom_SimpleGeometry$getStrideForLayout","_ol_geom_SimpleGeometry$transformGeom2D","_ol_geom_flat_area$linearRing","_ol_geom_flat_area$linearRings","_ol_geom_flat_area$linearRingss","_ol_geom_flat_center$linearRingss","closest","_ol_geom_flat_closest$arrayMaxSquaredDelta","_ol_geom_flat_closest$assignClosestArrayPoint","_ol_geom_flat_closest$assignClosestMultiArrayPoint","_ol_geom_flat_closest$assignClosestPoint","_ol_geom_flat_closest$maxSquaredDelta","_ol_geom_flat_closest$multiArrayMaxSquaredDelta","_ol_geom_flat_contains$linearRingContainsExtent","_ol_geom_flat_contains$linearRingContainsXY","_ol_geom_flat_contains$linearRingsContainsXY","_ol_geom_flat_contains$linearRingssContainsXY","deflate","_ol_geom_flat_deflate$deflateCoordinate","_ol_geom_flat_deflate$deflateCoordinates","_ol_geom_flat_deflate$deflateCoordinatesArray","_ol_geom_flat_deflate$deflateMultiCoordinatesArray","flip","_ol_geom_flat_flip$flipXY","geodesic","greatCircleArc","geoProjection","cosLat1","sinLat1","cosLat2","sinLat2","cosDeltaLon","sinDeltaLon","D","cosD","sinD","_ol_geom_flat_geodesic$meridian","_ol_geom_flat_geodesic$parallel","inflate","_ol_geom_flat_inflate$inflateCoordinates","_ol_geom_flat_inflate$inflateCoordinatesArray","_ol_geom_flat_inflate$inflateMultiCoordinatesArray","interiorpoint","_ol_geom_flat_interiorpoint$getInteriorPointOfArray","_ol_geom_flat_interiorpoint$getInteriorPointsOfMultiArray","_ol_geom_flat_interpolate$interpolatePoint","_ol_geom_flat_interpolate$lineStringCoordinateAtM","_ol_geom_flat_interpolate$lineStringsCoordinateAtM","intersectsextent","_ol_geom_flat_intersectsextent$intersectsLineString","_ol_geom_flat_intersectsextent$intersectsLineStringArray","_ol_geom_flat_intersectsextent$intersectsLinearRing","_ol_geom_flat_intersectsextent$intersectsLinearRingArray","_ol_geom_flat_intersectsextent$intersectsLinearRingMultiArray","_ol_geom_flat_length$lineStringLength","linearRingLength","perimeter","orient","_ol_geom_flat_orient$inflateEnds","_ol_geom_flat_orient$linearRingIsClockwise","_ol_geom_flat_orient$linearRingsAreOriented","_ol_geom_flat_orient$linearRingssAreOriented","_ol_geom_flat_orient$orientLinearRings","_ol_geom_flat_orient$orientLinearRingsArray","_ol_geom_flat_reverse$coordinates","_ol_geom_flat_segments$forEach","simplify","_ol_geom_flat_simplify$douglasPeucker","_ol_geom_flat_simplify$douglasPeuckerArray","douglasPeuckerMultiArray","_ol_geom_flat_simplify$quantize","_ol_geom_flat_simplify$quantizeArray","_ol_geom_flat_simplify$quantizeMultiArray","_ol_geom_flat_simplify$radialDistance","simplifyLineString","highQuality","opt_simplifiedFlatCoordinates","_ol_geom_flat_simplify$snap","straightchunk","_ol_geom_flat_straightchunk$matchingChunk","textpath","_ol_geom_flat_textpath$drawTextOnPath","topology","lineStringIsClosed","lastCoord","_ol_geom_flat_transform$rotate","_ol_geom_flat_transform$scale","_ol_geom_flat_transform$transform2D","_ol_geom_flat_transform$translate","_ol_has$DEVICE_PIXEL_RATIO","_ol_has$FIREFOX","_ol_has$IMAGE_DECODE","_ol_has$MAC","_ol_has$PASSIVE_EVENT_LISTENERS","_ol_has$SAFARI","_ol_has$SAFARI_BUG_237906","_ol_has$WEBKIT","_ol_has$WORKER_OFFSCREEN_CANVAS","$ol$interaction$DoubleClickZoom","$ol$interaction$DragAndDrop","_ol_interaction_DragAndDrop$DragAndDropEvent","$ol$interaction$DragBox","_ol_interaction_DragBox$DragBoxEvent","$ol$interaction$DragPan","$ol$interaction$DragRotate","$ol$interaction$DragRotateAndZoom","$ol$interaction$DragZoom","$ol$interaction$Draw","_ol_interaction_Draw$DrawEvent","createBox","opt_geometry","boxCoordinates","createRegularPolygon","$ol$interaction$Extent","_ol_interaction_Extent$ExtentEvent","$ol$interaction$Interaction","_ol_interaction_Interaction$pan","_ol_interaction_Interaction$zoomByDelta","$ol$interaction$KeyboardPan","$ol$interaction$KeyboardZoom","$ol$interaction$Link","$ol$interaction$Modify","_ol_interaction_Modify$ModifyEvent","$ol$interaction$MouseWheelZoom","$ol$interaction$PinchRotate","$ol$interaction$PinchZoom","Pointer","$ol$interaction$Pointer","_ol_interaction_Pointer$centroid","$ol$interaction$Select","_ol_interaction_Select$SelectEvent","$ol$interaction$Snap","$ol$interaction$Translate","_ol_interaction_Translate$TranslateEvent","_ol_interaction$defaults","Base","$ol$layer$Base","BaseImage","$ol$layer$BaseImage","BaseTile","$ol$layer$BaseTile","$ol$layer$BaseVector","$ol$layer$Graticule","Group","$ol$layer$Group","_ol_layer_Group$GroupEvent","$ol$layer$Heatmap","$ol$layer$Image","$ol$layer$Layer","_ol_layer_Layer$inView","MapboxVector","$ol$layer$MapboxVector","$ol$layer$Tile","Vector","$ol$layer$Vector","VectorImage","$ol$layer$VectorImage","$ol$layer$VectorTile","WebGLPoints","$ol$layer$WebGLPoints","WebGLTile","$ol$layer$WebGLTile","loadingstrategy","_ol_loadingstrategy$all","math","_ol_math$ceil","_ol_math$clamp","_ol_math$cosh","_ol_math$floor","_ol_math$lerp","_ol_math$log2","_ol_math$modulo","_ol_math$round","_ol_math$solveLinearSystem","_ol_math$squaredDistance","_ol_math$squaredSegmentDistance","_ol_math$toDegrees","_ol_math$toFixed","_ol_math$toRadians","net","_ol_net$ClientError","_ol_net$ResponseError","_ol_net$getJSON","_ol_net$jsonp","overrideXHR","_ol_net$resolveUrl","restoreXHR","_ol_obj$assign","_ol_obj$clear","_ol_obj$getValues","_ol_obj$isEmpty","$ol$proj$Projection","_ol_proj_Units$METERS_PER_UNIT","_ol_proj_Units$fromCode","_ol_proj$addCommon","_ol_proj$addCoordinateTransforms","_ol_proj$addEquivalentProjections","_ol_proj$addEquivalentTransforms","_ol_proj$addProjection","_ol_proj$addProjections","clearAllProjections","clearProj","clearTransformFuncs","clearUserProjection","_ol_proj$cloneTransform","_ol_proj$createProjection","_ol_proj$createSafeCoordinateTransform","_ol_proj$createTransformFromCoordinateTransform","_ol_proj$disableCoordinateWarning","epsg3857","_ol_proj_epsg3857$EXTENT","_ol_proj_epsg3857$HALF_SIZE","_ol_proj_epsg3857$MAX_SAFE_Y","_ol_proj_epsg3857$PROJECTIONS","_ol_proj_epsg3857$RADIUS","_ol_proj_epsg3857$WORLD_EXTENT","_ol_proj_epsg3857$fromEPSG4326","_ol_proj_epsg3857$toEPSG4326","epsg4326","_ol_proj_epsg4326$EXTENT","_ol_proj_epsg4326$METERS_PER_UNIT","_ol_proj_epsg4326$PROJECTIONS","_ol_proj_epsg4326$RADIUS","_ol_proj$equivalent","_ol_proj$fromLonLat","_ol_proj$fromUserCoordinate","_ol_proj$fromUserExtent","_ol_proj$fromUserResolution","_ol_proj$get","_ol_proj$getPointResolution","_ol_proj$getTransform","_ol_proj$getTransformFromProjections","_ol_proj$getUserProjection","_ol_proj$identityTransform","proj4","projCodes","defs","def","projName","to_meter","code1","proj1","code2","proj2","_ol_proj_projections$add","_ol_proj_projections$clear","_ol_proj_projections$get","_ol_proj$setUserProjection","toLonLat","lonLat","_ol_proj$toUserCoordinate","_ol_proj$toUserExtent","_ol_proj$toUserResolution","_ol_proj$transform","_ol_proj$transformExtent","transformWithProjections","_ol_proj_transforms$add","_ol_proj_transforms$clear","_ol_proj_transforms$get","useGeographic","Box","$ol$render$Box","$ol$render$Event","$ol$render$Feature","toFeature","opt_geometryName","_ol_render_Feature$toGeometry","$ol$render$VectorContext","$ol$render$canvas$Builder","$ol$render$canvas$BuilderGroup","$ol$render$canvas$Executor","$ol$render$canvas$ExecutorGroup","_ol_render_canvas_ExecutorGroup$getPixelIndexArray","$ol$render$canvas$ImageBuilder","Immediate","$ol$render$canvas$Immediate","_ol_render_canvas_Instruction$beginPathInstruction","_ol_render_canvas_Instruction$closePathInstruction","_ol_render_canvas_Instruction$fillInstruction","_ol_render_canvas_Instruction$strokeInstruction","$ol$render$canvas$LineStringBuilder","$ol$render$canvas$PolygonBuilder","$ol$render$canvas$TextBuilder","_ol_render_canvas$checkedFonts","_ol_render_canvas$defaultFillStyle","_ol_render_canvas$defaultFont","_ol_render_canvas$defaultLineCap","_ol_render_canvas$defaultLineDash","defaultLineDashOffset","_ol_render_canvas$defaultLineJoin","defaultLineWidth","_ol_render_canvas$defaultMiterLimit","_ol_render_canvas$defaultPadding","_ol_render_canvas$defaultStrokeStyle","_ol_render_canvas$defaultTextAlign","_ol_render_canvas$defaultTextBaseline","_ol_render_canvas$drawImageOrLabel","_ol_render_canvas$getTextDimensions","hitdetect","_ol_render_canvas_hitdetect$HIT_DETECT_RESOLUTION","_ol_render_canvas_hitdetect$createHitDetectionImageData","_ol_render_canvas_hitdetect$hitDetect","_ol_render_canvas$labelCache","_ol_render_canvas$measureAndCacheTextWidth","_ol_render_canvas$measureTextHeight","_ol_render_canvas$measureTextWidth","_ol_render_canvas$registerFont","rotateAtOffset","_ol_render_canvas$textHeights","getRenderPixel","_ol_render$getVectorContext","toContext","Composite","$ol$renderer$Composite","$ol$renderer$Layer","$ol$renderer$Map","$ol$renderer$canvas$ImageLayer","$ol$renderer$canvas$Layer","_ol_renderer_canvas_Layer$canvasPool","$ol$renderer$canvas$TileLayer","$ol$renderer$canvas$VectorImageLayer","$ol$renderer$canvas$VectorLayer","$ol$renderer$canvas$VectorTileLayer","common","_ol_renderer_canvas_common$IMAGE_SMOOTHING_DISABLED","_ol_renderer_canvas_common$IMAGE_SMOOTHING_ENABLED","vector","_ol_renderer_vector$defaultOrder","_ol_renderer_vector$getSquaredTolerance","_ol_renderer_vector$getTolerance","_ol_renderer_vector$renderFeature","webgl","$ol$renderer$webgl$Layer","_ol_renderer_webgl_Layer$colorDecodeId","_ol_renderer_webgl_Layer$colorEncodeId","getBlankImageData","writePointFeatureToBuffers","elementIndex","bufferPositions","customAttrs","vPos","iPos","baseIndex","PointsLayer","$ol$renderer$webgl$PointsLayer","$ol$renderer$webgl$TileLayer","_ol_renderer_webgl_TileLayer$Attributes","_ol_renderer_webgl_TileLayer$Uniforms","reproj","$ol$reproj$Image","$ol$reproj$Tile","$ol$reproj$Triangulation","_ol_reproj$calculateSourceExtentResolution","_ol_reproj$calculateSourceResolution","_ol_reproj$canvasPool","_ol_reproj_common$ENABLE_RASTER_REPROJECTION","ERROR_THRESHOLD","_ol_reproj$render","resolutionconstraint","_ol_resolutionconstraint$createMinMaxResolution","_ol_resolutionconstraint$createSnapToPower","_ol_resolutionconstraint$createSnapToResolutions","rotationconstraint","_ol_rotationconstraint$createSnapToN","_ol_rotationconstraint$createSnapToZero","_ol_rotationconstraint$disable","_ol_rotationconstraint$none","_ol_size$buffer","_ol_size$hasArea","_ol_size$scale","_ol_size$toSize","$ol$source$BingMaps","_ol_source_BingMaps$quadKey","$ol$source$CartoDB","$ol$source$Cluster","$ol$source$DataTile","$ol$source$GeoTIFF","IIIF","$ol$source$IIIF","$ol$source$Image","_ol_source_Image$ImageSourceEvent","_ol_source_Image$defaultImageLoadFunction","$ol$source$ImageArcGISRest","$ol$source$ImageCanvas","$ol$source$ImageMapGuide","ImageStatic","$ol$source$ImageStatic","$ol$source$ImageWMS","$ol$source$OGCMapTile","$ol$source$OGCVectorTile","OSM","$ol$source$OSM","_ol_source_OSM$ATTRIBUTION","Raster","$ol$source$Raster","_ol_source_Raster$Processor","_ol_source_Raster$RasterSourceEvent","_ol_source_Raster$newImageData","$ol$source$Source","Stamen","$ol$source$Stamen","$ol$source$Tile","_ol_source_Tile$TileSourceEvent","$ol$source$TileArcGISRest","TileDebug","$ol$source$TileDebug","$ol$source$TileImage","$ol$source$TileJSON","$ol$source$TileWMS","$ol$source$UTFGrid","_ol_source_UTFGrid$CustomTile","$ol$source$UrlTile","$ol$source$Vector","_ol_source_Vector$VectorSourceEvent","$ol$source$VectorTile","_ol_source_VectorTile$defaultLoadFunction","$ol$source$WMTS","optionsFromCapabilities","wmtsCap","tileMatrixSets","supportedCRS","matrixSetObj","projConfig","switchXY","TileMatrix","selectedMatrixLimit","MinTileCol","MinTileRow","MaxTileCol","MatrixWidth","MaxTileRow","MatrixHeight","tileMatrixValue","Identifier","ScaleDenominator","TopLeftCorner","tileSpanX","tileSpanY","TileHeight","matrixSetExtent","wgs84BoundingBox","wgs84ProjectionExtent","wgs84MatrixSetExtent","gets","encodings","$ol$source$XYZ","Zoomify","$ol$source$Zoomify","_ol_source_Zoomify$CustomTile","DEFAULT_WMS_VERSION","ogcTileUtil","_ol_source_ogcTileUtil$getMapTileUrlTemplate","_ol_source_ogcTileUtil$getTileSetInfo","_ol_source_ogcTileUtil$getVectorTileUrlTemplate","sourcesFromTileGrid","sourceCache","tileGridExtent","wantedSources","wms","_ol_source_wms$DEFAULT_VERSION","sphere","_ol_sphere$DEFAULT_RADIUS","_ol_sphere$getDistance","_ol_sphere$offset","_ol_string$compareVersions","_ol_string$padNumber","structs","$ol$structs$LRUCache","$ol$structs$LinkedList","$ol$structs$PriorityQueue","_ol_structs_PriorityQueue$DROP","$ol$structs$RBush","$ol$style$Circle","$ol$style$Fill","$ol$style$Icon","$ol$style$IconImage","_ol_style_IconImage$get","$ol$style$IconImageCache","_ol_style_IconImageCache$shared","$ol$style$Image","$ol$style$RegularShape","$ol$style$Stroke","$ol$style$Style","_ol_style_Style$createDefaultStyle","_ol_style_Style$createEditingStyle","_ol_style_Style$toFunction","$ol$style$Text","_ol_style_expressions$Operators","_ol_style_expressions$PALETTE_TEXTURE_ARRAY","_ol_style_expressions$arrayToGlsl","_ol_style_expressions$colorToGlsl","_ol_style_expressions$expressionToGlsl","_ol_style_expressions$getStringNumberEquivalent","_ol_style_expressions$getValueType","_ol_style_expressions$isTypeUnique","_ol_style_expressions$numberToGlsl","_ol_style_expressions$stringToGlsl","_ol_style_expressions$uniformNameForVariable","tilecoord","_ol_tilecoord$createOrUpdate","_ol_tilecoord$fromKey","_ol_tilecoord$getCacheKeyForTileKey","_ol_tilecoord$getKey","_ol_tilecoord$getKeyZXY","_ol_tilecoord$hash","_ol_tilecoord$withinExtentAndZ","$ol$tilegrid$TileGrid","$ol$tilegrid$WMTS","_ol_tilegrid_WMTS$createFromCapabilitiesMatrixSet","_ol_tilegrid_common$DEFAULT_TILE_SIZE","_ol_tilegrid$createForExtent","_ol_tilegrid$createForProjection","_ol_tilegrid$createXYZ","_ol_tilegrid$extentFromProjection","_ol_tilegrid$getForProjection","_ol_tilegrid$wrapX","tileurlfunction","_ol_tileurlfunction$createFromTemplate","_ol_tileurlfunction$createFromTemplates","_ol_tileurlfunction$createFromTileUrlFunctions","_ol_tileurlfunction$expandUrl","_ol_tileurlfunction$nullTileUrlFunction","_ol_transform$apply","_ol_transform$compose","composeCssTransform","_ol_transform$create","_ol_transform$determinant","invert","_ol_transform$makeInverse","_ol_transform$makeScale","_ol_transform$multiply","_ol_transform$reset","_ol_transform$rotate","_ol_transform$scale","_ol_transform$set","_ol_transform$setFromArray","_ol_transform$toString","_ol_transform$translate","_ol_uri$appendParams","util","_ol_util$VERSION","_ol_util$abstract","_ol_util$getUid","vec","_ol_vec_mat4$create","_ol_vec_mat4$fromTransform","_ol_webgl$ARRAY_BUFFER","$ol$webgl$Buffer","_ol_webgl_Buffer$getArrayClassForType","_ol_webgl$DYNAMIC_DRAW","_ol_webgl$ELEMENT_ARRAY_BUFFER","_ol_webgl$FLOAT","Helper","$ol$webgl$Helper","_ol_webgl_Helper$computeAttributesStride","$ol$webgl$PaletteTexture","PostProcessingPass","$ol$webgl$PostProcessingPass","RenderTarget","$ol$webgl$RenderTarget","_ol_webgl$STATIC_DRAW","STREAM_DRAW","_ol_webgl_ShaderBuilder$ShaderBuilder","_ol_webgl_ShaderBuilder$parseLiteralStyle","$ol$webgl$TileTexture","_ol_webgl$getContext","getSupportedExtensions","_ol_xml$OBJECT_PROPERTY_NODE_FACTORY","_ol_xml$XML_SCHEMA_INSTANCE_URI","_ol_xml$createElementNS","_ol_xml$getAllTextContent","_ol_xml$getAllTextContent_","_ol_xml$getAttributeNS","_ol_xml$getDocument","_ol_xml$getXMLSerializer","_ol_xml$isDocument","_ol_xml$makeArrayExtender","_ol_xml$makeArrayPusher","_ol_xml$makeArraySerializer","_ol_xml$makeChildAppender","_ol_xml$makeObjectPropertyPusher","_ol_xml$makeObjectPropertySetter","_ol_xml$makeReplacer","_ol_xml$makeSequence","_ol_xml$makeSimpleNodeFactory","_ol_xml$makeStructureNS","_ol_xml$parse","_ol_xml$parseNode","_ol_xml$pushParseAndPop","_ol_xml$pushSerializeAndPop","registerDocument","registerXMLSerializer","xmlSerializer","_ol_xml$serialize","fieldTags","StripRowCounts","SubIFDs","fieldTypeNames","WhiteIsZero","BlackIsZero","Palette","TransparencyMask","CMYK","YCbCr","CIELab","ICCLab","Unspecified","Assocalpha","Unassalpha","LercParameters","Version","AddCompression","LercAddCompression","None","Deflate","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","__webpack_modules__","chunkId","prop","needAttach","scripts","getElementsByTagName","charset","nc","onScriptComplete","doneFns","scriptUrl","importScripts","currentScript","installedChunks","installedChunkData","errorType","realSrc","webpackJsonpCallback","parentChunkLoadingFunction","chunkIds","moreModules","chunkLoadingGlobal","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file diff --git a/src/main/webapp/resources/engine/openlayers/proj4.js b/src/main/webapp/resources/engine/openlayers/proj4.js new file mode 100644 index 0000000..f622704 --- /dev/null +++ b/src/main/webapp/resources/engine/openlayers/proj4.js @@ -0,0 +1 @@ +!function(t,s){"object"==typeof exports&&"undefined"!=typeof module?module.exports=s():"function"==typeof define&&define.amd?define(s):t.proj4=s()}(this,function(){"use strict";function t(t,s){if(t[s])return t[s];for(var i,a=Object.keys(t),h=s.toLowerCase().replace(dt,""),e=-1;++e0?90:-90),t.lat_ts=t.lat1)}function o(t){var s=this;if(2===arguments.length){var i=arguments[1];"string"==typeof i?"+"===i.charAt(0)?o[t]=yt(arguments[1]):o[t]=At(arguments[1]):o[t]=i}else if(1===arguments.length){if(Array.isArray(t))return t.map(function(t){Array.isArray(t)?o.apply(s,t):o(t)});if("string"==typeof t){if(t in o)return o[t]}else"EPSG"in t?o["EPSG:"+t.EPSG]=t:"ESRI"in t?o["ESRI:"+t.ESRI]=t:"IAU2000"in t?o["IAU2000:"+t.IAU2000]=t:console.log(t);return}}function l(t){return"string"==typeof t}function c(t){return t in o}function M(t){return Ct.some(function(s){return t.indexOf(s)>-1})}function u(s){var i=t(s,"authority");if(i){var a=t(i,"epsg");return a&&Pt.indexOf(a)>-1}}function f(s){var i=t(s,"extension");if(i)return t(i,"proj4")}function m(t){return"+"===t[0]}function p(t){if(!l(t))return t;if(c(t))return o[t];if(M(t)){var s=At(t);if(u(s))return o["EPSG:3857"];var i=f(s);return i?yt(i):s}return m(t)?yt(t):void 0}function d(t){return t}function y(t,s){var i=Tt.length;return t.names?(Tt[i]=t,t.names.forEach(function(t){Gt[t.toLowerCase()]=i}),this):(console.log(s),!0)}function _(t,s,i,a){var h=t*t,e=s*s,n=(h-e)/h,r=0;return a?(h=(t*=1-n*(et+n*(nt+n*rt)))*t,n=0):r=Math.sqrt(n),{es:n,e:r,ep2:(h-e)/e}}function x(s,i,a,h,e){if(!s){var n=t(Lt,h);n||(n=zt),s=n.a,i=n.b,a=n.rf}return a&&!i&&(i=(1-1/a)*s),(0===a||Math.abs(s-i)3&&(0===n.datum_params[3]&&0===n.datum_params[4]&&0===n.datum_params[5]&&0===n.datum_params[6]||(n.datum_type=tt,n.datum_params[3]*=at,n.datum_params[4]*=at,n.datum_params[5]*=at,n.datum_params[6]=n.datum_params[6]/1e6+1))),n.a=i,n.b=a,n.es=h,n.ep2=e,n}function Projection(s,i){if(!(this instanceof Projection))return new Projection(s);i=i||function(t){if(t)throw t};var a=p(s);if("object"==typeof a){var h=Projection.projections.get(a.projName);if(h){if(a.datumCode&&"none"!==a.datumCode){var e=t(Bt,a.datumCode);e&&(a.datum_params=e.towgs84?e.towgs84.split(","):null,a.ellps=e.ellipse,a.datumName=e.datumName?e.datumName:a.datumCode)}a.k0=a.k0||1,a.axis=a.axis||"enu",a.ellps=a.ellps||"wgs84";var n=x(a.a,a.b,a.rf,a.ellps,a.sphere),r=_(n.a,n.b,n.rf,a.R_A),o=a.datum||v(a.datumCode,a.datum_params,n.a,n.b,r.es,r.ep2);Nt(this,a),Nt(this,h),this.a=n.a,this.b=n.b,this.rf=n.rf,this.sphere=n.sphere,this.es=r.es,this.e=r.e,this.ep2=r.ep2,this.datum=o,this.init(),i(null,this)}else i(s)}else i(s)}function g(t,s){return t.datum_type===s.datum_type&&(!(t.a!==s.a||Math.abs(t.es-s.es)>5e-11)&&(t.datum_type===$?t.datum_params[0]===s.datum_params[0]&&t.datum_params[1]===s.datum_params[1]&&t.datum_params[2]===s.datum_params[2]:t.datum_type!==tt||t.datum_params[0]===s.datum_params[0]&&t.datum_params[1]===s.datum_params[1]&&t.datum_params[2]===s.datum_params[2]&&t.datum_params[3]===s.datum_params[3]&&t.datum_params[4]===s.datum_params[4]&&t.datum_params[5]===s.datum_params[5]&&t.datum_params[6]===s.datum_params[6]))}function b(t,s,i){var a,h,e,n,r=t.x,o=t.y,l=t.z?t.z:0;if(o<-ht&&o>-1.001*ht)o=-ht;else if(o>ht&&o<1.001*ht)o=ht;else{if(o<-ht)return{x:-1/0,y:-1/0,z:t.z};if(o>ht)return{x:1/0,y:1/0,z:t.z}}return r>Math.PI&&(r-=2*Math.PI),h=Math.sin(o),n=Math.cos(o),e=h*h,a=i/Math.sqrt(1-s*e),{x:(a+l)*n*Math.cos(r),y:(a+l)*n*Math.sin(r),z:(a*(1-s)+l)*h}}function w(t,s,i,a){var h,e,n,r,o,l,c,M,u,f,m,p,d,y,_,x,v=t.x,g=t.y,b=t.z?t.z:0;if(h=Math.sqrt(v*v+g*g),e=Math.sqrt(v*v+g*g+b*b),h/i<1e-12){if(y=0,e/i<1e-12)return _=ht,x=-a,{x:t.x,y:t.y,z:t.z}}else y=Math.atan2(g,v);n=b/e,M=(r=h/e)*(1-s)*(o=1/Math.sqrt(1-s*(2-s)*r*r)),u=n*o,d=0;do{d++,l=s*(c=i/Math.sqrt(1-s*u*u))/(c+(x=h*M+b*u-c*(1-s*u*u))),p=(m=n*(o=1/Math.sqrt(1-l*(2-l)*r*r)))*M-(f=r*(1-l)*o)*u,M=f,u=m}while(p*p>1e-24&&d<30);return _=Math.atan(m/Math.abs(f)),{x:y,y:_,z:x}}function E(t,s,i){if(s===$)return{x:t.x+i[0],y:t.y+i[1],z:t.z+i[2]};if(s===tt){var a=i[0],h=i[1],e=i[2],n=i[3],r=i[4],o=i[5],l=i[6];return{x:l*(t.x-o*t.y+r*t.z)+a,y:l*(o*t.x+t.y-n*t.z)+h,z:l*(-r*t.x+n*t.y+t.z)+e}}}function A(t,s,i){if(s===$)return{x:t.x-i[0],y:t.y-i[1],z:t.z-i[2]};if(s===tt){var a=i[0],h=i[1],e=i[2],n=i[3],r=i[4],o=i[5],l=i[6],c=(t.x-a)/l,M=(t.y-h)/l,u=(t.z-e)/l;return{x:c+o*M-r*u,y:-o*c+M+n*u,z:r*c-n*M+u}}}function C(t){return t===$||t===tt}function P(t){if("function"==typeof Number.isFinite){if(Number.isFinite(t))return;throw new TypeError("coordinates must be finite numbers")}if("number"!=typeof t||t!==t||!isFinite(t))throw new TypeError("coordinates must be finite numbers")}function N(t,s){return(t.datum.datum_type===$||t.datum.datum_type===tt)&&"WGS84"!==s.datumCode||(s.datum.datum_type===$||s.datum.datum_type===tt)&&"WGS84"!==t.datumCode}function S(t,s,i){var a;if(Array.isArray(i)&&(i=Ft(i)),Qt(i),t.datum&&s.datum&&N(t,s)&&(i=S(t,a=new Projection("WGS84"),i),t=a),"enu"!==t.axis&&(i=Ut(t,!1,i)),"longlat"===t.projName)i={x:i.x*lt,y:i.y*lt,z:i.z||0};else if(t.to_meter&&(i={x:i.x*t.to_meter,y:i.y*t.to_meter,z:i.z||0}),!(i=t.inverse(i)))return;return t.from_greenwich&&(i.x+=t.from_greenwich),i=Dt(t.datum,s.datum,i),s.from_greenwich&&(i={x:i.x-s.from_greenwich,y:i.y,z:i.z||0}),"longlat"===s.projName?i={x:i.x*ct,y:i.y*ct,z:i.z||0}:(i=s.forward(i),s.to_meter&&(i={x:i.x/s.to_meter,y:i.y/s.to_meter,z:i.z||0})),"enu"!==s.axis?Ut(s,!0,i):i}function k(t,s,i){var a,h,e;return Array.isArray(i)?(a=S(t,s,i)||{x:NaN,y:NaN},i.length>2?void 0!==t.name&&"geocent"===t.name||void 0!==s.name&&"geocent"===s.name?"number"==typeof a.z?[a.x,a.y,a.z].concat(i.splice(3)):[a.x,a.y,i[2]].concat(i.splice(3)):[a.x,a.y].concat(i.splice(2)):[a.x,a.y]):(h=S(t,s,i),2===(e=Object.keys(i)).length?h:(e.forEach(function(a){if(void 0!==t.name&&"geocent"===t.name||void 0!==s.name&&"geocent"===s.name){if("x"===a||"y"===a||"z"===a)return}else if("x"===a||"y"===a)return;h[a]=i[a]}),h))}function O(t){return t instanceof Projection?t:t.oProj?t.oProj:Projection(t)}function I(t,s,i){t=O(t);var a,h=!1;return void 0===s?(s=t,t=Wt,h=!0):(void 0!==s.x||Array.isArray(s))&&(i=s,s=t,t=Wt,h=!0),s=O(s),i?k(t,s,i):(a={forward:function(i){return k(t,s,i)},inverse:function(i){return k(s,t,i)}},h&&(a.oProj=s),a)}function q(t,s){return s=s||5,B(j({lat:t[1],lon:t[0]}),s)}function R(t){var s=L(Q(t.toUpperCase()));return s.lat&&s.lon?[s.lon,s.lat]:[(s.left+s.right)/2,(s.top+s.bottom)/2]}function G(t){return t*(Math.PI/180)}function T(t){return t/Math.PI*180}function j(t){var s,i,a,h,e,n,r,o=t.lat,l=t.lon,c=6378137,M=G(o),u=G(l);r=Math.floor((l+180)/6)+1,180===l&&(r=60),o>=56&&o<64&&l>=3&&l<12&&(r=32),o>=72&&o<84&&(l>=0&&l<9?r=31:l>=9&&l<21?r=33:l>=21&&l<33?r=35:l>=33&&l<42&&(r=37)),n=G(6*(r-1)-180+3),s=c/Math.sqrt(1-.00669438*Math.sin(M)*Math.sin(M)),i=Math.tan(M)*Math.tan(M),a=.006739496752268451*Math.cos(M)*Math.cos(M);var f=.9996*s*((h=Math.cos(M)*(u-n))+(1-i+a)*h*h*h/6+(5-18*i+i*i+72*a-.39089081163157013)*h*h*h*h*h/120)+5e5,m=.9996*((e=c*(.9983242984503243*M-.002514607064228144*Math.sin(2*M)+2639046602129982e-21*Math.sin(4*M)-3.418046101696858e-9*Math.sin(6*M)))+s*Math.tan(M)*(h*h/2+(5-i+9*a+4*a*a)*h*h*h*h/24+(61-58*i+i*i+600*a-2.2240339282485886)*h*h*h*h*h*h/720));return o<0&&(m+=1e7),{northing:Math.round(m),easting:Math.round(f),zoneNumber:r,zoneLetter:z(o)}}function L(t){var s=t.northing,i=t.easting,a=t.zoneLetter,h=t.zoneNumber;if(h<0||h>60)return null;var e,n,r,o,l,c,M,u,f=6378137,m=(1-Math.sqrt(.99330562))/(1+Math.sqrt(.99330562)),p=i-5e5,d=s;a<"N"&&(d-=1e7),c=6*(h-1)-180+3,u=(M=d/.9996/6367449.145945056)+(3*m/2-27*m*m*m/32)*Math.sin(2*M)+(21*m*m/16-55*m*m*m*m/32)*Math.sin(4*M)+151*m*m*m/96*Math.sin(6*M),e=f/Math.sqrt(1-.00669438*Math.sin(u)*Math.sin(u)),n=Math.tan(u)*Math.tan(u),r=.006739496752268451*Math.cos(u)*Math.cos(u),o=.99330562*f/Math.pow(1-.00669438*Math.sin(u)*Math.sin(u),1.5),l=p/(.9996*e);var y=u-e*Math.tan(u)/o*(l*l/2-(5+3*n+10*r-4*r*r-.06065547077041606)*l*l*l*l/24+(61+90*n+298*r+45*n*n-1.6983531815716497-3*r*r)*l*l*l*l*l*l/720);y=T(y);var _=(l-(1+2*n+r)*l*l*l/6+(5-2*r+28*n-3*r*r+.05391597401814761+24*n*n)*l*l*l*l*l/120)/Math.cos(u);_=c+T(_);var x;if(t.accuracy){var v=L({northing:t.northing+t.accuracy,easting:t.easting+t.accuracy,zoneLetter:t.zoneLetter,zoneNumber:t.zoneNumber});x={top:v.lat,right:v.lon,bottom:y,left:_}}else x={lat:y,lon:_};return x}function z(t){var s="Z";return 84>=t&&t>=72?s="X":72>t&&t>=64?s="W":64>t&&t>=56?s="V":56>t&&t>=48?s="U":48>t&&t>=40?s="T":40>t&&t>=32?s="S":32>t&&t>=24?s="R":24>t&&t>=16?s="Q":16>t&&t>=8?s="P":8>t&&t>=0?s="N":0>t&&t>=-8?s="M":-8>t&&t>=-16?s="L":-16>t&&t>=-24?s="K":-24>t&&t>=-32?s="J":-32>t&&t>=-40?s="H":-40>t&&t>=-48?s="G":-48>t&&t>=-56?s="F":-56>t&&t>=-64?s="E":-64>t&&t>=-72?s="D":-72>t&&t>=-80&&(s="C"),s}function B(t,s){var i="00000"+t.easting,a="00000"+t.northing;return t.zoneNumber+t.zoneLetter+D(t.easting,t.northing,t.zoneNumber)+i.substr(i.length-5,s)+a.substr(a.length-5,s)}function D(t,s,i){var a=U(i);return F(Math.floor(t/1e5),Math.floor(s/1e5)%20,a)}function U(t){var s=t%Ht;return 0===s&&(s=Ht),s}function F(t,s,i){var a=i-1,h=Xt.charCodeAt(a),e=Kt.charCodeAt(a),n=h+t-1,r=e+s,o=!1;return n>$t&&(n=n-$t+Jt-1,o=!0),(n===Vt||hVt||(n>Vt||hZt||(n>Zt||h$t&&(n=n-$t+Jt-1),r>Yt?(r=r-Yt+Jt-1,o=!0):o=!1,(r===Vt||eVt||(r>Vt||eZt||(r>Zt||eYt&&(r=r-Yt+Jt-1),String.fromCharCode(n)+String.fromCharCode(r)}function Q(t){if(t&&0===t.length)throw"MGRSPoint coverting from nothing";for(var s,i=t.length,a=null,h="",e=0;!/[A-Z]/.test(s=t.charAt(e));){if(e>=2)throw"MGRSPoint bad conversion from: "+t;h+=s,e++}var n=parseInt(h,10);if(0===e||e+3>i)throw"MGRSPoint bad conversion from: "+t;var r=t.charAt(e++);if(r<="A"||"B"===r||"Y"===r||r>="Z"||"I"===r||"O"===r)throw"MGRSPoint zone letter "+r+" not handled: "+t;a=t.substring(e,e+=2);for(var o=U(n),l=W(a.charAt(0),o),c=H(a.charAt(1),o);c0&&(u=1e5/Math.pow(10,y),f=t.substring(e,e+y),_=parseFloat(f)*u,m=t.substring(e+y),x=parseFloat(m)*u),p=_+l,d=x+c,{easting:p,northing:d,zoneLetter:r,zoneNumber:n,accuracy:u}}function W(t,s){for(var i=Xt.charCodeAt(s-1),a=1e5,h=!1;i!==t.charCodeAt(0);){if(++i===Vt&&i++,i===Zt&&i++,i>$t){if(h)throw"Bad character: "+t;i=Jt,h=!0}a+=1e5}return a}function H(t,s){if(t>"V")throw"MGRSPoint given invalid Northing "+t;for(var i=Kt.charCodeAt(s-1),a=0,h=!1;i!==t.charCodeAt(0);){if(++i===Vt&&i++,i===Zt&&i++,i>Yt){if(h)throw"Bad character: "+t;i=Jt,h=!0}a+=1e5}return a}function X(t){var s;switch(t){case"C":s=11e5;break;case"D":s=2e6;break;case"E":s=28e5;break;case"F":s=37e5;break;case"G":s=46e5;break;case"H":s=55e5;break;case"J":s=64e5;break;case"K":s=73e5;break;case"L":s=82e5;break;case"M":s=91e5;break;case"N":s=0;break;case"P":s=8e5;break;case"Q":s=17e5;break;case"R":s=26e5;break;case"S":s=35e5;break;case"T":s=44e5;break;case"U":s=53e5;break;case"V":s=62e5;break;case"W":s=7e6;break;case"X":s=79e5;break;default:s=-1}if(s>=0)return s;throw"Invalid zone letter: "+t}function Point(t,s,i){if(!(this instanceof Point))return new Point(t,s,i);if(Array.isArray(t))this.x=t[0],this.y=t[1],this.z=t[2]||0;else if("object"==typeof t)this.x=t.x,this.y=t.y,this.z=t.z||0;else if("string"==typeof t&&void 0===s){var a=t.split(",");this.x=parseFloat(a[0],10),this.y=parseFloat(a[1],10),this.z=parseFloat(a[2],10)||0}else this.x=t,this.y=s,this.z=i||0;console.warn("proj4.Point will be removed in version 3, use proj4.toPoint")}function K(t){var s,i=[];return i[0]=t*Ts,s=t*t,i[0]+=s*js,i[1]=s*zs,s*=t,i[0]+=s*Ls,i[1]+=s*Bs,i[2]=s*Ds,i}function J(t,s){var i=t+t;return t+s[0]*Math.sin(i)+s[1]*Math.sin(i+i)+s[2]*Math.sin(i+i+i)}function V(t,s,i,a){var h;return tMt&&h<=ht+Mt?(a.value=ri.AREA_1,h-=ht):h>ht+Mt||h<=-(ht+Mt)?(a.value=ri.AREA_2,h=h>=0?h-ft:h+ft):(a.value=ri.AREA_3,h+=ht)),h}function Z(t,s){var i=t+s;return i<-ft?i+=ut:i>+ft&&(i-=ut),i}function Y(t,s,i,a){for(var h=s;a;--a){var e=t(h);if(h-=e,Math.abs(e)=this.text.length)return;t=this.text[this.place++]}switch(this.state){case _t:return this.neutral(t);case 2:return this.keyword(t);case 4:return this.quoted(t);case 5:return this.afterquote(t);case 3:return this.number(t);case-1:return}},s.prototype.afterquote=function(t){if('"'===t)return this.word+='"',void(this.state=4);if(bt.test(t))return this.word=this.word.trim(),void this.afterItem(t);throw new Error("havn't handled \""+t+'" in afterquote yet, index '+this.place)},s.prototype.afterItem=function(t){return","===t?(null!==this.word&&this.currentObject.push(this.word),this.word=null,void(this.state=_t)):"]"===t?(this.level--,null!==this.word&&(this.currentObject.push(this.word),this.word=null),this.state=_t,this.currentObject=this.stack.pop(),void(this.currentObject||(this.state=-1))):void 0},s.prototype.number=function(t){if(!wt.test(t)){if(bt.test(t))return this.word=parseFloat(this.word),void this.afterItem(t);throw new Error("havn't handled \""+t+'" in number yet, index '+this.place)}this.word+=t},s.prototype.quoted=function(t){'"'!==t?this.word+=t:this.state=5},s.prototype.keyword=function(t){if(gt.test(t))this.word+=t;else{if("["===t){var s=[];return s.push(this.word),this.level++,null===this.root?this.root=s:this.currentObject.push(s),this.stack.push(this.currentObject),this.currentObject=s,void(this.state=_t)}if(!bt.test(t))throw new Error("havn't handled \""+t+'" in keyword yet, index '+this.place);this.afterItem(t)}},s.prototype.neutral=function(t){if(vt.test(t))return this.word=t,void(this.state=2);if('"'===t)return this.word="",void(this.state=4);if(wt.test(t))return this.word=t,void(this.state=3);{if(!bt.test(t))throw new Error("havn't handled \""+t+'" in neutral yet, index '+this.place);this.afterItem(t)}},s.prototype.output=function(){for(;this.place90&&i*ct<-90&&s*ct>180&&s*ct<-180)return null;var a,h;if(Math.abs(Math.abs(i)-ht)<=ot)return null;if(this.sphere)a=this.x0+this.a*this.k0*Ot(s-this.long0),h=this.y0+this.a*this.k0*Math.log(Math.tan(Mt+.5*i));else{var e=Math.sin(i),n=It(this.e,i,e);a=this.x0+this.a*this.k0*Ot(s-this.long0),h=this.y0-this.a*this.k0*Math.log(n)}return t.x=a,t.y=h,t},inverse:function(t){var s,i,a=t.x-this.x0,h=t.y-this.y0;if(this.sphere)i=ht-2*Math.atan(Math.exp(-h/(this.a*this.k0)));else{var e=Math.exp(-h/(this.a*this.k0));if(-9999===(i=qt(this.e,e)))return null}return s=Ot(this.long0+a/(this.a*this.k0)),t.x=s,t.y=i,t},names:["Mercator","Popular Visualisation Pseudo Mercator","Mercator_1SP","Mercator_Auxiliary_Sphere","merc"]},{init:function(){},forward:d,inverse:d,names:["longlat","identity"]}],Gt={},Tt=[],jt={start:function(){Rt.forEach(y)},add:y,get:function(t){if(!t)return!1;var s=t.toLowerCase();return void 0!==Gt[s]&&Tt[Gt[s]]?Tt[Gt[s]]:void 0}},Lt={};Lt.MERIT={a:6378137,rf:298.257,ellipseName:"MERIT 1983"},Lt.SGS85={a:6378136,rf:298.257,ellipseName:"Soviet Geodetic System 85"},Lt.GRS80={a:6378137,rf:298.257222101,ellipseName:"GRS 1980(IUGG, 1980)"},Lt.IAU76={a:6378140,rf:298.257,ellipseName:"IAU 1976"},Lt.airy={a:6377563.396,b:6356256.91,ellipseName:"Airy 1830"},Lt.APL4={a:6378137,rf:298.25,ellipseName:"Appl. Physics. 1965"},Lt.NWL9D={a:6378145,rf:298.25,ellipseName:"Naval Weapons Lab., 1965"},Lt.mod_airy={a:6377340.189,b:6356034.446,ellipseName:"Modified Airy"},Lt.andrae={a:6377104.43,rf:300,ellipseName:"Andrae 1876 (Den., Iclnd.)"},Lt.aust_SA={a:6378160,rf:298.25,ellipseName:"Australian Natl & S. Amer. 1969"},Lt.GRS67={a:6378160,rf:298.247167427,ellipseName:"GRS 67(IUGG 1967)"},Lt.bessel={a:6377397.155,rf:299.1528128,ellipseName:"Bessel 1841"},Lt.bess_nam={a:6377483.865,rf:299.1528128,ellipseName:"Bessel 1841 (Namibia)"},Lt.clrk66={a:6378206.4,b:6356583.8,ellipseName:"Clarke 1866"},Lt.clrk80={a:6378249.145,rf:293.4663,ellipseName:"Clarke 1880 mod."},Lt.clrk58={a:6378293.645208759,rf:294.2606763692654,ellipseName:"Clarke 1858"},Lt.CPM={a:6375738.7,rf:334.29,ellipseName:"Comm. des Poids et Mesures 1799"},Lt.delmbr={a:6376428,rf:311.5,ellipseName:"Delambre 1810 (Belgium)"},Lt.engelis={a:6378136.05,rf:298.2566,ellipseName:"Engelis 1985"},Lt.evrst30={a:6377276.345,rf:300.8017,ellipseName:"Everest 1830"},Lt.evrst48={a:6377304.063,rf:300.8017,ellipseName:"Everest 1948"},Lt.evrst56={a:6377301.243,rf:300.8017,ellipseName:"Everest 1956"},Lt.evrst69={a:6377295.664,rf:300.8017,ellipseName:"Everest 1969"},Lt.evrstSS={a:6377298.556,rf:300.8017,ellipseName:"Everest (Sabah & Sarawak)"},Lt.fschr60={a:6378166,rf:298.3,ellipseName:"Fischer (Mercury Datum) 1960"},Lt.fschr60m={a:6378155,rf:298.3,ellipseName:"Fischer 1960"},Lt.fschr68={a:6378150,rf:298.3,ellipseName:"Fischer 1968"},Lt.helmert={a:6378200,rf:298.3,ellipseName:"Helmert 1906"},Lt.hough={a:6378270,rf:297,ellipseName:"Hough"},Lt.intl={a:6378388,rf:297,ellipseName:"International 1909 (Hayford)"},Lt.kaula={a:6378163,rf:298.24,ellipseName:"Kaula 1961"},Lt.lerch={a:6378139,rf:298.257,ellipseName:"Lerch 1979"},Lt.mprts={a:6397300,rf:191,ellipseName:"Maupertius 1738"},Lt.new_intl={a:6378157.5,b:6356772.2,ellipseName:"New International 1967"},Lt.plessis={a:6376523,rf:6355863,ellipseName:"Plessis 1817 (France)"},Lt.krass={a:6378245,rf:298.3,ellipseName:"Krassovsky, 1942"},Lt.SEasia={a:6378155,b:6356773.3205,ellipseName:"Southeast Asia"},Lt.walbeck={a:6376896,b:6355834.8467,ellipseName:"Walbeck"},Lt.WGS60={a:6378165,rf:298.3,ellipseName:"WGS 60"},Lt.WGS66={a:6378145,rf:298.25,ellipseName:"WGS 66"},Lt.WGS7={a:6378135,rf:298.26,ellipseName:"WGS 72"};var zt=Lt.WGS84={a:6378137,rf:298.257223563,ellipseName:"WGS 84"};Lt.sphere={a:6370997,b:6370997,ellipseName:"Normal Sphere (r=6370997)"};var Bt={};Bt.wgs84={towgs84:"0,0,0",ellipse:"WGS84",datumName:"WGS84"},Bt.ch1903={towgs84:"674.374,15.056,405.346",ellipse:"bessel",datumName:"swiss"},Bt.ggrs87={towgs84:"-199.87,74.79,246.62",ellipse:"GRS80",datumName:"Greek_Geodetic_Reference_System_1987"},Bt.nad83={towgs84:"0,0,0",ellipse:"GRS80",datumName:"North_American_Datum_1983"},Bt.nad27={nadgrids:"@conus,@alaska,@ntv2_0.gsb,@ntv1_can.dat",ellipse:"clrk66",datumName:"North_American_Datum_1927"},Bt.potsdam={towgs84:"606.0,23.0,413.0",ellipse:"bessel",datumName:"Potsdam Rauenberg 1950 DHDN"},Bt.carthage={towgs84:"-263.0,6.0,431.0",ellipse:"clark80",datumName:"Carthage 1934 Tunisia"},Bt.hermannskogel={towgs84:"653.0,-212.0,449.0",ellipse:"bessel",datumName:"Hermannskogel"},Bt.osni52={towgs84:"482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15",ellipse:"airy",datumName:"Irish National"},Bt.ire65={towgs84:"482.530,-130.596,564.557,-1.042,-0.214,-0.631,8.15",ellipse:"mod_airy",datumName:"Ireland 1965"},Bt.rassadiran={towgs84:"-133.63,-157.5,-158.62",ellipse:"intl",datumName:"Rassadiran"},Bt.nzgd49={towgs84:"59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993",ellipse:"intl",datumName:"New Zealand Geodetic Datum 1949"},Bt.osgb36={towgs84:"446.448,-125.157,542.060,0.1502,0.2470,0.8421,-20.4894",ellipse:"airy",datumName:"Airy 1830"},Bt.s_jtsk={towgs84:"589,76,480",ellipse:"bessel",datumName:"S-JTSK (Ferro)"},Bt.beduaram={towgs84:"-106,-87,188",ellipse:"clrk80",datumName:"Beduaram"},Bt.gunung_segara={towgs84:"-403,684,41",ellipse:"bessel",datumName:"Gunung Segara Jakarta"},Bt.rnb72={towgs84:"106.869,-52.2978,103.724,-0.33657,0.456955,-1.84218,1",ellipse:"intl",datumName:"Reseau National Belge 1972"},Projection.projections=jt,Projection.projections.start();var Dt=function(t,s,i){return g(t,s)?i:t.datum_type===it||s.datum_type===it?i:t.es!==s.es||t.a!==s.a||C(t.datum_type)||C(s.datum_type)?(i=b(i,t.es,t.a),C(t.datum_type)&&(i=E(i,t.datum_type,t.datum_params)),C(s.datum_type)&&(i=A(i,s.datum_type,s.datum_params)),w(i,s.es,s.a,s.b)):i},Ut=function(t,s,i){var a,h,e,n=i.x,r=i.y,o=i.z||0,l={};for(e=0;e<3;e++)if(!s||2!==e||void 0!==i.z)switch(0===e?(a=n,h=-1!=="ew".indexOf(t.axis[e])?"x":"y"):1===e?(a=r,h=-1!=="ns".indexOf(t.axis[e])?"y":"x"):(a=o,h="z"),t.axis[e]){case"e":l[h]=a;break;case"w":l[h]=-a;break;case"n":l[h]=a;break;case"s":l[h]=-a;break;case"u":void 0!==i[h]&&(l.z=a);break;case"d":void 0!==i[h]&&(l.z=-a);break;default:return null}return l},Ft=function(t){var s={x:t[0],y:t[1]};return t.length>2&&(s.z=t[2]),t.length>3&&(s.m=t[3]),s},Qt=function(t){P(t.x),P(t.y)},Wt=Projection("WGS84"),Ht=6,Xt="AJSAJS",Kt="AFAFAF",Jt=65,Vt=73,Zt=79,Yt=86,$t=90,ts={forward:q,inverse:function(t){var s=L(Q(t.toUpperCase()));return s.lat&&s.lon?[s.lon,s.lat,s.lon,s.lat]:[s.left,s.bottom,s.right,s.top]},toPoint:R};Point.fromMGRS=function(t){return new Point(R(t))},Point.prototype.toMGRS=function(t){return q([this.x,this.y],t)};var ss=.01068115234375,is=function(t){var s=[];s[0]=1-t*(.25+t*(.046875+t*(.01953125+t*ss))),s[1]=t*(.75-t*(.046875+t*(.01953125+t*ss)));var i=t*t;return s[2]=i*(.46875-t*(.013020833333333334+.007120768229166667*t)),i*=t,s[3]=i*(.3645833333333333-.005696614583333333*t),s[4]=i*t*.3076171875,s},as=function(t,s,i,a){return i*=s,s*=s,a[0]*t-i*(a[1]+s*(a[2]+s*(a[3]+s*a[4])))},hs=function(t,s,i){for(var a=1/(1-s),h=t,e=20;e;--e){var n=Math.sin(h),r=1-s*n*n;if(r=(as(h,n,Math.cos(h),i)-t)*(r*Math.sqrt(r))*a,h-=r,Math.abs(r)ot?Math.tan(e):0,m=Math.pow(f,2),p=Math.pow(m,2);s=1-this.es*Math.pow(r,2),l/=Math.sqrt(s);var d=as(e,r,o,this.en);i=this.a*(this.k0*l*(1+c/6*(1-m+M+c/20*(5-18*m+p+14*M-58*m*M+c/42*(61+179*p-p*m-479*m)))))+this.x0,a=this.a*(this.k0*(d-this.ml0+r*n*l/2*(1+c/12*(5-m+9*M+4*u+c/30*(61+p-58*m+270*M-330*m*M+c/56*(1385+543*p-p*m-3111*m))))))+this.y0}else{var y=o*Math.sin(n);if(Math.abs(Math.abs(y)-1)=1){if(y-1>ot)return 93;a=0}else a=Math.acos(a);e<0&&(a=-a),a=this.a*this.k0*(a-this.lat0)+this.y0}return t.x=i,t.y=a,t},inverse:function(t){var s,i,a,h,e=(t.x-this.x0)*(1/this.a),n=(t.y-this.y0)*(1/this.a);if(this.es)if(s=this.ml0+n/this.k0,i=hs(s,this.es,this.en),Math.abs(i)ot?Math.tan(i):0,c=this.ep2*Math.pow(o,2),M=Math.pow(c,2),u=Math.pow(l,2),f=Math.pow(u,2);s=1-this.es*Math.pow(r,2);var m=e*Math.sqrt(s)/this.k0,p=Math.pow(m,2);a=i-(s*=l)*p/(1-this.es)*.5*(1-p/12*(5+3*u-9*c*u+c-4*M-p/30*(61+90*u-252*c*u+45*f+46*c-p/56*(1385+3633*u+4095*f+1574*f*u)))),h=Ot(this.long0+m*(1-p/6*(1+2*u+c-p/20*(5+28*u+24*f+8*c*u+6*c-p/42*(61+662*u+1320*f+720*f*u))))/o)}else a=ht*kt(n),h=0;else{var d=Math.exp(e/this.k0),y=.5*(d-1/d),_=this.lat0+n/this.k0,x=Math.cos(_);s=Math.sqrt((1-Math.pow(x,2))/(1+Math.pow(y,2))),a=Math.asin(s),n<0&&(a=-a),h=0===y&&0===x?0:Ot(Math.atan2(y,x)+this.long0)}return t.x=h,t.y=a,t},names:["Transverse_Mercator","Transverse Mercator","tmerc"]},ns=function(t){var s=Math.exp(t);return s=(s-1/s)/2},rs=function(t,s){t=Math.abs(t),s=Math.abs(s);var i=Math.max(t,s),a=Math.min(t,s)/(i||1);return i*Math.sqrt(1+Math.pow(a,2))},os=function(t){var s=1+t,i=s-1;return 0===i?t:t*Math.log(s)/i},ls=function(t){var s=Math.abs(t);return s=os(s*(1+s/(rs(1,s)+1))),t<0?-s:s},cs=function(t,s){for(var i,a=2*Math.cos(2*s),h=t.length-1,e=t[h],n=0;--h>=0;)i=a*e-n+t[h],n=e,e=i;return s+i*Math.sin(2*s)},Ms=function(t,s){for(var i,a=2*Math.cos(s),h=t.length-1,e=t[h],n=0;--h>=0;)i=a*e-n+t[h],n=e,e=i;return Math.sin(s)*i},us=function(t){var s=Math.exp(t);return s=(s+1/s)/2},fs=function(t,s,i){for(var a,h,e=Math.sin(s),n=Math.cos(s),r=ns(i),o=us(i),l=2*n*o,c=-2*e*r,M=t.length-1,u=t[M],f=0,m=0,p=0;--M>=0;)a=m,h=f,u=l*(m=u)-a-c*(f=p)+t[M],p=c*m-h+l*f;return l=e*o,c=n*r,[l*u-c*p,l*p+c*u]},ms={init:function(){if(void 0===this.es||this.es<=0)throw new Error("incorrect elliptical usage");this.x0=void 0!==this.x0?this.x0:0,this.y0=void 0!==this.y0?this.y0:0,this.long0=void 0!==this.long0?this.long0:0,this.lat0=void 0!==this.lat0?this.lat0:0,this.cgb=[],this.cbg=[],this.utg=[],this.gtu=[];var t=this.es/(1+Math.sqrt(1-this.es)),s=t/(2-t),i=s;this.cgb[0]=s*(2+s*(-2/3+s*(s*(116/45+s*(26/45+s*(-2854/675)))-2))),this.cbg[0]=s*(s*(2/3+s*(4/3+s*(-82/45+s*(32/45+s*(4642/4725)))))-2),i*=s,this.cgb[1]=i*(7/3+s*(s*(-227/45+s*(2704/315+s*(2323/945)))-1.6)),this.cbg[1]=i*(5/3+s*(-16/15+s*(-13/9+s*(904/315+s*(-1522/945))))),i*=s,this.cgb[2]=i*(56/15+s*(-136/35+s*(-1262/105+s*(73814/2835)))),this.cbg[2]=i*(-26/15+s*(34/21+s*(1.6+s*(-12686/2835)))),i*=s,this.cgb[3]=i*(4279/630+s*(-332/35+s*(-399572/14175))),this.cbg[3]=i*(1237/630+s*(s*(-24832/14175)-2.4)),i*=s,this.cgb[4]=i*(4174/315+s*(-144838/6237)),this.cbg[4]=i*(-734/315+s*(109598/31185)),i*=s,this.cgb[5]=i*(601676/22275),this.cbg[5]=i*(444337/155925),i=Math.pow(s,2),this.Qn=this.k0/(1+s)*(1+i*(.25+i*(1/64+i/256))),this.utg[0]=s*(s*(2/3+s*(-37/96+s*(1/360+s*(81/512+s*(-96199/604800)))))-.5),this.gtu[0]=s*(.5+s*(-2/3+s*(5/16+s*(41/180+s*(-127/288+s*(7891/37800)))))),this.utg[1]=i*(-1/48+s*(-1/15+s*(437/1440+s*(-46/105+s*(1118711/3870720))))),this.gtu[1]=i*(13/48+s*(s*(557/1440+s*(281/630+s*(-1983433/1935360)))-.6)),i*=s,this.utg[2]=i*(-17/480+s*(37/840+s*(209/4480+s*(-5569/90720)))),this.gtu[2]=i*(61/240+s*(-103/140+s*(15061/26880+s*(167603/181440)))),i*=s,this.utg[3]=i*(-4397/161280+s*(11/504+s*(830251/7257600))),this.gtu[3]=i*(49561/161280+s*(-179/168+s*(6601661/7257600))),i*=s,this.utg[4]=i*(-4583/161280+s*(108847/3991680)),this.gtu[4]=i*(34729/80640+s*(-3418889/1995840)),i*=s,this.utg[5]=-.03233083094085698*i,this.gtu[5]=.6650675310896665*i;var a=cs(this.cbg,this.lat0);this.Zb=-this.Qn*(a+Ms(this.gtu,2*a))},forward:function(t){var s=Ot(t.x-this.long0),i=t.y;i=cs(this.cbg,i);var a=Math.sin(i),h=Math.cos(i),e=Math.sin(s),n=Math.cos(s);i=Math.atan2(a,n*h),s=Math.atan2(e*h,rs(a,h*n)),s=ls(Math.tan(s));var r=fs(this.gtu,2*i,2*s);i+=r[0],s+=r[1];var o,l;return Math.abs(s)<=2.623395162778?(o=this.a*(this.Qn*s)+this.x0,l=this.a*(this.Qn*i+this.Zb)+this.y0):(o=1/0,l=1/0),t.x=o,t.y=l,t},inverse:function(t){var s=(t.x-this.x0)*(1/this.a),i=(t.y-this.y0)*(1/this.a);i=(i-this.Zb)/this.Qn,s/=this.Qn;var a,h;if(Math.abs(s)<=2.623395162778){var e=fs(this.utg,2*i,2*s);i+=e[0],s+=e[1],s=Math.atan(ns(s));var n=Math.sin(i),r=Math.cos(i),o=Math.sin(s),l=Math.cos(s);i=Math.atan2(n*l,rs(o,l*r)),s=Math.atan2(o,l*r),a=Ot(s+this.long0),h=cs(this.cgb,i)}else a=1/0,h=1/0;return t.x=a,t.y=h,t},names:["Extended_Transverse_Mercator","Extended Transverse Mercator","etmerc"]},ps=function(t,s){if(void 0===t){if((t=Math.floor(30*(Ot(s)+Math.PI)/Math.PI)+1)<0)return 0;if(t>60)return 60}return t},ds={init:function(){var t=ps(this.zone,this.long0);if(void 0===t)throw new Error("unknown utm zone");this.lat0=0,this.long0=(6*Math.abs(t)-183)*lt,this.x0=5e5,this.y0=this.utmSouth?1e7:0,this.k0=.9996,ms.init.apply(this),this.forward=ms.forward,this.inverse=ms.inverse},names:["Universal Transverse Mercator System","utm"],dependsOn:"etmerc"},ys=function(t,s){return Math.pow((1-t)/(1+t),s)},_s=20,xs={init:function(){var t=Math.sin(this.lat0),s=Math.cos(this.lat0);s*=s,this.rc=Math.sqrt(1-this.es)/(1-this.es*t*t),this.C=Math.sqrt(1+this.es*s*s/(1-this.es)),this.phic0=Math.asin(t/this.C),this.ratexp=.5*this.C*this.e,this.K=Math.tan(.5*this.phic0+Mt)/(Math.pow(Math.tan(.5*this.lat0+Mt),this.C)*ys(this.e*t,this.ratexp))},forward:function(t){var s=t.x,i=t.y;return t.y=2*Math.atan(this.K*Math.pow(Math.tan(.5*i+Mt),this.C)*ys(this.e*Math.sin(i),this.ratexp))-ht,t.x=this.C*s,t},inverse:function(t){for(var s=t.x/this.C,i=t.y,a=Math.pow(Math.tan(.5*i+Mt)/this.K,1/this.C),h=_s;h>0&&(i=2*Math.atan(a*ys(this.e*Math.sin(t.y),-.5*this.e))-ht,!(Math.abs(i-t.y)<1e-14));--h)t.y=i;return h?(t.x=s,t.y=i,t):null},names:["gauss"]},vs={init:function(){xs.init.apply(this),this.rc&&(this.sinc0=Math.sin(this.phic0),this.cosc0=Math.cos(this.phic0),this.R2=2*this.rc,this.title||(this.title="Oblique Stereographic Alternative"))},forward:function(t){var s,i,a,h;return t.x=Ot(t.x-this.long0),xs.forward.apply(this,[t]),s=Math.sin(t.y),i=Math.cos(t.y),a=Math.cos(t.x),h=this.k0*this.R2/(1+this.sinc0*s+this.cosc0*i*a),t.x=h*i*Math.sin(t.x),t.y=h*(this.cosc0*s-this.sinc0*i*a),t.x=this.a*t.x+this.x0,t.y=this.a*t.y+this.y0,t},inverse:function(t){var s,i,a,h,e;if(t.x=(t.x-this.x0)/this.a,t.y=(t.y-this.y0)/this.a,t.x/=this.k0,t.y/=this.k0,e=Math.sqrt(t.x*t.x+t.y*t.y)){var n=2*Math.atan2(e,this.R2);s=Math.sin(n),i=Math.cos(n),h=Math.asin(i*this.sinc0+t.y*s*this.cosc0/e),a=Math.atan2(t.x*s,e*this.cosc0*i-t.y*this.sinc0*s)}else h=this.phic0,a=0;return t.x=a,t.y=h,xs.inverse.apply(this,[t]),t.x=Ot(t.x+this.long0),t},names:["Stereographic_North_Pole","Oblique_Stereographic","Polar_Stereographic","sterea","Oblique Stereographic Alternative","Double_Stereographic"]},gs={init:function(){this.coslat0=Math.cos(this.lat0),this.sinlat0=Math.sin(this.lat0),this.sphere?1===this.k0&&!isNaN(this.lat_ts)&&Math.abs(this.coslat0)<=ot&&(this.k0=.5*(1+kt(this.lat0)*Math.sin(this.lat_ts))):(Math.abs(this.coslat0)<=ot&&(this.lat0>0?this.con=1:this.con=-1),this.cons=Math.sqrt(Math.pow(1+this.e,1+this.e)*Math.pow(1-this.e,1-this.e)),1===this.k0&&!isNaN(this.lat_ts)&&Math.abs(this.coslat0)<=ot&&(this.k0=.5*this.cons*St(this.e,Math.sin(this.lat_ts),Math.cos(this.lat_ts))/It(this.e,this.con*this.lat_ts,this.con*Math.sin(this.lat_ts))),this.ms1=St(this.e,this.sinlat0,this.coslat0),this.X0=2*Math.atan(this.ssfn_(this.lat0,this.sinlat0,this.e))-ht,this.cosX0=Math.cos(this.X0),this.sinX0=Math.sin(this.X0))},forward:function(t){var s,i,a,h,e,n,r=t.x,o=t.y,l=Math.sin(o),c=Math.cos(o),M=Ot(r-this.long0);return Math.abs(Math.abs(r-this.long0)-Math.PI)<=ot&&Math.abs(o+this.lat0)<=ot?(t.x=NaN,t.y=NaN,t):this.sphere?(s=2*this.k0/(1+this.sinlat0*l+this.coslat0*c*Math.cos(M)),t.x=this.a*s*c*Math.sin(M)+this.x0,t.y=this.a*s*(this.coslat0*l-this.sinlat0*c*Math.cos(M))+this.y0,t):(i=2*Math.atan(this.ssfn_(o,l,this.e))-ht,h=Math.cos(i),a=Math.sin(i),Math.abs(this.coslat0)<=ot?(e=It(this.e,o*this.con,this.con*l),n=2*this.a*this.k0*e/this.cons,t.x=this.x0+n*Math.sin(r-this.long0),t.y=this.y0-this.con*n*Math.cos(r-this.long0),t):(Math.abs(this.sinlat0)0?this.long0+Math.atan2(t.x,-1*t.y):this.long0+Math.atan2(t.x,t.y):this.long0+Math.atan2(t.x*Math.sin(r),n*this.coslat0*Math.cos(r)-t.y*this.sinlat0*Math.sin(r))),t.x=s,t.y=i,t)}if(Math.abs(this.coslat0)<=ot){if(n<=ot)return i=this.lat0,s=this.long0,t.x=s,t.y=i,t;t.x*=this.con,t.y*=this.con,a=n*this.cons/(2*this.a*this.k0),i=this.con*qt(this.e,a),s=this.con*Ot(this.con*this.long0+Math.atan2(t.x,-1*t.y))}else h=2*Math.atan(n*this.cosX0/(2*this.a*this.k0*this.ms1)),s=this.long0,n<=ot?e=this.X0:(e=Math.asin(Math.cos(h)*this.sinX0+t.y*Math.sin(h)*this.cosX0/n),s=Ot(this.long0+Math.atan2(t.x*Math.sin(h),n*this.cosX0*Math.cos(h)-t.y*this.sinX0*Math.sin(h)))),i=-1*qt(this.e,Math.tan(.5*(ht+e)));return t.x=s,t.y=i,t},names:["stere","Stereographic_South_Pole","Polar Stereographic (variant B)"],ssfn_:function(t,s,i){return s*=i,Math.tan(.5*(ht+t))*Math.pow((1-s)/(1+s),.5*i)}},bs={init:function(){var t=this.lat0;this.lambda0=this.long0;var s=Math.sin(t),i=this.a,a=1/this.rf,h=2*a-Math.pow(a,2),e=this.e=Math.sqrt(h);this.R=this.k0*i*Math.sqrt(1-h)/(1-h*Math.pow(s,2)),this.alpha=Math.sqrt(1+h/(1-h)*Math.pow(Math.cos(t),4)),this.b0=Math.asin(s/this.alpha);var n=Math.log(Math.tan(Math.PI/4+this.b0/2)),r=Math.log(Math.tan(Math.PI/4+t/2)),o=Math.log((1+e*s)/(1-e*s));this.K=n-this.alpha*r+this.alpha*e/2*o},forward:function(t){var s=Math.log(Math.tan(Math.PI/4-t.y/2)),i=this.e/2*Math.log((1+this.e*Math.sin(t.y))/(1-this.e*Math.sin(t.y))),a=-this.alpha*(s+i)+this.K,h=2*(Math.atan(Math.exp(a))-Math.PI/4),e=this.alpha*(t.x-this.lambda0),n=Math.atan(Math.sin(e)/(Math.sin(this.b0)*Math.tan(h)+Math.cos(this.b0)*Math.cos(e))),r=Math.asin(Math.cos(this.b0)*Math.sin(h)-Math.sin(this.b0)*Math.cos(h)*Math.cos(e));return t.y=this.R/2*Math.log((1+Math.sin(r))/(1-Math.sin(r)))+this.y0,t.x=this.R*n+this.x0,t},inverse:function(t){for(var s=t.x-this.x0,i=t.y-this.y0,a=s/this.R,h=2*(Math.atan(Math.exp(i/this.R))-Math.PI/4),e=Math.asin(Math.cos(this.b0)*Math.sin(h)+Math.sin(this.b0)*Math.cos(h)*Math.cos(a)),n=Math.atan(Math.sin(a)/(Math.cos(this.b0)*Math.cos(a)-Math.sin(this.b0)*Math.tan(h))),r=this.lambda0+n/this.alpha,o=0,l=e,c=-1e3,M=0;Math.abs(l-c)>1e-7;){if(++M>20)return;o=1/this.alpha*(Math.log(Math.tan(Math.PI/4+e/2))-this.K)+this.e*Math.log(Math.tan(Math.PI/4+Math.asin(this.e*Math.sin(l))/2)),c=l,l=2*Math.atan(Math.exp(o))-Math.PI/2}return t.x=r,t.y=l,t},names:["somerc"]},ws={init:function(){this.no_off=this.no_off||!1,this.no_rot=this.no_rot||!1,isNaN(this.k0)&&(this.k0=1);var t=Math.sin(this.lat0),s=Math.cos(this.lat0),i=this.e*t;this.bl=Math.sqrt(1+this.es/(1-this.es)*Math.pow(s,4)),this.al=this.a*this.bl*this.k0*Math.sqrt(1-this.es)/(1-i*i);var a=It(this.e,this.lat0,t),h=this.bl/s*Math.sqrt((1-this.es)/(1-i*i));h*h<1&&(h=1);var e,n;if(isNaN(this.longc)){var r=It(this.e,this.lat1,Math.sin(this.lat1)),o=It(this.e,this.lat2,Math.sin(this.lat2));this.lat0>=0?this.el=(h+Math.sqrt(h*h-1))*Math.pow(a,this.bl):this.el=(h-Math.sqrt(h*h-1))*Math.pow(a,this.bl);var l=Math.pow(r,this.bl),c=Math.pow(o,this.bl);n=.5*((e=this.el/l)-1/e);var M=(this.el*this.el-c*l)/(this.el*this.el+c*l),u=(c-l)/(c+l),f=Ot(this.long1-this.long2);this.long0=.5*(this.long1+this.long2)-Math.atan(M*Math.tan(.5*this.bl*f)/u)/this.bl,this.long0=Ot(this.long0);var m=Ot(this.long1-this.long0);this.gamma0=Math.atan(Math.sin(this.bl*m)/n),this.alpha=Math.asin(h*Math.sin(this.gamma0))}else e=this.lat0>=0?h+Math.sqrt(h*h-1):h-Math.sqrt(h*h-1),this.el=e*Math.pow(a,this.bl),n=.5*(e-1/e),this.gamma0=Math.asin(Math.sin(this.alpha)/h),this.long0=this.longc-Math.asin(n*Math.tan(this.gamma0))/this.bl;this.no_off?this.uc=0:this.lat0>=0?this.uc=this.al/this.bl*Math.atan2(Math.sqrt(h*h-1),Math.cos(this.alpha)):this.uc=-1*this.al/this.bl*Math.atan2(Math.sqrt(h*h-1),Math.cos(this.alpha))},forward:function(t){var s,i,a,h=t.x,e=t.y,n=Ot(h-this.long0);if(Math.abs(Math.abs(e)-ht)<=ot)a=e>0?-1:1,i=this.al/this.bl*Math.log(Math.tan(Mt+a*this.gamma0*.5)),s=-1*a*ht*this.al/this.bl;else{var r=It(this.e,e,Math.sin(e)),o=this.el/Math.pow(r,this.bl),l=.5*(o-1/o),c=.5*(o+1/o),M=Math.sin(this.bl*n),u=(l*Math.sin(this.gamma0)-M*Math.cos(this.gamma0))/c;i=Math.abs(Math.abs(u)-1)<=ot?Number.POSITIVE_INFINITY:.5*this.al*Math.log((1-u)/(1+u))/this.bl,s=Math.abs(Math.cos(this.bl*n))<=ot?this.al*this.bl*n:this.al*Math.atan2(l*Math.cos(this.gamma0)+M*Math.sin(this.gamma0),Math.cos(this.bl*n))/this.bl}return this.no_rot?(t.x=this.x0+s,t.y=this.y0+i):(s-=this.uc,t.x=this.x0+i*Math.cos(this.alpha)+s*Math.sin(this.alpha),t.y=this.y0+s*Math.cos(this.alpha)-i*Math.sin(this.alpha)),t},inverse:function(t){var s,i;this.no_rot?(i=t.y-this.y0,s=t.x-this.x0):(i=(t.x-this.x0)*Math.cos(this.alpha)-(t.y-this.y0)*Math.sin(this.alpha),s=(t.y-this.y0)*Math.cos(this.alpha)+(t.x-this.x0)*Math.sin(this.alpha),s+=this.uc);var a=Math.exp(-1*this.bl*i/this.al),h=.5*(a-1/a),e=.5*(a+1/a),n=Math.sin(this.bl*s/this.al),r=(n*Math.cos(this.gamma0)+h*Math.sin(this.gamma0))/e,o=Math.pow(this.el/Math.sqrt((1+r)/(1-r)),1/this.bl);return Math.abs(r-1)ot?this.ns=Math.log(a/r)/Math.log(h/o):this.ns=s,isNaN(this.ns)&&(this.ns=s),this.f0=a/(this.ns*Math.pow(h,this.ns)),this.rh=this.a*this.f0*Math.pow(l,this.ns),this.title||(this.title="Lambert Conformal Conic")}},forward:function(t){var s=t.x,i=t.y;Math.abs(2*Math.abs(i)-Math.PI)<=ot&&(i=kt(i)*(ht-2*ot));var a,h,e=Math.abs(Math.abs(i)-ht);if(e>ot)a=It(this.e,i,Math.sin(i)),h=this.a*this.f0*Math.pow(a,this.ns);else{if((e=i*this.ns)<=0)return null;h=0}var n=this.ns*Ot(s-this.long0);return t.x=this.k0*(h*Math.sin(n))+this.x0,t.y=this.k0*(this.rh-h*Math.cos(n))+this.y0,t},inverse:function(t){var s,i,a,h,e,n=(t.x-this.x0)/this.k0,r=this.rh-(t.y-this.y0)/this.k0;this.ns>0?(s=Math.sqrt(n*n+r*r),i=1):(s=-Math.sqrt(n*n+r*r),i=-1);var o=0;if(0!==s&&(o=Math.atan2(i*n,i*r)),0!==s||this.ns>0){if(i=1/this.ns,a=Math.pow(s/(this.a*this.f0),i),-9999===(h=qt(this.e,a)))return null}else h=-ht;return e=Ot(o/this.ns+this.long0),t.x=e,t.y=h,t},names:["Lambert Tangential Conformal Conic Projection","Lambert_Conformal_Conic","Lambert_Conformal_Conic_2SP","lcc"]},As={init:function(){this.a=6377397.155,this.es=.006674372230614,this.e=Math.sqrt(this.es),this.lat0||(this.lat0=.863937979737193),this.long0||(this.long0=.4334234309119251),this.k0||(this.k0=.9999),this.s45=.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},forward:function(t){var s,i,a,h,e,n,r,o=t.x,l=t.y,c=Ot(o-this.long0);return s=Math.pow((1+this.e*Math.sin(l))/(1-this.e*Math.sin(l)),this.alfa*this.e/2),i=2*(Math.atan(this.k*Math.pow(Math.tan(l/2+this.s45),this.alfa)/s)-this.s45),a=-c*this.alfa,h=Math.asin(Math.cos(this.ad)*Math.sin(i)+Math.sin(this.ad)*Math.cos(i)*Math.cos(a)),e=Math.asin(Math.cos(i)*Math.sin(a)/Math.cos(h)),n=this.n*e,r=this.ro0*Math.pow(Math.tan(this.s0/2+this.s45),this.n)/Math.pow(Math.tan(h/2+this.s45),this.n),t.y=r*Math.cos(n)/1,t.x=r*Math.sin(n)/1,this.czech||(t.y*=-1,t.x*=-1),t},inverse:function(t){var s,i,a,h,e,n,r,o=t.x;t.x=t.y,t.y=o,this.czech||(t.y*=-1,t.x*=-1),e=Math.sqrt(t.x*t.x+t.y*t.y),h=Math.atan2(t.y,t.x)/Math.sin(this.s0),a=2*(Math.atan(Math.pow(this.ro0/e,1/this.n)*Math.tan(this.s0/2+this.s45))-this.s45),s=Math.asin(Math.cos(this.ad)*Math.sin(a)-Math.sin(this.ad)*Math.cos(a)*Math.cos(h)),i=Math.asin(Math.cos(a)*Math.sin(h)/Math.cos(s)),t.x=this.long0-i/this.alfa,n=s,r=0;var l=0;do{t.y=2*(Math.atan(Math.pow(this.k,-1/this.alfa)*Math.pow(Math.tan(s/2+this.s45),1/this.alfa)*Math.pow((1+this.e*Math.sin(n))/(1-this.e*Math.sin(n)),this.e/2))-this.s45),Math.abs(n-t.y)<1e-10&&(r=1),n=t.y,l+=1}while(0===r&&l<15);return l>=15?null:t},names:["Krovak","krovak"]},Cs=function(t,s,i,a,h){return t*h-s*Math.sin(2*h)+i*Math.sin(4*h)-a*Math.sin(6*h)},Ps=function(t){return 1-.25*t*(1+t/16*(3+1.25*t))},Ns=function(t){return.375*t*(1+.25*t*(1+.46875*t))},Ss=function(t){return.05859375*t*t*(1+.75*t)},ks=function(t){return t*t*t*(35/3072)},Os=function(t,s,i){var a=s*i;return t/Math.sqrt(1-a*a)},Is=function(t){return Math.abs(t)1e-7?(i=t*s,(1-t*t)*(s/(1-i*i)-.5/t*Math.log((1-i)/(1+i)))):2*s},Ts=.3333333333333333,js=.17222222222222222,Ls=.10257936507936508,zs=.06388888888888888,Bs=.0664021164021164,Ds=.016415012942191543,Us={init:function(){var t=Math.abs(this.lat0);if(Math.abs(t-ht)0){var s;switch(this.qp=Gs(this.e,1),this.mmf=.5/(1-this.es),this.apa=K(this.es),this.mode){case this.N_POLE:case this.S_POLE:this.dd=1;break;case this.EQUIT:this.rq=Math.sqrt(.5*this.qp),this.dd=1/this.rq,this.xmf=1,this.ymf=.5*this.qp;break;case this.OBLIQ:this.rq=Math.sqrt(.5*this.qp),s=Math.sin(this.lat0),this.sinb1=Gs(this.e,s)/this.qp,this.cosb1=Math.sqrt(1-this.sinb1*this.sinb1),this.dd=Math.cos(this.lat0)/(Math.sqrt(1-this.es*s*s)*this.rq*this.cosb1),this.ymf=(this.xmf=this.rq)/this.dd,this.xmf*=this.dd}}else this.mode===this.OBLIQ&&(this.sinph0=Math.sin(this.lat0),this.cosph0=Math.cos(this.lat0))},forward:function(t){var s,i,a,h,e,n,r,o,l,c,M=t.x,u=t.y;if(M=Ot(M-this.long0),this.sphere){if(e=Math.sin(u),c=Math.cos(u),a=Math.cos(M),this.mode===this.OBLIQ||this.mode===this.EQUIT){if((i=this.mode===this.EQUIT?1+c*a:1+this.sinph0*e+this.cosph0*c*a)<=ot)return null;s=(i=Math.sqrt(2/i))*c*Math.sin(M),i*=this.mode===this.EQUIT?e:this.cosph0*e-this.sinph0*c*a}else if(this.mode===this.N_POLE||this.mode===this.S_POLE){if(this.mode===this.N_POLE&&(a=-a),Math.abs(u+this.lat0)=0?(s=(l=Math.sqrt(n))*h,i=a*(this.mode===this.S_POLE?l:-l)):s=i=0}}return t.x=this.a*s+this.x0,t.y=this.a*i+this.y0,t},inverse:function(t){t.x-=this.x0,t.y-=this.y0;var s,i,a,h,e,n,r,o=t.x/this.a,l=t.y/this.a;if(this.sphere){var c,M=0,u=0;if(c=Math.sqrt(o*o+l*l),(i=.5*c)>1)return null;switch(i=2*Math.asin(i),this.mode!==this.OBLIQ&&this.mode!==this.EQUIT||(u=Math.sin(i),M=Math.cos(i)),this.mode){case this.EQUIT:i=Math.abs(c)<=ot?0:Math.asin(l*u/c),o*=u,l=M*c;break;case this.OBLIQ:i=Math.abs(c)<=ot?this.lat0:Math.asin(M*this.sinph0+l*u*this.cosph0/c),o*=u*this.cosph0,l=(M-Math.sin(i)*this.sinph0)*c;break;case this.N_POLE:l=-l,i=ht-i;break;case this.S_POLE:i-=ht}s=0!==l||this.mode!==this.EQUIT&&this.mode!==this.OBLIQ?Math.atan2(o,l):0}else{if(r=0,this.mode===this.OBLIQ||this.mode===this.EQUIT){if(o/=this.dd,l*=this.dd,(n=Math.sqrt(o*o+l*l))1&&(t=t>1?1:-1),Math.asin(t)},Qs={init:function(){Math.abs(this.lat1+this.lat2)ot?this.ns0=(this.ms1*this.ms1-this.ms2*this.ms2)/(this.qs2-this.qs1):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)},forward:function(t){var s=t.x,i=t.y;this.sin_phi=Math.sin(i),this.cos_phi=Math.cos(i);var a=Gs(this.e3,this.sin_phi,this.cos_phi),h=this.a*Math.sqrt(this.c-this.ns0*a)/this.ns0,e=this.ns0*Ot(s-this.long0),n=h*Math.sin(e)+this.x0,r=this.rh-h*Math.cos(e)+this.y0;return t.x=n,t.y=r,t},inverse:function(t){var s,i,a,h,e,n;return t.x-=this.x0,t.y=this.rh-t.y+this.y0,this.ns0>=0?(s=Math.sqrt(t.x*t.x+t.y*t.y),a=1):(s=-Math.sqrt(t.x*t.x+t.y*t.y),a=-1),h=0,0!==s&&(h=Math.atan2(a*t.x,a*t.y)),a=s*this.ns0/this.a,this.sphere?n=Math.asin((this.c-a*a)/(2*this.ns0)):(i=(this.c-a*a)/this.ns0,n=this.phi1z(this.e3,i)),e=Ot(h/this.ns0+this.long0),t.x=e,t.y=n,t},names:["Albers_Conic_Equal_Area","Albers","aea"],phi1z:function(t,s){var i,a,h,e,n,r=Fs(.5*s);if(t0||Math.abs(e)<=ot?(n=this.x0+1*this.a*i*Math.sin(a)/e,r=this.y0+1*this.a*(this.cos_p14*s-this.sin_p14*i*h)/e):(n=this.x0+this.infinity_dist*i*Math.sin(a),r=this.y0+this.infinity_dist*(this.cos_p14*s-this.sin_p14*i*h)),t.x=n,t.y=r,t},inverse:function(t){var s,i,a,h,e,n;return t.x=(t.x-this.x0)/this.a,t.y=(t.y-this.y0)/this.a,t.x/=this.k0,t.y/=this.k0,(s=Math.sqrt(t.x*t.x+t.y*t.y))?(h=Math.atan2(s,this.rc),i=Math.sin(h),a=Math.cos(h),n=Fs(a*this.sin_p14+t.y*i*this.cos_p14/s),e=Math.atan2(t.x*i,s*this.cos_p14*a-t.y*this.sin_p14*i),e=Ot(this.long0+e)):(n=this.phic0,e=0),t.x=e,t.y=n,t},names:["gnom"]},Hs=function(t,s){var i=1-(1-t*t)/(2*t)*Math.log((1-t)/(1+t));if(Math.abs(Math.abs(s)-i)<1e-6)return s<0?-1*ht:ht;for(var a,h,e,n,r=Math.asin(.5*s),o=0;o<30;o++)if(h=Math.sin(r),e=Math.cos(r),n=t*h,a=Math.pow(1-n*n,2)/(2*e)*(s/(1-t*t)-h/(1-n*n)+.5/t*Math.log((1-n)/(1+n))),r+=a,Math.abs(a)<=1e-10)return r;return NaN},Xs={init:function(){this.sphere||(this.k0=St(this.e,Math.sin(this.lat_ts),Math.cos(this.lat_ts)))},forward:function(t){var s,i,a=t.x,h=t.y,e=Ot(a-this.long0);if(this.sphere)s=this.x0+this.a*e*Math.cos(this.lat_ts),i=this.y0+this.a*Math.sin(h)/Math.cos(this.lat_ts);else{var n=Gs(this.e,Math.sin(h));s=this.x0+this.a*this.k0*e,i=this.y0+this.a*n*.5/this.k0}return t.x=s,t.y=i,t},inverse:function(t){t.x-=this.x0,t.y-=this.y0;var s,i;return this.sphere?(s=Ot(this.long0+t.x/this.a/Math.cos(this.lat_ts)),i=Math.asin(t.y/this.a*Math.cos(this.lat_ts))):(i=Hs(this.e,2*t.y*this.k0/this.a),s=Ot(this.long0+t.x/(this.a*this.k0))),t.x=s,t.y=i,t},names:["cea"]},Ks={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)},forward:function(t){var s=t.x,i=t.y,a=Ot(s-this.long0),h=Is(i-this.lat0);return t.x=this.x0+this.a*a*this.rc,t.y=this.y0+this.a*h,t},inverse:function(t){var s=t.x,i=t.y;return t.x=Ot(this.long0+(s-this.x0)/(this.a*this.rc)),t.y=Is(this.lat0+(i-this.y0)/this.a),t},names:["Equirectangular","Equidistant_Cylindrical","eqc"]},Js=20,Vs={init:function(){this.temp=this.b/this.a,this.es=1-Math.pow(this.temp,2),this.e=Math.sqrt(this.es),this.e0=Ps(this.es),this.e1=Ns(this.es),this.e2=Ss(this.es),this.e3=ks(this.es),this.ml0=this.a*Cs(this.e0,this.e1,this.e2,this.e3,this.lat0)},forward:function(t){var s,i,a,h=t.x,e=t.y,n=Ot(h-this.long0);if(a=n*Math.sin(e),this.sphere)Math.abs(e)<=ot?(s=this.a*n,i=-1*this.a*this.lat0):(s=this.a*Math.sin(a)/Math.tan(e),i=this.a*(Is(e-this.lat0)+(1-Math.cos(a))/Math.tan(e)));else if(Math.abs(e)<=ot)s=this.a*n,i=-1*this.ml0;else{var r=Os(this.a,this.e,Math.sin(e))/Math.tan(e);s=r*Math.sin(a),i=this.a*Cs(this.e0,this.e1,this.e2,this.e3,e)-this.ml0+r*(1-Math.cos(a))}return t.x=s+this.x0,t.y=i+this.y0,t},inverse:function(t){var s,i,a,h,e,n,r,o,l;if(a=t.x-this.x0,h=t.y-this.y0,this.sphere)if(Math.abs(h+this.a*this.lat0)<=ot)s=Ot(a/this.a+this.long0),i=0;else{n=this.lat0+h/this.a,r=a*a/this.a/this.a+n*n,o=n;var c;for(e=Js;e;--e)if(c=Math.tan(o),l=-1*(n*(o*c+1)-o-.5*(o*o+r)*c)/((o-n)/c-1),o+=l,Math.abs(l)<=ot){i=o;break}s=Ot(this.long0+Math.asin(a*Math.tan(o)/this.a)/Math.sin(i))}else if(Math.abs(h+this.ml0)<=ot)i=0,s=Ot(this.long0+a/this.a);else{n=(this.ml0+h)/this.a,r=a*a/this.a/this.a+n*n,o=n;var M,u,f,m,p;for(e=Js;e;--e)if(p=this.e*Math.sin(o),M=Math.sqrt(1-p*p)*Math.tan(o),u=this.a*Cs(this.e0,this.e1,this.e2,this.e3,o),f=this.e0-2*this.e1*Math.cos(2*o)+4*this.e2*Math.cos(4*o)-6*this.e3*Math.cos(6*o),m=u/this.a,l=(n*(M*m+1)-m-.5*M*(m*m+r))/(this.es*Math.sin(2*o)*(m*m+r-2*n*m)/(4*M)+(n-m)*(M*f-2/Math.sin(2*o))-f),o-=l,Math.abs(l)<=ot){i=o;break}M=Math.sqrt(1-this.es*Math.pow(Math.sin(i),2))*Math.tan(i),s=Ot(this.long0+Math.asin(a*M/this.a)/Math.sin(i))}return t.x=s,t.y=i,t},names:["Polyconic","poly"]},Zs={init:function(){this.A=[],this.A[1]=.6399175073,this.A[2]=-.1358797613,this.A[3]=.063294409,this.A[4]=-.02526853,this.A[5]=.0117879,this.A[6]=-.0055161,this.A[7]=.0026906,this.A[8]=-.001333,this.A[9]=67e-5,this.A[10]=-34e-5,this.B_re=[],this.B_im=[],this.B_re[1]=.7557853228,this.B_im[1]=0,this.B_re[2]=.249204646,this.B_im[2]=.003371507,this.B_re[3]=-.001541739,this.B_im[3]=.04105856,this.B_re[4]=-.10162907,this.B_im[4]=.01727609,this.B_re[5]=-.26623489,this.B_im[5]=-.36249218,this.B_re[6]=-.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]=-.577245789,this.C_im[2]=-.007809598,this.C_re[3]=.508307513,this.C_im[3]=-.112208952,this.C_re[4]=-.15094762,this.C_im[4]=.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]=.5185406398,this.D[3]=-.03333098,this.D[4]=-.1052906,this.D[5]=-.0368594,this.D[6]=.007317,this.D[7]=.0122,this.D[8]=.00394,this.D[9]=-.0013},forward:function(t){var s,i=t.x,a=t.y-this.lat0,h=i-this.long0,e=a/at*1e-5,n=h,r=1,o=0;for(s=1;s<=10;s++)r*=e,o+=this.A[s]*r;var l,c=o,M=n,u=1,f=0,m=0,p=0;for(s=1;s<=6;s++)l=f*c+u*M,u=u*c-f*M,f=l,m=m+this.B_re[s]*u-this.B_im[s]*f,p=p+this.B_im[s]*u+this.B_re[s]*f;return t.x=p*this.a+this.x0,t.y=m*this.a+this.y0,t},inverse:function(t){var s,i,a=t.x,h=t.y,e=a-this.x0,n=(h-this.y0)/this.a,r=e/this.a,o=1,l=0,c=0,M=0;for(s=1;s<=6;s++)i=l*n+o*r,o=o*n-l*r,l=i,c=c+this.C_re[s]*o-this.C_im[s]*l,M=M+this.C_im[s]*o+this.C_re[s]*l;for(var u=0;u.999999999999&&(i=.999999999999),s=Math.asin(i);var a=Ot(this.long0+t.x/(.900316316158*this.a*Math.cos(s)));a<-Math.PI&&(a=-Math.PI),a>Math.PI&&(a=Math.PI),i=(2*s+Math.sin(2*s))/Math.PI,Math.abs(i)>1&&(i=1);var h=Math.asin(i);return t.x=a,t.y=h,t},names:["Mollweide","moll"]},ii={init:function(){Math.abs(this.lat1+this.lat2)=0?(i=Math.sqrt(t.x*t.x+t.y*t.y),s=1):(i=-Math.sqrt(t.x*t.x+t.y*t.y),s=-1);var e=0;if(0!==i&&(e=Math.atan2(s*t.x,s*t.y)),this.sphere)return h=Ot(this.long0+e/this.ns),a=Is(this.g-i/this.a),t.x=h,t.y=a,t;var n=this.g-i/this.a;return a=qs(n,this.e0,this.e1,this.e2,this.e3),h=Ot(this.long0+e/this.ns),t.x=h,t.y=a,t},names:["Equidistant_Conic","eqdc"]},ai={init:function(){this.R=this.a},forward:function(t){var s,i,a=t.x,h=t.y,e=Ot(a-this.long0);Math.abs(h)<=ot&&(s=this.x0+this.R*e,i=this.y0);var n=Fs(2*Math.abs(h/Math.PI));(Math.abs(e)<=ot||Math.abs(Math.abs(h)-ht)<=ot)&&(s=this.x0,i=h>=0?this.y0+Math.PI*this.R*Math.tan(.5*n):this.y0+Math.PI*this.R*-Math.tan(.5*n));var r=.5*Math.abs(Math.PI/e-e/Math.PI),o=r*r,l=Math.sin(n),c=Math.cos(n),M=c/(l+c-1),u=M*M,f=M*(2/l-1),m=f*f,p=Math.PI*this.R*(r*(M-m)+Math.sqrt(o*(M-m)*(M-m)-(m+o)*(u-m)))/(m+o);e<0&&(p=-p),s=this.x0+p;var d=o+M;return p=Math.PI*this.R*(f*d-r*Math.sqrt((m+o)*(o+1)-d*d))/(m+o),i=h>=0?this.y0+p:this.y0-p,t.x=s,t.y=i,t},inverse:function(t){var s,i,a,h,e,n,r,o,l,c,M,u,f;return t.x-=this.x0,t.y-=this.y0,M=Math.PI*this.R,a=t.x/M,h=t.y/M,e=a*a+h*h,n=-Math.abs(h)*(1+e),r=n-2*h*h+a*a,o=-2*n+1+2*h*h+e*e,f=h*h/o+(2*r*r*r/o/o/o-9*n*r/o/o)/27,l=(n-r*r/3/o)/o,c=2*Math.sqrt(-l/3),M=3*f/l/c,Math.abs(M)>1&&(M=M>=0?1:-1),u=Math.acos(M)/3,i=t.y>=0?(-c*Math.cos(u+Math.PI/3)-r/3/o)*Math.PI:-(-c*Math.cos(u+Math.PI/3)-r/3/o)*Math.PI,s=Math.abs(a)2*ht*this.a)return;return i=s/this.a,a=Math.sin(i),h=Math.cos(i),e=this.long0,Math.abs(s)<=ot?n=this.lat0:(n=Fs(h*this.sin_p12+t.y*a*this.cos_p12/s),r=Math.abs(this.lat0)-ht,e=Ot(Math.abs(r)<=ot?this.lat0>=0?this.long0+Math.atan2(t.x,-t.y):this.long0-Math.atan2(-t.x,t.y):this.long0+Math.atan2(t.x*a,s*this.cos_p12*h-t.y*this.sin_p12*a))),t.x=e,t.y=n,t}return o=Ps(this.es),l=Ns(this.es),c=Ss(this.es),M=ks(this.es),Math.abs(this.sin_p12-1)<=ot?(u=this.a*Cs(o,l,c,M,ht),s=Math.sqrt(t.x*t.x+t.y*t.y),f=u-s,n=qs(f/this.a,o,l,c,M),e=Ot(this.long0+Math.atan2(t.x,-1*t.y)),t.x=e,t.y=n,t):Math.abs(this.sin_p12+1)<=ot?(u=this.a*Cs(o,l,c,M,ht),s=Math.sqrt(t.x*t.x+t.y*t.y),f=s-u,n=qs(f/this.a,o,l,c,M),e=Ot(this.long0+Math.atan2(t.x,t.y)),t.x=e,t.y=n,t):(s=Math.sqrt(t.x*t.x+t.y*t.y),d=Math.atan2(t.x,t.y),m=Os(this.a,this.e,this.sin_p12),y=Math.cos(d),_=this.e*this.cos_p12*y,x=-_*_/(1-this.es),v=3*this.es*(1-x)*this.sin_p12*this.cos_p12*y/(1-this.es),g=s/m,b=g-x*(1+x)*Math.pow(g,3)/6-v*(1+3*x)*Math.pow(g,4)/24,w=1-x*b*b/2-g*b*b*b/6,p=Math.asin(this.sin_p12*Math.cos(b)+this.cos_p12*Math.sin(b)*y),e=Ot(this.long0+Math.asin(Math.sin(d)*Math.sin(b)/Math.cos(p))),E=Math.sin(p),n=Math.atan2((E-this.es*w*this.sin_p12)*Math.tan(p),E*(1-this.es)),t.x=e,t.y=n,t)},names:["Azimuthal_Equidistant","aeqd"]},ei={init:function(){this.sin_p14=Math.sin(this.lat0),this.cos_p14=Math.cos(this.lat0)},forward:function(t){var s,i,a,h,e,n,r,o=t.x,l=t.y;return a=Ot(o-this.long0),s=Math.sin(l),i=Math.cos(l),h=Math.cos(a),((e=this.sin_p14*s+this.cos_p14*i*h)>0||Math.abs(e)<=ot)&&(n=1*this.a*i*Math.sin(a),r=this.y0+1*this.a*(this.cos_p14*s-this.sin_p14*i*h)),t.x=n,t.y=r,t},inverse:function(t){var s,i,a,h,e,n,r;return t.x-=this.x0,t.y-=this.y0,s=Math.sqrt(t.x*t.x+t.y*t.y),i=Fs(s/this.a),a=Math.sin(i),h=Math.cos(i),n=this.long0,Math.abs(s)<=ot?(r=this.lat0,t.x=n,t.y=r,t):(r=Fs(h*this.sin_p14+t.y*a*this.cos_p14/s),e=Math.abs(this.lat0)-ht,Math.abs(e)<=ot?(n=Ot(this.lat0>=0?this.long0+Math.atan2(t.x,-t.y):this.long0-Math.atan2(-t.x,t.y)),t.x=n,t.y=r,t):(n=Ot(this.long0+Math.atan2(t.x*a,s*this.cos_p14*h-t.y*this.sin_p14*a)),t.x=n,t.y=r,t))},names:["ortho"]},ni={FRONT:1,RIGHT:2,BACK:3,LEFT:4,TOP:5,BOTTOM:6},ri={AREA_0:1,AREA_1:2,AREA_2:3,AREA_3:4},oi={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||"Quadrilateralized Spherical Cube",this.lat0>=ht-Mt/2?this.face=ni.TOP:this.lat0<=-(ht-Mt/2)?this.face=ni.BOTTOM:Math.abs(this.long0)<=Mt?this.face=ni.FRONT:Math.abs(this.long0)<=ht+Mt?this.face=this.long0>0?ni.RIGHT:ni.LEFT:this.face=ni.BACK,0!==this.es&&(this.one_minus_f=1-(this.a-this.b)/this.a,this.one_minus_f_squared=this.one_minus_f*this.one_minus_f)},forward:function(t){var s,i,a,h,e,n,r={x:0,y:0},o={value:0};if(t.x-=this.long0,s=0!==this.es?Math.atan(this.one_minus_f_squared*Math.tan(t.y)):t.y,i=t.x,this.face===ni.TOP)h=ht-s,i>=Mt&&i<=ht+Mt?(o.value=ri.AREA_0,a=i-ht):i>ht+Mt||i<=-(ht+Mt)?(o.value=ri.AREA_1,a=i>0?i-ft:i+ft):i>-(ht+Mt)&&i<=-Mt?(o.value=ri.AREA_2,a=i+ht):(o.value=ri.AREA_3,a=i);else if(this.face===ni.BOTTOM)h=ht+s,i>=Mt&&i<=ht+Mt?(o.value=ri.AREA_0,a=-i+ht):i=-Mt?(o.value=ri.AREA_1,a=-i):i<-Mt&&i>=-(ht+Mt)?(o.value=ri.AREA_2,a=-i-ht):(o.value=ri.AREA_3,a=i>0?-i+ft:-i-ft);else{var l,c,M,u,f,m;this.face===ni.RIGHT?i=Z(i,+ht):this.face===ni.BACK?i=Z(i,+ft):this.face===ni.LEFT&&(i=Z(i,-ht)),u=Math.sin(s),f=Math.cos(s),m=Math.sin(i),l=f*Math.cos(i),c=f*m,M=u,this.face===ni.FRONT?a=V(h=Math.acos(l),M,c,o):this.face===ni.RIGHT?a=V(h=Math.acos(c),M,-l,o):this.face===ni.BACK?a=V(h=Math.acos(-l),M,-c,o):this.face===ni.LEFT?a=V(h=Math.acos(-c),M,l,o):(h=a=0,o.value=ri.AREA_0)}return n=Math.atan(12/ft*(a+Math.acos(Math.sin(a)*Math.cos(Mt))-ht)),e=Math.sqrt((1-Math.cos(h))/(Math.cos(n)*Math.cos(n))/(1-Math.cos(Math.atan(1/Math.cos(a))))),o.value===ri.AREA_1?n+=ht:o.value===ri.AREA_2?n+=ft:o.value===ri.AREA_3&&(n+=1.5*ft),r.x=e*Math.cos(n),r.y=e*Math.sin(n),r.x=r.x*this.a+this.x0,r.y=r.y*this.a+this.y0,t.x=r.x,t.y=r.y,t},inverse:function(t){var s,i,a,h,e,n,r,o,l,c={lam:0,phi:0},M={value:0};if(t.x=(t.x-this.x0)/this.a,t.y=(t.y-this.y0)/this.a,i=Math.atan(Math.sqrt(t.x*t.x+t.y*t.y)),s=Math.atan2(t.y,t.x),t.x>=0&&t.x>=Math.abs(t.y)?M.value=ri.AREA_0:t.y>=0&&t.y>=Math.abs(t.x)?(M.value=ri.AREA_1,s-=ht):t.x<0&&-t.x>=Math.abs(t.y)?(M.value=ri.AREA_2,s=s<0?s+ft:s-ft):(M.value=ri.AREA_3,s+=ht),l=ft/12*Math.tan(s),e=Math.sin(l)/(Math.cos(l)-1/Math.sqrt(2)),n=Math.atan(e),a=Math.cos(s),h=Math.tan(i),(r=1-a*a*h*h*(1-Math.cos(Math.atan(1/Math.cos(n)))))<-1?r=-1:r>1&&(r=1),this.face===ni.TOP)o=Math.acos(r),c.phi=ht-o,M.value===ri.AREA_0?c.lam=n+ht:M.value===ri.AREA_1?c.lam=n<0?n+ft:n-ft:M.value===ri.AREA_2?c.lam=n-ht:c.lam=n;else if(this.face===ni.BOTTOM)o=Math.acos(r),c.phi=o-ht,M.value===ri.AREA_0?c.lam=-n+ht:M.value===ri.AREA_1?c.lam=-n:M.value===ri.AREA_2?c.lam=-n-ht:c.lam=n<0?-n-ft:-n+ft;else{var u,f,m;l=(u=r)*u,f=(l+=(m=l>=1?0:Math.sqrt(1-l)*Math.sin(n))*m)>=1?0:Math.sqrt(1-l),M.value===ri.AREA_1?(l=f,f=-m,m=l):M.value===ri.AREA_2?(f=-f,m=-m):M.value===ri.AREA_3&&(l=f,f=m,m=-l),this.face===ni.RIGHT?(l=u,u=-f,f=l):this.face===ni.BACK?(u=-u,f=-f):this.face===ni.LEFT&&(l=u,u=f,f=-l),c.phi=Math.acos(-m)-ht,c.lam=Math.atan2(f,u),this.face===ni.RIGHT?c.lam=Z(c.lam,-ht):this.face===ni.BACK?c.lam=Z(c.lam,-ft):this.face===ni.LEFT&&(c.lam=Z(c.lam,+ht))}if(0!==this.es){var p,d,y;p=c.phi<0?1:0,d=Math.tan(c.phi),y=this.b/Math.sqrt(d*d+this.one_minus_f_squared),c.phi=Math.atan(Math.sqrt(this.a*this.a-y*y)/(this.one_minus_f*y)),p&&(c.phi=-c.phi)}return c.lam+=this.long0,t.x=c.lam,t.y=c.phi,t},names:["Quadrilateralized Spherical Cube","Quadrilateralized_Spherical_Cube","qsc"]},li=[[1,2.2199e-17,-715515e-10,31103e-10],[.9986,-482243e-9,-24897e-9,-13309e-10],[.9954,-83103e-8,-448605e-10,-9.86701e-7],[.99,-.00135364,-59661e-9,36777e-10],[.9822,-.00167442,-449547e-11,-572411e-11],[.973,-.00214868,-903571e-10,1.8736e-8],[.96,-.00305085,-900761e-10,164917e-11],[.9427,-.00382792,-653386e-10,-26154e-10],[.9216,-.00467746,-10457e-8,481243e-11],[.8962,-.00536223,-323831e-10,-543432e-11],[.8679,-.00609363,-113898e-9,332484e-11],[.835,-.00698325,-640253e-10,9.34959e-7],[.7986,-.00755338,-500009e-10,9.35324e-7],[.7597,-.00798324,-35971e-9,-227626e-11],[.7186,-.00851367,-701149e-10,-86303e-10],[.6732,-.00986209,-199569e-9,191974e-10],[.6213,-.010418,883923e-10,624051e-11],[.5722,-.00906601,182e-6,624051e-11],[.5322,-.00677797,275608e-9,624051e-11]],ci=[[-5.20417e-18,.0124,1.21431e-18,-8.45284e-11],[.062,.0124,-1.26793e-9,4.22642e-10],[.124,.0124,5.07171e-9,-1.60604e-9],[.186,.0123999,-1.90189e-8,6.00152e-9],[.248,.0124002,7.10039e-8,-2.24e-8],[.31,.0123992,-2.64997e-7,8.35986e-8],[.372,.0124029,9.88983e-7,-3.11994e-7],[.434,.0123893,-369093e-11,-4.35621e-7],[.4958,.0123198,-102252e-10,-3.45523e-7],[.5571,.0121916,-154081e-10,-5.82288e-7],[.6176,.0119938,-241424e-10,-5.25327e-7],[.6769,.011713,-320223e-10,-5.16405e-7],[.7346,.0113541,-397684e-10,-6.09052e-7],[.7903,.0109107,-489042e-10,-104739e-11],[.8435,.0103431,-64615e-9,-1.40374e-9],[.8936,.00969686,-64636e-9,-8547e-9],[.9394,.00840947,-192841e-9,-42106e-10],[.9761,.00616527,-256e-6,-42106e-10],[1,.00328947,-319159e-9,-42106e-10]],Mi=.8487,ui=1.3523,fi=ct/5,mi=1/fi,pi=18,di=function(t,s){return t[0]+s*(t[1]+s*(t[2]+s*t[3]))},yi=function(t,s){return t[1]+s*(2*t[2]+3*s*t[3])},_i={init:function(){this.x0=this.x0||0,this.y0=this.y0||0,this.long0=this.long0||0,this.es=0,this.title=this.title||"Robinson"},forward:function(t){var s=Ot(t.x-this.long0),i=Math.abs(t.y),a=Math.floor(i*fi);a<0?a=0:a>=pi&&(a=pi-1),i=ct*(i-mi*a);var h={x:di(li[a],i)*s,y:di(ci[a],i)};return t.y<0&&(h.y=-h.y),h.x=h.x*this.a*Mi+this.x0,h.y=h.y*this.a*ui+this.y0,h},inverse:function(t){var s={x:(t.x-this.x0)/(this.a*Mi),y:Math.abs(t.y-this.y0)/(this.a*ui)};if(s.y>=1)s.x/=li[pi][0],s.y=t.y<0?-ht:ht;else{var i=Math.floor(s.y*pi);for(i<0?i=0:i>=pi&&(i=pi-1);;)if(ci[i][0]>s.y)--i;else{if(!(ci[i+1][0]<=s.y))break;++i}var a=ci[i],h=5*(s.y-a[0])/(ci[i+1][0]-a[0]);h=Y(function(t){return(di(a,t)-s.y)/yi(a,t)},h,ot,100),s.x/=di(li[i],h),s.y=(5*i+h)*lt,t.y<0&&(s.y=-s.y)}return s.x=Ot(s.x+this.long0),s},names:["Robinson","robin"]},xi={init:function(){this.name="geocent"},forward:function(t){return b(t,this.es,this.a)},inverse:function(t){return w(t,this.es,this.a,this.b)},names:["Geocentric","geocentric","geocent","Geocent"]},vi={N_POLE:0,S_POLE:1,EQUIT:2,OBLIQ:3},gi={h:{def:1e5,num:!0},azi:{def:0,num:!0,degrees:!0},tilt:{def:0,num:!0,degrees:!0},long0:{def:0,num:!0},lat0:{def:0,num:!0}},bi={init:function(){if(Object.keys(gi).forEach(function(t){if(void 0===this[t])this[t]=gi[t].def;else{if(gi[t].num&&isNaN(this[t]))throw new Error("Invalid parameter value, must be numeric "+t+" = "+this[t]);gi[t].num&&(this[t]=parseFloat(this[t]))}gi[t].degrees&&(this[t]=this[t]*lt)}.bind(this)),Math.abs(Math.abs(this.lat0)-ht)1e10)throw new Error("Invalid height");this.p=1+this.pn1,this.rp=1/this.p,this.h1=1/this.pn1,this.pfact=(this.p+1)*this.h1,this.es=0;var t=this.tilt,s=this.azi;this.cg=Math.cos(s),this.sg=Math.sin(s),this.cw=Math.cos(t),this.sw=Math.sin(t)},forward:function(t){t.x-=this.long0;var s,i,a=Math.sin(t.y),h=Math.cos(t.y),e=Math.cos(t.x);switch(this.mode){case vi.OBLIQ:i=this.sinph0*a+this.cosph0*h*e;break;case vi.EQUIT:i=h*e;break;case vi.S_POLE:i=-a;break;case vi.N_POLE:i=a}switch(i=this.pn1/(this.p-i),s=i*h*Math.sin(t.x),this.mode){case vi.OBLIQ:i*=this.cosph0*a-this.sinph0*h*e;break;case vi.EQUIT:i*=a;break;case vi.N_POLE:i*=-h*e;break;case vi.S_POLE:i*=h*e}var n,r;return n=i*this.cg+s*this.sg,r=1/(n*this.sw*this.h1+this.cw),s=(s*this.cg-i*this.sg)*this.cw*r,i=n*r,t.x=s*this.a,t.y=i*this.a,t},inverse:function(t){t.x/=this.a,t.y/=this.a;var s,i,a,h={x:t.x,y:t.y};a=1/(this.pn1-t.y*this.sw),s=this.pn1*t.x*a,i=this.pn1*t.y*this.cw*a,t.x=s*this.cg+i*this.sg,t.y=i*this.cg-s*this.sg;var e=rs(t.x,t.y);if(Math.abs(e)'; + html+=''+nodeColumn.getAttribute('d')+' '; + html+=''; + }else + { + } + + i++; + }else if(nodeColumn.nodeName=="divide") + { + html+=''; + html+=''+nodeColumn.getAttribute('d')+''; + html+=''; + } + nodeColumn = nodeColumn.nextSibling; + } + html+=''; + m_winPP.setContent(html); + m_winPP.setCenter(); + + //Call data + callFrmLocustDataPopup(id); +} + +//Update user interfase in popup window +function updateFrmLocustDelDataPopupInterface(node,id) +{ + let html=""; //Line for building HTML + nodeList=findNodeOnPath(node, "type/objects-list"); + html+=''; + m_winPP.setContent(html); + m_winPP.setCenter(); + + //Call data + callFrmLocustDelDataPopup(id); +} + +// Call data for filling popup window +function callFrmLocustDataPopup(id) +{ + let xs=''; + xs='\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + + let request=new TRequest(this); + request.userData="FrmLocustDataPopup"; + + if(request.callServer(ScriptName,xs)) + { + m_winPP.showProgressBar(); + } +} + +//Call data for filling popup window +function callFrmLocustDelDataPopup(id) +{ + let xs=''; + xs='\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + + let request=new TRequest(this); + request.userData="FrmLocustDelDataPopup"; + + if(request.callServer(ScriptName,xs)) + { + m_winPP.showProgressBar(); + } +} + +function updatePopupLocust(obj) +{ + for(let j=0;j'+obj.data[j].row[i]+''; + else + elm.innerHTML=obj.data[j].row[i]; + if(obj.data[j].row[i]==null || obj.data[j].row[i]=='') //if empty hide line + { + deleteHTML(i+'_tr_popup'); + } + } + } + } + let elm=document.getElementById('FrmLocustDataPopup'); + if(elm!=null) elm.style.display="block"; + m_winPP.setHeight(200); + m_winPP.setCenter(); +} + +function updatePopupLocustDel(obj) +{ + for(let j=0;j'+obj.data[j].row[i]+''; + else + elm.innerHTML=obj.data[j].row[i]; + if(obj.data[j].row[i]==null || obj.data[j].row[i]=='') //if empty hide line + { + deleteHTML(i+'_tr_popup'); + } + } + } + } + let elm=document.getElementById('FrmLocustDelDataPopup'); + if(elm!=null) elm.style.display="block"; + m_winPP.setHeight(200); + m_winPP.setCenter(); +} \ No newline at end of file diff --git a/src/main/webapp/resources/engine/r.png b/src/main/webapp/resources/engine/r.png new file mode 100644 index 0000000..0282cbf Binary files /dev/null and b/src/main/webapp/resources/engine/r.png differ diff --git a/src/main/webapp/resources/engine/split.js b/src/main/webapp/resources/engine/split.js new file mode 100644 index 0000000..0477e05 --- /dev/null +++ b/src/main/webapp/resources/engine/split.js @@ -0,0 +1,560 @@ +// The programming goals of Split.js are to deliver readable, understandable and +// maintainable code, while at the same time manually optimizing for tiny minified file size, +// browser compatibility without additional requirements, graceful fallback (IE8 is supported) +// and very few assumptions about the user's page layout. +// +// Make sure all browsers handle this JS library correctly with ES5. +// More information here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode +'use strict'; + +// A wrapper function that does a couple things: +// +// 1. Doesn't pollute the global namespace. This is important for a library. +// 2. Allows us to mount the library in different module systems, as well as +// directly in the browser. +(function() { + +// Save the global `this` for use later. In this case, since the library only +// runs in the browser, it will refer to `window`. Also, figure out if we're in IE8 +// or not. IE8 will still render correctly, but will be static instead of draggable. +// +// Save a couple long function names that are used frequently. +// This optimization saves around 400 bytes. +var global = this + , isIE8 = global.attachEvent && !global[addEventListener] + , document = global.document + , addEventListener = 'addEventListener' + , removeEventListener = 'removeEventListener' + , getBoundingClientRect = 'getBoundingClientRect' + + // This library only needs two helper functions: + // + // The first determines which prefixes of CSS calc we need. + // We only need to do this once on startup, when this anonymous function is called. + // + // Tests -webkit, -moz and -o prefixes. Modified from StackOverflow: + // http://stackoverflow.com/questions/16625140/js-feature-detection-to-detect-the-usage-of-webkit-calc-over-calc/16625167#16625167 + , calc = (function () { + var el + , prefixes = ["", "-webkit-", "-moz-", "-o-"] + + for (var i = 0; i < prefixes.length; i++) { + el = document.createElement('div') + el.style.cssText = "width:" + prefixes[i] + "calc(9px)" + + if (el.style.length) { + return prefixes[i] + "calc" + } + } + })() + + // The second helper function allows elements and string selectors to be used + // interchangeably. In either case an element is returned. This allows us to + // do `Split(elem1, elem2)` as well as `Split('#id1', '#id2')`. + , elementOrSelector = function (el) { + if (typeof el === 'string' || el instanceof String) { + return document.querySelector(el) + } else { + return el + } + } + + // The main function to initialize a split. Split.js thinks about each pair + // of elements as an independant pair. Dragging the gutter between two elements + // only changes the dimensions of elements in that pair. This is key to understanding + // how the following functions operate, since each function is bound to a pair. + // + // A pair object is shaped like this: + // + // { + // a: DOM element, + // b: DOM element, + // aMin: Number, + // bMin: Number, + // dragging: Boolean, + // parent: DOM element, + // isFirst: Boolean, + // isLast: Boolean, + // direction: 'horizontal' | 'vertical' + // } + // + // The basic sequence: + // + // 1. Set defaults to something sane. `options` doesn't have to be passed at all. + // 2. Initialize a bunch of strings based on the direction we're splitting. + // A lot of the behavior in the rest of the library is paramatized down to + // rely on CSS strings and classes. + // 3. Define the dragging helper functions, and a few helpers to go with them. + // 4. Define a few more functions that "balance" the entire split instance. + // Split.js tries it's best to cope with min sizes that don't add up. + // 5. Loop through the elements while pairing them off. Every pair gets an + // `pair` object, a gutter, and special isFirst/isLast properties. + // 6. Actually size the pair elements, insert gutters and attach event listeners. + // 7. Balance all of the pairs to accomodate min sizes as best as possible. + , Split = function (ids, options) { + var dimension + , i + , clientDimension + , clientAxis + , position + , gutterClass + , paddingA + , paddingB + , pairs = [] + + // 1. Set defaults to something sane. `options` doesn't have to be passed at all, + // so create an options object if none exists. Pixel values 10, 100 and 30 are + // arbitrary but feel natural. + options = typeof options !== 'undefined' ? options : {} + + if (typeof options.gutterSize === 'undefined') options.gutterSize = 10 + if (typeof options.minSize === 'undefined') options.minSize = 100 + if (typeof options.snapOffset === 'undefined') options.snapOffset = 30 + if (typeof options.direction === 'undefined') options.direction = 'horizontal' + + // 2. Initialize a bunch of strings based on the direction we're splitting. + // A lot of the behavior in the rest of the library is paramatized down to + // rely on CSS strings and classes. + if (options.direction == 'horizontal') { + dimension = 'width' + clientDimension = 'clientWidth' + clientAxis = 'clientX' + position = 'left' + gutterClass = 'gutter gutter-horizontal' + paddingA = 'paddingLeft' + paddingB = 'paddingRight' + if (!options.cursor) options.cursor = 'ew-resize' + } else if (options.direction == 'vertical') { + dimension = 'height' + clientDimension = 'clientHeight' + clientAxis = 'clientY' + position = 'top' + gutterClass = 'gutter gutter-vertical' + paddingA = 'paddingTop' + paddingB = 'paddingBottom' + if (!options.cursor) options.cursor = 'ns-resize' + } + + // 3. Define the dragging helper functions, and a few helpers to go with them. + // Each helper is bound to a pair object that contains it's metadata. This + // also makes it easy to store references to listeners that that will be + // added and removed. + // + // Even though there are no other functions contained in them, aliasing + // this to self saves 50 bytes or so since it's used so frequently. + // + // The pair object saves metadata like dragging state, position and + // event listener references. + // + // startDragging calls `calculateSizes` to store the inital size in the pair object. + // It also adds event listeners for mouse/touch events, + // and prevents selection while dragging so avoid the selecting text. + var startDragging = function (e) { + // Alias frequently used variables to save space. 200 bytes. + var self = this + , a = self.a + , b = self.b + + // Call the onDragStart callback. + if (!self.dragging && options.onDragStart) { + options.onDragStart() + } + + // Don't actually drag the element. We emulate that in the drag function. + e.preventDefault() + + // Set the dragging property of the pair object. + self.dragging = true + + // Create two event listeners bound to the same pair object and store + // them in the pair object. + self.move = drag.bind(self) + self.stop = stopDragging.bind(self) + + // All the binding. `window` gets the stop events in case we drag out of the elements. + global[addEventListener]('mouseup', self.stop) + global[addEventListener]('touchend', self.stop) + global[addEventListener]('touchcancel', self.stop) + + self.parent[addEventListener]('mousemove', self.move) + self.parent[addEventListener]('touchmove', self.move) + + // Disable selection. Disable! + a[addEventListener]('selectstart', noop) + a[addEventListener]('dragstart', noop) + b[addEventListener]('selectstart', noop) + b[addEventListener]('dragstart', noop) + + a.style.userSelect = 'none' + a.style.webkitUserSelect = 'none' + a.style.MozUserSelect = 'none' + a.style.pointerEvents = 'none' + + b.style.userSelect = 'none' + b.style.webkitUserSelect = 'none' + b.style.MozUserSelect = 'none' + b.style.pointerEvents = 'none' + + // Set the cursor, both on the gutter and the parent element. + // Doing only a, b and gutter causes flickering. + self.gutter.style.cursor = options.cursor + self.parent.style.cursor = options.cursor + + // Cache the initial sizes of the pair. + calculateSizes.call(self) + } + + // stopDragging is very similar to startDragging in reverse. + , stopDragging = function () { + var self = this + , a = self.a + , b = self.b + + if (self.dragging && options.onDragEnd) { + options.onDragEnd() + } + + self.dragging = false + + // Remove the stored event listeners. This is why we store them. + global[removeEventListener]('mouseup', self.stop) + global[removeEventListener]('touchend', self.stop) + global[removeEventListener]('touchcancel', self.stop) + + self.parent[removeEventListener]('mousemove', self.move) + self.parent[removeEventListener]('touchmove', self.move) + + // Delete them once they are removed. I think this makes a difference + // in memory usage with a lot of splits on one page. But I don't know for sure. + delete self.stop + delete self.move + + a[removeEventListener]('selectstart', noop) + a[removeEventListener]('dragstart', noop) + b[removeEventListener]('selectstart', noop) + b[removeEventListener]('dragstart', noop) + + a.style.userSelect = '' + a.style.webkitUserSelect = '' + a.style.MozUserSelect = '' + a.style.pointerEvents = '' + + b.style.userSelect = '' + b.style.webkitUserSelect = '' + b.style.MozUserSelect = '' + b.style.pointerEvents = '' + + self.gutter.style.cursor = '' + self.parent.style.cursor = '' + } + + // drag, where all the magic happens. The logic is really quite simple: + // + // 1. Ignore if the pair is not dragging. + // 2. Get the offset of the event. + // 3. Snap offset to min if within snappable range (within min + snapOffset). + // 4. Actually adjust each element in the pair to offset. + // + // --------------------------------------------------------------------- + // | | <- this.aMin || this.bMin -> | | + // | | | <- this.snapOffset || this.snapOffset -> | | | + // | | | || | | | + // | | | || | | | + // --------------------------------------------------------------------- + // | <- this.start this.size -> | + , drag = function (e) { + var offset + + if (!this.dragging) return + + // Get the offset of the event from the first side of the + // pair `this.start`. Supports touch events, but not multitouch, so only the first + // finger `touches[0]` is counted. + if ('touches' in e) { + offset = e.touches[0][clientAxis] - this.start + } else { + offset = e[clientAxis] - this.start + } + + // If within snapOffset of min or max, set offset to min or max. + // snapOffset buffers aMin and bMin, so logic is opposite for both. + // Include the appropriate gutter sizes to prevent overflows. + if (offset <= this.aMin + options.snapOffset + this.aGutterSize) { + offset = this.aMin + this.aGutterSize + } else if (offset >= this.size - (this.bMin + options.snapOffset + this.bGutterSize)) { + offset = this.size - (this.bMin + this.bGutterSize) + } + + // Actually adjust the size. + adjust.call(this, offset) + + // Call the drag callback continously. Don't do anything too intensive + // in this callback. + if (options.onDrag) { + options.onDrag() + } + } + + // Cache some important sizes when drag starts, so we don't have to do that + // continously: + // + // `size`: The total size of the pair. First element + second element + first gutter + second gutter. + // `percentage`: The percentage between 0-100 that the pair occupies in the parent. + // `start`: The leading side of the first element. + // + // ------------------------------------------------ - - - - - - - - - - - + // | aGutterSize -> ||| | | + // | ||| | | + // | ||| | | + // | ||| <- bGutterSize | | + // ------------------------------------------------ - - - - - - - - - - - + // | <- start size -> | parentSize -> | + , calculateSizes = function () { + // Figure out the parent size minus padding. + var computedStyle = global.getComputedStyle(this.parent) + , parentSize = this.parent[clientDimension] - parseFloat(computedStyle[paddingA]) - parseFloat(computedStyle[paddingB]) + + this.size = this.a[getBoundingClientRect]()[dimension] + this.b[getBoundingClientRect]()[dimension] + this.aGutterSize + this.bGutterSize + this.percentage = Math.min(this.size / parentSize * 100, 100) + this.start = this.a[getBoundingClientRect]()[position] + } + + // Actually adjust the size of elements `a` and `b` to `offset` while dragging. + // calc is used to allow calc(percentage + gutterpx) on the whole split instance, + // which allows the viewport to be resized without additional logic. + // Element a's size is the same as offset. b's size is total size - a size. + // Both sizes are calculated from the initial parent percentage, then the gutter size is subtracted. + , adjust = function (offset) { + this.a.style[dimension] = calc + '(' + (offset / this.size * this.percentage) + '% - ' + this.aGutterSize + 'px)' + this.b.style[dimension] = calc + '(' + (this.percentage - (offset / this.size * this.percentage)) + '% - ' + this.bGutterSize + 'px)' + } + + // 4. Define a few more functions that "balance" the entire split instance. + // Split.js tries it's best to cope with min sizes that don't add up. + // At some point this should go away since it breaks out of the calc(% - px) model. + // Maybe it's a user error if you pass uncomputable minSizes. + , fitMin = function () { + var self = this + , a = self.a + , b = self.b + + if (a[getBoundingClientRect]()[dimension] < self.aMin) { + a.style[dimension] = (self.aMin - self.aGutterSize) + 'px' + b.style[dimension] = (self.size - self.aMin - self.aGutterSize) + 'px' + } else if (b[getBoundingClientRect]()[dimension] < self.bMin) { + a.style[dimension] = (self.size - self.bMin - self.bGutterSize) + 'px' + b.style[dimension] = (self.bMin - self.bGutterSize) + 'px' + } + } + , fitMinReverse = function () { + var self = this + , a = self.a + , b = self.b + + if (b[getBoundingClientRect]()[dimension] < self.bMin) { + a.style[dimension] = (self.size - self.bMin - self.bGutterSize) + 'px' + b.style[dimension] = (self.bMin - self.bGutterSize) + 'px' + } else if (a[getBoundingClientRect]()[dimension] < self.aMin) { + a.style[dimension] = (self.aMin - self.aGutterSize) + 'px' + b.style[dimension] = (self.size - self.aMin - self.aGutterSize) + 'px' + } + } + , balancePairs = function (pairs) { + for (var i = 0; i < pairs.length; i++) { + calculateSizes.call(pairs[i]) + fitMin.call(pairs[i]) + } + + for (i = pairs.length - 1; i >= 0; i--) { + calculateSizes.call(pairs[i]) + fitMinReverse.call(pairs[i]) + } + } + , setElementSize = function (el, size, gutterSize) { + // Split.js allows setting sizes via numbers (ideally), or if you must, + // by string, like '300px'. This is less than ideal, because it breaks + // the fluid layout that `calc(% - px)` provides. You're on your own if you do that, + // make sure you calculate the gutter size by hand. + if (typeof size !== 'string' && !(size instanceof String)) { + if (!isIE8) { + size = calc + '(' + size + '% - ' + gutterSize + 'px)' + } else { + size = options.sizes[i] + '%' + } + } + + el.style[dimension] = size + } + + // No-op function to prevent default. Used to prevent selection. + , noop = function () { return false } + + // All DOM elements in the split should have a common parent. We can grab + // the first elements parent and hope users read the docs because the + // behavior will be whacky otherwise. + , parent = elementOrSelector(ids[0]).parentNode + + // Set default options.sizes to equal percentages of the parent element. + if (!options.sizes) { + var percent = 100 / ids.length + + options.sizes = [] + + for (i = 0; i < ids.length; i++) { + options.sizes.push(percent) + } + } + + // Standardize minSize to an array if it isn't already. This allows minSize + // to be passed as a number. + if (!Array.isArray(options.minSize)) { + var minSizes = [] + + for (i = 0; i < ids.length; i++) { + minSizes.push(options.minSize) + } + + options.minSize = minSizes + } + + // 5. Loop through the elements while pairing them off. Every pair gets a + // `pair` object, a gutter, and isFirst/isLast properties. + // + // Basic logic: + // + // - Starting with the second element `i > 0`, create `pair` objects with + // `a = ids[i - 1]` and `b = ids[i]` + // - Set gutter sizes based on the _pair_ being first/last. The first and last + // pair have gutterSize / 2, since they only have one half gutter, and not two. + // - Create gutter elements and add event listeners. + // - Set the size of the elements, minus the gutter sizes. + // + // ----------------------------------------------------------------------- + // | i=0 | i=1 | i=2 | i=3 | + // | | isFirst | | isLast | + // | pair 0 pair 1 pair 2 | + // | | | | | + // ----------------------------------------------------------------------- + for (i = 0; i < ids.length; i++) { + var el = elementOrSelector(ids[i]) + , isFirstPair = (i == 1) + , isLastPair = (i == ids.length - 1) + , size = options.sizes[i] + , gutterSize = options.gutterSize + , pair + + if (i > 0) { + // Create the pair object with it's metadata. + pair = { + a: elementOrSelector(ids[i - 1]), + b: el, + aMin: options.minSize[i - 1], + bMin: options.minSize[i], + dragging: false, + parent: parent, + isFirst: isFirstPair, + isLast: isLastPair, + direction: options.direction + } + + // For first and last pairs, first and last gutter width is half. + pair.aGutterSize = options.gutterSize + pair.bGutterSize = options.gutterSize + + if (isFirstPair) { + pair.aGutterSize = options.gutterSize / 2 + } + + if (isLastPair) { + pair.bGutterSize = options.gutterSize / 2 + } + } + + // Determine the size of the current element. IE8 is supported by + // staticly assigning sizes without draggable gutters. Assigns a string + // to `size`. + // + // IE9 and above + if (!isIE8) { + // Create gutter elements for each pair. + if (i > 0) { + var gutter = document.createElement('div') + + gutter.className = gutterClass + gutter.style[dimension] = options.gutterSize + 'px' + + gutter[addEventListener]('mousedown', startDragging.bind(pair)) + gutter[addEventListener]('touchstart', startDragging.bind(pair)) + + parent.insertBefore(gutter, el) + + pair.gutter = gutter + } + + // Half-size gutters for first and last elements. + if (i === 0 || i == ids.length - 1) { + gutterSize = options.gutterSize / 2 + } + } + + // Set the element size to our determined size. + setElementSize(el, size, gutterSize) + + // After the first iteration, and we have a pair object, append it to the + // list of pairs. + if (i > 0) { + pairs.push(pair) + } + } + + // Balance the pairs to try to accomodate min sizes. + balancePairs(pairs) + + return { + setSizes: function (sizes) { + for (var i = 0; i < sizes.length; i++) { + if (i > 0) { + var pair = pairs[i - 1] + + setElementSize(pair.a, sizes[i - 1], pair.aGutterSize) + setElementSize(pair.b, sizes[i], pair.bGutterSize) + } + } + }, + collapse: function (i) { + var pair + + if (i === pairs.length) { + pair = pairs[i - 1] + + calculateSizes.call(pair) + adjust.call(pair, pair.size - pair.bGutterSize) + } else { + pair = pairs[i] + + calculateSizes.call(pair) + adjust.call(pair, pair.aGutterSize) + } + }, + destroy: function () { + for (var i = 0; i < pairs.length; i++) { + pairs[i].parent.removeChild(pairs[i].gutter) + pairs[i].a.style[dimension] = '' + pairs[i].b.style[dimension] = '' + } + } + } +} + +// Play nicely with module systems, and the browser too if you include it raw. +if (typeof exports !== 'undefined') { + if (typeof module !== 'undefined' && module.exports) { + exports = module.exports = Split + } + exports.Split = Split +} else { + global.Split = Split +} + +// Call our wrapper function with the current global. In this case, `window`. +}).call(window); diff --git a/src/main/webapp/resources/engine/user.js b/src/main/webapp/resources/engine/user.js new file mode 100644 index 0000000..635af8d --- /dev/null +++ b/src/main/webapp/resources/engine/user.js @@ -0,0 +1,731 @@ +//Current user with role name and access +class TUser +{ + constructor(){ + this.name="TUser"; //Class name (not used) + this.win=null; + this.access = {}; //Associative array + this.onLoadAccess = null; //this.onUpdate = null; //Listener update access array + this.settings = {'':''}; //ассоциативный массив настроек для текущего пользователя + + this.divsh = null; + + this.checkSession(); + this.loadSettings(); + } + + applyReq(req,fn,node) + { + if(node.errorCode>0) { + let fullText = node.errorMessage; + let smallText = ''; + let pos1=fullText.indexOf('[['); + let pos2=fullText.indexOf(']]'); + if(pos1>=0 && pos2>=0 && pos1=0){ //Если есть идентификатор того что это перезапись + let okFunc=()=>{ + this.setValue('seq',0); + this.sendData(); //Применить ещё раз + }; + if (smallText != '') + confirm2(trt('Warning'),smallText, fullText, okFunc, null); + else + confirm2(trt('Warning'),smallText, '', okFunc, null); + }else { + if (smallText != '') + alert2(trt('Alert'), smallText, fullText); + else + alert2(trt('Alert'), fullText); + } + if(this.win!=null) this.win.hideProgressBar(); + return; + } + + if (fn==4) + { + if(node.n=="_ChangePassword"){ + if(node.data[0].row[0]=='t') + { + alert2(trt('Alert'),trt('Password_changed_successfully')); + this.win.Close(); + this.win=null; + }else + { + alert2(trt('Alert'),trt('Failed_to_change_password') +'\n'+ trt('Check_the_entered_data')); + this.win.hideProgressBar(); + } + + }else if(node.n=="SysUsersSettings"){ + this.updateSettings(node); + }else if(node.n=="SysAccessList"){ + this.updateAccess(node); + }else + { + log.error(trt("Unknown_XML_node")+": "+node.n); + } + }else if (fn==7) + { + let nCmd=findFirstNode(node, "cmd"); + if(nCmd!=null) + { + if(findFirstNode(nCmd,'#cdata-section').nodeValue=="1") //Logout + { + location.reload(); + }else if(findFirstNode(nCmd,'#cdata-section').nodeValue=="2") //Check if user not logged + { + if(findNode(node,'#cdata-section').nodeValue=="0") //if not logged + { + this.showLoginForm(); + }else + { + configGUIbyAccessLevel(); + + let shadow=document.getElementById("shadow"); + if(shadow.parentNode!=null) shadow.parentNode.removeChild(shadow); + } + + }else if(findFirstNode(nCmd,'#cdata-section').nodeValue=="3") //Login + { + if(findNode(node,'#cdata-section').nodeValue=="0") //if not logged + { + alert2(trt('Attention'),trt('Invalid_username_and_or_password')); + }else + { + location.reload(); + } + }else if(findFirstNode(nCmd,'#cdata-section').nodeValue=="4") //Register + { + if(findNode(node,'#cdata-section').nodeValue=="1") //if register + { + alert2(trt('Attention'),trt('New_user_is_registered')+'\n'+trt('The_password_has_been_sent_to_you_by_Email'),'',function(){ location.reload(); }); + } + } + } + }else + { alert("Unknown function! fn=\""+fn+"\"" ); + } + + if(this.win!=null) this.win.hideProgressBar(); + } + + loadAccess() + { + let xs='\n\ + \n\ + \n\ + \n\ + \n\ + '; + let request=new TRequest(this); + if(request.callServer(ScriptName,xs)) + { + //m_winPP.showProgressBar(); + } + }; + //Запросить загрузку параметров настроек + loadSettings() + { + //alert('call loadSettings'); + let xs='\n\ + \n\ + \n\ + \n\ + \n\ + '; + let request=new TRequest(this); + if(request.callServer(ScriptName,xs)) + { + //m_winPP.showProgressBar(); + } + } + + updateAccess(obj) + { + this.access={}; + for(let i=0;i\n\ +
\n\ + \n\ + \n\ + '+trt('Old_password')+':\n\ +
\n\ + \n\ + \n\ + '+trt('New_password')+':\n\ +
\n\ + \n\ + \n\ + '+trt('Repeat_password')+':\n\ +
\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + + this.win.setContent(str); + this.win.setSize("500px","180px"); + this.win.setCenter(); + this.win.shadow=true; + this.win.hide(false); + + document.getElementById('id_change_pass').onclick=function(thiz){return function(){ + + let login=document.getElementById('id_ch_login').value; + let pass=document.getElementById('id_ch_oldpassword').value; + let newpass=document.getElementById('id_ch_newpassword').value; + let newrpass=document.getElementById('id_ch_newrpassword').value; + + if(!isEmail(login)) + { + alert2(trt('Alert'),sprintf(trt('The_s_is_not_Email'),login)); + return; + } + if(newpass!=newrpass) + { + alert2(trt('Alert'),trt('Passwords_did_not_match')); + return; + } + if(!newpass.match(/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,20}$/)) + { + alert2(trt('Alert'),trt('Password_error_text')); + return; + } + + let xs='\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + + + let request=new TRequest(thiz); + //request.user="_ChangePassword"; + if(request.callServer(ScriptName,xs)) + { + thiz.win.showProgressBar(); + } + + };}(this); + + document.getElementById('id_exit_pass').onclick=function(win){return function(){win.Close();};}(this.win); + }; + + //logout current user + Logout() + { + xs=''; + let request=new TRequest(this); + if(request.callServer(ScriptName,xs)) + { + //m_winPP.showProgressBar(); + } + }; + + //Display login and registration form + showLoginForm() + { + if(this.win==null || this.win.closed) + { + this.win=new TWin(true); + this.win.disableClosing=true; + this.win.BuildGUI(10,10); + this.win.setCaption(trt('Authorization')+' / '+trt('Registration')); + + //win.setContent('str2'); + this.win.setSize("450px","100px"); + + let tab=new tcTabs(document.getElementById('TWin_Co_'+this.win.tWinId)); + tb=tab.addTab({caption:trt('Authorization')}); + let str='
\n\ + \n\ + \n\ + \n\ + \n\ +
\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ +
'+trt('Login')+' ('+trt('E_mail')+'):
'+trt('Password')+':
'+trt('Password_recovery')+'
\n\ +
\n\ +
'; + + tb.setConText(str); + tb.setSel(); + tb=tab.addTab({caption:trt('Registration')}); + str='
\n\ +
\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ +
'+trt('Country')+' *
'+trt('Surname')+'
'+trt('Name')+' *
'+trt('Company')+'
'+trt('Position')+'
'+trt('Phone')+'
'+trt('E_mail')+' *
\n\ +
\n\ +
'; + tb.setConText(str); + //tb.setSel() + + //Center the window and display the shadow + if(this.win.tbl.offsetHeight>this.win.div.offsetHeight) this.win.div.style.height=this.win.tbl.offsetHeight+"px"; + if(this.win.tbl.offsetWidth>this.win.div.offsetWidth) this.win.div.style.width=this.win.tbl.offsetWidth+"px"; + this.win.setCenter(); + this.win.shadow=true; + this.win.hide(false); + + let obj=null; + //Fill companies list by country + obj=document.getElementById(this.win.uid+'_country_id'); + obj.onchange = ()=>{ + let obj=document.getElementById(this.win.uid+'_country_id'); + $.ajax({ + url: '../get_companies?country_id='+obj.value, + //data: JSON.stringify(rData), + contentType: 'application/json; charset=utf-8', + type: "GET", + dataType: "json", + success: function(id){ return function(data,status){ + if(status=='success') + { + if(data.errorCode=='0') + { + let obj=document.getElementById(id+'_companies_list'); + obj.innerHTML=''; + let option; + for(let i=0;i\ + \ + '; + + let request=new TRequest(thiz); + if(request.callServer(ScriptName,xs)) + { + thiz.win.showProgressBar(); + } + }; + }(this); + } + + obj=document.getElementById(this.win.uid+'_registration'); + + if(obj!==null) + { + obj.onclick=function(thiz) + { return function() + { + //showProgressBar(document.getElementById('TWin_Co_'+thiz.win.tWinId),thiz.win.uid); + + let country_id = document.getElementById(thiz.win.uid+'_country_id').value; + let lastname = document.getElementById(thiz.win.uid+'_lastname').value; + let firstname = document.getElementById(thiz.win.uid+'_firstname').value; + let company=document.getElementById(thiz.win.uid+'_company').value; + let position=document.getElementById(thiz.win.uid+'_position').value; + let phone=document.getElementById(thiz.win.uid+'_phone').value; + let email=document.getElementById(thiz.win.uid+'_email').value; + + //Check for completeness of the fields + if(country_id==''){ document.getElementById(thiz.win.uid+'_country_id').focus(); alert(sprintf(trt('The_"%s"_field_is_empty'),trt('Country'))); return; } + if(firstname==''){ document.getElementById(thiz.win.uid+'_firstname').select(); alert(sprintf(trt('The_"%s"_field_is_empty'),trt('Name'))); return; } + if(email==''){ document.getElementById(thiz.win.uid+'_email').select(); alert(sprintf(trt('The_"%s"_field_is_empty'),trt('Email'))); return; } + if(! isEmail(email)){ document.getElementById(thiz.win.uid+'_email').select(); alert(trt('Please_enter_a_valid_email_address')); return; } + + thiz.addNewUser(country_id,lastname,firstname,company,position,phone,email); + }; + }(this); + } + } + + + /*var field1=document.getElementById("lang_1"); + if(field1!=null) + { + field1.value=getURLParam("lng"); + } + var field2=document.getElementById("lang_2"); + if(field2!=null) + { + field2.value=getURLParam("lng"); + }*/ + } + + //Create a new user (only if under temporary) + addNewUser(country_id,lastname,firstname,company,position,phone,email) + { + let xs='\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + '; + + let request=new TRequest(this); + if(request.callServer(ScriptName,xs)) + { + this.win.showProgressBar(); + } + + }; + + //Check whether the already authorized (+ attempt to log in through "hash"). + isLogined() + { + let xs=''; + //var xs='{"fn":7,"cmd":2}'; + let request=new TRequest(this); + if(request.callServer(ScriptName,xs)) + { + //m_winPP.showProgressBar(); + } + }; + + showLock(visible) { + if(this.divsh==null) { + this.divsh = document.createElement('div'); //Shadow + this.divsh.style.cssText = "display: none; position: fixed; z-index: 1000; top:0; left:0; height: 100%; width: 100%; background: rgba(0,0,0,0.3);"; + document.body.append(this.divsh); + } + if(!visible) + this.divsh.style.display='none'; + else + this.divsh.style.display='block'; + } + + //Checking the session without its extension, if it is completed, we display the authorization window. + checkSession() + { + + $.ajax({ + url: ScriptSName,//'./session.php', + data: "{}", + type: "POST", + dataType: "json", + success: (data,status) => { + if(status=='success') + { + if(data.result=='ERROR'){ + this.showLoginForm(); + }else + if(data.result=='OK'){ + this.id=data.user_id; + } + this.showLock(false); + }else + { + this.showLock(true); + } + }, + error: (jqXHR, exception)=> + { + this.showLock(true); + } + }); + setTimeout(()=>this.checkSession(), 10000); + } + + //Display password recovery form + showRestoreForm() + { + let win=new TWin(true); + win.BuildGUI(10,10); + win.setCaption(trt("Password_recovery")); + + let str='
\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ +
'+trt('Login')+' (E-mail)\n\ +
\n\ + \n\ +
'; + win.setContent(str); + + //Центрируем окно и отображаем тень + if(win.tbl.offsetHeight>win.div.offsetHeight) win.div.style.height=win.tbl.offsetHeight+"px"; + if(win.tbl.offsetWidth>win.div.offsetWidth) win.div.style.width=win.tbl.offsetWidth+"px"; + win.setCenter(); + win.shadow=true; + win.hide(false); + + //Click on restore button + let obj=null; + obj=document.getElementById(win.uid+'_restore'); + if(obj!=null) + { + obj.onclick=function(win) + { return function() + { + win.showProgressBar(); + + let em=document.getElementById(win.uid+'_email').value; + + if(em==''){ document.getElementById(win.uid+'_email').select(); alert(trt('Not_filled_Email_address')); win.hideProgressBar(); return; } + if(! isEmail(em)){ document.getElementById(win.uid+'_email').select(); alert(trt('Please_enter_a_valid_email_address')); win.hideProgressBar(); return; } + + //Send AJAX reqwest to server + let xml='\ + \ + \ + \ + \ + '; + + //Anonymous object + obj=new function(win) + { + this.processReqChange = function(xmlHttpRequest, url, xmlString) + { + if(typeof(xmlHttpRequest.status)=='undefined' || xmlHttpRequest.status == 200) + { + //if(typeof(xmlHttpRequest.responseXML)=='undefined' && xmlHttpRequest.contentType.match(/\/xml/)) //For IE XDomainRequest + // xmlHttpRequest.responseXML=CreateXMLDOC(xmlHttpRequest.responseText); + let fn = -1; + if(xmlHttpRequest.responseXML!=null) { + //загрузился xml документ начинаем его разбирать (по id функции в документе) + let xmldoc = xmlHttpRequest.responseXML + if(xmldoc==null) { + alert2(trt('Alert'), trt('Wrong_XML_document') + "!\n" + xmlHttpRequest.responseText); + return; + } + + let node = xmldoc.documentElement; + if((node==null)||(node.getAttribute("fn")==null)){ + alert2(trt('Error'),trt("No_data")+"!\n"+xmlHttpRequest.responseText); + }else + { + //alert("Принятый браузером XML=\n"+getXMLNodeSerialisation(node)); + let fn = node.getAttribute("fn"); + if(fn==7) + { + alert2(trt('Alert'),findFirstNode(node,'#cdata-section').nodeValue); + this.win.Close(); + } + } + }else{ + let obj = JSON.parse(xmlHttpRequest.responseText); + if(obj==null) { + alert2(trt('Alert'), trt('Wrong_JSON_document') + "!\nJSON=(" + xmlHttpRequest.responseText + ')'); + return; + }else{ + let node=obj; + if(node.errorCode>0) { + let fullText = node.errorMessage; + let smallText = ''; + let pos1=fullText.indexOf('[['); + let pos2=fullText.indexOf(']]'); + if(pos1>=0 && pos2>=0 && pos1=0){ //Если есть идентификатор того что это перезапись + let okFunc=()=>{ + this.setValue('seq',0); + this.sendData(); //Применить ещё раз + }; + if (smallText != '') + confirm2(trt('Warning'),smallText, fullText, okFunc, null); + else + confirm2(trt('Warning'),smallText, '', okFunc, null); + }else { + if (smallText != '') + alert2(trt('Alert'), smallText, fullText); + else + alert2(trt('Alert'), fullText); + } + return; + } + } + } + + + + }else + { + if(confirm(trt('Failed_to_get_data')+"\n URL: "+url+"\n"+xmlHttpRequest.statusText+"\nRedo the request?")) + { + let call=new myXMLHttpRequest(this); + call.callServer(url,xmlString); + } + } + return null; + }; + this.win=win; //For close after showing message. + } + (win); + + let call=new myXMLHttpRequest(obj); + call.callServer(ScriptName,xml); + + }; + }(win); + } + } + //Сохранить параметр настройки для текущего пользователя в базе данных. + sendSettings(name, value, func) + { + showProgressBarIco(); + this.settings[name]=''+value; + let xs=` + + + + + `; + $.ajax({ + url: ScriptName, + type: "POST", + contentType: 'text/xml; charset=utf-8', + dataType: "text", + data: xs, + success: function(response) { + hideProgressBarIco(); + if(func !== undefined && func!=null){ + func(); + } + }, + error: function(xhr) { + hideProgressBarIco(); + alert2(trt("Alert"),trt("Failed_to_write_settings")+"!"); + } + }); + } + + //Запросить загрузку компаний для выбранной страны при регистрации + loadCompanies(country_id){ + let xs='\n\ + \n\ + \n\ + \n\ + \n\ + '; + let request=new TRequest(this); + if(request.callServer(ScriptName,xs)) + { + //m_winPP.showProgressBar(); + } + } +} diff --git a/src/main/webapp/resources/engine/vertical.png b/src/main/webapp/resources/engine/vertical.png new file mode 100644 index 0000000..a133216 Binary files /dev/null and b/src/main/webapp/resources/engine/vertical.png differ diff --git a/src/main/webapp/resources/engine/wkt-parser/.eslintrc b/src/main/webapp/resources/engine/wkt-parser/.eslintrc new file mode 100644 index 0000000..c185b57 --- /dev/null +++ b/src/main/webapp/resources/engine/wkt-parser/.eslintrc @@ -0,0 +1,21 @@ +{ +extends: "eslint:recommended", + "env": { + "node": true, + "browser": true }, + "parserOptions": { + "sourceType": "module", + }, + "rules": { +"indent": [2, 2, {"SwitchCase": 1}], + "brace-style": [2, "1tbs"], + "quotes": [2, "single"], + "no-console": 0, + "no-shadow": 0, + "no-use-before-define": [2, "nofunc"], + "no-underscore-dangle": 0, + "no-constant-condition": 0, + "space-after-function-name": 0, + "consistent-return": 0 + } +} diff --git a/src/main/webapp/resources/engine/wkt-parser/README.md b/src/main/webapp/resources/engine/wkt-parser/README.md new file mode 100644 index 0000000..edcae99 --- /dev/null +++ b/src/main/webapp/resources/engine/wkt-parser/README.md @@ -0,0 +1,4 @@ +wkt-parser +=== + +The wkt parser pulled out of proj4 so it can be hacked on. diff --git a/src/main/webapp/resources/engine/wkt-parser/index.js b/src/main/webapp/resources/engine/wkt-parser/index.js new file mode 100644 index 0000000..77e4687 --- /dev/null +++ b/src/main/webapp/resources/engine/wkt-parser/index.js @@ -0,0 +1,171 @@ +var D2R = 0.01745329251994329577; +import parser from './parser'; +import {sExpr} from './process'; + + + +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) { + if (wkt.type === 'GEOGCS') { + if (wkt.DATUM && wkt.DATUM.SPHEROID) { + wkt.to_meter = wkt.UNIT.convert*wkt.DATUM.SPHEROID.a; + } + } else { + wkt.to_meter = wkt.UNIT.convert; + } + } + } + var geogcs = wkt.GEOGCS; + if (wkt.type === 'GEOGCS') { + geogcs = wkt; + } + if (geogcs) { + //if(wkt.GEOGCS.PRIMEM&&wkt.GEOGCS.PRIMEM.convert){ + // wkt.from_greenwich=wkt.GEOGCS.PRIMEM.convert*D2R; + //} + if (geogcs.DATUM) { + wkt.datumCode = geogcs.DATUM.name.toLowerCase(); + } else { + wkt.datumCode = 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 (geogcs.DATUM && geogcs.DATUM.SPHEROID) { + wkt.ellps = geogcs.DATUM.SPHEROID.name.replace('_19', '').replace(/[Cc]larke\_18/, 'clrk'); + if (wkt.ellps.toLowerCase().slice(0, 13) === 'international') { + wkt.ellps = 'intl'; + } + + wkt.a = geogcs.DATUM.SPHEROID.a; + wkt.rf = parseFloat(geogcs.DATUM.SPHEROID.rf, 10); + } + + if (geogcs.DATUM && geogcs.DATUM.TOWGS84) { + wkt.datum_params = geogcs.DATUM.TOWGS84; + } + if (~wkt.datumCode.indexOf('osgb_1936')) { + wkt.datumCode = 'osgb36'; + } + if (~wkt.datumCode.indexOf('osni_1952')) { + wkt.datumCode = 'osni52'; + } + if (~wkt.datumCode.indexOf('tm65') + || ~wkt.datumCode.indexOf('geodetic_datum_of_1965')) { + wkt.datumCode = 'ire65'; + } + if (wkt.datumCode === 'ch1903+') { + wkt.datumCode = 'ch1903'; + } + if (~wkt.datumCode.indexOf('israel')) { + wkt.datumCode = 'isr93'; + } + } + if (wkt.b && !isFinite(wkt.b)) { + wkt.b = wkt.a; + } + + function toMeter(input) { + var ratio = wkt.to_meter || 1; + return input * 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'], + ['latitude_of_origin', 'Central_Parallel'], + ['scale_factor', 'Scale_Factor'], + ['k0', 'scale_factor'], + ['latitude_of_center', 'Latitude_Of_Center'], + ['latitude_of_center', 'Latitude_of_center'], + ['lat0', 'latitude_of_center', d2r], + ['longitude_of_center', 'Longitude_Of_Center'], + ['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], + ['azimuth', 'Azimuth'], + ['alpha', 'azimuth', d2r], + ['srsCode', 'name'] + ]; + list.forEach(renamer); + if (!wkt.long0 && wkt.longc && (wkt.projName === 'Albers_Conic_Equal_Area' || wkt.projName === 'Lambert_Azimuthal_Equal_Area')) { + wkt.long0 = wkt.longc; + } + if (!wkt.lat_ts && wkt.lat1 && (wkt.projName === 'Stereographic_South_Pole' || wkt.projName === 'Polar Stereographic (variant B)')) { + wkt.lat0 = d2r(wkt.lat1 > 0 ? 90 : -90); + wkt.lat_ts = wkt.lat1; + } +} +export default function(wkt) { + var lisp = parser(wkt); + var type = lisp.shift(); + var name = lisp.shift(); + lisp.unshift(['name', name]); + lisp.unshift(['type', type]); + var obj = {}; + sExpr(lisp, obj); + cleanWKT(obj); + return obj; +} diff --git a/src/main/webapp/resources/engine/wkt-parser/package.json b/src/main/webapp/resources/engine/wkt-parser/package.json new file mode 100644 index 0000000..a3ee37d --- /dev/null +++ b/src/main/webapp/resources/engine/wkt-parser/package.json @@ -0,0 +1,63 @@ +{ + "_from": "wkt-parser@^1.2.0", + "_id": "wkt-parser@1.2.3", + "_inBundle": false, + "_integrity": "sha512-s7zrOedGuHbbzMaQOuf8HacuCYp3LmmrHjkkN//7UEAzsYz7xJ6J+j/84ZWZkQcrRqi3xXyuc4odPHj7PEB0bw==", + "_location": "/wkt-parser", + "_phantomChildren": {}, + "_requested": { + "type": "range", + "registry": true, + "raw": "wkt-parser@^1.2.0", + "name": "wkt-parser", + "escapedName": "wkt-parser", + "rawSpec": "^1.2.0", + "saveSpec": null, + "fetchSpec": "^1.2.0" + }, + "_requiredBy": [ + "/proj4" + ], + "_resolved": "https://registry.npmjs.org/wkt-parser/-/wkt-parser-1.2.3.tgz", + "_shasum": "240fe1dacc816bfe5674b66180041059eaa9a9ba", + "_spec": "wkt-parser@^1.2.0", + "_where": "O:\\temp\\node_modules\\proj4", + "author": "", + "browserify": { + "transform": [ + [ + "babelify", + { + "presets": [ + "es2015" + ] + } + ] + ] + }, + "bugs": { + "url": "https://github.com/proj4js/wkt-parser/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "wkt-parser ===", + "devDependencies": { + "rollup": "^0.41.4", + "tape": "^4.6.3" + }, + "homepage": "https://github.com/proj4js/wkt-parser#readme", + "license": "MIT", + "main": "wkt.build.js", + "module": "index.js", + "name": "wkt-parser", + "repository": { + "type": "git", + "url": "git+https://github.com/proj4js/wkt-parser.git" + }, + "scripts": { + "build": "rollup -c", + "pretest": "npm run build", + "test": "node test.js" + }, + "version": "1.2.3" +} diff --git a/src/main/webapp/resources/engine/wkt-parser/parser.js b/src/main/webapp/resources/engine/wkt-parser/parser.js new file mode 100644 index 0000000..d7f14b1 --- /dev/null +++ b/src/main/webapp/resources/engine/wkt-parser/parser.js @@ -0,0 +1,169 @@ +export default parseString; + +var NEUTRAL = 1; +var KEYWORD = 2; +var NUMBER = 3; +var QUOTED = 4; +var AFTERQUOTE = 5; +var ENDED = -1; +var whitespace = /\s/; +var latin = /[A-Za-z]/; +var keyword = /[A-Za-z84]/; +var endThings = /[,\]]/; +var digets = /[\d\.E\-\+]/; +// const ignoredChar = /[\s_\-\/\(\)]/g; +function Parser(text) { + if (typeof text !== 'string') { + throw new Error('not a string'); + } + this.text = text.trim(); + this.level = 0; + this.place = 0; + this.root = null; + this.stack = []; + this.currentObject = null; + this.state = NEUTRAL; +} +Parser.prototype.readCharicter = function() { + var char = this.text[this.place++]; + if (this.state !== QUOTED) { + while (whitespace.test(char)) { + if (this.place >= this.text.length) { + return; + } + char = this.text[this.place++]; + } + } + switch (this.state) { + case NEUTRAL: + return this.neutral(char); + case KEYWORD: + return this.keyword(char) + case QUOTED: + return this.quoted(char); + case AFTERQUOTE: + return this.afterquote(char); + case NUMBER: + return this.number(char); + case ENDED: + return; + } +}; +Parser.prototype.afterquote = function(char) { + if (char === '"') { + this.word += '"'; + this.state = QUOTED; + return; + } + if (endThings.test(char)) { + this.word = this.word.trim(); + this.afterItem(char); + return; + } + throw new Error('havn\'t handled "' +char + '" in afterquote yet, index ' + this.place); +}; +Parser.prototype.afterItem = function(char) { + if (char === ',') { + if (this.word !== null) { + this.currentObject.push(this.word); + } + this.word = null; + this.state = NEUTRAL; + return; + } + if (char === ']') { + this.level--; + if (this.word !== null) { + this.currentObject.push(this.word); + this.word = null; + } + this.state = NEUTRAL; + this.currentObject = this.stack.pop(); + if (!this.currentObject) { + this.state = ENDED; + } + + return; + } +}; +Parser.prototype.number = function(char) { + if (digets.test(char)) { + this.word += char; + return; + } + if (endThings.test(char)) { + this.word = parseFloat(this.word); + this.afterItem(char); + return; + } + throw new Error('havn\'t handled "' +char + '" in number yet, index ' + this.place); +}; +Parser.prototype.quoted = function(char) { + if (char === '"') { + this.state = AFTERQUOTE; + return; + } + this.word += char; + return; +}; +Parser.prototype.keyword = function(char) { + if (keyword.test(char)) { + this.word += char; + return; + } + if (char === '[') { + var newObjects = []; + newObjects.push(this.word); + this.level++; + if (this.root === null) { + this.root = newObjects; + } else { + this.currentObject.push(newObjects); + } + this.stack.push(this.currentObject); + this.currentObject = newObjects; + this.state = NEUTRAL; + return; + } + if (endThings.test(char)) { + this.afterItem(char); + return; + } + throw new Error('havn\'t handled "' +char + '" in keyword yet, index ' + this.place); +}; +Parser.prototype.neutral = function(char) { + if (latin.test(char)) { + this.word = char; + this.state = KEYWORD; + return; + } + if (char === '"') { + this.word = ''; + this.state = QUOTED; + return; + } + if (digets.test(char)) { + this.word = char; + this.state = NUMBER; + return; + } + if (endThings.test(char)) { + this.afterItem(char); + return; + } + throw new Error('havn\'t handled "' +char + '" in neutral yet, index ' + this.place); +}; +Parser.prototype.output = function() { + while (this.place < this.text.length) { + this.readCharicter(); + } + if (this.state === ENDED) { + return this.root; + } + throw new Error('unable to parse string "' +this.text + '". State is ' + this.state); +}; + +function parseString(txt) { + var parser = new Parser(txt); + return parser.output(); +} diff --git a/src/main/webapp/resources/engine/wkt-parser/process.js b/src/main/webapp/resources/engine/wkt-parser/process.js new file mode 100644 index 0000000..9837587 --- /dev/null +++ b/src/main/webapp/resources/engine/wkt-parser/process.js @@ -0,0 +1,106 @@ + + +function mapit(obj, key, value) { + if (Array.isArray(key)) { + value.unshift(key); + key = null; + } + var thing = key ? {} : obj; + + var out = value.reduce(function(newObj, item) { + sExpr(item, newObj); + return newObj + }, thing); + if (key) { + obj[key] = out; + } +} + +export function sExpr(v, obj) { + if (!Array.isArray(v)) { + obj[v] = true; + return; + } + var 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]); + return; + } + obj[key] = v[0]; + return; + } + if (!v.length) { + obj[key] = true; + return; + } + if (key === 'TOWGS84') { + obj[key] = v; + return; + } + if (!Array.isArray(key)) { + obj[key] = {}; + } + + var i; + switch (key) { + case 'UNIT': + case 'PRIMEM': + case 'VERT_DATUM': + obj[key] = { + name: v[0].toLowerCase(), + convert: v[1] + }; + if (v.length === 3) { + sExpr(v[2], obj[key]); + } + return; + case 'SPHEROID': + case 'ELLIPSOID': + obj[key] = { + name: v[0], + a: v[1], + rf: v[2] + }; + if (v.length === 4) { + sExpr(v[3], obj[key]); + } + return; + case 'PROJECTEDCRS': + case 'PROJCRS': + case 'GEOGCS': + case 'GEOCCS': + case 'PROJCS': + case 'LOCAL_CS': + case 'GEODCRS': + case 'GEODETICCRS': + case 'GEODETICDATUM': + case 'EDATUM': + case 'ENGINEERINGDATUM': + case 'VERT_CS': + case 'VERTCRS': + case 'VERTICALCRS': + case 'COMPD_CS': + case 'COMPOUNDCRS': + case 'ENGINEERINGCRS': + case 'ENGCRS': + case 'FITTED_CS': + case 'LOCAL_DATUM': + case 'DATUM': + v[0] = ['name', v[0]]; + mapit(obj, key, v); + return; + default: + i = -1; + while (++i < v.length) { + if (!Array.isArray(v[i])) { + return sExpr(v, obj[key]); + } + } + return mapit(obj, key, v); + } +} diff --git a/src/main/webapp/resources/engine/wkt-parser/rollup.config.js b/src/main/webapp/resources/engine/wkt-parser/rollup.config.js new file mode 100644 index 0000000..1c0c53d --- /dev/null +++ b/src/main/webapp/resources/engine/wkt-parser/rollup.config.js @@ -0,0 +1,6 @@ + +export default { + entry: 'index.js', + dest: 'wkt.build.js', + format: 'cjs' +}; diff --git a/src/main/webapp/resources/engine/wkt-parser/test-fixtures.json b/src/main/webapp/resources/engine/wkt-parser/test-fixtures.json new file mode 100644 index 0000000..fb5a988 --- /dev/null +++ b/src/main/webapp/resources/engine/wkt-parser/test-fixtures.json @@ -0,0 +1,391 @@ +[{ + "code": "PROJCS[\"NZGD49 / New Zealand Map Grid\",GEOGCS[\"NZGD49\",DATUM[\"New_Zealand_Geodetic_Datum_1949\",SPHEROID[\"International 1924\",6378388,297,AUTHORITY[\"EPSG\",\"7022\"]],TOWGS84[59.47,-5.04,187.44,0.47,-0.1,1.024,-4.5993],AUTHORITY[\"EPSG\",\"6272\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4272\"]],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],PROJECTION[\"New_Zealand_Map_Grid\"],PARAMETER[\"latitude_of_origin\",-41],PARAMETER[\"central_meridian\",173],PARAMETER[\"false_easting\",2510000],PARAMETER[\"false_northing\",6023150],AUTHORITY[\"EPSG\",\"27200\"],AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH]]", + "intermediate": [ + "PROJCS", + "NZGD49 / New Zealand Map Grid", + [ + "GEOGCS", + "NZGD49", + [ + "DATUM", + "New_Zealand_Geodetic_Datum_1949", + [ + "SPHEROID", + "International 1924", + 6378388, + 297, + [ + "AUTHORITY", + "EPSG", + "7022" + ] + ], + [ + "TOWGS84", + 59.47, + -5.04, + 187.44, + 0.47, + -0.1, + 1.024, + -4.5993 + ], + [ + "AUTHORITY", + "EPSG", + "6272" + ] + ], + [ + "PRIMEM", + "Greenwich", + 0, + [ + "AUTHORITY", + "EPSG", + "8901" + ] + ], + [ + "UNIT", + "degree", + 0.01745329251994328, + [ + "AUTHORITY", + "EPSG", + "9122" + ] + ], + [ + "AUTHORITY", + "EPSG", + "4272" + ] + ], + [ + "UNIT", + "metre", + 1, + [ + "AUTHORITY", + "EPSG", + "9001" + ] + ], + [ + "PROJECTION", + "New_Zealand_Map_Grid" + ], + [ + "PARAMETER", + "latitude_of_origin", + -41 + ], + [ + "PARAMETER", + "central_meridian", + 173 + ], + [ + "PARAMETER", + "false_easting", + 2510000 + ], + [ + "PARAMETER", + "false_northing", + 6023150 + ], + [ + "AUTHORITY", + "EPSG", + "27200" + ], + [ + "AXIS", + "Easting", + "EAST" + ], + [ + "AXIS", + "Northing", + "NORTH" + ] +], + "value": { + "type": "PROJCS", + "name": "NZGD49 / New Zealand Map Grid", + "GEOGCS": { + "name": "NZGD49", + "DATUM": { + "name": "New_Zealand_Geodetic_Datum_1949", + "SPHEROID": { + "name": "International 1924", + "a": 6378388, + "rf": 297, + "auth": [ + "AUTHORITY", + "EPSG", + "7022" + ] + }, + "TOWGS84": [ + 59.47, -5.04, + 187.44, + 0.47, -0.1, + 1.024, -4.5993 + ], + "AUTHORITY": { + "EPSG": "6272" + } + }, + "PRIMEM": { + "name": "greenwich", + "convert": 0, + "auth": [ + "AUTHORITY", + "EPSG", + "8901" + ] + }, + "UNIT": { + "name": "degree", + "convert": 0.01745329251994328, + "auth": [ + "AUTHORITY", + "EPSG", + "9122" + ] + }, + "AUTHORITY": { + "EPSG": "4272" + } + }, + "UNIT": { + "name": "metre", + "convert": 1, + "auth": [ + "AUTHORITY", + "EPSG", + "9001" + ] + }, + "PROJECTION": "New_Zealand_Map_Grid", + "latitude_of_origin": -41, + "central_meridian": 173, + "false_easting": 2510000, + "false_northing": 6023150, + "AUTHORITY": { + "EPSG": "27200" + }, + "AXIS": { + "Northing": "NORTH" + }, + "projName": "New_Zealand_Map_Grid", + "units": "meter", + "to_meter": 1, + "datumCode": "nzgd49", + "ellps": "intl", + "a": 6378388, + "rf": 297, + "x0": 2510000, + "y0": 6023150, + "long0": 3.01941960595019, + "lat0": -0.7155849933176751, + "srsCode": "NZGD49 / New Zealand Map Grid" + } +}, { + "code": "PROJCS[\"NAD83 / Massachusetts Mainland\",GEOGCS[\"NAD83\",DATUM[\"North_American_Datum_1983\",SPHEROID[\"GRS 1980\",6378137,298.257222101,AUTHORITY[\"EPSG\",\"7019\"]],AUTHORITY[\"EPSG\",\"6269\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.01745329251994328,AUTHORITY[\"EPSG\",\"9122\"]],AUTHORITY[\"EPSG\",\"4269\"]],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],PROJECTION[\"Lambert_Conformal_Conic_2SP\"],PARAMETER[\"standard_parallel_1\",42.68333333333333],PARAMETER[\"standard_parallel_2\",41.71666666666667],PARAMETER[\"latitude_of_origin\",41],PARAMETER[\"central_meridian\",-71.5],PARAMETER[\"false_easting\",200000],PARAMETER[\"false_northing\",750000],AUTHORITY[\"EPSG\",\"26986\"],AXIS[\"X\",EAST],AXIS[\"Y\",NORTH]]", + "intermediate":[ + "PROJCS", + "NAD83 / Massachusetts Mainland", + [ + "GEOGCS", + "NAD83", + [ + "DATUM", + "North_American_Datum_1983", + [ + "SPHEROID", + "GRS 1980", + 6378137, + 298.257222101, + [ + "AUTHORITY", + "EPSG", + "7019" + ] + ], + [ + "AUTHORITY", + "EPSG", + "6269" + ] + ], + [ + "PRIMEM", + "Greenwich", + 0, + [ + "AUTHORITY", + "EPSG", + "8901" + ] + ], + [ + "UNIT", + "degree", + 0.01745329251994328, + [ + "AUTHORITY", + "EPSG", + "9122" + ] + ], + [ + "AUTHORITY", + "EPSG", + "4269" + ] + ], + [ + "UNIT", + "metre", + 1, + [ + "AUTHORITY", + "EPSG", + "9001" + ] + ], + [ + "PROJECTION", + "Lambert_Conformal_Conic_2SP" + ], + [ + "PARAMETER", + "standard_parallel_1", + 42.68333333333333 + ], + [ + "PARAMETER", + "standard_parallel_2", + 41.71666666666667 + ], + [ + "PARAMETER", + "latitude_of_origin", + 41 + ], + [ + "PARAMETER", + "central_meridian", + -71.5 + ], + [ + "PARAMETER", + "false_easting", + 200000 + ], + [ + "PARAMETER", + "false_northing", + 750000 + ], + [ + "AUTHORITY", + "EPSG", + "26986" + ], + [ + "AXIS", + "X", + "EAST" + ], + [ + "AXIS", + "Y", + "NORTH" + ] +], + "value": { + "type": "PROJCS", + "name": "NAD83 / Massachusetts Mainland", + "GEOGCS": { + "name": "NAD83", + "DATUM": { + "name": "North_American_Datum_1983", + "SPHEROID": { + "name": "GRS 1980", + "a": 6378137, + "rf": 298.257222101, + "auth": [ + "AUTHORITY", + "EPSG", + "7019" + ] + }, + "AUTHORITY": { + "EPSG": "6269" + } + }, + "PRIMEM": { + "name": "greenwich", + "convert": 0, + "auth": [ + "AUTHORITY", + "EPSG", + "8901" + ] + }, + "UNIT": { + "name": "degree", + "convert": 0.01745329251994328, + "auth": [ + "AUTHORITY", + "EPSG", + "9122" + ] + }, + "AUTHORITY": { + "EPSG": "4269" + } + }, + "UNIT": { + "name": "metre", + "convert": 1, + "auth": [ + "AUTHORITY", + "EPSG", + "9001" + ] + }, + "PROJECTION": "Lambert_Conformal_Conic_2SP", + "standard_parallel_1": 42.68333333333333, + "standard_parallel_2": 41.71666666666667, + "latitude_of_origin": 41, + "central_meridian": -71.5, + "false_easting": 200000, + "false_northing": 750000, + "AUTHORITY": { + "EPSG": "26986" + }, + "AXIS": { + "Y": "NORTH" + }, + "projName": "Lambert_Conformal_Conic_2SP", + "units": "meter", + "to_meter": 1, + "datumCode": "north_american_datum_1983", + "ellps": "GRS 1980", + "a": 6378137, + "rf": 298.257222101, + "x0": 200000, + "y0": 750000, + "long0": -1.2479104151759457, + "lat0": 0.7155849933176751, + "lat1": 0.7449647023929129, + "lat2": 0.7280931862903012, + "srsCode": "NAD83 / Massachusetts Mainland" + } +}] diff --git a/src/main/webapp/resources/engine/wkt-parser/test.js b/src/main/webapp/resources/engine/wkt-parser/test.js new file mode 100644 index 0000000..a54f0ca --- /dev/null +++ b/src/main/webapp/resources/engine/wkt-parser/test.js @@ -0,0 +1,12 @@ +var test = require('tape'); +var wktParser = require('./wkt.build.js'); +var fixtures = require('./test-fixtures'); + +fixtures.forEach((item, i)=>{ + test(`fixture ${i}`, t=>{ + var out = wktParser(item.code); + //var out = parser(item.code); + console.log(JSON.stringify(out, false, 2)); + t.end(); + }); +}) diff --git a/src/main/webapp/resources/engine/wkt-parser/wkt.build.js b/src/main/webapp/resources/engine/wkt-parser/wkt.build.js new file mode 100644 index 0000000..21ad650 --- /dev/null +++ b/src/main/webapp/resources/engine/wkt-parser/wkt.build.js @@ -0,0 +1,443 @@ +'use strict'; + +var NEUTRAL = 1; +var KEYWORD = 2; +var NUMBER = 3; +var QUOTED = 4; +var AFTERQUOTE = 5; +var ENDED = -1; +var whitespace = /\s/; +var latin = /[A-Za-z]/; +var keyword = /[A-Za-z84]/; +var endThings = /[,\]]/; +var digets = /[\d\.E\-\+]/; +// const ignoredChar = /[\s_\-\/\(\)]/g; +function Parser(text) { + if (typeof text !== 'string') { + throw new Error('not a string'); + } + this.text = text.trim(); + this.level = 0; + this.place = 0; + this.root = null; + this.stack = []; + this.currentObject = null; + this.state = NEUTRAL; +} +Parser.prototype.readCharicter = function() { + var char = this.text[this.place++]; + if (this.state !== QUOTED) { + while (whitespace.test(char)) { + if (this.place >= this.text.length) { + return; + } + char = this.text[this.place++]; + } + } + switch (this.state) { + case NEUTRAL: + return this.neutral(char); + case KEYWORD: + return this.keyword(char) + case QUOTED: + return this.quoted(char); + case AFTERQUOTE: + return this.afterquote(char); + case NUMBER: + return this.number(char); + case ENDED: + return; + } +}; +Parser.prototype.afterquote = function(char) { + if (char === '"') { + this.word += '"'; + this.state = QUOTED; + return; + } + if (endThings.test(char)) { + this.word = this.word.trim(); + this.afterItem(char); + return; + } + throw new Error('havn\'t handled "' +char + '" in afterquote yet, index ' + this.place); +}; +Parser.prototype.afterItem = function(char) { + if (char === ',') { + if (this.word !== null) { + this.currentObject.push(this.word); + } + this.word = null; + this.state = NEUTRAL; + return; + } + if (char === ']') { + this.level--; + if (this.word !== null) { + this.currentObject.push(this.word); + this.word = null; + } + this.state = NEUTRAL; + this.currentObject = this.stack.pop(); + if (!this.currentObject) { + this.state = ENDED; + } + + return; + } +}; +Parser.prototype.number = function(char) { + if (digets.test(char)) { + this.word += char; + return; + } + if (endThings.test(char)) { + this.word = parseFloat(this.word); + this.afterItem(char); + return; + } + throw new Error('havn\'t handled "' +char + '" in number yet, index ' + this.place); +}; +Parser.prototype.quoted = function(char) { + if (char === '"') { + this.state = AFTERQUOTE; + return; + } + this.word += char; + return; +}; +Parser.prototype.keyword = function(char) { + if (keyword.test(char)) { + this.word += char; + return; + } + if (char === '[') { + var newObjects = []; + newObjects.push(this.word); + this.level++; + if (this.root === null) { + this.root = newObjects; + } else { + this.currentObject.push(newObjects); + } + this.stack.push(this.currentObject); + this.currentObject = newObjects; + this.state = NEUTRAL; + return; + } + if (endThings.test(char)) { + this.afterItem(char); + return; + } + throw new Error('havn\'t handled "' +char + '" in keyword yet, index ' + this.place); +}; +Parser.prototype.neutral = function(char) { + if (latin.test(char)) { + this.word = char; + this.state = KEYWORD; + return; + } + if (char === '"') { + this.word = ''; + this.state = QUOTED; + return; + } + if (digets.test(char)) { + this.word = char; + this.state = NUMBER; + return; + } + if (endThings.test(char)) { + this.afterItem(char); + return; + } + throw new Error('havn\'t handled "' +char + '" in neutral yet, index ' + this.place); +}; +Parser.prototype.output = function() { + while (this.place < this.text.length) { + this.readCharicter(); + } + if (this.state === ENDED) { + return this.root; + } + throw new Error('unable to parse string "' +this.text + '". State is ' + this.state); +}; + +function parseString(txt) { + var parser = new Parser(txt); + return parser.output(); +} + +function mapit(obj, key, value) { + if (Array.isArray(key)) { + value.unshift(key); + key = null; + } + var thing = key ? {} : obj; + + var out = value.reduce(function(newObj, item) { + sExpr(item, newObj); + return newObj + }, thing); + if (key) { + obj[key] = out; + } +} + +function sExpr(v, obj) { + if (!Array.isArray(v)) { + obj[v] = true; + return; + } + var 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]); + return; + } + obj[key] = v[0]; + return; + } + if (!v.length) { + obj[key] = true; + return; + } + if (key === 'TOWGS84') { + obj[key] = v; + return; + } + if (!Array.isArray(key)) { + obj[key] = {}; + } + + var i; + switch (key) { + case 'UNIT': + case 'PRIMEM': + case 'VERT_DATUM': + obj[key] = { + name: v[0].toLowerCase(), + convert: v[1] + }; + if (v.length === 3) { + sExpr(v[2], obj[key]); + } + return; + case 'SPHEROID': + case 'ELLIPSOID': + obj[key] = { + name: v[0], + a: v[1], + rf: v[2] + }; + if (v.length === 4) { + sExpr(v[3], obj[key]); + } + return; + case 'PROJECTEDCRS': + case 'PROJCRS': + case 'GEOGCS': + case 'GEOCCS': + case 'PROJCS': + case 'LOCAL_CS': + case 'GEODCRS': + case 'GEODETICCRS': + case 'GEODETICDATUM': + case 'EDATUM': + case 'ENGINEERINGDATUM': + case 'VERT_CS': + case 'VERTCRS': + case 'VERTICALCRS': + case 'COMPD_CS': + case 'COMPOUNDCRS': + case 'ENGINEERINGCRS': + case 'ENGCRS': + case 'FITTED_CS': + case 'LOCAL_DATUM': + case 'DATUM': + v[0] = ['name', v[0]]; + mapit(obj, key, v); + return; + default: + i = -1; + while (++i < v.length) { + if (!Array.isArray(v[i])) { + return sExpr(v, obj[key]); + } + } + return mapit(obj, key, v); + } +} + +var D2R = 0.01745329251994329577; +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) { + if (wkt.type === 'GEOGCS') { + if (wkt.DATUM && wkt.DATUM.SPHEROID) { + wkt.to_meter = wkt.UNIT.convert*wkt.DATUM.SPHEROID.a; + } + } else { + wkt.to_meter = wkt.UNIT.convert; + } + } + } + var geogcs = wkt.GEOGCS; + if (wkt.type === 'GEOGCS') { + geogcs = wkt; + } + if (geogcs) { + //if(wkt.GEOGCS.PRIMEM&&wkt.GEOGCS.PRIMEM.convert){ + // wkt.from_greenwich=wkt.GEOGCS.PRIMEM.convert*D2R; + //} + if (geogcs.DATUM) { + wkt.datumCode = geogcs.DATUM.name.toLowerCase(); + } else { + wkt.datumCode = 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 (geogcs.DATUM && geogcs.DATUM.SPHEROID) { + wkt.ellps = geogcs.DATUM.SPHEROID.name.replace('_19', '').replace(/[Cc]larke\_18/, 'clrk'); + if (wkt.ellps.toLowerCase().slice(0, 13) === 'international') { + wkt.ellps = 'intl'; + } + + wkt.a = geogcs.DATUM.SPHEROID.a; + wkt.rf = parseFloat(geogcs.DATUM.SPHEROID.rf, 10); + } + + if (geogcs.DATUM && geogcs.DATUM.TOWGS84) { + wkt.datum_params = geogcs.DATUM.TOWGS84; + } + if (~wkt.datumCode.indexOf('osgb_1936')) { + wkt.datumCode = 'osgb36'; + } + if (~wkt.datumCode.indexOf('osni_1952')) { + wkt.datumCode = 'osni52'; + } + if (~wkt.datumCode.indexOf('tm65') + || ~wkt.datumCode.indexOf('geodetic_datum_of_1965')) { + wkt.datumCode = 'ire65'; + } + if (wkt.datumCode === 'ch1903+') { + wkt.datumCode = 'ch1903'; + } + if (~wkt.datumCode.indexOf('israel')) { + wkt.datumCode = 'isr93'; + } + } + if (wkt.b && !isFinite(wkt.b)) { + wkt.b = wkt.a; + } + + function toMeter(input) { + var ratio = wkt.to_meter || 1; + return input * 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'], + ['latitude_of_origin', 'Central_Parallel'], + ['scale_factor', 'Scale_Factor'], + ['k0', 'scale_factor'], + ['latitude_of_center', 'Latitude_Of_Center'], + ['latitude_of_center', 'Latitude_of_center'], + ['lat0', 'latitude_of_center', d2r], + ['longitude_of_center', 'Longitude_Of_Center'], + ['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], + ['azimuth', 'Azimuth'], + ['alpha', 'azimuth', d2r], + ['srsCode', 'name'] + ]; + list.forEach(renamer); + if (!wkt.long0 && wkt.longc && (wkt.projName === 'Albers_Conic_Equal_Area' || wkt.projName === 'Lambert_Azimuthal_Equal_Area')) { + wkt.long0 = wkt.longc; + } + if (!wkt.lat_ts && wkt.lat1 && (wkt.projName === 'Stereographic_South_Pole' || wkt.projName === 'Polar Stereographic (variant B)')) { + wkt.lat0 = d2r(wkt.lat1 > 0 ? 90 : -90); + wkt.lat_ts = wkt.lat1; + } +} +var index = function(wkt) { + var lisp = parseString(wkt); + var type = lisp.shift(); + var name = lisp.shift(); + lisp.unshift(['name', name]); + lisp.unshift(['type', type]); + var obj = {}; + sExpr(lisp, obj); + cleanWKT(obj); + return obj; +}; + +module.exports = index; diff --git a/src/main/webapp/resources/engine/y.png b/src/main/webapp/resources/engine/y.png new file mode 100644 index 0000000..2d8f172 Binary files /dev/null and b/src/main/webapp/resources/engine/y.png differ diff --git a/src/main/webapp/resources/favicon.ico b/src/main/webapp/resources/favicon.ico new file mode 100644 index 0000000..b06efb9 Binary files /dev/null and b/src/main/webapp/resources/favicon.ico differ diff --git a/src/main/webapp/resources/images/1d71ebfd_locust_1621222861.jpg b/src/main/webapp/resources/images/1d71ebfd_locust_1621222861.jpg new file mode 100644 index 0000000..e734b54 Binary files /dev/null and b/src/main/webapp/resources/images/1d71ebfd_locust_1621222861.jpg differ diff --git a/src/main/webapp/resources/images/FAO_logo_White_2lines_en.svg b/src/main/webapp/resources/images/FAO_logo_White_2lines_en.svg new file mode 100644 index 0000000..1e8d0b2 --- /dev/null +++ b/src/main/webapp/resources/images/FAO_logo_White_2lines_en.svg @@ -0,0 +1 @@ +FAO_logo_White_2lines_en \ No newline at end of file diff --git a/src/main/webapp/resources/images/FAO_logo_White_2lines_ru.svg b/src/main/webapp/resources/images/FAO_logo_White_2lines_ru.svg new file mode 100644 index 0000000..95f61df --- /dev/null +++ b/src/main/webapp/resources/images/FAO_logo_White_2lines_ru.svg @@ -0,0 +1,180 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/webapp/resources/images/air400.jpg b/src/main/webapp/resources/images/air400.jpg new file mode 100644 index 0000000..7322d4f Binary files /dev/null and b/src/main/webapp/resources/images/air400.jpg differ diff --git a/src/main/webapp/resources/images/byulleten.jpg b/src/main/webapp/resources/images/byulleten.jpg new file mode 100644 index 0000000..6529377 Binary files /dev/null and b/src/main/webapp/resources/images/byulleten.jpg differ diff --git a/src/main/webapp/resources/images/config.svg b/src/main/webapp/resources/images/config.svg new file mode 100644 index 0000000..255c807 --- /dev/null +++ b/src/main/webapp/resources/images/config.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/main/webapp/resources/images/eggs.png b/src/main/webapp/resources/images/eggs.png new file mode 100644 index 0000000..db02064 Binary files /dev/null and b/src/main/webapp/resources/images/eggs.png differ diff --git a/src/main/webapp/resources/images/eggs.svg b/src/main/webapp/resources/images/eggs.svg new file mode 100644 index 0000000..53e3d73 --- /dev/null +++ b/src/main/webapp/resources/images/eggs.svg @@ -0,0 +1,66 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/main/webapp/resources/images/environment400.jpg b/src/main/webapp/resources/images/environment400.jpg new file mode 100644 index 0000000..4ffc0ba Binary files /dev/null and b/src/main/webapp/resources/images/environment400.jpg differ diff --git a/src/main/webapp/resources/images/flex.png b/src/main/webapp/resources/images/flex.png new file mode 100644 index 0000000..902ceb5 Binary files /dev/null and b/src/main/webapp/resources/images/flex.png differ diff --git a/src/main/webapp/resources/images/google_android_download.png b/src/main/webapp/resources/images/google_android_download.png new file mode 100644 index 0000000..241adb8 Binary files /dev/null and b/src/main/webapp/resources/images/google_android_download.png differ diff --git a/src/main/webapp/resources/images/head.jpg b/src/main/webapp/resources/images/head.jpg new file mode 100644 index 0000000..2ece47b Binary files /dev/null and b/src/main/webapp/resources/images/head.jpg differ diff --git a/src/main/webapp/resources/images/imago.png b/src/main/webapp/resources/images/imago.png new file mode 100644 index 0000000..b80004a Binary files /dev/null and b/src/main/webapp/resources/images/imago.png differ diff --git a/src/main/webapp/resources/images/imago.svg b/src/main/webapp/resources/images/imago.svg new file mode 100644 index 0000000..d0ce97c --- /dev/null +++ b/src/main/webapp/resources/images/imago.svg @@ -0,0 +1,67 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/main/webapp/resources/images/ivi400.jpg b/src/main/webapp/resources/images/ivi400.jpg new file mode 100644 index 0000000..c9e9bf3 Binary files /dev/null and b/src/main/webapp/resources/images/ivi400.jpg differ diff --git a/src/main/webapp/resources/images/kuligi.svg b/src/main/webapp/resources/images/kuligi.svg new file mode 100644 index 0000000..7fc68d5 --- /dev/null +++ b/src/main/webapp/resources/images/kuligi.svg @@ -0,0 +1,78 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/main/webapp/resources/images/lichinki.png b/src/main/webapp/resources/images/lichinki.png new file mode 100644 index 0000000..424a2ca Binary files /dev/null and b/src/main/webapp/resources/images/lichinki.png differ diff --git a/src/main/webapp/resources/images/lichinki.svg b/src/main/webapp/resources/images/lichinki.svg new file mode 100644 index 0000000..1e21ff8 --- /dev/null +++ b/src/main/webapp/resources/images/lichinki.svg @@ -0,0 +1,79 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/main/webapp/resources/images/loader3.gif b/src/main/webapp/resources/images/loader3.gif new file mode 100644 index 0000000..9810938 Binary files /dev/null and b/src/main/webapp/resources/images/loader3.gif differ diff --git a/src/main/webapp/resources/images/locust.png b/src/main/webapp/resources/images/locust.png new file mode 100644 index 0000000..856462b Binary files /dev/null and b/src/main/webapp/resources/images/locust.png differ diff --git a/src/main/webapp/resources/images/logo_en.svg b/src/main/webapp/resources/images/logo_en.svg new file mode 100644 index 0000000..244fa3c --- /dev/null +++ b/src/main/webapp/resources/images/logo_en.svg @@ -0,0 +1,261 @@ + + + + + + image/svg+xml + + FAO_logo_White_2lines_en + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FAO_logo_White_2lines_en + + + + + + + + + + + + Caucasus and Central Asia + Locusts Management system + diff --git a/src/main/webapp/resources/images/ndsi400.jpg b/src/main/webapp/resources/images/ndsi400.jpg new file mode 100644 index 0000000..cb40135 Binary files /dev/null and b/src/main/webapp/resources/images/ndsi400.jpg differ diff --git a/src/main/webapp/resources/images/ndvi400.jpg b/src/main/webapp/resources/images/ndvi400.jpg new file mode 100644 index 0000000..fc974b1 Binary files /dev/null and b/src/main/webapp/resources/images/ndvi400.jpg differ diff --git a/src/main/webapp/resources/images/ndwi400.jpg b/src/main/webapp/resources/images/ndwi400.jpg new file mode 100644 index 0000000..62a5ed3 Binary files /dev/null and b/src/main/webapp/resources/images/ndwi400.jpg differ diff --git a/src/main/webapp/resources/images/point.png b/src/main/webapp/resources/images/point.png new file mode 100644 index 0000000..0a190c2 Binary files /dev/null and b/src/main/webapp/resources/images/point.png differ diff --git a/src/main/webapp/resources/images/point.svg b/src/main/webapp/resources/images/point.svg new file mode 100644 index 0000000..ae2d17f --- /dev/null +++ b/src/main/webapp/resources/images/point.svg @@ -0,0 +1,68 @@ + + + +image/svg+xml + + + + + + \ No newline at end of file diff --git a/src/main/webapp/resources/images/precipitation400.jpg b/src/main/webapp/resources/images/precipitation400.jpg new file mode 100644 index 0000000..50a238b Binary files /dev/null and b/src/main/webapp/resources/images/precipitation400.jpg differ diff --git a/src/main/webapp/resources/images/sel400.jpg b/src/main/webapp/resources/images/sel400.jpg new file mode 100644 index 0000000..a4731cb Binary files /dev/null and b/src/main/webapp/resources/images/sel400.jpg differ diff --git a/src/main/webapp/resources/images/shell400.jpg b/src/main/webapp/resources/images/shell400.jpg new file mode 100644 index 0000000..1713e1f Binary files /dev/null and b/src/main/webapp/resources/images/shell400.jpg differ diff --git a/src/main/webapp/resources/images/soil400.jpg b/src/main/webapp/resources/images/soil400.jpg new file mode 100644 index 0000000..2832e66 Binary files /dev/null and b/src/main/webapp/resources/images/soil400.jpg differ diff --git a/src/main/webapp/resources/images/spraying.png b/src/main/webapp/resources/images/spraying.png new file mode 100644 index 0000000..6024d4f Binary files /dev/null and b/src/main/webapp/resources/images/spraying.png differ diff --git a/src/main/webapp/resources/images/spraying.svg b/src/main/webapp/resources/images/spraying.svg new file mode 100644 index 0000000..01b3b4c --- /dev/null +++ b/src/main/webapp/resources/images/spraying.svg @@ -0,0 +1,70 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/src/main/webapp/resources/images/stai.svg b/src/main/webapp/resources/images/stai.svg new file mode 100644 index 0000000..90c3206 --- /dev/null +++ b/src/main/webapp/resources/images/stai.svg @@ -0,0 +1,66 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/src/main/webapp/resources/images/swarms400.jpg b/src/main/webapp/resources/images/swarms400.jpg new file mode 100644 index 0000000..8d459ee Binary files /dev/null and b/src/main/webapp/resources/images/swarms400.jpg differ diff --git a/src/main/webapp/resources/index.js b/src/main/webapp/resources/index.js new file mode 100644 index 0000000..fa95106 --- /dev/null +++ b/src/main/webapp/resources/index.js @@ -0,0 +1,610 @@ +/** + * Igor Ivanov ivanov.i@istt.kz + * [^\x00-\x7F] + */ + +//http://127.0.0.1:8080/CCALM/dataindex +var ScriptName='./records'; +var ScriptDName='./download'; +var ScriptUName='./upload'; +var ScriptRName='./reports'; //For download reports (?file=name) +var ScriptSName='./session'; + + +var g_rowColor1='#ffffff'; //Grey +var g_rowColor2='#f0f0f0'; //DimGray +var g_backColor1= '#ffffff'; //#3a3a3a +var g_backColor2= '#ffffff'; //#000000 +var g_backColor3= '#ffffff'; //#454555 +var g_textColor1= '#000000'; //#ffffff + + +//Style for icons +function createFatypeStyleEvent(feature) +{ + return function(){ + let imgPath=''; + switch(parseInt(feature.userType)) + { + case 0: + imgPath='./resources/images/point.png'; + break; + case 1: + imgPath='./resources/images/imago.png'; + break; + case 2: + imgPath='./resources/images/lichinki.png'; + break; + case 3: + imgPath='./resources/images/eggs.png'; + break; + case 4: + imgPath='./resources/images/spraying.png'; + break; + default: + imgPath='./resources/images/point.png'; + } + + let zoom = g_map.getView().getZoom(); + //var text = zoom > 6 ? feature.get('name') : ''; + let iconStyleG; + + iconStyleG = new ol.style.Style({ + image: new ol.style.Icon(({ + anchor: [0.5, 0.5], + anchorXUnits: 'fraction', + anchorYUnits: 'fraction', + opacity: 0.75, + src: imgPath + }))/*, + text: new ol.style.Text({ + font: '12px helvetica,sans-serif', + //text: text, + fill: new ol.style.Fill({color: '#000'}), + stroke: new ol.style.Stroke({color: '#fff', width: 2}) + })*/ + }); + return iconStyleG; + } +} + +//spraying.png + +//Call data for create markers +function callDataIndex(date_start, date_end) +{ + let data = {}; + $.ajax({ + url: './dataindex?date_start='+date_start+'&date_end='+date_end, + data: JSON.stringify(data), + //contentType: 'application/json; charset=utf-8', + type: "POST", + //dataType: "json", + dataType: "text", + success: function(thiz){return function(data,status){ + if(status=='success') + { + try{ + data=JSON.parse(data); + }catch(e) + { + return; + } + + if(data.errorMessage !== undefined && data.errorMessage!='') + { + alert2("Error",data.errorMessage); + return; + } + + //Приходит JSON уже в объектах + features = []; + for(let i=0;i\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ +
\n\ + '; + + var request=new TRequest(this); + request.userData="FrmLocustData"; + request.userIndicator=indicator; + if(request.callServer(ScriptName,xs)) + { + showProgressBar("FrmLocustData"); + } + + //Show legend + if(typeof g_WinLegend1 == "undefined" || g_WinLegend1==null || g_WinLegend1.closed) + { + g_WinLegend1=new TWin(); + g_WinLegend1.BuildGUI(window.innerWidth-150,40); + } + g_WinLegend1.setCaption(trt('Legend')); + g_WinLegend1.setSize("100px","80px"); + + if(indicator=="1") + { + g_WinLegend1.setContent('
>1'+trt('Danger')+'
<=1'+trt('Attention')+'
=0'+trt('Quietly')+'
'+trt('No_data')+'
'); + } + if(indicator=="2") + { + g_WinLegend1.setContent('
>=5'+trt('Danger')+'
>=3 ... <5'+trt('Caution')+'
<=2'+trt('Calm')+'
'+trt('No_data')+'
'); + } + if(indicator=="3") + { + g_WinLegend1.setLeftTop(window.innerWidth-200,40) + g_WinLegend1.setContent('
>=1'+trt('Danger')+'
<1'+trt('Calm')+'
'+trt('No_data')+'
'); + } + if(indicator=="4") + { + g_WinLegend1.setContent('
>=5'+trt('Danger')+'
>=3 ... <5'+trt('Caution')+'
<=2'+trt('Calm')+'
'+trt('No_data')+'
'); + } + if(indicator=="5") + { + g_WinLegend1.setContent('
>=1'+trt('Danger')+'
<1'+trt('Calm')+'
'+trt('No_data')+'
'); + } + g_WinLegend1.hide(false); + g_WinLegend1.setLeftTop(window.innerWidth-g_WinLegend1.getWidth()-20,40); + setTimeout(function() { g_WinLegend1.setLeftTop(window.innerWidth-g_WinLegend1.getWidth()-20,40); }, 1000); +*/ +} + +function applyReq(req,fn,node) +{ + if(node.errorCode>0) { + let fullText = node.errorMessage; + let smallText = ''; + let pos1=fullText.indexOf('[['); + let pos2=fullText.indexOf(']]'); + if(pos1>=0 && pos2>=0 && pos1=0){ //Если есть идентификатор того что это перезапись + let okFunc=()=>{ + this.setValue('seq',0); + this.sendData(); //Применить ещё раз + }; + if (smallText != '') + confirm2(trt('Warning'),smallText, fullText, okFunc, null); + else + confirm2(trt('Warning'),smallText, '', okFunc, null); + }else { + if (smallText != '') + alert2(trt('Alert'), smallText, fullText); + else + alert2(trt('Alert'), fullText); + } + return; + } + + if (fn==0) + { + if(req.userData=="FrmLocustDataPopupInterface") + { + m_winPP.hideProgressBar(); + updateFrmLocustDataPopupInterface(node,req.userDataID); + } + if(req.userData=="FrmLocustDelDataPopupInterface") + { + m_winPP.hideProgressBar(); + updateFrmLocustDelDataPopupInterface(node,req.userDataID); + } + + }else if (fn==1) + { + //alert('fn==1'); + }else if (fn==11) + { + //alert('fn==11'); + }else if (fn==3) + { + //alert('fn==3'); + }else if (fn==4) + { + //alert(req.userData); + if(req.userData=="FrmLocustDataPopup") + { + m_winPP.hideProgressBar(); + updatePopupLocust(node); + }else if(req.userData=="FrmLocustDelDataPopup") + { + m_winPP.hideProgressBar(); + updatePopupLocustDel(node); + } + }else if (fn==6) + { + alert('fn==6'); + }else if (fn==8) + { + alert('fn==8'); + }else + alert("Unknown function! fn=\""+fn+"\"" ); +} + +//Locust survey +function showPopUpSurvey() { + let win=new TWin(true,'./resources'); + win.BuildGUI(pageX-100,pageY-100); + + win.setSize(400,200); + win.setCaption(trt('Locust_survey')); + //win.showProgressBar(); + win.shadow = true; + let html='
Россия, 2021г. ©Ткачнко Н.А.'; + if(g_lng=="1") + html+='

Мониторинг популяций саранчи в ключевые периоды развития имеет основополагающее значение для понимания уровня заселенности, стадии развития и фазы популяций саранчовых. Это позволяет обеспечить раннее обнаружение изменений в поведении саранчи, внешнем виде, количестве и плотности и, как таковое, имеет решающее значение для прогнозирования роста популяций и вспышек, а также обеспечить раннее предупреждение и раннее реагирование в случае, если обнаружены заселения или признаки грегаризации. Мониторинг саранчи осуществляется путем проведения различных видов обследования, во время которых собирается широкий спектр полевых данных. Такие полевые данные касаются саранчовых и их сред обитания, данные передаются и должны быть проанализированы, с учетом информации о погоде, климате и растительности, а также имеющейся информации о саранчовых ситуациях в предыдущие годы.

'; + else + html+='

Monitoring of locust populations at key periods of their development is fundamental to know importance, development stage and phase of the locust populations. It permits an early detection of changes in locust behaviour, appearance, number and density and as such is crucial to anticipate population increase and outbreak and allows early warning and early reaction if infestations or gregarizing populations are observed. Locust monitoring is ensured by survey operations, during which a wide range of field data are collected. Such field data concern locusts and their habitats; they are transmitted and have to be analysed, taking into account information on weather, climate and vegetation as well as available information on past locust situations.

'; + + + if(g_lng=="1") + html+='
Чтобы просмотреть текущие данные, войдите в CCALM >>>
'; + else + html+='
To view the current data, please go in CCALM >>>
'; + + win.setContent(html); + win.setCenter(); + win.hide(false); +} +//Spray monitoring +function showPopUpSpray() { + let win=new TWin(true,'./resources'); + win.BuildGUI(pageX-100,pageY-100); + + win.setSize(400,200); + win.setCaption(trt('Spray_monitoring')); + //win.showProgressBar(); + win.shadow = true; + + let html='
Uzbekistan, 2021г. ©Aziz'; + if(g_lng=="1") + html+='

Ранние ответные действия, т.е. адекватное и своевременное реагирование на заселения саранчовых необходимы для предотвращения или ограничения ущерба сельскохозяйственным культурам и пастбищам, а также для сведения к минимуму воздействия противосаранчовых обработок на здоровье человека и окружающую среду, а также финансовых затрат на противосаранчовые кампании.

'; + else + html+='

Monitoring of locust populations at key periods of their development is fundamental to know importance, development stage and phase of the locust populations. It permits an early detection of changes in locust behaviour, appearance, number and density and as such is crucial to anticipate population increase and outbreak and allows early warning and early reaction if infestations or gregarizing populations are observed. Locust monitoring is ensured by survey operations, during which a wide range of field data are collected. Such field data concern locusts and their habitats; they are transmitted and have to be analysed, taking into account information on weather, climate and vegetation as well as available information on past locust situations.

'; + + if(g_lng=="1") + html+='
Чтобы просмотреть текущие данные, войдите в CCALM >>>
'; + else + html+='
To view the current data, please go in CCALM >>>
'; + + win.setContent(html); + win.setCenter(); + win.hide(false); +} + +//Safety and environment +function showPopUpSafety() { + let win=new TWin(true,'./resources'); + win.BuildGUI(pageX-100,pageY-100); + + win.setSize(400,200); + win.setCaption(trt('Safety_and_environment')); + //win.showProgressBar(); + win.shadow = true; + let html='
Azerbaijan, 2019г. ©Tələt Mehdiyevalt'; + + if(g_lng=="1") + html+='

Управление по изменению климата, биоразнообразию и окружающей среде (OCB) оказывает странам и заинтересованным сторонам содействие в борьбе с проблемами, связанными с изменением климата, утратой биоразнообразия и деградацией окружающей среды, уделяя при этом пристальное внимание обеспечению устойчивости производства продовольствия и ведения сельского хозяйства.

'; + else + html+='

The Office of Climate Change, Biodiversity and Environment (OCB) works to ensure that countries and stakeholders respond to the challenges of climate change, biodiversity loss, and environmental degradation, keeping food and agriculture sustainability high on the agenda.

'; + + if(g_lng=="1") + html+='
Чтобы просмотреть текущие данные, войдите в CCALM >>>
'; + else + html+='
To view the current data, please go in CCALM >>>
'; + + win.setContent(html); + win.setCenter(); + win.hide(false); +} + +function showPopUpSoil() { + let win=new TWin(true,'./resources'); + win.BuildGUI(pageX-100,pageY-100); + + win.setSize(400,200); + win.setCaption(trt('Soil_temperature_at_a_depth_of_10_cm')); + //win.showProgressBar(); + win.shadow = true; + let html='
'; + + if(g_lng=="1"){ + html+='

Источник данных для температуры почвы: www.noaa.gov (Национальное управление океанических и атмосферных исследований США) Расстояние между точками около 20 километров. Исходные данные для построения температуры почвы представлены в виде набора точек, данные выкладываются каждый день

'; + }else{ + html+='

Data source for soil temperature: www.noaa.gov (US National Oceanic and Atmospheric Administration) Distance between points about 20 kilometers. The initial data for plotting the soil temperature is presented as a set of points, the data is laid out every day.

'; + } + + if(g_lng=="1") + html+='
Чтобы просмотреть текущие данные, войдите в CCALM >>>
'; + else + html+='
To view the current data, please go in CCALM >>>
'; + + win.setContent(html); + win.setCenter(); + win.hide(false); +} + +function showPopUpAir() { + let win=new TWin(true,'./resources'); + win.BuildGUI(pageX-100,pageY-100); + + win.setSize(400,200); + win.setCaption(trt('Air_temperature_2m_above_the_ground')); + //win.showProgressBar(); + win.shadow = true; + let html='
'; + + if(g_lng=="1"){ + html+='

Источник данных для температуры воздуха: www.noaa.gov (Национальное управление океанических и атмосферных исследований США) Расстояние между точками около 20 километров. Исходные данные для построения температуры воздуха представлены в виде набора точек, данные выкладываются каждый день.

'; + }else{ + html+='

Air temperature data source: www.noaa.gov (US National Oceanic and Atmospheric Administration) Distance between points is about 20 kilometers. The initial data for plotting the air temperature is presented as a set of points, the data is laid out every day.

'; + } + + if(g_lng=="1") + html+='
Чтобы просмотреть текущие данные, войдите в CCALM >>>
'; + else + html+='
To view the current data, please go in CCALM >>>
'; + + win.setContent(html); + win.setCenter(); + win.hide(false); +} + +function showPopUpPre() { + let win=new TWin(true,'./resources'); + win.BuildGUI(pageX-100,pageY-100); + + win.setSize(400,200); + win.setCaption(trt('Accumulated_precipitation_in_24_hours')); + //win.showProgressBar(); + win.shadow = true; + let html='
'; + + if(g_lng=="1"){ + html+='

Источник данных для построения карты осадков: www.noaa.gov (Национальное управление океанических и атмосферных исследований США) Расстояние между точками около 20 километров. Исходные данные для построения карты осадков представлены в виде набора точек, данные выкладываются каждый день

'; + }else{ + html+='

Data source for building a precipitation map: www.noaa.gov (US National Oceanic and Atmospheric Administration) Distance between points is about 20 kilometers. The initial data for constructing a precipitation map is presented as a set of points, the data is laid out every day

'; + } + + if(g_lng=="1") + html+='
Чтобы просмотреть текущие данные, войдите в CCALM >>>
'; + else + html+='
To view the current data, please go in CCALM >>>
'; + + win.setContent(html); + win.setCenter(); + win.hide(false); +} +function showPopUpSel() { + let win=new TWin(true,'./resources'); + win.BuildGUI(pageX-100,pageY-100); + + win.setSize(400,200); + win.setCaption(trt('Accumulated_precipitation_in_24_hours')); + //win.showProgressBar(); + win.shadow = true; + let html='
'; + + if(g_lng=="1"){ + html+='

Расчёт гидротермического коэффициента Селянинова производиться по формуле: ГТК =r/(∑t/10) (где: r — сумма осадков в миллиметрах за период с температурами выше +10°, Σt – сумма температур в градусах за то же период) с возможностью задания страны КЦА и выбора дат для расчёта. Данные расчёта основывается на продуктах: “Температура воздуха на высоте 2м над землей” и “Суммарные осадки за 24 часа, миллилитр/м2” которые скачиваются один раз в 24 часа.

'; + }else{ + html+='

For calculating the Selyaninov hydrothermal coefficient using the formula: HTC = r/(∑t/10) (where: r is the sum of precipitation in millimeters for a period with temperatures above +10°, Σt is the sum of temperatures in degrees for the same period) the ability to specify the CCA country and select dates for the calculation. The calculation data is based on the product “Air temperature 2m above the ground” and the product: “Accumulated precipitation in 24 hours, milliliter/m2” which are downloaded once every 24 hours.

'; + } + + if(g_lng=="1") + html+='
Чтобы просмотреть текущие данные, войдите в CCALM >>>
'; + else + html+='
To view the current data, please go in CCALM >>>
'; + + win.setContent(html); + win.setCenter(); + win.hide(false); +} +function showPopUpNDVI() { + let win=new TWin(true,'./resources'); + win.BuildGUI(pageX-100,pageY-100); + + win.setSize(400,200); + win.setCaption(trt('Normalized_difference_vegetation_index')); + //win.showProgressBar(); + win.shadow = true; + + let html='
'; + if(g_lng=="1"){ + html+='

Для визуализации NDVI (нормализованный относительный индекс растительности) используются данные спутника MODIS (продукт: «MOD13Q1»). Данные выкладываются каждые 16 дней, с отставание актуальности данных в те же 16 дней. Размер пикселя около 250 метров.

'; + }else{ + html+='

The MODIS satellite data (product: "MOD13Q1") is used to visualize the NDVI (Normalized difference vegetation index). The data is posted every 16 days, with a lag of data relevance in the same 16 days. Pixel size is about 250 meters.

'; + } + + if(g_lng=="1") + html+='
Чтобы просмотреть текущие данные, войдите в CCALM >>>
'; + else + html+='
To view the current data, please go in CCALM >>>
'; + + win.setContent(html); + win.setCenter(); + win.hide(false); +} +function showPopUpIVI() { + let win=new TWin(true,'./resources'); + win.BuildGUI(pageX-100,pageY-100); + + win.setSize(400,200); + win.setCaption(trt('Integral_vegetation_index')); + //win.showProgressBar(); + win.shadow = true; + + let html='
'; + if(g_lng=="1"){ + html+='

Для расчёта IVI c марта по июнь (4 месяца) используется продукт NDVI который скачивается раз в 16 дней в следующие дни года: 65, 81, 97, 113, 129, 145, 161, 177 всего 8 скачиваний. Соответственно для расчёта используется формула: IVI=∑NDVI Так как значение NDVI колеблется от 0.0 до 10 000 в течении года то максимальное число после суммирования для одного пикселя для IVI может составлять 80 000.

'; + }else{ + html+='

To calculate IVI from March to June (4 months), the NDVI product is used, which is downloaded once every 16 days on the following days of the year: 65, 81, 97, 113, 129, 145, 161, 177 in total 8 downloads. Accordingly, the formula is used to calculate: IVI=∑NDVI Since the value of NDVI fluctuates from 0.0 to 10,000 during the year, the maximum number after summation for one pixel for IVI can be 80,000.

'; + } + + if(g_lng=="1") + html+='
Чтобы просмотреть текущие данные, войдите в CCALM >>>
'; + else + html+='
To view the current data, please go in CCALM >>>
'; + + win.setContent(html); + win.setCenter(); + win.hide(false); +} +function showPopUpNDWI() { + let win=new TWin(true,'./resources'); + win.BuildGUI(pageX-100,pageY-100); + + win.setSize(400,200); + win.setCaption(trt('Normalized_difference_water_index')); + //win.showProgressBar(); + win.shadow = true; + + let html='
'; + if(g_lng=="1"){ + html+='

Для расчёта NDWI используются данные со спутника MODIS (продукт: «MCD43A4»). Данные для расчета NDWI выкладываются каждый день с запаздыванием актуальности данных на 8 дней. Размер пикселя около 500 метров.

'; + html+='

Для расчета используется следующее выражение:

NDWI = (Xvis - Xnir) / (Xvis + Xnir)

'; + html+='

'+trt('Where')+':

  • NIR: BAND5 (1.23 to 1.25 µm)
  • VIS: BAND4 (0.545 - 0.565 µm)

'; + }else{ + html+='

Data from MODIS satellite (product: "MCD43A4") are used to calculate NDWI. The data for calculating the NDWI is laid out every day with a delay of the relevance of the data by 8 days. Pixel size is about 500 meters.

'; + html+='

For the calculation, the following expression is used:

NDWI = (Xvis - Xnir) / (Xvis + Xnir)

'; + html+='

'+trt('Where')+':

  • NIR: BAND5 (1.23 to 1.25 µm)
  • VIS: BAND4 (0.545 - 0.565 µm)

'; + } + + if(g_lng=="1") + html+='
Чтобы просмотреть текущие данные, войдите в CCALM >>>
'; + else + html+='
To view the current data, please go in CCALM >>>
'; + + win.setContent(html); + win.setCenter(); + win.hide(false); +} + +function showPopUpNDSI() { + let win=new TWin(true,'./resources'); + win.BuildGUI(pageX-100,pageY-100); + + win.setSize(400,200); + win.setCaption(trt('Normalised_difference_snow_index')); + //win.showProgressBar(); + win.shadow = true; + + let html='
'; + if(g_lng=="1"){ + html+='

Для расчёта NDSI используются данные со спутника MODIS (продукт: «MCD43A4»). Данные для расчета NDSI выкладываются каждый день с запаздыванием актуальности данных на 8 дней. Размер пикселя около 500 метров.

'; + html+='

Для расчета используется следующее выражение:

NDSI = (Rvis - Rswir) / (Rvis + Rswir)

'; + html+='

'+trt('Where')+':

  • SWIR: BAND6 (1.628 - 1.652 µm)
  • VIS: BAND4 (0.545 - 0.565 µm)

'; + }else{ + html+='

Data from MODIS satellite (product: "MCD43A4") are used to calculate NDSI. Data for calculating NDSI is laid out every day with a delay of data relevance by 8 days. Pixel size is about 500 meters.

'; + html+='

For the calculation, the following expression is used:

NDSI = (Rvis - Rswir) / (Rvis + Rswir)

'; + html+='

'+trt('Where')+':

  • SWIR: BAND6 (1.628 - 1.652 µm)
  • VIS: BAND4 (0.545 - 0.565 µm)

'; + } + + if(g_lng=="1") + html+='
Чтобы просмотреть текущие данные, войдите в CCALM >>>
'; + else + html+='
To view the current data, please go in CCALM >>>
'; + + win.setContent(html); + win.setCenter(); + win.hide(false); +} diff --git a/src/main/webapp/resources/test.html b/src/main/webapp/resources/test.html new file mode 100644 index 0000000..e364f38 --- /dev/null +++ b/src/main/webapp/resources/test.html @@ -0,0 +1,127 @@ + + + + + + + + + + + + +Результат:
+ + + + \ No newline at end of file diff --git a/src/test/resources/log4j.xml b/src/test/resources/log4j.xml new file mode 100644 index 0000000..628a071 --- /dev/null +++ b/src/test/resources/log4j.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/target/classes/messages_az.properties_not_used b/target/classes/messages_az.properties_not_used new file mode 100644 index 0000000..cd672c3 --- /dev/null +++ b/target/classes/messages_az.properties_not_used @@ -0,0 +1,535 @@ +language = en +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Language = Language +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) + +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/target/classes/messages_en.properties_not_used b/target/classes/messages_en.properties_not_used new file mode 100644 index 0000000..4715ab4 --- /dev/null +++ b/target/classes/messages_en.properties_not_used @@ -0,0 +1,534 @@ +language = en +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/target/classes/messages_hy.properties_not_used b/target/classes/messages_hy.properties_not_used new file mode 100644 index 0000000..f703777 --- /dev/null +++ b/target/classes/messages_hy.properties_not_used @@ -0,0 +1,535 @@ +language = en +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) + +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/target/classes/messages_ka.properties_not_used b/target/classes/messages_ka.properties_not_used new file mode 100644 index 0000000..f703777 --- /dev/null +++ b/target/classes/messages_ka.properties_not_used @@ -0,0 +1,535 @@ +language = en +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) + +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/target/classes/messages_kg.properties_not_used b/target/classes/messages_kg.properties_not_used new file mode 100644 index 0000000..f703777 --- /dev/null +++ b/target/classes/messages_kg.properties_not_used @@ -0,0 +1,535 @@ +language = en +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) + +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/target/classes/messages_ps.properties_not_used b/target/classes/messages_ps.properties_not_used new file mode 100644 index 0000000..d4774ac --- /dev/null +++ b/target/classes/messages_ps.properties_not_used @@ -0,0 +1,534 @@ +language = ps +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/target/classes/messages_ru.properties_not_used b/target/classes/messages_ru.properties_not_used new file mode 100644 index 0000000..655a64a --- /dev/null +++ b/target/classes/messages_ru.properties_not_used @@ -0,0 +1,540 @@ +language = ru +Language = Язык +label_registration = Регистрация +label_login = Войти на сайт +From_DPA = С планшета +Days = Дней +Hours = Часов +Company_User = Компания -> Пользователь +Object_Geofence = Объект –> Геозона +Sensor_for_ComboBox = Датчик для выпадающего списка +The_boundary_values_of_the_sensors = Граничные значения датчиков. +CountriesRegions = Границы регионов +Types_of_locust = Виды саранчи +Help = Помощь +Unknown_function = Неизвестная функция! +Not_yet_implemented = Пока не реализовано! +Layout = Слой +Company = Компания +Path = Путь +Description = Описание +Layouts = Слои +Type_of_locust = Вид саранчи +Kind_of_locust = Вид саранчи +Sorting_index = Индекс сортировки +Name = Имя +Types_of_locust = Вид саранчи +Markings = Маркировка +Formulation = Препаративная форма +Vegetation = Растительность +Fledgling = Окрыление +Age = Возраст +Biotop = Биотоп +Capacity = Ёмкость +Capacities = Ёмкости +Borns = Отрождение +Сontainers = Контейнеры +Breeding = Поведение +Containers = Контейнеры +Types_of_operators = Типы операторов +Types_of_operator = Тип оператора +Density_of_vegetation = Густота растительного покрова +Height = Высота +Damage = Повреждения +Density = Плотность +Directions = Направления +Angle = Угол +Methods_of_calculating_mortality = Методы подсчёта смертности +Method_of_calculating_mortality = Метод подсчёта смертности +Phase = Фаза +Condition_of_vegetation = Состояние растительности +Actions_of_bands = Действия кулиги +Behaviors = Поведение +Paintings = Окраска +Painting = Окрас +Enemies = Наличие естественных врагов +Report_by_tablets = Отчёт по планшетам +Country = Страна +From_date = С даты +To_date = По дату +The_tabblet = Планшет +Forms_for_locust_survey = Формы обследования саранчи +Forms_for_spray_monitoring = Формы мониторинга противосаранчовых обработок +Completed_forms_by_tablets = Заполнение форм по планшетам +Filling_forms_by_countries = Заполнение форм по странам +Method_filling_form = Способ заполнения формы +The_tablet_registered = Планшет зарегистрирован +IDENTIFICATION_OF_THE_PLACE = ИДЕНТИФИКАЦИЯ МЕСТА +Region = Область +Regions = Области +Rayon = Район +Rual_district = Сельский округ +Name_of_the_village = Поселок +Farm_or_site = Хозяйство или местность +Name_of_survey_team_leader = Имя лидера команды обследования +Date = Дата +Latitude_of_point = Широта точки +Longitude_of_point = Долгота точки +Surveyed_area_ha = Обследованная площадь(га) +ECOLOGICAL_INFORMATION = ЭКОЛОГИЧЕСКАЯ ИНФОРМАЦИЯ +Type_of_biotope = Тип биотопа +Vegetation_cover = Густота растительного покрова +Air_temperature = Погода: температура воздуха(ºC) +Wind_m_s = Погода: ветер(м/с) +bio_wind = Погода: ветер(м/с) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = ИНФОРМАЦИЯ О САРАНЧОВЫХ (В Т.Ч. КУБЫШКИ) +Present = Присутствуют саранчовые +Locust_species = Вид саранчи +Area_infested_ha = Заселённая площадь(га) +EGGS = ЯЙЦА +Egg_bed_surface_in_ha = Залежь кубышек (площадь га) +Egg_pods_density_m2 = Плотность кубышек (/м²) +Egg_pods_density = Плотность кубышек +Egg_pod = Кубышки +to = до +Eggs_average_number_egg_pod = Яйца (в среднем в кубышке) +Eggs_viable = Яйца(% жизнеспособных) +Natural_enemies_present = Естественны враги +HOPPERS_SCATTERED = ЛИЧИНКИ (РАЗРЕЖЕННЫЕ) +Hatching = Отрождение +Hopper_stages = Возраст личинок +Appearance = Фаза +Behaviour = Поведение +Hopper_density_m2 = Плотность личинок (/м²) +Hopper_density = Плотность личинок +Hopper_density_m2_to = Плотность личинок (/м²) до +HOPPER_BANDS = КУЛИГИ +Minimum_density_in_the_band_in_m2 = Плотность минимальная в кулиге (/м²) +Maximum_density_in_the_band_in_m2 = Плотность максимальная в кулиге (/м²) +Band_sizes_m2 = Размер кулиг (м²) +Number_of_bands = Количество кулиг +Behavior = Поведение +ADULTS = ИМАГО +Fledging = Окрыление +Maturity = Половозрелость +Adult_density_ha = Плотность имаго /га +Adult_density_m2 = Имаго (плотность/м²) +Adult_density = Плотность имаго +Feeding_and_roosting = Питание и размещение на растениях +Copulating = Спаривание +Laying = Яйцекладка +Flying = Полёты +SWARMS = СТАИ +Density_of_swarm = Плотность в стае +Swarm_size_ha = Размер стаи (га) +Number_of_swarms = Число стай +Flying_direction = Направление полёта +Flying_height = Высота полёта +COMMENTS = КОММЕНТАРИИ +Locust_Survey_Form = Форма обследования саранчи +Locust_Survey_Forms = Формы обследования саранчи +From_the_tablet = С планшета +From_WEB_interface = С WEB интерфейса +User = Пользователь +Weather_air_temperature_C = Погода: температура воздуха(ºC) +Weather = Погода +larva_behavior = Поведение +Spray_Monitoring_Form = Форма противосаранчовых обработок +Rural_district = Сельский округ +Name_of_control_team_leader = Имя лидера команды по обработке +Latitude_center_portion = Широта (центр участка) +Longitude_center_portion = Долгота (центр участка) +Area_treated_ha = Обработанная площадь(га) +VEGETATION_DATA = РАСТИТЕЛЬНОСТЬ +Kind = Вид +Type = Тип +type = тип +types = типы +Height_cm = Высота (см) +Crop_name = Наименование сельхозкультуры +Damage_area_ha = Площадь повреждения (га) +INSECTICIDE_DATA = ИНФОРМАЦИЯ ОБ ИНСЕКТИЦИДАХ +Trade_name = Коммерческое название +The_active_substance = Действующее вещество +Concentration_A_S = Концентрация (%) +Dose_rate_l_of_commercial_product_ha = Норма расхода (л коммерческого продукта/гa) +Rate_of_working_solution_l_ha = Расход рабочей жидкости (л/га) +Total_volume_of_working_solution_actually_applied_l = Общий объем использованной рабочей жидкости (л) +Number_of_spores_ml = Концентрация спор(/мл) +WEATHER_CONDITIONS = ПОГОДНЫЕ УСЛОВИЯ +Time_start = Время начала обработки +Time_end = Время окончания обработки +Temperature_start = Температура нач.(°C) +Temperature_end = Температура кон.(°C) +Relative_humidity_start = Отн. влажность воздуха нач.(%) +Relative_humidity_end = Отн. влажность воздуха кон.(%) +Wind_speed_start_m_s = Скорость ветра нач. (м/с) +Wind_speed_end_m_s = Скорость ветра кон. (м/с) +Wind_direction_start = Направление ветра нач. +Wind_direction_end = Направление ветра кон. +Spray_direction_start = Направление опрыскивания нач. +Spray_direction_end = Направление опрыскивания кон. +LOCUST_INFORMATION = ИНФОРМАЦИЯ О САРАНЧОВЫХ (В Т.Ч. КУБЫШКИ) +Imago = Имаго +Density_m2 = Плотность на м² +Bands = Кулиги +Swarms = Стаи +Scattered = Разреженные +SPRAY_APPLICATION = СВЕДЕНИЯ ПО ОПРЫСКИВАНИЮ +Spray_platform = Способ опрыскивания +Aerial = Авиа +Ground = Наземное +Person = Ручное +Spray_type = Вид опрыскивания +Spray_manufacturer = Марка опрыскивателя +Model_sprayer = Модель опрыскивателя +Atomizer_height_above_ground_m = Высота распылителя над поверхностью почвы (м) +Barriers = Барьеры +Barrier_width_m = Ширина барьера (м) +Spacing_of_barriers_m = Промежуток барьера (м) +spray_height = Высота над поверхностью почвы (м) +Forward_speed_km_h = Средняя скорость движения (км/ч) +Antenna_DGPS_used = Антенна: DGPS использовалась +Ground_marking = Наземная маркировка +CONTROL_EFFICACY = КОНТРОЛЬ ЭФФЕКТИВНОСТИ +Biological_efficiency_of_treatment = Биологическая эффективность обработки (%) +Time_after_treatment_hours = Прошло времени после обработки (часов) +Method_of_biological_efficiency_estimation = Метод подсчета биологической эффективности +SAFETY_AND_ENVIRONMENT = БЕЗОПАСНОСТЬ И ОКРУЖАЮЩАЯ СРЕДА +Protective_clothing = Индивидуальные средства защиты +Goggles = Очки +Masks = Маска +Gloves = Перчатки +Overalls = Комбинезон +Caps = Шапка +Boots = Сапоги +Absent = Отсутствуют +Protective_clothing_clean_and_in_good_state = Защитная одежда чистая и в хорошем состоянии? +Operator_accidentally_exposed_to_insecticide_or_feeling_unwell = Оператор случайно подвергся воздействию инсектицида или плохое самочувствие +Inform_abaut_spraying = Оповещенные об обработках +Farmer = Фермер +Shepherd = Пастух +Official = Должностное лицо +Beekeeper = Пчеловод +Villager = Сельский житель +Other = Другие +Empty_containers = Пустые контейнеры +Effect_on_non_terget_organism = Воздействие на нецелевые организмы +If_yes_describe_what_happened_description = Если да, опишите, что произошло +if_Yes_type_of_organisms_and_effects_description = Если Да, тип организмов и эффекты (описание) +If_Yes_type_of_incident_and_reported_by_whom_description = Если Да, тип инцидента и кем сообщен (описание) +Other_environmental_or_health_incident_reported_that_might_have_been_caused_by_the_treatment = Другие инциденты по здоровью или окружающей среде, возникшие при обработке +Comments = Коментарии +Spray_Monitoring_Forms = Формы противосаранчовых обработок +Information_on_the_distribution_of_locust = Информация о распространении и борьбе со стадными саранчовыми +Year = Год +year = год +Inspect_thous_ha = Обследовано (тыс. га) +Infested_thous_ha = Заселено (тыс. га) +Infested_over_ETD_thous_ha = Заселено выше ЭПВ (тыс. га) +Treated_thous_ha = Обработано (тыс. га) +The_tablet = Планшеты +Organization = Организация +Phone_number = Номер телефона +Responsible_person = Ответственное лицо за планшет (инспектор) +Serial_number = Серийный номер +The_tablet_model = Модель планшета +The_tablets = Планшеты +Phone = Телефон +Responsible_person = Ответственное лицо +Change_password = Сменить пароль +Login = Логин +Password = Пароль +New_password = Новый пароль +Repeat_password = Повторить пароль +User_settings = Пользовательские настройки +Named = Наименование +Value = Значение +Values = Значения +Object = Объект +sensor = сенсор +Groups_of_objects = Группы объектов +Object_of_observation = Объект наблюдения +Access = Доступ +Identifier = Идентификатор +Allow = Разрешить +Sensor = Сенсор +objects = объекты +Sensor_values = Показание датчика +Terminal = Терминал +Units_of_measurement = Единицы измерения +Fix_date = Дата фиксации +Messages = Сообщения +Read = Прочтённые +Readed = Прочтённые +Content = Содержание +Date_read = Дата чтения +Date_create = Дата создания +Day_mileage_and_speed = Дневной пробег и скорость +Kilometers_distance = Дистанция км. +Kilometers_distance_without_signal = Дистанция км. без сигнала +Company_site = Сайт компании +Contact_phone = Контактный телефон +Organizations = Организации +Site = Сайт +Users = Пользователи +Terminal_model = Модель терминала +Models_of_terminals = Модели терминалов +Sensor_type = Тип датчика +Sensor_of_devices = Датчик оборудования +Measurement = Измерение +Sensor_model = Модель датчика +Rounded_to = Округлять до +Sensors_models = Модели датчиков +Count_objects = Количество объектов +Group = Группа +Terminals = Терминалы +Stationary = Стационарный +Latitude = Широта +Longitude = Долгота +Icon = Иконка +Objects_of_observation = Объекты наблюдения +Count_of_sensors = Количество датчиков +Icons = Иконки +name = имя +File = Файл +Size = Размер +byte = байт +Geofence = Геозона +Geofences = Геозоны +Coordinate = Координаты +Coordinates_Geofence = Координаты геозоны +Position = Должность +True_position = Правильное положение +outside = снаружи +inside = внутри +Boundary = Граничное +Inform = Информировать +Inside = Внутри +Sensor_of_object = Датчик объекта +Sensors_of_objects = Датчики объектов +Last_value = Последнее значение +Date_of_the_last_value = Дата посл. знач. +Readings = Показание +Devices = Устройства +Sensor_readings = Показание датчика +GPS_readings = GPS показание +Fixation_date = Дата фиксации +Speed = Скорость +Message = Сообщение +Subject = Тема +Creation_date = Дата создания +Contents = Содержимое +User_messages = Сообщения пользователя +Reading_date = Дата прочтения +Users_messages = Сообщения пользователей +Minimum_value = Минимальное значение +Maximum_value = Максимальное значение +Only_on_the_boundary = Только на границе +Action = Действие +Rule = Правило +Actions = Действия +Access_role = Роль доступа +Parental_role = Родительская роль +Role_name = Наименование роли +Role_description = Описание роли +Role = Роль +Surname = Фамилия +Patronymic = Отчество +Phones = Телефоны +Password_expiration = Срок действия пароля +Renewal_password = Продление пароля +days = дней +day = день +S_N_P = Ф.И.О. +Last_enter = Посл. заход +Roles = Роли +User_roles = Пользовательские роли +Synchronization_objects = Объекты синхронизации +Synchronization_service = Сервис синхронизации +Synchronization_order = Порядок синхронизации +The_interval_between_the_update_in_s = Интервал между обн. в (сек) +At_a_time = Записей за раз +Time_of_the_last_synchronization = Времени с последней синхронизации +Service = Сервис +Order = Порядок +Interval = Интервал +Limit = Лимит +Synchronization_services = Сервисы синхронизации +Host = Хост +History = История +Table = Таблица +Field = Поле +Data = Данные +Short_name = Короткое имя +Translation = Перевод +Sprayer_type = Вид опрыскивателя +Sprayers = Опрыскиватели +Sprayer = Опрыскиватель +SprayersTypes = Вид опрыскивателя +Sprayer_type_name = Наименование опрыскивателя +Countries = Страны +Regions = Районы +Automated_system_of_data_collection = Автоматизированная система сбора данных +Download_android_app_Inspector = Скачать андроид приложение инспектора +Run_the_application_of_the_situational_center = Запустить приложение ситуационного центра +For_any_questions_contact_us_at_tel_Fax = По всем интересующим вопросам обращаться по тел./факс +You_are_not_logged_in = Вы не авторизованы! +Not_found_the_requested_node: = Не найден запрошенный узел: +The_number_of_records_is_not_equal_to_one = Количество записей не равно одному! +Filter_options = Параметры фильтра +Time_and_date_of_generation = Время и дата генерации +Creator = Создатель +E_mail_already_exists_in_the_database = Адрес электронной почты уже существует в базе данных! +Registration_form = Форма регистрации +You_have_successfully_registered = Вы успешно зарегистрировались! +Password_sent_to_your_e_mail = Пароль отправлен на ваш е-mail. +Operator_registration_form = Форма регистрации оператора +Security_Code = Защитный код +Update = Обновить +image = рисунок +Registering = Регистрация +Failed_to_send_your_password_to_the_e_mail = Не удалось отправить пароль на электронную почту. +Failed_to_update_the_password = Не удалось обновить пароль. +configuration_section_s = Раздел конфигурации; %s +configuration_option_s = опция конфигурации; %s +Locust_survey = Обследования саранчи +Spray_monitoring = Противосаранчовые обработки +Reports = Отчёты +Report = Отчёт +Map_layers = Слои карты +Administration = Администрирование +Standard_survey_forms = Стандартные формы обследования +Companies = Компании +Report_by_countries = Отчёт по странам +Lists = Справочники +Members = Пользователи +Photo = Фотография +Indicator = Показатель +PDA_registered = Планшеты зарегистрированы +From_PDA = С планшета +From_WEB_interface = С WEB интерфейса +Open_in_a_table_format = Открыть в табличном виде +Request_data = Запросить данные +Not = Нет +Yes = Да +Attention = Внимание +Quietly = Спокойно +Number_forms = Количество форм +Open_data_on_the_map = Открыть данные на карте +No_data = Данные отсутствуют +From_date = С даты +To_date = По дату +or = или +Dangerous = Опасно +Distribution_of_locust = Распространение и борьба со стадными саранчовыми +Hide = Скрыть +For_what_year = За какой год +Displayed_data = Отображаемые данные +Automated_system_of_data_collection_ASDC = Автоматизированная система сбора данных (ASDC) +Invalid_username_and_or_password = Неверный логин и/или пароль! +CIT_Italian_locust = CIT - итальянский прус +DMA_Moroccan_locust = DMA - мароккская саранча +LMI_Asian_migratory_locust = LMI - азиатская перелетная саранча +Substrate = Подложка +Change_login_password = Изменить логин/пароль +Displaying_data = Отображение данных +Show_data = Отобразить данные +All_types = Все виды +All_kinds = Все виды +Maps_of_areas_infested_above_Economic_Threshold_ET = Карты площадей, заселенных с плотностями выше экономического порога вредоносности (ЭПВ) +Maps_of_treated_areas_above_ET = Карты обработанных площадей выше ЭПВ +Map_of_the_level_of_threat = Карта уровня угрозы +Download_QGIS_project = Скачать QGIS проект +Danger = Опасно +Caution = Внимание +Calm = Спокойно +Increase = Подъём +Decrease = Спад +On_the_same_level = На том же уровне +Normal_Multiyear_average_level = Нормальный/Среднемноголетний уровень +Device_id = Идентификатор устройства +All_countries_of_CCA = Страны КЦА +The_Caucasus_countries_and_Russia = Страны Кавказа и Россия +Countries_of_Central_Asia_and_Russia = Станы Центральной Азии и Россия +from = от +The_forecast_of_hatching_periods = Прогноз инкубационного периода +Weather_forecast = Прогноз погоды +soil_temperature = температура почвы +Soil_temperature = Температура почвы +Passwords_did_not_match = Пароли не совпадают! +The_s_is_not_Email = Логин «%s» не электронная почта! +Password_changed_successfully = Пароль успешно изменен. +Failed_to_change_password = Не удалось изменить пароль. +Check_the_entered_data = Проверьте введенные данные. +for_ = для +Earth_temperature = Температура земли +Point = Точка +Forecast_of_hours = Часы прогноза +hours = часов +Change_login_password = Сменить логин/пароль +Type = Тип +Legend = Легенда +Spraying = Опрыскивание +Chart = График +Average = Среднее +Percent = Процент +For_s_year = За %s год +and = и +Time_and_date_of_generation = Дата создания +Filter_options = Параметры фильтра +Export_to_Excel = Экспорт в Excel +Preparing_of_report = Подготовка отчёта +Download_report = Скачать отчёт +Old_password = Старый пароль +Not_filled_Email_address = Не заполнен email +Wrong_XML_document = Неверный XML-документ +Please_enter_a_valid_email_address = Пожалуйста, введите правильный адрес электронной почты +For_new_users = Для новых пользователей +For_returning_users = Для вернувшихся пользователей +Phone = Телефон +Log_in = Авторизоваться +Registration = Регистрация +Authorization = Авторизация +Password_recovery = Восстановление пароля +The_s_field_is_empty = Не заполнено поле "%s" +New_user_is_registered = Новый пользователь зарегистрирован. +The_password_has_been_sent_to_you_by_Email = Пароль отправлен вам на Email. +Others = Другие +District = Район +Districts = Районы +All = Всё +Region = Область +Edit = Редактировать +thous_ha = тыс. га +Thous_ha = Тыс. га +Average = Среднее +Year = Год +Deviation = Отклонение +Dev_of_average = Откл. от среднего +Cancel = Отмена +Responsible_person_for_data_verification = Ответственное лицо по верификации данных +Upload = Загрузить +Delete = Удалить +Download = Скачать +Repeat_the_addition_of_the_entry = Повторить добавление записи +Apply = Применить +Calcel = Закрыть +Hoppers = Личинки (разреженные) +Kuliguli = Кулиги +Adult = Имаго +Restore = Восстановить +Add_more = Добавить ещё +Successfully_added_data = Данные успешно добавлены +Are_you_sure_you_want_to_delete_the_entries = Вы действительно хотите удалить записи? +Increase_by_1 = Увеличить на 1 +Decrease_by_1 = Уменьшить на 1 +No_results_were_found_for_your_search = По вашему запросу ничего не найдено! +Selection = Выбор +Add_record = Добавить запись +Delete_record = Удалить записи +Filtering = Фильтровать +Invert_selection = Инвертировать выделение +No_locust = Нет саранчи + +Triple_rinsed=Трижды промытые +Punctured=Проколотые +Taken_back_to_base=Возвращенные на базу +Left_in_field=Оставленные в поле +Buried=Закопанные +Burned=Сожженные \ No newline at end of file diff --git a/target/classes/messages_tg.properties_not_used b/target/classes/messages_tg.properties_not_used new file mode 100644 index 0000000..f703777 --- /dev/null +++ b/target/classes/messages_tg.properties_not_used @@ -0,0 +1,535 @@ +language = en +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) + +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/target/classes/messages_tk.properties_not_used b/target/classes/messages_tk.properties_not_used new file mode 100644 index 0000000..f703777 --- /dev/null +++ b/target/classes/messages_tk.properties_not_used @@ -0,0 +1,535 @@ +language = en +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) + +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/target/classes/messages_uz.properties_not_used b/target/classes/messages_uz.properties_not_used new file mode 100644 index 0000000..f703777 --- /dev/null +++ b/target/classes/messages_uz.properties_not_used @@ -0,0 +1,535 @@ +language = en +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) + +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/target/classes/not_used b/target/classes/not_used new file mode 100644 index 0000000..4715ab4 --- /dev/null +++ b/target/classes/not_used @@ -0,0 +1,534 @@ +language = en +Language = Language +label_registration = Registration +label_login = Log In +Types_of_locust = Kinds of locust +Unknown_function = Unknown function! +Not_yet_implemented = Not yet implemented! +Type_of_locust = Type of locust +Kind_of_locust = Kind of locust +Name = Name +Types_of_locust = Kinds of locust +Age = Age +Biotop = Biotop +Sorting_index = Index of sorting +Capacity = Capacity +Capacities = Capacities +Types_of_operators = Types of operators +Types_of_operator = Types of operator +Density_of_vegetation = Density of vegetation +Damage = Damage +Density = Density +Directions = Directions +Angle = Angle +Methods_of_calculating_mortality = Methods of calculating mortality +Method_of_calculating_mortality = Method of calculating mortality +Phase = Phase +Condition_of_vegetation = Vegetation state +Actions_of_bands = Actions of hopper bands +Behaviors = Behaviour +Paintings = Paintings +Painting = Painting +Report_by_inspectors = Report by inspectors +From_date = From date +To_date = To date +Surname = Surname +Patronymic = Patronymic +Completed_questionnaires_locusts = Completed questionnaires locusts +Completed_questionnaires_for_the_destruction_of_locusts = Completed questionnaires for the destruction of locusts +FrmLocust = FrmLocust +User = User +Photo = Photo +Photo_name = Photo name +Country = Country +Area = Area +Region = Region +District = District +Observer = Observer +Date = Date +Terrain = Terrain +Latitude = Latitude +Longitude = Longitude +bio_hectare = Surveyed area (ha) +bio_biotope = Type of habitat +bio_greenery = Vegetation +bio_greenery_cover = The vegetation cover +bio_temperature = Weather: air temperature (ºC) +Weather = Weather +bio_wind = Weather: wind (m/s) +Wind_m_s = Weather: wind (m/s) +LOCUST_INFORMATION_INCLUDING_EGG_PODS = _LOCUST INFORMATION (INCLUDING EGG-PODS) +Air_temperature = Weather: air temperature (ºC) +locust_have = Present locusts +locust_populated = Populated area (ha) +eggs_capsules_area = Deposit egg capsules (area in m²) +eggs_capsules_density = Potbelly (density per m²) +Egg_bed_surface_in_ha = Egg-bed (surface in m²) +eggs_capsules = Eggs (average per pod) +eggs_live = Eggs (% viable) +eggs_enemies = The presence of natural enemies (what?) +larva_born = Born +larva_age = Age +larva_painting = Painting +larva_behavior = Behavior +larva_density = Density (per m²) +kuliguli_age = Mean age +kuliguli_density = Tighter. in the swarm (in m²) +kuliguli_size = Swarms size (m²) +kuliguli_count = By swarms +kuliguli_action = Behavior +imago_wing = Stand on the wing +imago_maturity = Maturity +imago_phase = Phase +imago_action = Behavior +imago_density = Density (per he.) +imago_copulation = Mating or egg-laying +imago_flying = Flying +swarm_maturity = Maturity +swarm_density = Density (per m²) +swarm_size = Size rooms (per km²) +swarm_count = Count of swarms +swarm_copulation = Mating or egg-laying +swarm_flying = Flying +swarm_height = Height +Description = Description +Inspector = Inspector +Changed = Changed +Lon = Longitude +Lat = Latitude +locust_type = Kind of locust +imago_laying = Egg-laying +swarm_laying = Egg-laying +Comments = Comments +Locust_Survey_Forms = Locust survey forms +Spray_Monitoring_Forms = Spray monitoring forms +FrmLocustDel = Standard forms for locust +infested_area = Populated area (ha) +treated_area = Cultivated area (ha) +vegetation_type = Type (wild, cultural) +Vegetation_type = Vegetation type +vegetation_height = Height (m) +vegetation_cover = Vegetation cover (%) +vegetation_crop = Vegetation +vegetation_damage = Damage to vegetation cover (%) +vegetation_damage_area = Area damage +insecticide_name = Commercial name +The_active_substance = The active substance +insecticide_concentration = Concentration (%) +insecticide_formulation = Formulation +insecticide_dose = Consumption rate (l/ha) +insecticide_rate = Working fluid flow (l/ha) +insecticide_expiry_date = Expiration +insecticide_mixed = Do insecticide mixed with water or solvent? +insecticide_mixed_name = Solvent +insecticide_mixed_ratio = If so, in what proportion (%) +weather_time_start = Start time +weather_time_end = End time +weather_temperature_start = Temperature at the start (°C) +weather_temperature_end = Temperature at the end (°C) +weather_humidity_start = Humidity start (%) +weather_humidity_end = Humidity end (%) +weather_wind_speed_start = Wind speed at the start (m/s) +weather_wind_speed_end = Wind speed at the end (m/s) +weather_direction_start = Start direction +weather_direction_end = End direction +weather_spray_direction_start = Spray direction at the start +weather_spray_direction_end = Spray direction at the end +locust_speciese = Species +locust_hoppers = Instar larvae +locust_density = Density (per m²) +spray_platform = Spray platform +spray_operator = Operator of spraying +spray_operator_name = Name of operator +spray_manufacturer_name = Brand sprayer +spray_model_name = Model of sprayer +spray_date_calibration = Date of last calibration +spray_height = Atomizer height above ground (m) +spray_width = Width (m) +spray_barrier = Barriers (m) +spray_speed = Speed (km/h) +spray_gps = Antenna: GPS used +spray_marking = Ground marking +efficacy_mortality = Locust mortality (%) +efficacy_passed_time = Elapsed time after working +efficacy_mortality_method = Method of counting mortality +safety_clothing = What protective clothing used operator +safety_inform = Who was notified about the workings? +safety_non_target = Impact on non-target organisms +safety_non_target_effect = If yes, what? +description = description +locust_kuliguli = Kuligi +locust_swarm = Swarms +locust_sparse = Sparse +Air_platform = Air platform +Ground_platform = Ground platform +Hand_platform = Hand platform +Type_of_operator = Type of operator +spray_barrier_width = Width (m) +spray_barrier_space = Space (m) +Terminal = Terminal +Named = Name +Phone = Phone +Serial_number = Serial number +Terminal_model = Terminal model +Terminals = Terminals +Coordinates_Geofence = Coordinates of geozone +Geofence = Geozone +Change_password = Change password +Login = Login +Password = Password +New_password = New password +Repeat_password = Repeat password +User_settings = User settings +Value = Value +Company = Company +Values = Values +Object = Object +sensor = sensor +Groups_of_objects = Groups of objects +Object_of_observation = Object of observation +Access = Access +Identifier = Identifier +Allow = Allow +Sensor = Sensor +objects = objects +Sensor_values = Sensor values +Units_of_measurement = Units of measurement +Fix_date = Fix date +Messages = Messages +Read = Read +Readed = Read +Content = Content +Date_read = Read date +Date_create = Date of creation +Day_mileage_and_speed = Day mileage and speed +Kilometers_distance = Kilometers distance +Kilometers_distance_without_signal = Kilometers distance without signal +Company_site = Company site +Contact_phone = Contact phone +Site = Site +Users = Users +Models_of_terminals = Models of terminals +Sensor_type = Sensor type +Sensor_of_devices = Sensor of devices +Measurement = Measurement +Sensor_model = Sensor model +Rounded_to = Approximately count to +Sensors_models = Sensors models +Count_objects = Number of objects +Group = Group +Stationary = Stationary +Icon = Icon +Objects_of_observation = Objects of observation +Count_of_sensors = Number of sensors +Icons = Icons +name = name +File = File +Size = Size +byte = byte +Geofences = Geozones +Geofence = Geozone +Coordinate = Coordinate +Position = Position +True_position = Right location +outside = outside +inside = inside +Boundary = Boundary +Inform = Inform +Inside = Inside +Sensor_of_object = Sensor of object +Sensors_of_objects = Sensors of objects +Last_value = Last value +Date_of_the_last_value = Date of the last value +Readings = Measerement +Devices = Devices +Sensor_readings = Sensor readings +GPS_readings = GPS data +Fixation_date = Date of fixing +Speed = Speed +Message = Message +Subject = Subject +Creation_date = Date of creation +Contents = Contents +User_messages = User messages +Reading_date = Reading date +Users_messages = Users messages +The_boundary_values_of_the_sensors = The limit values of the sensors +Minimum_value = Minimum value +Maximum_value = Maximum value +Only_on_the_boundary = Only on the boundary +Action = Action +Rule = Rule +Actions = Actions +Access_role = Access role +Parental_role = Parental_role +Role_name = Role name +Role_description = Role description +Role = Role +Phones = Phones +Password_expiration = Password expiration +Renewal_password = Renewal password +days = days +day = day +S_N_P = S.N.P. +Last_enter = Last enter +Roles = Roles +User_roles = User roles +Synchronization_objects = Synchronization objects +Synchronization_service = Synchronization service +Synchronization_order = Synchronization order +The_interval_between_the_update_in_s = The interval between the update in (s) +At_a_time = Records per one time +Time_of_the_last_synchronization = Time of the last synchronization +Service = Service +Order = Order +Interval = Interval +Limit = Limit +Synchronization_services = Synchronization services +Host = Host +History = History +Table = Table +Field = Field +Data = Data +Short_name = Short name +Translation = Translation +Sprayer_type = Sprayer type +Sprayers = Sprayers +Sprayer = Sprayer +Sprayer_type_name = Sprayer type name +Countries = Countries +Regions = Regions +Automated_system_of_data_collection = Automated system of data collection +Download_android_app_Inspector = Download the android app of Inspector +Run_the_application_of_the_situational_center = Run the application of the situational center +For_any_questions_contact_us_at_tel_Fax = Contact us by phone/fax +Your_session_is_canceled = Your session is canceled! +Simultaneous_operation_of_multiple_users = Simultaneous operation of multiple users! +You_are_not_logged_in = You are not logged in! +Not_found_the_requested_node: = Not found the requested node: +The_number_of_records_is_not_equal_to_one = The number of records is not equal to one! +Registration_Form_Inspector = Registration Form Inspector +Post = Post +The_device_ID = The device ID +Security_Code = Security Code +Update = Update +image = image +Registering = Registering +configuration_section_s = configuration section; %s +configuration_option_s = configuration option; %s +Locust_survey = Locust survey +Spray_monitoring = Spray monitoring +Reports = Reports +Report = Report +Map_layers = Map layers +Administration = Administration +Completed_forms_by_tablets = Completed forms by tablets +Filling_forms_by_countries = Filling forms by countries +Standard_survey_forms = Standard survey forms +Companies = Companies +Report_by_countries = Report by countries +Lists = Lists +Members = Members +Photo = Photo +Egg_pods_density_m2 = Egg-pods (density/m²) +Egg_pods_density = Egg-pods density +Egg_pod = Egg-pod +Eggs_average_number_egg_pod = Eggs (average number egg pod) +Number_forms = Number of forms +Open_data_on_the_map = Open data on the map +From_date = From date +To_date = To date +Distribution_of_locust = Information on the distribution of locust +Hide = Hide +For_what_year = For what year +Invalid_username_and_or_password = Invalid username and/or password! +Automated_system_of_data_collection_ASDC = Automated system of data collection (ASDC) +Method_filling_form = Method of filling the form +From_PDA = From tablet +From_WEB_interface = From WEB interface +PDA_registered = PDA registered +Yes = Yes +Not = Not +Displayed_data = Displayed data +Adult_density_m2 = Adult (density/m²) +Adult_density = Adult density +Hopper_density_m2 = Hopper (density/m²) +Swarms = Swarms +Bands = Hopper bands +Band_sizes_m2 = Band sizes (m²) +Open_in_a_table_format = Open in a table format +Request_data = Request data +Method_filling_form = Method filling form +From_DPA = From DPA +From_WEB_interface = From WEB interface +PDA_registered = Tablets registered +Yes = Yes +Not = Not +Open_in_a_table_format = Open in a table format +Request_data = Request data +Displayed_data = Displayed data +Open_in_a_table_format = Open in a table format +Request_data = Request data +The_tablet = The tablet +Spray_Monitoring_Form = Spray Monitoring Form +Information_on_the_distribution_of_locust = Information about locusts’ distribution and its control +Organization = Organization +User_roles = User_roles +Layout = Layer +Markings = Markings +Formulation = Formulation +Fledgling = Fledgling +Borns = Hatching +Breeding = Behaviour +Containers = Containers +Height = Height +Enemies = Natural enemies present +Report_by_tablets = Tablets’ report +Value = Value +Days = Days +Hours = Hours +Company_User = Company->User +Object_Geofence = Object->Geozone +Sensor_for_ComboBox = Sensor for drop-down list +SprayersTypes = Sprayers Types +CountriesRegions = The boundaries of Regions +CIT_Italian_locust = CIT - Italian locust +DMA_Moroccan_locust = DMA - Moroccan locust +LMI_Asian_migratory_locust = LMI - Asian migratory locust +Substrate = Substrate +Displaying_data = Displaying data +Show_data = Show data +All_types = All types +All_kinds = All kinds +Maps_of_areas_infested_above_Economic_Threshold_ET = Maps of areas infested above Economic Threshold (ET) +Maps_of_treated_areas_above_ET = Maps of treated areas above ET +Map_of_the_level_of_threat = Map of the level of threat +Download_QGIS_project = Download QGIS project +Caution = Caution +Calm = Calm +Danger = Danger +Increase = Increase +Decrease = Decrease +On_the_same_level = On the same level +Normal_Multiyear_average_level = Normal/Multiyear average level +Device_id = Device id +All_countries_of_CCA = All countries of CCA +The_Caucasus_countries_and_Russia = The Caucasus countries and Russia +Countries_of_Central_Asia_and_Russia = Countries of Central Asia and Russia +The_forecast_of_hatching_periods = The forecast of hatching periods +Weather_forecast = Weather forecast +soil_temperature = soil temperature +Soil_temperature = Soil temperature +Passwords_did_not_match = Passwords do not coincide! +The_s_is_not_Email = The "%s" is not Email! +Password_changed_successfully = Password changed successfully. +Failed_to_change_password = Failed to change password. +Check_the_entered_data = Check the entered data. +for_ = for +Earth_temperature = Earth temperature +Point = Point +Forecast_of_hours = Hours of forecast +hours = hours +Change_login_password = Change login/password +Type = Type +Legend = Legend +Spraying = Spraying +Chart = Chart +Percent = Percent +For_s_year = For %s year +and = and +Time_and_date_of_generation = Time and date of generation +Filter_options = Filter_options +Export_to_Excel = Export to Excel +Preparing_of_report = Preparing of report +Download_report = Download report +Old_password = Old password +Not_filled_Email_address = Not filled Email address +Wrong_XML_document = Wrong XML document +Organizations = Organizations +Vegetation = Vegetation +Please_enter_a_valid_email_address = Please enter a valid Email address +Log_in = Log in +Registration = Registration +Password_recovery = Password recovery +The_s_field_is_empty = The "%s" field is empty +New_user_is_registered = New user is registered. +The_password_has_been_sent_to_you_by_Email = The password has been sent to you by Email. +Others = Others +Absent = Absent +No_data = No data +District = District +Districts = Districts +The_tablets = The tablets +Other = Other +Regions = Oblasts +Region = Oblast +All = All +Edit = Edit +thous_ha = thous. ha +Thous_ha = Thous. ha +Average = Average +Year = Year +Deviation = Deviation +Dev_of_average = Dev. of average +Average = Average +Layouts = Layers +The_tabblet = Tablet +Forms_for_locust_survey = Locust Survey Form +Forms_for_spray_monitoring = Spray Monitoring Form +The_tablet_registered = The tablet is registered +Area_infested_ha = Infested area (ha) +Minimum_density_in_the_band_in_m2 = Minimum band density (/m²) +Maximum_density_in_the_band_in_m2 = Maximum band density (/m²) +Adult_density_ha = Adult density (/ha) +Adult_density_m2 = Adult density (/m²) +Feeding_and_roosting = Feeding and roosting +Density_of_swarm = Swarm density +Swarm_size_ha = Swarm size (ha) +Number_of_swarms = Number of swarms +Flying_direction = Flying direction +Flying_height = Flying height +Weather_air_temperature_C = Weather: air temperature (ºC) +Locust_Survey_Form = Locust Survey Form +Locust_Survey_Forms = Locust survey forms +Latitude_center_portion = Latitude (site center) +Longitude_center_portion = Longitude (site center) +INSECTICIDE_DATA = Insecticide information +Concentration_A_S = Concentration (%) +Relative_humidity_start = Relative humidity at the start (%) +Relative_humidity_end = Relative humidity at the end (%) +Wind_direction_start = Wind direction at the start +Wind_direction_end = Wind direction at the end +Density_m2 = Density (/m2) +Model_sprayer = Sprayer model +Biological_efficiency_of_treatment = Biological efficiency of treatment (%) +Inform_abaut_spraying = Informed about spraying +Inspect_thous_ha = Surveyed (thous. ha) +Responsible_person = Responsible person for the tablet (inspector) +Upload = Upload +Delete = Delete +Download = Download +Hoppers = Hoppers (scattered) +Kuliguli = Bands +Adult = Adult +Restore = Restore +Add_more = Add more +Successfully_added_data = Successfully added data +Are_you_sure_you_want_to_delete_the_entries = Are you sure you want to delete the entries? +Increase_by_1 = Increase by 1 +Decrease_by_1 = Decrease by 1 +No_results_were_found_for_your_search = No results were found for your search! +Selection = Selection +Add_record = Add record +Delete_record = Delete record +Filtering = Filtering +Invert_selection = Invert selection +Antenna_DGPS_used = Antenna: DGPS used +No_locust = No locust +Total_volume_of_working_solution_actually_applied_l = Total volume of working solution actually applied (l) +Triple_rinsed=Triple_rinsed +Punctured=Punctured +Taken_back_to_base=Taken_back_to_base +Left_in_field=Left_in_field +Buried=Buried +Burned=Burned \ No newline at end of file diff --git a/target/m2e-wtp/web-resources/META-INF/MANIFEST.MF b/target/m2e-wtp/web-resources/META-INF/MANIFEST.MF new file mode 100644 index 0000000..0bb6f7b --- /dev/null +++ b/target/m2e-wtp/web-resources/META-INF/MANIFEST.MF @@ -0,0 +1,5 @@ +Manifest-Version: 1.0 +Built-By: ivanov.i +Build-Jdk: 17.0.8.1 +Created-By: Maven Integration for Eclipse + diff --git a/target/m2e-wtp/web-resources/META-INF/maven/kz.locust/CCALM/pom.properties b/target/m2e-wtp/web-resources/META-INF/maven/kz.locust/CCALM/pom.properties new file mode 100644 index 0000000..9218cb5 --- /dev/null +++ b/target/m2e-wtp/web-resources/META-INF/maven/kz.locust/CCALM/pom.properties @@ -0,0 +1,7 @@ +#Generated by Maven Integration for Eclipse +#Mon Nov 06 12:39:00 ALMT 2023 +m2e.projectLocation=O\:\\projects\\Workspace_Java\\CCALM_TOMCAT +m2e.projectName=CCALM_TOMCAT +groupId=kz.locust +artifactId=CCALM +version=1.0.0-BUILD-SNAPSHOT diff --git a/target/m2e-wtp/web-resources/META-INF/maven/kz.locust/CCALM/pom.xml b/target/m2e-wtp/web-resources/META-INF/maven/kz.locust/CCALM/pom.xml new file mode 100644 index 0000000..635dbc7 --- /dev/null +++ b/target/m2e-wtp/web-resources/META-INF/maven/kz.locust/CCALM/pom.xml @@ -0,0 +1,257 @@ + + 4.0.0 + kz.locust + CCALM + Locust + war + 1.0.0-BUILD-SNAPSHOT + + 1.8 + 5.0.0.RELEASE + 1.8.12 + 1.7.25 + + + + + + + + + + org.gdal + gdal + 2.4.0 + system + O:\projects\_Libs\gdal-2.4.0.jar + + + + + + + org.json + json + 20200518 + + + + + org.postgresql + postgresql + 42.1.4 + + + + + + + edu.ucar + netcdfAll + 5.3.1 + system + O:\projects\_Libs\netcdfAll-5.3.1.jar + + + + + javax.mail + mail + 1.4 + + + + + org.apache.commons + commons-io + 1.3.2 + + + + + commons-fileupload + commons-fileupload + 1.3.1 + + + + + com.fasterxml.jackson.core + jackson-core + 2.13.0 + + + + + + com.fasterxml.jackson.core + jackson-databind + 2.9.1 + + + + + org.springframework + spring-context + ${org.springframework-version} + + + + commons-logging + commons-logging + + + + + org.springframework + spring-webmvc + ${org.springframework-version} + + + + + org.aspectj + aspectjrt + ${org.aspectj-version} + + + + + org.slf4j + slf4j-api + ${org.slf4j-version} + + + org.slf4j + jcl-over-slf4j + ${org.slf4j-version} + runtime + + + org.slf4j + slf4j-log4j12 + ${org.slf4j-version} + runtime + + + log4j + log4j + 1.2.15 + + + javax.mail + mail + + + javax.jms + jms + + + com.sun.jdmk + jmxtools + + + com.sun.jmx + jmxri + + + runtime + + + + + javax.inject + javax.inject + 1 + + + + + javax.servlet + servlet-api + 2.5 + provided + + + javax.servlet.jsp + jsp-api + 2.1 + provided + + + javax.servlet + jstl + 1.2 + + + + + junit + junit + 4.7 + test + + + + + + maven-war-plugin + 3.2.1 + + WebContent + + + + maven-eclipse-plugin + 2.9 + + + org.springframework.ide.eclipse.core.springnature + + + org.springframework.ide.eclipse.core.springbuilder + + true + true + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.5.1 + + 1.8 + 1.8 + -Xlint:all + true + true + + + + org.codehaus.mojo + exec-maven-plugin + 1.2.1 + + org.test.int1.Main + + + + +