From: Mathieu Baudier Date: Tue, 20 Nov 2018 14:22:11 +0000 (+0100) Subject: Merge branch 'master' of https://github.com/argeo/argeo-suite.git X-Git-Tag: argeo-suite-2.1.14~6 X-Git-Url: https://git.argeo.org/?p=gpl%2Fargeo-suite.git;a=commitdiff_plain;h=f0953fddc11686629a53a4100327dd414203db56;hp=b1c250b0f82d8a33c4b7e33bf7168cc175060a63 Merge branch 'master' of https://github.com/argeo/argeo-suite.git --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e3d2422 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target/ +/.DS_Store diff --git a/.project b/.project new file mode 100644 index 0000000..ff41893 --- /dev/null +++ b/.project @@ -0,0 +1,11 @@ + + + argeo-suite + + + + + + + + diff --git a/dep/.gitignore b/dep/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/dep/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/dep/org.argeo.suite.dep.e4.rap/.gitignore b/dep/org.argeo.suite.dep.e4.rap/.gitignore new file mode 100644 index 0000000..76df179 --- /dev/null +++ b/dep/org.argeo.suite.dep.e4.rap/.gitignore @@ -0,0 +1,2 @@ +/target/ +/*.target diff --git a/dep/org.argeo.suite.dep.e4.rap/META-INF/.gitignore b/dep/org.argeo.suite.dep.e4.rap/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/dep/org.argeo.suite.dep.e4.rap/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/dep/org.argeo.suite.dep.e4.rap/bnd.bnd b/dep/org.argeo.suite.dep.e4.rap/bnd.bnd new file mode 100644 index 0000000..991aa1a --- /dev/null +++ b/dep/org.argeo.suite.dep.e4.rap/bnd.bnd @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dep/org.argeo.suite.dep.e4.rap/p2.inf b/dep/org.argeo.suite.dep.e4.rap/p2.inf new file mode 100644 index 0000000..0423aa5 --- /dev/null +++ b/dep/org.argeo.suite.dep.e4.rap/p2.inf @@ -0,0 +1,2 @@ +properties.1.name=org.eclipse.equinox.p2.type.category +properties.1.value=true \ No newline at end of file diff --git a/dep/org.argeo.suite.dep.e4.rap/pom.xml b/dep/org.argeo.suite.dep.e4.rap/pom.xml new file mode 100644 index 0000000..016d9d9 --- /dev/null +++ b/dep/org.argeo.suite.dep.e4.rap/pom.xml @@ -0,0 +1,134 @@ + + + 4.0.0 + + org.argeo.suite + dep + 2.1.14-SNAPSHOT + .. + + org.argeo.suite.dep.e4.rap + Suite E4 Platform RAP + jar + + + + org.argeo.suite + org.argeo.suite.cms + 2.1.14-SNAPSHOT + + + org.argeo.suite + org.argeo.suite.e4 + 2.1.14-SNAPSHOT + + + org.argeo.suite + org.argeo.suite.e4.rap + 2.1.14-SNAPSHOT + + + + + + + + + + org.argeo.connect + org.argeo.connect.dep.e4.rap + ${version.argeo-connect} + pom + + + + + org.argeo.tp.payment + com.stripe + + + + + + rpmbuild + + + + maven-assembly-plugin + + + prepare-source + package + + single + + + + a2-source + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.codehaus.mojo + rpm-maven-plugin + + + rpm-argeo + package + + rpm + + + argeo-suite-e4-rap + + + /usr/share/osgi + root + root + 644 + true + + + ${project.build.directory}/${project.artifactId}-${project.version}-a2-source + + **/*.jar + + + + + + + argeo-connect-e4-rap + + + + + + + + + + diff --git a/dep/org.argeo.suite.dep.e4.rcp/.gitignore b/dep/org.argeo.suite.dep.e4.rcp/.gitignore new file mode 100644 index 0000000..76df179 --- /dev/null +++ b/dep/org.argeo.suite.dep.e4.rcp/.gitignore @@ -0,0 +1,2 @@ +/target/ +/*.target diff --git a/dep/org.argeo.suite.dep.e4.rcp/META-INF/.gitignore b/dep/org.argeo.suite.dep.e4.rcp/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/dep/org.argeo.suite.dep.e4.rcp/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/dep/org.argeo.suite.dep.e4.rcp/bnd.bnd b/dep/org.argeo.suite.dep.e4.rcp/bnd.bnd new file mode 100644 index 0000000..991aa1a --- /dev/null +++ b/dep/org.argeo.suite.dep.e4.rcp/bnd.bnd @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dep/org.argeo.suite.dep.e4.rcp/p2.inf b/dep/org.argeo.suite.dep.e4.rcp/p2.inf new file mode 100644 index 0000000..0423aa5 --- /dev/null +++ b/dep/org.argeo.suite.dep.e4.rcp/p2.inf @@ -0,0 +1,2 @@ +properties.1.name=org.eclipse.equinox.p2.type.category +properties.1.value=true \ No newline at end of file diff --git a/dep/org.argeo.suite.dep.e4.rcp/pom.xml b/dep/org.argeo.suite.dep.e4.rcp/pom.xml new file mode 100644 index 0000000..11bfbf6 --- /dev/null +++ b/dep/org.argeo.suite.dep.e4.rcp/pom.xml @@ -0,0 +1,129 @@ + + + 4.0.0 + + org.argeo.suite + dep + 2.1.14-SNAPSHOT + .. + + org.argeo.suite.dep.e4.rcp + Suite E4 Platform RCP + jar + + + + org.argeo.suite + org.argeo.suite.cms + 2.1.14-SNAPSHOT + + + org.argeo.suite + org.argeo.suite.e4 + 2.1.14-SNAPSHOT + + + + + + + + + + org.argeo.connect + org.argeo.connect.dep.e4.rcp + ${version.argeo-connect} + pom + + + + + org.argeo.tp.payment + com.stripe + + + + + + rpmbuild + + + + maven-assembly-plugin + + + prepare-source + package + + single + + + + a2-source + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.codehaus.mojo + rpm-maven-plugin + + + rpm-argeo + package + + rpm + + + argeo-suite-e4-rcp + + + /usr/share/osgi + root + root + 644 + true + + + ${project.build.directory}/${project.artifactId}-${project.version}-a2-source + + **/*.jar + + + + + + + argeo-connect-e4-rcp + + + + + + + + + + diff --git a/dep/org.argeo.suite.platform/.gitignore b/dep/org.argeo.suite.platform/.gitignore new file mode 100644 index 0000000..d6c033c --- /dev/null +++ b/dep/org.argeo.suite.platform/.gitignore @@ -0,0 +1,2 @@ +/target +/org.argeo.suite.platform-maven.target diff --git a/dep/org.argeo.suite.platform/META-INF/.gitignore b/dep/org.argeo.suite.platform/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/dep/org.argeo.suite.platform/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/dep/org.argeo.suite.platform/bnd.bnd b/dep/org.argeo.suite.platform/bnd.bnd new file mode 100644 index 0000000..991aa1a --- /dev/null +++ b/dep/org.argeo.suite.platform/bnd.bnd @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/dep/org.argeo.suite.platform/pom.xml b/dep/org.argeo.suite.platform/pom.xml new file mode 100644 index 0000000..421d204 --- /dev/null +++ b/dep/org.argeo.suite.platform/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + + org.argeo.suite + dep + 2.1.14-SNAPSHOT + .. + + org.argeo.suite.platform + Argeo Suite Platform + jar + + + + org.argeo.suite + org.argeo.suite.apps + 2.1.14-SNAPSHOT + + + org.argeo.suite + org.argeo.suite.workbench.rap + 2.1.14-SNAPSHOT + + + org.argeo.suite + org.argeo.suite.web + 2.1.14-SNAPSHOT + + + + + org.argeo.connect + org.argeo.connect.platform + ${version.argeo-connect} + pom + + + + + org.argeo.tp.payment + com.stripe + + + + + + diff --git a/dep/pom.xml b/dep/pom.xml new file mode 100644 index 0000000..baf1eda --- /dev/null +++ b/dep/pom.xml @@ -0,0 +1,104 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.1.14-SNAPSHOT + .. + + dep + Argeo Suite Dependencies + pom + + org.argeo.suite.platform + org.argeo.suite.dep.e4.rap + org.argeo.suite.dep.e4.rcp + + + + + org.apache.felix + maven-bundle-plugin + + + default + + + + + org.argeo.maven.plugins + maven-argeo-osgi-plugin + + + generate-descriptors + + descriptors + + generate-resources + + + + + maven-assembly-plugin + + + org.argeo.commons + assembly-descriptors + ${version.argeo-commons} + + + + false + + + + + + + + org.argeo.tp.equinox + org.eclipse.osgi + test + + + org.argeo.tp.sdk + org.junit + test + + + + + check-osgi + + + + org.argeo.maven.plugins + maven-argeo-osgi-plugin + + + check-osgi + test + + equinox + + + true + + + + + + + + + + org.argeo.commons + org.argeo.osgi.boot + ${version.argeo-commons} + test + + + + + diff --git a/dist/.gitignore b/dist/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/dist/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/dist/argeo-office/.gitignore b/dist/argeo-office/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/dist/argeo-office/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/dist/argeo-office/assembly/argeo-office-e4-rap.xml b/dist/argeo-office/assembly/argeo-office-e4-rap.xml new file mode 100644 index 0000000..30733b4 --- /dev/null +++ b/dist/argeo-office/assembly/argeo-office-e4-rap.xml @@ -0,0 +1,47 @@ + + dist + argeo-office + + dir + zip + + + + base + + 0644 + + ** + + + offline.bat + + + + + + false + ${artifact.groupId}/${artifact.artifactId}-${artifact.version}.${artifact.extension} + share/osgi + + + true + true + + + org.argeo.commons:osgi-boot:zip:*:* + + + + true + true + + + org.argeo.commons:argeo-node:zip:*:* + + + + \ No newline at end of file diff --git a/dist/argeo-office/base/etc/argeo/conf.d/argeo-office.ini b/dist/argeo-office/base/etc/argeo/conf.d/argeo-office.ini new file mode 100644 index 0000000..cbfa365 --- /dev/null +++ b/dist/argeo-office/base/etc/argeo/conf.d/argeo-office.ini @@ -0,0 +1,5 @@ +argeo.osgi.start.3.suite=\ +org.argeo.suite.cms + +argeo.osgi.start.5.suite=\ +org.argeo.suite.e4.rap diff --git a/dist/argeo-office/pom.xml b/dist/argeo-office/pom.xml new file mode 100644 index 0000000..21b6652 --- /dev/null +++ b/dist/argeo-office/pom.xml @@ -0,0 +1,150 @@ + + 4.0.0 + + org.argeo.suite + dist + 2.1.14-SNAPSHOT + .. + + argeo-office + pom + Argeo Office + + + org.argeo.suite + org.argeo.suite.standard + 2.1.14-SNAPSHOT + + + org.argeo.suite + org.argeo.suite.tracker + 2.1.14-SNAPSHOT + + + + + dist + + + org.argeo.suite + org.argeo.suite.dep.e4.rap + 2.1.14-SNAPSHOT + + + org.argeo.commons + osgi-boot + zip + ${version.argeo-commons} + + + org.argeo.commons + argeo-node + zip + ${version.argeo-commons} + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + argeo-suite-${project.version} + false + + assembly/argeo-office-e4-rap.xml + + + + + assembly-base + package + + single + + + + + + + + + rpmbuild + + + + maven-assembly-plugin + + + prepare-source + package + + single + + + + a2-source + + + + + + + org.codehaus.mojo + rpm-maven-plugin + + + rpm-node + package + + rpm + + + argeo-office + + + /etc/argeo/conf.d + root + argeo + 640 + noreplace + false + + + base/etc/argeo/conf.d + + *.ini + *.txt + + + + + + /usr/share/osgi + root + root + 644 + true + + + ${project.build.directory}/${project.artifactId}-${project.version}-a2-source + + **/*.jar + + + + + + + argeo-node + argeo-suite-e4-rap + + + + + + + + + + diff --git a/dist/pom.xml b/dist/pom.xml new file mode 100644 index 0000000..dcfab9b --- /dev/null +++ b/dist/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.1.14-SNAPSHOT + .. + + dist + Argeo Suite Distributions + pom + + argeo-office + + + + + maven-assembly-plugin + + + org.argeo.commons + assembly-descriptors + ${version.argeo-commons} + + + + false + + + + + diff --git a/license-GPLwithException-header.txt b/license-GPLwithException-header.txt new file mode 100644 index 0000000..fe08ba0 --- /dev/null +++ b/license-GPLwithException-header.txt @@ -0,0 +1,24 @@ +Argeo Smart Data Productivity Suite +Copyright (C) 2017 Argeo GmbH + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see + +Additional permission under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or combining it +with software covered by the terms of the Eclipse Public License, the +licensors of this Program grant you additional permission to convey the +resulting work. Corresponding Source for a non-source form of such a +combination shall include the source code for the parts of such software +which are used as well as that of the covered work. \ No newline at end of file diff --git a/org.argeo.suite.apps.web/.classpath b/org.argeo.suite.apps.web/.classpath new file mode 100644 index 0000000..dc7ce67 --- /dev/null +++ b/org.argeo.suite.apps.web/.classpath @@ -0,0 +1,5 @@ + + + + + diff --git a/org.argeo.suite.apps.web/.gitignore b/org.argeo.suite.apps.web/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/org.argeo.suite.apps.web/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/org.argeo.suite.apps.web/.project b/org.argeo.suite.apps.web/.project new file mode 100644 index 0000000..542a4e8 --- /dev/null +++ b/org.argeo.suite.apps.web/.project @@ -0,0 +1,22 @@ + + + org.argeo.suite.apps.web + + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + + diff --git a/org.argeo.suite.apps.web/META-INF/.gitignore b/org.argeo.suite.apps.web/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.suite.apps.web/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/org.argeo.suite.apps.web/META-INF/spring/osgi.xml b/org.argeo.suite.apps.web/META-INF/spring/osgi.xml new file mode 100644 index 0000000..2ef3e0d --- /dev/null +++ b/org.argeo.suite.apps.web/META-INF/spring/osgi.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/org.argeo.suite.apps.web/META-INF/spring/ui-commons.xml b/org.argeo.suite.apps.web/META-INF/spring/ui-commons.xml new file mode 100644 index 0000000..9f579b7 --- /dev/null +++ b/org.argeo.suite.apps.web/META-INF/spring/ui-commons.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.argeo.suite.apps.web/META-INF/spring/ui-people.xml b/org.argeo.suite.apps.web/META-INF/spring/ui-people.xml new file mode 100644 index 0000000..6c9c382 --- /dev/null +++ b/org.argeo.suite.apps.web/META-INF/spring/ui-people.xml @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.argeo.suite.apps.web/META-INF/spring/ui.xml b/org.argeo.suite.apps.web/META-INF/spring/ui.xml new file mode 100644 index 0000000..e1963c1 --- /dev/null +++ b/org.argeo.suite.apps.web/META-INF/spring/ui.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + a:link, a:visited { color: #333333; text-decoration:none; } + a:hover { text-decoration:underline; } + + + + + +]]> + + + + + + + + + + + + + + + + + a:link, a:visited { color: #333333; text-decoration:none; } + a:hover { text-decoration:underline;} + +]]> + + + + + + + + + + theme/argeo-classic/argeo-classic.css + theme/argeo-classic/people-classic.css + theme/argeo-classic/documents-classic.css + theme/argeo-classic/maintenance-classic.css + + + + + + + diff --git a/org.argeo.suite.apps.web/bnd.bnd b/org.argeo.suite.apps.web/bnd.bnd new file mode 100644 index 0000000..d8a3588 --- /dev/null +++ b/org.argeo.suite.apps.web/bnd.bnd @@ -0,0 +1,17 @@ +Require-Capability: cms.datamodel; filter:="(name=people)",\ +cms.datamodel; filter:="(name=documents)",\ +cms.datamodel; filter:="(name=tracker)" + +Import-Package:\ +javax.jcr.nodetype,\ +javax.jcr.security,\ +org.argeo.cms,\ +org.argeo.connect,\ +org.argeo.activities,\ +org.argeo.connect.resources,\ +org.argeo.connect.ui,\ +org.argeo.cms.spring,\ +org.argeo.eclipse.spring,\ +org.argeo.node,\ +org.argeo.util,\ +* \ No newline at end of file diff --git a/org.argeo.suite.apps.web/pom.xml b/org.argeo.suite.apps.web/pom.xml new file mode 100644 index 0000000..5fa1221 --- /dev/null +++ b/org.argeo.suite.apps.web/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.1.14-SNAPSHOT + .. + + org.argeo.suite.apps.web + Default Web Deployment + jar + + + org.argeo.suite + org.argeo.suite.web + 2.1.14-SNAPSHOT + + + diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/argeo-classic.css b/org.argeo.suite.apps.web/theme/argeo-classic/argeo-classic.css new file mode 100644 index 0000000..71fc1b7 --- /dev/null +++ b/org.argeo.suite.apps.web/theme/argeo-classic/argeo-classic.css @@ -0,0 +1,149 @@ +/* For reference, Argeo colors +Orange: #f6712e; +Blue: #00294b; */ + +/* TEXT STYLES */ +.text_title { + font: bold 26px sans-serif; +} + +.text_title_box { + padding: 20px; +} + +.text_h1 { + font: bold 24px sans-serif; +} + +.text_h1_box { + padding: 10px 10px 5px; +} + +.text_h2 { + font: bold italic 20px serif; +} + +.text_h2_box { + padding: 0px 15px 10px; +} + +.text_h3 { + font: bold 18px sans-serif; +} + +.text_h3_box { + padding: 0px 20px 10px; +} + +.text_default { + font: 18px sans-serif; +} + +.text_default_box { + padding: 0px 10px 10px; +} + +.text_pre { + font: 16px monospace; + background-color: inherit; +} + +.text_pre_box { + padding: 10px; + border: 1px dashed gray; + background-color: #ababab +} + +.text_pre_container { + padding: 0px 10px 10px; +} + +.text_quote { + font: italic 22px serif; + text-shadow: 2px 3px 3px #ababab; + background-color: inherit; +} + +.text_quote_box { + padding: 10px; + background-color: #d6d6d6 +} + +.text_quote_container { + padding: 20px 50px 20px 80px; +} + +/* TEXT */ +.text_styled_tools_dialog { + border: 1px solid #00294b; + padding: 10px 5px; +} + +.text_styled_composite { + /*border: 1px solid red;*/ + +} + +.text_section { +/* border: 1px solid green; */ +} + +.text_paragraph { +/* border: 1px solid blue; */ +} + +.text_editor { + border: 2px outset #00294b; +} + +/* CMS ICONS */ +.cms_icon_delete { + background-image: url(theme/argeo-classic/icons/delete.gif); + border: none; +} + +/* CMS */ +.cms_header { + background-color: #00294b; + height: 30px; +} + +.cms_link { + text-decoration: underline; +} + +.cms_link:hover { + text-decoration: none; + color: black; +} + +a { + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +.cms_header-logo { + padding: 5px; +} + +.cms_user_menu-link, +.cms_menu_link { + color: white; + font: 15px Helvetica, Verdana, sans-serif; + padding: 10px; + text-decoration: none; +} + +.cms_user_menu-link:hover, +.cms_menu_link:hover { + color: #ededed; + text-decoration: underline; +} + +.cms_user_menu { + border: 1px solid #00294b; + padding: 10px 5px; +} \ No newline at end of file diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/documents-classic.css b/org.argeo.suite.apps.web/theme/argeo-classic/documents-classic.css new file mode 100644 index 0000000..8721244 --- /dev/null +++ b/org.argeo.suite.apps.web/theme/argeo-classic/documents-classic.css @@ -0,0 +1,116 @@ +/** +Argeo Blue: #00294b +*/ + + + +/** Same styles are also provided by the workbench CSS. TODO: enhance single sourcing */ + + +/* Breadcrumb ***/ +Button.breadCrumb_btn { + border: 1px solid #f4f6f7; + border-radius: 3px; + padding: 2px 2px 2px 2px; + background-color: transparent; + background-repeat: no-repeat; + animation: hoverOut 500ms ease-out; + cursor: pointer; + font-color: #00294b; + text-decoration: none; +} + +Button.breadCrumb_btn:hover { + text-decoration: underline; +} + +/* Documents lists context menu */ +.contextMenu_box { + border: 0px solid #fde2d5; + padding: 0px; + box-shadow: 2px 2px 5px #fde2d5; +} + +Button[PUSH][FLAT].createFolder_btn { + background-image: url( theme/argeo-classic/icons/fs/addFolder.gif); +} + +Button[PUSH][FLAT].shareFolder_btn { + background-image: url( theme/argeo-classic/icons/fs/shareFolder.png); +} + +Button[PUSH][FLAT].bookmarkFolder_btn { + background-image: url( theme/argeo-classic/icons/fs/bookmarkFolder.png); +} + +Button[PUSH][FLAT].downloadFolder_btn { + background-image: url( theme/argeo-classic/icons/fs/downloadFolder.png); +} + +Button[PUSH][FLAT].delete_btn, +Button[PUSH][FLAT].deleteBookmark_btn { + background-image: url( theme/argeo-classic/icons/fs/delete.png); +} + +Button[PUSH][FLAT].rename_btn, +Button[PUSH][FLAT].renameBookmark_btn { + background-image: url( theme/argeo-classic/icons/fs/rename.png); +} + + +Button[PUSH][FLAT].uploadFiles_btn { + background-image: url( theme/argeo-classic/icons/fs/upload.png); +} + +Button[PUSH][FLAT].open_btn { + background-image: url( theme/argeo-classic/icons/fs/open.png); +} + + +Button[PUSH][FLAT].createFolder_btn, +Button[PUSH][FLAT].shareFolder_btn, +Button[PUSH][FLAT].bookmarkFolder_btn, +Button[PUSH][FLAT].downloadFolder_btn, +Button[PUSH][FLAT].delete_btn, +Button[PUSH][FLAT].rename_btn, +Button[PUSH][FLAT].uploadFiles_btn, +Button[PUSH][FLAT].open_btn, +Button[PUSH][FLAT].deleteBookmark_btn, +Button[PUSH][FLAT].renameBookmark_btn { + border: 0px solid white; + border-left: 10px solid transparent; + border-radius: 0px; + padding: 4px 5px 4px 24px; + background-color: transparent; + background-repeat: no-repeat; + background-position: left; + animation: hoverOut 500ms ease-out; + cursor: pointer; +} + +Button[PUSH][FLAT].createFolder_btn:hover, +Button[PUSH][FLAT].shareFolder_btn:hover, +Button[PUSH][FLAT].bookmarkFolder_btn:hover, +Button[PUSH][FLAT].downloadFolder_btn:hover, +Button[PUSH][FLAT].delete_btn:hover, +Button[PUSH][FLAT].rename_btn:hover, +Button[PUSH][FLAT].uploadFiles_btn:hover, +Button[PUSH][FLAT].open_btn:hover, +Button[PUSH][FLAT].deleteBookmark_btn:hover, +Button[PUSH][FLAT].renameBookmark_btn:hover { + background-color: #fef0ea; +} + +Button[PUSH][FLAT].createFolder_btn:pressed, +Button[PUSH][FLAT].shareFolder_btn:pressed, +Button[PUSH][FLAT].bookmarkFolder_btn:pressed, +Button[PUSH][FLAT].shareFolder_btn:pressed, +Button[PUSH][FLAT].downloadFolder_btn:pressed, +Button[PUSH][FLAT].delete_btn:pressed, +Button[PUSH][FLAT].rename_btn:pressed, +Button[PUSH][FLAT].uploadFiles_btn:pressed, +Button[PUSH][FLAT].open_btn:pressed, +Button[PUSH][FLAT].deleteBookmark_btn:pressed, +Button[PUSH][FLAT].renameBookmark_btn:pressed{ + background-color: #fde2d5; +} \ No newline at end of file diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/actions/deleteSmall.gif b/org.argeo.suite.apps.web/theme/argeo-classic/icons/actions/deleteSmall.gif new file mode 100644 index 0000000..d7c5c11 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/actions/deleteSmall.gif differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/actions/openCalendar.gif b/org.argeo.suite.apps.web/theme/argeo-classic/icons/actions/openCalendar.gif new file mode 100644 index 0000000..5a89e33 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/actions/openCalendar.gif differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/add.gif b/org.argeo.suite.apps.web/theme/argeo-classic/icons/add.gif new file mode 100644 index 0000000..252d7eb Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/add.gif differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/dashboard.gif b/org.argeo.suite.apps.web/theme/argeo-classic/icons/dashboard.gif new file mode 100644 index 0000000..fd0c669 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/dashboard.gif differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/delete.gif b/org.argeo.suite.apps.web/theme/argeo-classic/icons/delete.gif new file mode 100644 index 0000000..1aca259 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/delete.gif differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/favicon.ico b/org.argeo.suite.apps.web/theme/argeo-classic/icons/favicon.ico new file mode 100644 index 0000000..6e6a050 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/favicon.ico differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/addFolder.gif b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/addFolder.gif new file mode 100644 index 0000000..d3f43d9 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/addFolder.gif differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/bookmarkFolder.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/bookmarkFolder.png new file mode 100644 index 0000000..8bb2361 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/bookmarkFolder.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/delete.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/delete.png new file mode 100644 index 0000000..9150e40 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/delete.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/downloadFolder.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/downloadFolder.png new file mode 100644 index 0000000..3f56074 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/downloadFolder.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/file.gif b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/file.gif new file mode 100644 index 0000000..ef30288 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/file.gif differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/folder.gif b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/folder.gif new file mode 100644 index 0000000..42e027c Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/folder.gif differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/fsBrowser.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/fsBrowser.png new file mode 100644 index 0000000..3f56074 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/fsBrowser.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/open.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/open.png new file mode 100644 index 0000000..3836e12 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/open.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/rename.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/rename.png new file mode 100644 index 0000000..ad3db9f Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/rename.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/shareFolder.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/shareFolder.png new file mode 100644 index 0000000..269cdac Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/shareFolder.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/upload.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/upload.png new file mode 100644 index 0000000..71c80e8 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/fs/upload.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/Icon-credit.txt b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/Icon-credit.txt new file mode 100644 index 0000000..4e60cf3 --- /dev/null +++ b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/Icon-credit.txt @@ -0,0 +1,17 @@ +Some of the icons have been downloaded from http://www.fatcow.com/free-icons. +They are licenced under Creative Commons Attribution 3.0 License. + +These icons were as from October 3rd, 2013 the following: +fax.png +mail_black.png +phone-vintage.png +telephone.png + +Some of the icons have been downloaded from http://somerandomdude.com/work/iconic/. +They are licenced under Creative Commons Attribution 3.0 License. + +These icons were as from October 15th, 2013 the following: +socialmedia.png (former chat_alt_stroke_16x16.png) +home.png (former home_16x16.png) +mobile.png (former iphone_12x16.png) +link.png (former link_16x16.png) diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/facebook.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/facebook.png new file mode 100644 index 0000000..8e7e44c Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/facebook.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/fax.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/fax.png new file mode 100644 index 0000000..791f511 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/fax.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/googleplus.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/googleplus.png new file mode 100644 index 0000000..ff97843 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/googleplus.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/home.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/home.png new file mode 100644 index 0000000..16834e3 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/home.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/impp.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/impp.png new file mode 100644 index 0000000..b334f91 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/impp.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/link.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/link.png new file mode 100644 index 0000000..f223cfa Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/link.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/linkedin.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/linkedin.png new file mode 100644 index 0000000..d86dc0e Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/linkedin.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/mail_black.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/mail_black.png new file mode 100644 index 0000000..790f750 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/mail_black.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/mobile.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/mobile.png new file mode 100644 index 0000000..08ac54b Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/mobile.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/myspace.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/myspace.png new file mode 100644 index 0000000..beb04fc Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/myspace.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/phone_vintage.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/phone_vintage.png new file mode 100644 index 0000000..7e463ad Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/phone_vintage.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/reddit.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/reddit.png new file mode 100644 index 0000000..0eac7b8 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/reddit.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/skype.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/skype.png new file mode 100644 index 0000000..e31a04d Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/skype.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/socialmedia.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/socialmedia.png new file mode 100644 index 0000000..f0d1722 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/socialmedia.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/telephone.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/telephone.png new file mode 100644 index 0000000..e04ec63 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/telephone.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/twitter.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/twitter.png new file mode 100644 index 0000000..1023e5b Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/twitter.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/xing.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/xing.png new file mode 100644 index 0000000..26fd283 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/contacts/xing.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/misc/primary.gif b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/misc/primary.gif new file mode 100644 index 0000000..1965b84 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/misc/primary.gif differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/misc/primaryNOT.gif b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/misc/primaryNOT.gif new file mode 100644 index 0000000..acb0268 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/misc/primaryNOT.gif differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/people.gif b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/people.gif new file mode 100644 index 0000000..d28c326 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/people.gif differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/types/company.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/types/company.png new file mode 100644 index 0000000..06aa725 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/types/company.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/types/person.gif b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/types/person.gif new file mode 100644 index 0000000..90a0014 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/people/types/person.gif differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/icons/search.png b/org.argeo.suite.apps.web/theme/argeo-classic/icons/search.png new file mode 100644 index 0000000..6588de8 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/icons/search.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/img/logo-argeo.png b/org.argeo.suite.apps.web/theme/argeo-classic/img/logo-argeo.png new file mode 100644 index 0000000..f107230 Binary files /dev/null and b/org.argeo.suite.apps.web/theme/argeo-classic/img/logo-argeo.png differ diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/maintenance-classic.css b/org.argeo.suite.apps.web/theme/argeo-classic/maintenance-classic.css new file mode 100644 index 0000000..e2a8597 --- /dev/null +++ b/org.argeo.suite.apps.web/theme/argeo-classic/maintenance-classic.css @@ -0,0 +1,48 @@ +/**************************** +*** The browser ***/ + +/* Management of border for edition */ +.user_form_text[BORDER]:read-only, +.user_form_text[BORDER]:read-only:focused, +.user_form_text[BORDER][MULTI]:read-only:focused, +.user_form_text[BORDER][MULTI]:read-only { + box-shadow: none; + border: 0px solid #ffffff; +} + +/* Signal focus gained ********/ +.user_form_text[BORDER]:focused, +.user_form_text[MULTI][BORDER]:focused { + box-shadow: 1px 1px 2px #00294b;; + border: 1px solid #00294b;; +} + +.user_form_title{ + font: bold italic 20px serif; + background-color: #00294b; + color: #eeeeee; +} + + +/* Tests and work in progress */ +.maintenance_browser_column { + background-color: white; + color: black; +} + +/* PB: Css class given to a table is not herited by Table-RowOverlay */ +Table-RowOverlay:unfocused { + color: #00294b; +} + +Table-RowOverlay:selected, +Table-RowOverlay:linesvisible:even:selected { + background-color: #fcd4c0; + color: #00294b; +} + +Table-RowOverlay:selected:unfocused, +Table-RowOverlay:linesvisible:even:selected:unfocused { + color: #00294b; + background-color: #6e869b; +} diff --git a/org.argeo.suite.apps.web/theme/argeo-classic/people-classic.css b/org.argeo.suite.apps.web/theme/argeo-classic/people-classic.css new file mode 100644 index 0000000..4614fa1 --- /dev/null +++ b/org.argeo.suite.apps.web/theme/argeo-classic/people-classic.css @@ -0,0 +1,85 @@ +/* PEOPLE ICONS */ + + +/* MISCELLANEOUS */ + +.people_icon_primary { + background-image: url(theme/argeo-classic/icons/people/misc/primary.gif); + border: none; +} + +.people_icon_not_primary { + background-image: url(theme/argeo-classic/icons/people/misc/primaryNOT.gif); + border: none; +} + +/* CONTACTS */ +.people_icon_email { + background-image: url(theme/argeo-classic/icons/people/contacts/mail_black.png); + border: none; +} + +.people_icon_mobile { + background-image: url(theme/argeo-classic/icons/people/contacts/mobile.png); + border: none; +} + +.people_icon_fax { + background-image: url(theme/argeo-classic/icons/people/contacts/fax.png); + border: none; +} + +.people_icon_phone { + background-image: url(theme/argeo-classic/icons/people/contacts/phone_vintage.png); + border: none; +} + +.people_icon_work { + background-image: url(theme/argeo-classic/icons/people/contacts/home.png); + border: none; +} + +.people_icon_address { + background-image: url(theme/argeo-classic/icons/people/contacts/home.png); + border: none; +} + +.people_icon_url { + background-image: url(theme/argeo-classic/icons/people/contacts/link.png); + border: none; +} + +.people_icon_google_plus { + background-image: url(theme/argeo-classic/icons/people/contacts/googleplus.png); + border: none; +} + +.people_icon_facebook { + background-image: url(theme/argeo-classic/icons/people/contacts/facebook.png); + border: none; +} + +.people_icon_twitter { + background-image: url(theme/argeo-classic/icons/people/contacts/twitter.png); + border: none; +} + +.people_icon_linkedin { + background-image: url(theme/argeo-classic/icons/people/contacts/linkedin.png); + border: none; +} + +.people_icon_xing { + background-image: url(theme/argeo-classic/icons/people/contacts/xing.png); + border: none; +} + +.people_icon_social_media { + background-image: url(theme/argeo-classic/icons/people/contacts/socialmedia.png); + border: none; +} + +.people_icon_impp { + background-image: url(theme/argeo-classic/icons/people/contacts/impp.png); + border: none; +} diff --git a/org.argeo.suite.apps/.classpath b/org.argeo.suite.apps/.classpath new file mode 100644 index 0000000..dc7ce67 --- /dev/null +++ b/org.argeo.suite.apps/.classpath @@ -0,0 +1,5 @@ + + + + + diff --git a/org.argeo.suite.apps/.gitignore b/org.argeo.suite.apps/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/org.argeo.suite.apps/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/org.argeo.suite.apps/.project b/org.argeo.suite.apps/.project new file mode 100644 index 0000000..d71ff76 --- /dev/null +++ b/org.argeo.suite.apps/.project @@ -0,0 +1,28 @@ + + + org.argeo.suite.apps + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + diff --git a/org.argeo.suite.apps/META-INF/.gitignore b/org.argeo.suite.apps/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.suite.apps/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/org.argeo.suite.apps/META-INF/spring/backend-services.xml b/org.argeo.suite.apps/META-INF/spring/backend-services.xml new file mode 100644 index 0000000..3fdd310 --- /dev/null +++ b/org.argeo.suite.apps/META-INF/spring/backend-services.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.argeo.suite.apps/META-INF/spring/maintenance-services.xml b/org.argeo.suite.apps/META-INF/spring/maintenance-services.xml new file mode 100644 index 0000000..d4678f1 --- /dev/null +++ b/org.argeo.suite.apps/META-INF/spring/maintenance-services.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.argeo.suite.apps/META-INF/spring/osgi.xml b/org.argeo.suite.apps/META-INF/spring/osgi.xml new file mode 100644 index 0000000..de5e38e --- /dev/null +++ b/org.argeo.suite.apps/META-INF/spring/osgi.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.argeo.suite.apps/META-INF/spring/workbench-services.xml b/org.argeo.suite.apps/META-INF/spring/workbench-services.xml new file mode 100644 index 0000000..054a601 --- /dev/null +++ b/org.argeo.suite.apps/META-INF/spring/workbench-services.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.argeo.suite.apps/bnd.bnd b/org.argeo.suite.apps/bnd.bnd new file mode 100644 index 0000000..077a108 --- /dev/null +++ b/org.argeo.suite.apps/bnd.bnd @@ -0,0 +1,32 @@ +Require-Capability: cms.datamodel; filter:="(name=people)",\ +cms.datamodel; filter:="(name=documents)",\ +cms.datamodel; filter:="(name=tracker)" + +Bundle-Activator: org.argeo.suite.workbench.AsUiPlugin +Bundle-SymbolicName: org.argeo.suite.apps;singleton:=true +#Require-Bundle: org.eclipse.core.runtime,\ +# org.eclipse.rap.ui,\ +# org.eclipse.rap.ui.workbench +#Require-Bundle: org.eclipse.core.runtime,\ +#org.eclipse.core.commands + +Import-Package:\ +javax.jcr.nodetype,\ +javax.jcr.security,\ +org.argeo.cms,\ +org.argeo.cms.ui.workbench,\ +org.argeo.cms.ui.workbench.jcr,\ +org.argeo.connect,\ +org.argeo.activities,\ +org.argeo.activities.workbench.parts,\ +org.argeo.documents.workbench.parts,\ +org.argeo.people.workbench.rap.parts,\ +org.argeo.connect.resources,\ +org.argeo.connect.ui,\ +org.argeo.connect.workbench,\ +org.argeo.connect.workbench.util,\ +org.argeo.eclipse.spring,\ +org.argeo.node,\ +org.argeo.suite.workbench.rap,\ +org.argeo.util,\ +* \ No newline at end of file diff --git a/org.argeo.suite.apps/pom.xml b/org.argeo.suite.apps/pom.xml new file mode 100644 index 0000000..e62bfb4 --- /dev/null +++ b/org.argeo.suite.apps/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.1.14-SNAPSHOT + .. + + org.argeo.suite.apps + Default Deployment + jar + + + org.argeo.suite + org.argeo.suite.workbench.rap + 2.1.14-SNAPSHOT + + + org.argeo.suite + org.argeo.suite.web + 2.1.14-SNAPSHOT + + + + org.argeo.tp + argeo-tp-rap-e3 + ${version.argeo-tp} + pom + provided + + + + diff --git a/org.argeo.suite.cms/.classpath b/org.argeo.suite.cms/.classpath new file mode 100644 index 0000000..eca7bdb --- /dev/null +++ b/org.argeo.suite.cms/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.suite.cms/.gitignore b/org.argeo.suite.cms/.gitignore new file mode 100644 index 0000000..09e3bc9 --- /dev/null +++ b/org.argeo.suite.cms/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/org.argeo.suite.cms/.project b/org.argeo.suite.cms/.project new file mode 100644 index 0000000..159bcce --- /dev/null +++ b/org.argeo.suite.cms/.project @@ -0,0 +1,33 @@ + + + org.argeo.suite.cms + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.argeo.suite.cms/META-INF/.gitignore b/org.argeo.suite.cms/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.suite.cms/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/org.argeo.suite.cms/OSGI-INF/activitiesMaintenanceService.xml b/org.argeo.suite.cms/OSGI-INF/activitiesMaintenanceService.xml new file mode 100644 index 0000000..54f50d2 --- /dev/null +++ b/org.argeo.suite.cms/OSGI-INF/activitiesMaintenanceService.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/org.argeo.suite.cms/OSGI-INF/activitiesService.xml b/org.argeo.suite.cms/OSGI-INF/activitiesService.xml new file mode 100644 index 0000000..c84eaa2 --- /dev/null +++ b/org.argeo.suite.cms/OSGI-INF/activitiesService.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/org.argeo.suite.cms/OSGI-INF/documentsService.xml b/org.argeo.suite.cms/OSGI-INF/documentsService.xml new file mode 100644 index 0000000..c4cc045 --- /dev/null +++ b/org.argeo.suite.cms/OSGI-INF/documentsService.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.argeo.suite.cms/OSGI-INF/peopleMaintenanceService.xml b/org.argeo.suite.cms/OSGI-INF/peopleMaintenanceService.xml new file mode 100644 index 0000000..0b083cb --- /dev/null +++ b/org.argeo.suite.cms/OSGI-INF/peopleMaintenanceService.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/org.argeo.suite.cms/OSGI-INF/peopleService.xml b/org.argeo.suite.cms/OSGI-INF/peopleService.xml new file mode 100644 index 0000000..0286f7c --- /dev/null +++ b/org.argeo.suite.cms/OSGI-INF/peopleService.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/org.argeo.suite.cms/OSGI-INF/resourcesMaintenanceService.xml b/org.argeo.suite.cms/OSGI-INF/resourcesMaintenanceService.xml new file mode 100644 index 0000000..06b3ebf --- /dev/null +++ b/org.argeo.suite.cms/OSGI-INF/resourcesMaintenanceService.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/org.argeo.suite.cms/OSGI-INF/resourcesService.xml b/org.argeo.suite.cms/OSGI-INF/resourcesService.xml new file mode 100644 index 0000000..5f7bce1 --- /dev/null +++ b/org.argeo.suite.cms/OSGI-INF/resourcesService.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.argeo.suite.cms/OSGI-INF/systemAppService.xml b/org.argeo.suite.cms/OSGI-INF/systemAppService.xml new file mode 100644 index 0000000..fd7f32a --- /dev/null +++ b/org.argeo.suite.cms/OSGI-INF/systemAppService.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.argeo.suite.cms/OSGI-INF/systemMaintenanceService.xml b/org.argeo.suite.cms/OSGI-INF/systemMaintenanceService.xml new file mode 100644 index 0000000..01dfebd --- /dev/null +++ b/org.argeo.suite.cms/OSGI-INF/systemMaintenanceService.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/org.argeo.suite.cms/OSGI-INF/userManagerService.xml b/org.argeo.suite.cms/OSGI-INF/userManagerService.xml new file mode 100644 index 0000000..f568a05 --- /dev/null +++ b/org.argeo.suite.cms/OSGI-INF/userManagerService.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/org.argeo.suite.cms/bnd.bnd b/org.argeo.suite.cms/bnd.bnd new file mode 100644 index 0000000..f5c82d4 --- /dev/null +++ b/org.argeo.suite.cms/bnd.bnd @@ -0,0 +1,28 @@ +Bundle-ActivationPolicy: lazy +Service-Component: OSGI-INF/systemAppService.xml,\ +OSGI-INF/userManagerService.xml,\ +OSGI-INF/resourcesService.xml,\ +OSGI-INF/activitiesService.xml,\ +OSGI-INF/peopleService.xml,\ +OSGI-INF/documentsService.xml,\ +OSGI-INF/systemMaintenanceService.xml,\ +OSGI-INF/activitiesMaintenanceService.xml,\ +OSGI-INF/resourcesMaintenanceService.xml,\ +OSGI-INF/peopleMaintenanceService.xml + +Import-Package: javax.jcr,\ +javax.transaction,\ +org.osgi.service.useradmin,\ +org.argeo.connect,\ +org.argeo.activities,\ +org.argeo.people,\ +org.argeo.documents,\ +org.argeo.tracker,\ +org.argeo.connect.resources,\ +org.argeo.connect.core,\ +org.argeo.activities.core,\ +org.argeo.people.core,\ +org.argeo.documents.core,\ +org.argeo.tracker.core,\ +org.argeo.connect.resources.core,\ +* diff --git a/org.argeo.suite.cms/build.properties b/org.argeo.suite.cms/build.properties new file mode 100644 index 0000000..5833b74 --- /dev/null +++ b/org.argeo.suite.cms/build.properties @@ -0,0 +1,16 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/resourcesService.xml,\ + OSGI-INF/activitiesService.xml,\ + OSGI-INF/systemAppService.xml,\ + OSGI-INF/userManagerService.xml,\ + OSGI-INF/peopleService.xml,\ + OSGI-INF/systemMaintenanceService.xml,\ + OSGI-INF/activitiesMaintenanceService.xml,\ + OSGI-INF/resourcesMaintenanceService.xml,\ + OSGI-INF/peopleMaintenanceService.xml,\ + OSGI-INF/trackerService.xml,\ + OSGI-INF/documentsService.xml,\ + OSGI-INF/trackerMaintenanceService.xml +source.. = src/ diff --git a/org.argeo.suite.cms/pom.xml b/org.argeo.suite.cms/pom.xml new file mode 100644 index 0000000..b0a09dd --- /dev/null +++ b/org.argeo.suite.cms/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.1.14-SNAPSHOT + .. + + org.argeo.suite.cms + Suite Deployment + jar + + + org.argeo.connect + org.argeo.connect.core + ${version.argeo-connect} + + + diff --git a/org.argeo.suite.e4.rap/.classpath b/org.argeo.suite.e4.rap/.classpath new file mode 100644 index 0000000..eca7bdb --- /dev/null +++ b/org.argeo.suite.e4.rap/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.suite.e4.rap/.gitignore b/org.argeo.suite.e4.rap/.gitignore new file mode 100644 index 0000000..09e3bc9 --- /dev/null +++ b/org.argeo.suite.e4.rap/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/org.argeo.suite.e4.rap/.project b/org.argeo.suite.e4.rap/.project new file mode 100644 index 0000000..ab1169e --- /dev/null +++ b/org.argeo.suite.e4.rap/.project @@ -0,0 +1,33 @@ + + + org.argeo.suite.e4.rap + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.argeo.suite.e4.rap/META-INF/.gitignore b/org.argeo.suite.e4.rap/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.suite.e4.rap/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/org.argeo.suite.e4.rap/OSGI-INF/argeo-office-rap.xml b/org.argeo.suite.e4.rap/OSGI-INF/argeo-office-rap.xml new file mode 100644 index 0000000..74b518f --- /dev/null +++ b/org.argeo.suite.e4.rap/OSGI-INF/argeo-office-rap.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.argeo.suite.e4.rap/bnd.bnd b/org.argeo.suite.e4.rap/bnd.bnd new file mode 100644 index 0000000..e1c4e67 --- /dev/null +++ b/org.argeo.suite.e4.rap/bnd.bnd @@ -0,0 +1,10 @@ +Bundle-SymbolicName: org.argeo.suite.e4.rap;singleton:=true + +Service-Component: OSGI-INF/argeo-office-rap.xml + +Import-Package: org.argeo.node,\ +org.eclipse.swt,\ +org.eclipse.rap.rwt,\ +org.eclipse.rap.rwt.client,\ +org.argeo.cms.ui,\ +* diff --git a/org.argeo.suite.e4.rap/build.properties b/org.argeo.suite.e4.rap/build.properties new file mode 100644 index 0000000..8a9000c --- /dev/null +++ b/org.argeo.suite.e4.rap/build.properties @@ -0,0 +1,10 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/systemE4Service.xml,\ + OSGI-INF/activitiesE4Service.xml,\ + OSGI-INF/peopleE4Service.xml,\ + OSGI-INF/documentsE4Service.xml,\ + e4xmi/argeo-suite-rap-addons.e4xmi,\ + plugin.xml +source.. = src/ diff --git a/org.argeo.suite.e4.rap/e4xmi/argeo-suite-rap-addons.e4xmi b/org.argeo.suite.e4.rap/e4xmi/argeo-suite-rap-addons.e4xmi new file mode 100644 index 0000000..fe4dfc8 --- /dev/null +++ b/org.argeo.suite.e4.rap/e4xmi/argeo-suite-rap-addons.e4xmi @@ -0,0 +1,6 @@ + + + + + + diff --git a/org.argeo.suite.e4.rap/plugin.xml b/org.argeo.suite.e4.rap/plugin.xml new file mode 100644 index 0000000..27fe8b9 --- /dev/null +++ b/org.argeo.suite.e4.rap/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/org.argeo.suite.e4.rap/pom.xml b/org.argeo.suite.e4.rap/pom.xml new file mode 100644 index 0000000..66cd077 --- /dev/null +++ b/org.argeo.suite.e4.rap/pom.xml @@ -0,0 +1,34 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.1.14-SNAPSHOT + .. + + org.argeo.suite.e4.rap + Eclipse 4 RAP + jar + + + org.argeo.suite + org.argeo.suite.e4 + 2.1.14-SNAPSHOT + + + org.argeo.commons + org.argeo.cms.e4.rap + ${version.argeo-commons} + + + + + org.argeo.tp + argeo-tp-rap-e4 + ${version.argeo-tp} + pom + provided + + + diff --git a/org.argeo.suite.e4.rap/src/org/argeo/suite/e4/rap/ArgeoOffice.java b/org.argeo.suite.e4.rap/src/org/argeo/suite/e4/rap/ArgeoOffice.java new file mode 100644 index 0000000..3e13fe7 --- /dev/null +++ b/org.argeo.suite.e4.rap/src/org/argeo/suite/e4/rap/ArgeoOffice.java @@ -0,0 +1,16 @@ +package org.argeo.suite.e4.rap; + +import org.argeo.cms.e4.rap.CmsE4EntryPointFactory; + +public class ArgeoOffice extends CmsE4EntryPointFactory { + + public ArgeoOffice(String e4Xmi, String lifeCycleUri) { + super(e4Xmi, lifeCycleUri); + } + + public ArgeoOffice() { + super("org.argeo.suite.e4/e4xmi/argeo-office.e4xmi", + "bundleclass://org.argeo.suite.e4.rap/org.argeo.suite.e4.rap.ArgeoSuiteLoginLifecycle"); + } + +} diff --git a/org.argeo.suite.e4.rap/src/org/argeo/suite/e4/rap/ArgeoOfficeRapE4App.java b/org.argeo.suite.e4.rap/src/org/argeo/suite/e4/rap/ArgeoOfficeRapE4App.java new file mode 100644 index 0000000..f9180c7 --- /dev/null +++ b/org.argeo.suite.e4.rap/src/org/argeo/suite/e4/rap/ArgeoOfficeRapE4App.java @@ -0,0 +1,45 @@ +package org.argeo.suite.e4.rap; + +import java.util.Map; + +import org.argeo.cms.e4.rap.AbstractRapE4App; +import org.argeo.cms.util.BundleResourceLoader; +import org.eclipse.rap.e4.E4ApplicationConfig; +import org.eclipse.rap.rwt.RWT; +import org.eclipse.rap.rwt.application.Application; +import org.eclipse.rap.rwt.client.WebClient; +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; + +public class ArgeoOfficeRapE4App extends AbstractRapE4App { + private BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext(); + + public ArgeoOfficeRapE4App() { + setPageTitle("Argeo Office"); + setE4Xmi("org.argeo.suite.e4/e4xmi/argeo-office.e4xmi"); + setPath("/office"); + setLifeCycleUri("bundleclass://org.argeo.suite.e4.rap/org.argeo.suite.e4.rap.ArgeoSuiteLoginLifecycle"); + } + + @Override + protected void addEntryPoint(Application application, E4ApplicationConfig config, Map properties) { + // String theme ="org.argeo.theme.argeo2.office"; + String theme = RWT.DEFAULT_THEME_ID; + Bundle themeBundle = findTheme("org.argeo.theme.argeo2"); + // application.addStyleSheet(theme, "rap/office-rwt.css", new + // BundleResourceLoader(themeBundle)); + application.addStyleSheet(theme, "rap/office.css", new BundleResourceLoader(themeBundle)); + properties.put(WebClient.THEME_ID, theme); + String font = ""; + properties.put(WebClient.HEAD_HTML, font); + super.addEntryPoint(application, config, properties); + } + + Bundle findTheme(String symbolicName) { + for (Bundle b : bc.getBundles()) + if (symbolicName.equals(b.getSymbolicName())) + return b; + throw new RuntimeException("Theme bundle " + symbolicName + " not found"); + } +} diff --git a/org.argeo.suite.e4.rap/src/org/argeo/suite/e4/rap/ArgeoSuiteLoginLifecycle.java b/org.argeo.suite.e4.rap/src/org/argeo/suite/e4/rap/ArgeoSuiteLoginLifecycle.java new file mode 100644 index 0000000..f3145c3 --- /dev/null +++ b/org.argeo.suite.e4.rap/src/org/argeo/suite/e4/rap/ArgeoSuiteLoginLifecycle.java @@ -0,0 +1,71 @@ +package org.argeo.suite.e4.rap; + +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.security.auth.Subject; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.cms.e4.rap.CmsLoginLifecycle; +import org.argeo.connect.ui.SystemWorkbenchService; +import org.argeo.jcr.JcrUtils; + +public class ArgeoSuiteLoginLifecycle extends CmsLoginLifecycle { + private final static Log log = LogFactory.getLog(ArgeoSuiteLoginLifecycle.class); + @Inject + SystemWorkbenchService systemWorkbenchService; + + @Inject + @Named("(cn=home)") + Repository repository; + + @Override + protected void startupComplete() { + loadState(); + } + + @Override + protected void stateChanged() { + loadState(); + } + + private void loadState() { + String state = getState(); + // for the time being we systematically open a session, in order to make sure + // that home is initialised + Session session = null; + try { + Subject subject = getSubject(); + session = Subject.doAs(subject, new PrivilegedExceptionAction() { + + @Override + public Session run() throws PrivilegedActionException { + try { + return repository.login(); + } catch (RepositoryException e) { + throw new PrivilegedActionException(e); + } + } + + }); + if (state != null && state.startsWith("/")) { + if (state.startsWith("/")) { + Node node = session.getNode(state); + systemWorkbenchService.openEntityEditor(node); + } + } + } catch (RepositoryException | PrivilegedActionException e) { + log.error("Cannot load state " + state, e); + getBrowserNavigation().pushState("~", null); + } finally { + JcrUtils.logoutQuietly(session); + } + } +} diff --git a/org.argeo.suite.e4.rap/src/org/argeo/suite/e4/rap/RapMainShellAddon.java b/org.argeo.suite.e4.rap/src/org/argeo/suite/e4/rap/RapMainShellAddon.java new file mode 100644 index 0000000..4564e11 --- /dev/null +++ b/org.argeo.suite.e4.rap/src/org/argeo/suite/e4/rap/RapMainShellAddon.java @@ -0,0 +1,26 @@ +package org.argeo.suite.e4.rap; + +import javax.annotation.PostConstruct; + +import org.eclipse.e4.ui.model.application.MApplication; +import org.eclipse.e4.ui.model.application.ui.basic.MWindow; +import org.eclipse.e4.ui.workbench.modeling.EModelService; +import org.eclipse.swt.SWT; + +public class RapMainShellAddon { + private final static String STYLE_OVERRIDE = "styleOverride"; + private final static String SHELL_MAXIMIZED = "shellMaximized"; + + @PostConstruct + void init(EModelService modelService, MApplication application) { + MWindow window = (MWindow) modelService.find("org.argeo.suite.e4.trimmedwindow.main", application); + String currentStyle = window.getPersistedState().get(STYLE_OVERRIDE); + int style = 8; + if (currentStyle != null) { + style = Integer.parseInt(currentStyle); + } + style = style | SWT.NO_TRIM; + window.getPersistedState().put(STYLE_OVERRIDE, Integer.toString(style)); + window.getTags().add(SHELL_MAXIMIZED); + } +} diff --git a/org.argeo.suite.e4/.classpath b/org.argeo.suite.e4/.classpath new file mode 100644 index 0000000..eca7bdb --- /dev/null +++ b/org.argeo.suite.e4/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.suite.e4/.gitignore b/org.argeo.suite.e4/.gitignore new file mode 100644 index 0000000..09e3bc9 --- /dev/null +++ b/org.argeo.suite.e4/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/org.argeo.suite.e4/.project b/org.argeo.suite.e4/.project new file mode 100644 index 0000000..38541c0 --- /dev/null +++ b/org.argeo.suite.e4/.project @@ -0,0 +1,33 @@ + + + org.argeo.suite.e4 + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.argeo.suite.e4/META-INF/.gitignore b/org.argeo.suite.e4/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.suite.e4/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/org.argeo.suite.e4/OSGI-INF/activitiesE4Service.xml b/org.argeo.suite.e4/OSGI-INF/activitiesE4Service.xml new file mode 100644 index 0000000..f6eaccb --- /dev/null +++ b/org.argeo.suite.e4/OSGI-INF/activitiesE4Service.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/org.argeo.suite.e4/OSGI-INF/documentsE4Service.xml b/org.argeo.suite.e4/OSGI-INF/documentsE4Service.xml new file mode 100644 index 0000000..8cd25e0 --- /dev/null +++ b/org.argeo.suite.e4/OSGI-INF/documentsE4Service.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.argeo.suite.e4/OSGI-INF/l10n/bundle.properties b/org.argeo.suite.e4/OSGI-INF/l10n/bundle.properties new file mode 100644 index 0000000..37e5f5d --- /dev/null +++ b/org.argeo.suite.e4/OSGI-INF/l10n/bundle.properties @@ -0,0 +1,23 @@ +# Standard toolbar +save=Save +saveAll=Save all +closeAll=Close all +delete=Delete +exit=Exit +changePassword=Change password... + +# Dashboard perspective +dashboard=Dashboard +search=Search +documents=Documents + +# Folders perspective +folders=Folders + +# Commands +newEntity=New... +newTodo=New task + +# Editors +person=Person +organisation=Organisation diff --git a/org.argeo.suite.e4/OSGI-INF/l10n/bundle_ar.properties b/org.argeo.suite.e4/OSGI-INF/l10n/bundle_ar.properties new file mode 100644 index 0000000..115943f --- /dev/null +++ b/org.argeo.suite.e4/OSGI-INF/l10n/bundle_ar.properties @@ -0,0 +1,20 @@ +# Standard toolbar +save=\u062D\u0641\u0638 +saveAll=\u0627\u062D\u0641\u0638 \u0627\u0644\u0643\u0644 +closeAll=\u0623\u063A\u0644\u0642 \u0643\u0644 \u0634\u064A\u0621 +delete=\u062D\u0630\u0641 +exit=\u0649\u062E\u0631\u062C + +# Dashboard perspective +dashboard=\u0644\u0648\u062D\u0629 \u0627\u0644\u0642\u064A\u0627\u062F\u0629 +search=\u0627\u0643\u062A\u0634\u0641 +documents=\u0645\u0633\u062A\u0646\u062F\u0627\u062A + +# Folders perspective +folders=\u0645\u0644\u0641\u0627\u062A + +# Commands +newEntity=\u062E\u0644\u0642... +newTodo=\u0645\u0647\u0645\u0629 \u062C\u062F\u064A\u062F\u0629 + +# Editors diff --git a/org.argeo.suite.e4/OSGI-INF/l10n/bundle_de.properties b/org.argeo.suite.e4/OSGI-INF/l10n/bundle_de.properties new file mode 100644 index 0000000..fb12b59 --- /dev/null +++ b/org.argeo.suite.e4/OSGI-INF/l10n/bundle_de.properties @@ -0,0 +1,23 @@ +# Standard toolbar +save=Speichern +saveAll=Alles speichern +closeAll=Alles schließen +delete=Entfernen +exit=Verlassen +changePassword=Password ändern... + +# Dashboard perspective +dashboard=Dashboard +search=Suchen +documents=Dokumente + +# Folders perspective +folders=Ordner + +# Commands +newEntity=Neu... +newTodo=Neue Aufgabe + +# Editors +person=Person +organisation=Organisation diff --git a/org.argeo.suite.e4/OSGI-INF/l10n/bundle_fr.properties b/org.argeo.suite.e4/OSGI-INF/l10n/bundle_fr.properties new file mode 100644 index 0000000..4c44e5a --- /dev/null +++ b/org.argeo.suite.e4/OSGI-INF/l10n/bundle_fr.properties @@ -0,0 +1,23 @@ +# Standard toolbar +save=Sauver +saveAll=Tout sauver +closeAll=Tout fermer +delete=Supprimer +exit=Quitter +changePassword=Changer de mot de passe... + +# Dashboard perspective +dashboard=Dashboard +search=Recherche +documents=Documents + +# Folders perspective +folders=Fichiers + +# Commands +newEntity=Nouveau... +newTodo=Nouvelle tâche + +# Editors +person=Personne +organisation=Organisation diff --git a/org.argeo.suite.e4/OSGI-INF/peopleE4Service.xml b/org.argeo.suite.e4/OSGI-INF/peopleE4Service.xml new file mode 100644 index 0000000..5855f4a --- /dev/null +++ b/org.argeo.suite.e4/OSGI-INF/peopleE4Service.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/org.argeo.suite.e4/OSGI-INF/resourcesE4Service.xml b/org.argeo.suite.e4/OSGI-INF/resourcesE4Service.xml new file mode 100644 index 0000000..7617639 --- /dev/null +++ b/org.argeo.suite.e4/OSGI-INF/resourcesE4Service.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/org.argeo.suite.e4/OSGI-INF/systemE4Service.xml b/org.argeo.suite.e4/OSGI-INF/systemE4Service.xml new file mode 100644 index 0000000..c5be2de --- /dev/null +++ b/org.argeo.suite.e4/OSGI-INF/systemE4Service.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/org.argeo.suite.e4/bnd.bnd b/org.argeo.suite.e4/bnd.bnd new file mode 100644 index 0000000..5b76067 --- /dev/null +++ b/org.argeo.suite.e4/bnd.bnd @@ -0,0 +1,20 @@ +Bundle-ActivationPolicy: lazy +Service-Component: OSGI-INF/systemE4Service.xml,\ +OSGI-INF/resourcesE4Service.xml,\ +OSGI-INF/activitiesE4Service.xml,\ +OSGI-INF/peopleE4Service.xml,\ +OSGI-INF/documentsE4Service.xml + +Import-Package: org.eclipse.swt,\ +org.eclipse.core.commands.common,\ +javax.jcr.nodetype,\ +org.eclipse.e4.core.contexts,\ +org.argeo.connect.ui,\ +org.argeo.connect.e4,\ +org.argeo.connect.e4.handlers,\ +org.argeo.activities.e4,\ +org.argeo.people.e4,\ +org.argeo.people.e4.handlers,\ +org.argeo.documents.e4,\ +org.argeo.connect.e4.resources,\ +* diff --git a/org.argeo.suite.e4/build.properties b/org.argeo.suite.e4/build.properties new file mode 100644 index 0000000..afd6873 --- /dev/null +++ b/org.argeo.suite.e4/build.properties @@ -0,0 +1,9 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + OSGI-INF/,\ + e4xmi/,\ + plugin.xml,\ + e4xmi/argeo-suite-toolbars.e4xmi,\ + OSGI-INF/resourcesE4Service.xml +source.. = src/ diff --git a/org.argeo.suite.e4/e4xmi/argeo-office.e4xmi b/org.argeo.suite.e4/e4xmi/argeo-office.e4xmi new file mode 100644 index 0000000..3dd3dda --- /dev/null +++ b/org.argeo.suite.e4/e4xmi/argeo-office.e4xmi @@ -0,0 +1,142 @@ + + + + + shellMaximized + + + + + minimized + + + + + + + + + + + + + + + + + + + + + entityEditorArea + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + removeOnHide + + + + + + removeOnHide + + + + + + + + + + + + + ViewMenu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.argeo.suite.e4/e4xmi/argeo-wm.e4xmi b/org.argeo.suite.e4/e4xmi/argeo-wm.e4xmi new file mode 100644 index 0000000..e45f138 --- /dev/null +++ b/org.argeo.suite.e4/e4xmi/argeo-wm.e4xmi @@ -0,0 +1,42 @@ + + + + + shellMaximized + + + + + + + + + + + + + + + + + + + + + dataExplorer + + + + + + + + + + + + + + + + diff --git a/org.argeo.suite.e4/icons/argeo-icon-32.png b/org.argeo.suite.e4/icons/argeo-icon-32.png new file mode 100644 index 0000000..42dd206 Binary files /dev/null and b/org.argeo.suite.e4/icons/argeo-icon-32.png differ diff --git a/org.argeo.suite.e4/pom.xml b/org.argeo.suite.e4/pom.xml new file mode 100644 index 0000000..f99abe3 --- /dev/null +++ b/org.argeo.suite.e4/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.1.14-SNAPSHOT + .. + + org.argeo.suite.e4 + Eclipse 4 + jar + + + org.argeo.connect + org.argeo.connect.e4 + ${version.argeo-connect} + + + + + org.argeo.tp + argeo-tp-rap-e4 + ${version.argeo-tp} + pom + provided + + + diff --git a/org.argeo.suite.e4/src/org/argeo/suite/e4/ActiveFeature.java b/org.argeo.suite.e4/src/org/argeo/suite/e4/ActiveFeature.java new file mode 100644 index 0000000..24a17b0 --- /dev/null +++ b/org.argeo.suite.e4/src/org/argeo/suite/e4/ActiveFeature.java @@ -0,0 +1,17 @@ + +package org.argeo.suite.e4; + +import org.eclipse.e4.core.di.annotations.Evaluate; + +public class ActiveFeature { + + + public ActiveFeature() { + super(); + } + + @Evaluate + public boolean evaluate() { + return false; + } +} diff --git a/org.argeo.suite.e4/src/org/argeo/suite/e4/SuiteMsg.java b/org.argeo.suite.e4/src/org/argeo/suite/e4/SuiteMsg.java new file mode 100644 index 0000000..ad2d8bc --- /dev/null +++ b/org.argeo.suite.e4/src/org/argeo/suite/e4/SuiteMsg.java @@ -0,0 +1,7 @@ +package org.argeo.suite.e4; + +import org.argeo.cms.i18n.Localized; + +public enum SuiteMsg implements Localized { + newTodo; +} diff --git a/org.argeo.suite.e4/src/org/argeo/suite/e4/parts/AbstractSuiteDashboard.java b/org.argeo.suite.e4/src/org/argeo/suite/e4/parts/AbstractSuiteDashboard.java new file mode 100644 index 0000000..7aeb67b --- /dev/null +++ b/org.argeo.suite.e4/src/org/argeo/suite/e4/parts/AbstractSuiteDashboard.java @@ -0,0 +1,180 @@ +package org.argeo.suite.e4.parts; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.inject.Inject; +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.Session; + +import org.argeo.cms.ui.eclipse.forms.FormToolkit; +import org.argeo.cms.util.CmsUtils; +import org.argeo.connect.SystemAppService; +import org.argeo.connect.resources.ResourcesService; +import org.argeo.connect.ui.AppWorkbenchService; +import org.argeo.connect.ui.ConnectUiStyles; +import org.argeo.connect.ui.SystemWorkbenchService; +import org.argeo.connect.util.ConnectJcrUtils; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.jcr.JcrUtils; +import org.eclipse.e4.ui.di.Focus; +import org.eclipse.rap.rwt.RWT; +import org.eclipse.rap.rwt.client.service.BrowserNavigation; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; + +/** Generic dashboard for Argeo Suite applications */ +public abstract class AbstractSuiteDashboard { + // private final static Log log = + // LogFactory.getLog(AbstractSuiteDashboard.class); + + // DEPENDENCY INJECTION + @Inject + private Repository repository; + @Inject + private ResourcesService resourcesService; + @Inject + private SystemAppService systemAppService; + @Inject + private SystemWorkbenchService systemWorkbenchService; + + private Session session; + + // UI Objects + private FormToolkit toolkit; + + // RAP specific + private BrowserNavigation browserNavigation; + + public void init() { + session = ConnectJcrUtils.login(repository); + // updateTooltip(input); + } + + // private void updateTooltip(IEditorInput input) { + // if (input instanceof EntityEditorInput) { + // EntityEditorInput sei = (EntityEditorInput) input; + // sei.setTooltipText("My Dashboard"); + // } + // } + + /** + * Implementing classes must call super in order to create the correct form + * toolkit + */ + @PostConstruct + public void createPartControl(Composite parent) { + toolkit = new FormToolkit(Display.getCurrent()); + init(); + browserNavigation = RWT.getClient().getService(BrowserNavigation.class); + } + + // UTILS + protected Composite createGadgetCmp(Composite parent, int widthHint, int heightHint) { + Composite gadgetCmp = toolkit.createComposite(parent, SWT.BORDER); + GridData gd = new GridData(SWT.CENTER, SWT.CENTER, false, false); + gd.widthHint = widthHint; + gd.heightHint = heightHint; + gadgetCmp.setLayoutData(gd); + CmsUtils.style(gadgetCmp, ConnectUiStyles.GADGET_BOX); + return gadgetCmp; + } + + protected Composite createGadgetTitleCmp(Composite parent, String title) { + Composite titleCmp = toolkit.createComposite(parent, SWT.BACKGROUND | SWT.INHERIT_NONE); + CmsUtils.style(titleCmp, ConnectUiStyles.GADGET_HEADER); + titleCmp.setBackground(null); + GridData gd = new GridData(SWT.FILL, SWT.TOP, true, false); + titleCmp.setLayoutData(gd); + titleCmp.setLayout(new GridLayout()); + + Label titleLbl = toolkit.createLabel(titleCmp, title + " ", SWT.BOLD); + CmsUtils.style(titleLbl, ConnectUiStyles.GADGET_HEADER); + titleLbl.setBackground(null); + return titleCmp; + } + + protected Composite createGadgetBodyCmp(Composite parent) { + Composite bodyCmp = toolkit.createComposite(parent, SWT.BACKGROUND | SWT.INHERIT_NONE); + bodyCmp.setLayoutData(EclipseUiUtils.fillAll()); + bodyCmp.setLayout(new GridLayout()); + return bodyCmp; + } + + protected Link createOpenEntityEditorLink(final AppWorkbenchService peopleUiService, Composite parent, + final String label, final Node entity) { + Link link = new Link(parent, SWT.NONE); + link.setText("" + label + ""); + link.setLayoutData(EclipseUiUtils.fillWidth()); + link.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = 1L; + + @Override + public void widgetSelected(final SelectionEvent event) { + // Map params = new HashMap(); + // params.put(ConnectEditor.PARAM_JCR_ID, + // ConnectJcrUtils.getIdentifier(entity)); + // CommandUtils.callCommand(peopleUiService.getOpenEntityEditorCmdId(), params); + peopleUiService.openEntityEditor(entity); + } + }); + return link; + } + + // Life cycle + @PreDestroy + public void dispose() { + JcrUtils.logoutQuietly(session); + } + + @Focus + public void setFocus() { + browserNavigation.pushState("~", "Dashboard"); + } + + // Expose to implementing classes + protected Session getSession() { + return session; + } + + public ResourcesService getResourcesService() { + return resourcesService; + } + + protected SystemAppService getSystemAppService() { + return systemAppService; + } + + protected SystemWorkbenchService getSystemWorkbenchService() { + return systemWorkbenchService; + } + + protected FormToolkit getFormToolkit() { + return toolkit; + } + + /* DEPENDENCY INJECTION */ + // public void setRepository(Repository repository) { + // this.repository = repository; + // } + // + // public void setResourcesService(ResourcesService resourcesService) { + // this.resourcesService = resourcesService; + // } + // + // public void setSystemAppService(SystemAppService systemAppService) { + // this.systemAppService = systemAppService; + // } + // + // public void setSystemWorkbenchService(SystemWorkbenchService + // systemWorkbenchService) { + // this.systemWorkbenchService = systemWorkbenchService; + // } +} diff --git a/org.argeo.suite.e4/src/org/argeo/suite/e4/parts/DefaultDashboardEditor.java b/org.argeo.suite.e4/src/org/argeo/suite/e4/parts/DefaultDashboardEditor.java new file mode 100644 index 0000000..2061f14 --- /dev/null +++ b/org.argeo.suite.e4/src/org/argeo/suite/e4/parts/DefaultDashboardEditor.java @@ -0,0 +1,420 @@ +package org.argeo.suite.e4.parts; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.List; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.Property; +import javax.jcr.RepositoryException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.activities.ActivitiesNames; +import org.argeo.activities.ActivitiesService; +import org.argeo.activities.ActivitiesTypes; +import org.argeo.activities.ui.TaskViewerContextMenu; +import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.util.CmsUtils; +import org.argeo.connect.ConnectException; +import org.argeo.connect.ConnectNames; +import org.argeo.connect.ui.ConnectWorkbenchUtils; +import org.argeo.connect.ui.Refreshable; +import org.argeo.connect.util.ConnectJcrUtils; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.jcr.JcrUtils; +import org.argeo.node.NodeUtils; +import org.argeo.suite.e4.SuiteMsg; +import org.argeo.tracker.TrackerNames; +import org.argeo.tracker.TrackerService; +import org.argeo.tracker.core.TrackerUtils; +import org.argeo.tracker.ui.TaskListLabelProvider; +import org.argeo.tracker.ui.TaskVirtualListComposite; +import org.eclipse.e4.core.di.annotations.Optional; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; + +/** Argeo Suite Default Dashboard */ +public class DefaultDashboardEditor extends AbstractSuiteDashboard implements Refreshable { + final static Log log = LogFactory.getLog(DefaultDashboardEditor.class); + // public final static String ID = AsUiPlugin.PLUGIN_ID + + // ".defaultDashboardEditor"; + + @Inject + private ActivitiesService activitiesService; + + @Inject + @Optional + private TrackerService trackerService; + + private String datePattern = "dd MMM yyyy"; + + private Composite headerCmp; + private Composite taskListCmp; + private TaskVirtualListComposite tvlc; + + @PostConstruct + public void createPartControl(Composite parent) { + super.createPartControl(parent); + parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); + Composite bodyCmp = new Composite(parent, SWT.NO_FOCUS); + bodyCmp.setLayoutData(EclipseUiUtils.fillAll()); + bodyCmp.setLayout(new GridLayout()); + + headerCmp = new Composite(bodyCmp, SWT.NO_FOCUS); + headerCmp.setLayoutData(EclipseUiUtils.fillWidth()); + + taskListCmp = new Composite(bodyCmp, SWT.NO_FOCUS); + taskListCmp.setLayoutData(EclipseUiUtils.fillAll()); + forceRefresh(null); + } + + @Override + public void forceRefresh(Object object) { + CmsUtils.clear(headerCmp); + populateHeaderPart(headerCmp, NodeUtils.getUserHome(getSession())); + + CmsUtils.clear(taskListCmp); + populateTaskListCmp(taskListCmp); + + headerCmp.getParent().layout(true, true); + } + + private void populateTaskListCmp(Composite parent) { + parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); + NodeIterator nit = activitiesService.getMyTasks(getSession(), true); + if (!nit.hasNext()) { + Composite noTaskCmp = new Composite(parent, SWT.NO_FOCUS); + noTaskCmp.setLayoutData(EclipseUiUtils.fillAll()); + noTaskCmp.setLayout(new GridLayout()); + + // Label noTaskLbl = new Label(noTaskCmp, SWT.CENTER); + // noTaskLbl.setText(" You have no pending Task. "); + // CmsUtils.markup(noTaskLbl); + // noTaskLbl.setLayoutData(new GridData(SWT.CENTER, SWT.BOTTOM, true, true)); + + } else { + TaskListLabelProvider labelProvider = new TaskListLabelProvider(getSystemAppService()); + tvlc = new TaskVirtualListComposite(parent, SWT.NO_FOCUS, (ILabelProvider) labelProvider, 54); + tvlc.setLayoutData(EclipseUiUtils.fillAll()); + final TableViewer viewer = tvlc.getTableViewer(); + viewer.setInput(JcrUtils.nodeIteratorToList(nit).toArray()); + final TaskViewerContextMenu contextMenu = new TaskViewerContextMenu(viewer, getSession(), + activitiesService) { + @Override + public boolean performAction(String actionId) { + boolean hasChanged = super.performAction(actionId); + if (hasChanged) { + viewer.getTable().setFocus(); + forceRefresh(null); + // NodeIterator nit = + // activitiesService.getMyTasks(getSession(), true); + // viewer.setInput(JcrUtils.nodeIteratorToList(nit).toArray()); + } + return hasChanged; + } + }; + viewer.getTable().addMouseListener(new MouseAdapter() { + private static final long serialVersionUID = 6737579410648595940L; + + @Override + public void mouseDown(MouseEvent e) { + if (e.button == 3) { + // contextMenu.setCurrFolderPath(currDisplayedFolder); + contextMenu.show(viewer.getTable(), new Point(e.x, e.y), + (IStructuredSelection) viewer.getSelection()); + } + } + }); + viewer.addDoubleClickListener(new IDoubleClickListener() { + + @Override + public void doubleClick(DoubleClickEvent event) { + IStructuredSelection sel = (IStructuredSelection) viewer.getSelection(); + Node task = (Node) sel.getFirstElement(); + getSystemWorkbenchService().openEntityEditor(task); + } + }); + } + } + + private boolean isOverdue(Node node, String propName) { + try { + Calendar now = GregorianCalendar.getInstance(); + return node.hasProperty(propName) && node.getProperty(propName).getDate().before(now); + } catch (RepositoryException e) { + throw new ConnectException("Cannot check overdue status with property " + propName + " on " + node, e); + } + } + + private void populateHeaderPart(Composite bodyCmp, Node context) { + bodyCmp.setLayout(EclipseUiUtils.noSpaceGridLayout(new GridLayout(2, true))); + + Composite leftCmp = new Composite(bodyCmp, SWT.NO_FOCUS); + leftCmp.setLayout(new GridLayout()); + leftCmp.setLayoutData(EclipseUiUtils.fillWidth()); + Composite rightCmp = new Composite(bodyCmp, SWT.NO_FOCUS); + rightCmp.setLayout(new GridLayout()); + rightCmp.setLayoutData(EclipseUiUtils.fillWidth()); + + // Title + Label titleLbl = new Label(leftCmp, SWT.WRAP | SWT.LEAD); + CmsUtils.markup(titleLbl); + String titleStr = "" + CurrentUser.getDisplayName() + ""; + titleLbl.setText(titleStr); + GridData gd = new GridData(SWT.BEGINNING, SWT.TOP, false, false); + // gd.verticalIndent = 5; + // gd.horizontalIndent = 10; + titleLbl.setLayoutData(gd); + + final Link createTaskLk = new Link(leftCmp, SWT.CENTER); + // createTaskLk.setText("Create a task"); + createTaskLk.setText("" + SuiteMsg.newTodo.lead() + ""); + gd = new GridData(SWT.BEGINNING, SWT.TOP, false, false); + // gd.verticalIndent = 5; + gd.horizontalIndent = 10; + createTaskLk.setLayoutData(gd); + + createTaskLk.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = -9028457805156989935L; + + @Override + public void widgetSelected(SelectionEvent e) { + // String mainMixin = TrackerTypes.TRACKER_TASK; + String mainMixin = ActivitiesTypes.ACTIVITIES_TASK; + String pathCreated = ConnectWorkbenchUtils.createAndConfigureEntity(createTaskLk.getShell(), + getSession(), getSystemAppService(), getSystemWorkbenchService(), mainMixin); + if (EclipseUiUtils.notEmpty(pathCreated)) + forceRefresh(null); + } + }); + + NodeIterator nit = activitiesService.getMyTasks(getSession(), true); + if (nit.hasNext()) { + List overdueTasks = new ArrayList<>(); + while (nit.hasNext()) { + Node currNode = nit.nextNode(); + if (isOverdue(currNode, ActivitiesNames.ACTIVITIES_DUE_DATE)) + overdueTasks.add(currNode); + } + if (!overdueTasks.isEmpty()) { + Composite overdueCmp = new Composite(leftCmp, SWT.NO_FOCUS); + long size = overdueTasks.size(); + String overdueStr = "You have " + size + " overdue task" + (size > 1 ? "s" : "") + ": "; + populateMuliValueClickableList(overdueCmp, overdueTasks.toArray(new Node[0]), new TaskLp(), overdueStr); + } + } + + if (trackerService != null) { + nit = trackerService.getMyMilestones(getSession(), true); + List openMilestones = new ArrayList<>(); + + if (nit.hasNext()) { + List overdueMilestones = new ArrayList<>(); + while (nit.hasNext()) { + Node currNode = nit.nextNode(); + openMilestones.add(currNode); + if (isOverdue(currNode, TrackerNames.TRACKER_TARGET_DATE)) + overdueMilestones.add(currNode); + } + if (!overdueMilestones.isEmpty()) { + Composite overdueCmp = new Composite(leftCmp, SWT.NO_FOCUS); + long size = overdueMilestones.size(); + String overdueStr = "You have " + size + " overdue milestone" + (size > 1 ? "s" : "") + ": "; + populateMuliValueClickableList(overdueCmp, overdueMilestones.toArray(new Node[0]), + new MilestoneLp(), overdueStr); + } + } + + // My projects + List openProjects = JcrUtils.nodeIteratorToList(trackerService.getMyProjects(getSession(), true)); + if (!openProjects.isEmpty()) { + Group myProjectsGp = new Group(rightCmp, SWT.NO_FOCUS); + myProjectsGp.setText("My open projects"); + myProjectsGp.setLayoutData(EclipseUiUtils.fillWidth()); + populateMuliValueClickableList(myProjectsGp, openProjects.toArray(new Node[0]), new ProjectLp(), null); + } + + // My Milestones + if (!openMilestones.isEmpty()) { + Group myMilestoneGp = new Group(rightCmp, SWT.NO_FOCUS); + myMilestoneGp.setText("My open milestones"); + myMilestoneGp.setLayoutData(EclipseUiUtils.fillWidth()); + populateMuliValueClickableList(myMilestoneGp, openMilestones.toArray(new Node[0]), new MilestoneLp(), + null); + } + } + } + + private class ProjectLp extends ColumnLabelProvider { + private static final long serialVersionUID = 7231233932794865555L; + + @Override + public String getText(Object element) { + Node project = (Node) element; + + String percent; + NodeIterator nit = TrackerUtils.getIssues(project, null, null, null, true); + long openNb = nit.getSize(); + + nit = TrackerUtils.getIssues(project, null, null, null, false); + long allNb = nit.getSize(); + + if (allNb < 1) + percent = "empty"; + else { + double num = allNb - openNb; + double result = num / allNb * 100; + percent = String.format("%.1f", result) + "% done"; + } + StringBuilder builder = new StringBuilder(); + builder.append("").append(ConnectJcrUtils.get(project, Property.JCR_TITLE)).append(""); + builder.append(" (").append(percent).append(")"); + + return builder.toString(); + } + } + + private class MilestoneLp extends ColumnLabelProvider { + private static final long serialVersionUID = 7231233932794865555L; + + @Override + public String getText(Object element) { + Node milestone = (Node) element; + Node project = TrackerUtils.getRelatedProject(trackerService, milestone); + String dueDate = ConnectJcrUtils.getDateFormattedAsString(milestone, TrackerNames.TRACKER_TARGET_DATE, + datePattern); + + String percent; + String propName = TrackerNames.TRACKER_MILESTONE_UID; + String muid = ConnectJcrUtils.get(milestone, ConnectNames.CONNECT_UID); + NodeIterator nit = TrackerUtils.getIssues(project, null, propName, muid, true); + long openNb = nit.getSize(); + + nit = TrackerUtils.getIssues(project, null, propName, muid, false); + long allNb = nit.getSize(); + + if (allNb < 1) + percent = "empty"; + else { + double num = allNb - openNb; + double result = num / allNb * 100; + percent = String.format("%.1f", result) + "% done"; + } + StringBuilder builder = new StringBuilder(); + builder.append("").append(ConnectJcrUtils.get(milestone, Property.JCR_TITLE)).append(""); + builder.append(" ("); + if (EclipseUiUtils.notEmpty(dueDate)) + builder.append("due to ").append(dueDate).append(", "); + + builder.append(percent).append(")"); + return builder.toString(); + } + + @Override + public Color getForeground(Object element) { + Node milestone = (Node) element; + Calendar dueDate = ConnectJcrUtils.getDateValue(milestone, TrackerNames.TRACKER_TARGET_DATE); + if (dueDate != null && dueDate.before(Calendar.getInstance())) + return Display.getCurrent().getSystemColor(SWT.COLOR_RED); + return null; + } + } + + private class TaskLp extends ColumnLabelProvider { + private static final long serialVersionUID = 7231233932794865555L; + + @Override + public String getText(Object element) { + Node task = (Node) element; + String dueDate = ConnectJcrUtils.getDateFormattedAsString(task, ActivitiesNames.ACTIVITIES_DUE_DATE, + datePattern); + + StringBuilder builder = new StringBuilder(); + builder.append("").append(ConnectJcrUtils.get(task, Property.JCR_TITLE)).append(""); + if (EclipseUiUtils.notEmpty(dueDate)) + builder.append(" (").append("due to ").append(dueDate).append(")"); + return builder.toString(); + } + + @Override + public Color getForeground(Object element) { + Node milestone = (Node) element; + Calendar dueDate = ConnectJcrUtils.getDateValue(milestone, TrackerNames.TRACKER_TARGET_DATE); + if (dueDate != null && dueDate.before(Calendar.getInstance())) + return Display.getCurrent().getSystemColor(SWT.COLOR_RED); + return null; + } + } + + // public void setActivitiesService(ActivitiesService activitiesService) { + // this.activitiesService = activitiesService; + // } + // + // public void setTrackerService(TrackerService trackerService) { + // this.trackerService = trackerService; + // } + + // LOCAL HELPERS + private void populateMuliValueClickableList(Composite parent, Node[] nodes, ColumnLabelProvider lp, + String listLabel) { + CmsUtils.clear(parent); + RowLayout rl = new RowLayout(SWT.HORIZONTAL | SWT.WRAP); + rl.wrap = true; + rl.marginLeft = rl.marginTop = rl.marginBottom = 0; + rl.marginRight = 8; + parent.setLayout(rl); + + if (EclipseUiUtils.notEmpty(listLabel)) { + Link link = new Link(parent, SWT.NONE); + link.setText(listLabel); + link.setFont(EclipseUiUtils.getBoldFont(parent)); + } + + int i = 1; + for (Node node : nodes) { + Link link = new Link(parent, SWT.NONE); + CmsUtils.markup(link); + link.setText(lp.getText(node) + (i != nodes.length ? ", " : "")); + i++; + // Color fc = lp.getForeground(node); + // if (fc != null) + // link.setForeground(fc); + + link.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = 1L; + + @Override + public void widgetSelected(final SelectionEvent event) { + // CommandUtils.callCommand(getSystemWorkbenchService().getOpenEntityEditorCmdId(), + // ConnectEditor.PARAM_JCR_ID, ConnectJcrUtils.getIdentifier(node)); + getSystemWorkbenchService().openEntityEditor(node); + } + }); + } + } + +} diff --git a/org.argeo.suite.e4/src/org/argeo/suite/e4/parts/EntitySingleColumnLabelProvider.java b/org.argeo.suite.e4/src/org/argeo/suite/e4/parts/EntitySingleColumnLabelProvider.java new file mode 100644 index 0000000..c075574 --- /dev/null +++ b/org.argeo.suite.e4/src/org/argeo/suite/e4/parts/EntitySingleColumnLabelProvider.java @@ -0,0 +1,89 @@ +package org.argeo.suite.e4.parts; + +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.RepositoryException; +import javax.jcr.nodetype.NodeType; + +import org.argeo.activities.ActivitiesService; +import org.argeo.activities.ActivitiesTypes; +import org.argeo.activities.ui.ActivityListLabelProvider; +import org.argeo.connect.resources.ResourcesService; +import org.argeo.connect.ui.ConnectUiConstants; +import org.argeo.connect.ui.SystemWorkbenchService; +import org.argeo.connect.ui.util.TagLabelProvider; +import org.argeo.connect.util.ConnectUtils; +import org.argeo.people.PeopleException; +import org.argeo.people.PeopleNames; +import org.argeo.people.PeopleService; +import org.argeo.people.PeopleTypes; +import org.argeo.people.ui.providers.GroupLabelProvider; +import org.argeo.people.ui.providers.OrgListLabelProvider; +import org.argeo.people.ui.providers.PersonListLabelProvider; +import org.argeo.tracker.TrackerTypes; +import org.argeo.tracker.ui.TrackerSingleColLP; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.swt.graphics.Image; + +/** + * Provide a single column label provider for entity lists. Icon and displayed + * text vary with the element node type + */ +public class EntitySingleColumnLabelProvider extends ColumnLabelProvider implements PeopleNames { + private static final long serialVersionUID = 3111885324210673320L; + + private SystemWorkbenchService systemWorkbenchService; + + private ActivityListLabelProvider activityLP; + private TrackerSingleColLP trackerLP; + private OrgListLabelProvider orgLp; + private PersonListLabelProvider personLp; + private GroupLabelProvider groupLp = new GroupLabelProvider(ConnectUiConstants.LIST_TYPE_SMALL); + private TagLabelProvider mlInstanceLp; + + public EntitySingleColumnLabelProvider(ResourcesService resourceService, ActivitiesService activitiesService, + PeopleService peopleService, SystemWorkbenchService systemWorkbenchService) { + this.systemWorkbenchService = systemWorkbenchService; + activityLP = new ActivityListLabelProvider(activitiesService); + trackerLP = new TrackerSingleColLP(activitiesService); + personLp = new PersonListLabelProvider(peopleService); + orgLp = new OrgListLabelProvider(resourceService, peopleService); + mlInstanceLp = new TagLabelProvider(resourceService, ConnectUiConstants.LIST_TYPE_SMALL); + } + + @Override + public String getText(Object element) { + try { + Node entity = (Node) element; + String result; + + if (entity.isNodeType(TrackerTypes.TRACKER_TASK) || entity.isNodeType(TrackerTypes.TRACKER_PROJECT) + || entity.isNodeType(TrackerTypes.TRACKER_MILESTONE)) + result = trackerLP.getText(element); + else if (entity.isNodeType(ActivitiesTypes.ACTIVITIES_ACTIVITY)) + result = activityLP.getText(element); + else if (entity.isNodeType(PeopleTypes.PEOPLE_PERSON)) + result = personLp.getText(element); + else if (entity.isNodeType(PeopleTypes.PEOPLE_ORG)) + result = orgLp.getText(element); + else if (entity.isNodeType(PeopleTypes.PEOPLE_MAILING_LIST)) + result = mlInstanceLp.getText(element); + else if (entity.isNodeType(PeopleTypes.PEOPLE_GROUP)) + result = groupLp.getText(element); + else if (entity.isNodeType(NodeType.MIX_TITLE) && entity.hasProperty(Property.JCR_TITLE)) + result = entity.getProperty(Property.JCR_TITLE).getString(); + else + result = ""; + return ConnectUtils.replaceAmpersand(result); + } catch (RepositoryException re) { + throw new PeopleException("Unable to get formatted value for node", re); + } + } + + /** Overwrite this method to provide project specific images */ + @Override + public Image getImage(Object element) { + return systemWorkbenchService.getIconForType((Node) element); + } + +} diff --git a/org.argeo.suite.e4/src/org/argeo/suite/e4/parts/QuickSearchView.java b/org.argeo.suite.e4/src/org/argeo/suite/e4/parts/QuickSearchView.java new file mode 100644 index 0000000..99fd5cd --- /dev/null +++ b/org.argeo.suite.e4/src/org/argeo/suite/e4/parts/QuickSearchView.java @@ -0,0 +1,279 @@ +package org.argeo.suite.e4.parts; + +import static org.argeo.eclipse.ui.EclipseUiUtils.notEmpty; + +import java.util.List; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.inject.Inject; +import javax.jcr.NodeIterator; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.observation.Event; +import javax.jcr.observation.EventIterator; +import javax.jcr.observation.EventListener; +import javax.jcr.query.Query; +import javax.jcr.query.QueryResult; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.activities.ActivitiesService; +import org.argeo.cms.util.CmsUtils; +import org.argeo.connect.ConnectException; +import org.argeo.connect.ConnectTypes; +import org.argeo.connect.resources.ResourcesService; +import org.argeo.connect.ui.ConnectUiConstants; +import org.argeo.connect.ui.Refreshable; +import org.argeo.connect.ui.SystemWorkbenchService; +import org.argeo.connect.ui.util.BasicNodeListContentProvider; +import org.argeo.connect.ui.util.JcrViewerDClickListener; +import org.argeo.connect.ui.widgets.DelayedText; +import org.argeo.connect.util.ConnectJcrUtils; +import org.argeo.connect.util.XPathUtils; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.jcr.JcrUtils; +import org.argeo.people.PeopleService; +import org.eclipse.e4.ui.di.Focus; +import org.eclipse.e4.ui.workbench.modeling.ESelectionService; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; + +/** A table with a quick search field. */ +public class QuickSearchView implements Refreshable { + private final static Log log = LogFactory.getLog(QuickSearchView.class); + // public static final String ID = AsUiPlugin.PLUGIN_ID + ".quickSearchView"; + + /* DEPENDENCY INJECTION */ + @Inject + private Repository repository; + @Inject + private ResourcesService resourcesService; + @Inject + private ActivitiesService activitiesService; + @Inject + private PeopleService peopleService; + @Inject + private SystemWorkbenchService systemWorkbenchService; + + @Inject + private ESelectionService selectionService; + + // This page widgets + private TableViewer entityViewer; + private Text filterTxt; + + private Session session; + + // @Override + // public void init(IViewSite site) throws PartInitException { + // super.init(site); + // } + + @PostConstruct + public void createPartControl(Composite parent) { + session = ConnectJcrUtils.login(repository); + // MainLayout + parent.setLayout(new GridLayout()); + addFilterPanel(parent); + entityViewer = createListPart(parent, new EntitySingleColumnLabelProvider(resourcesService, activitiesService, + peopleService, systemWorkbenchService)); + refreshFilteredList(); + + try { + // new String[] { ConnectTypes.CONNECT_ENTITY } + session.getWorkspace().getObservationManager().addEventListener(new EventListener() { + + @Override + public void onEvent(EventIterator events) { + parent.getDisplay().asyncExec(() -> refreshFilteredList()); + } + }, Event.PROPERTY_CHANGED | Event.NODE_ADDED | Event.NODE_REMOVED | Event.PROPERTY_ADDED, "/", true, null, + null, false); + } catch (RepositoryException e) { + throw new ConnectException("Cannot add JCR observer", e); + } + + } + + private void addFilterPanel(Composite parent) { + // Use a delayed text: the query won't be done until the user stop + // typing for 800ms + int style = SWT.BORDER | SWT.SEARCH | SWT.ICON_CANCEL; + DelayedText delayedText = new DelayedText(parent, style, ConnectUiConstants.SEARCH_TEXT_DELAY); + filterTxt = delayedText.getText(); + filterTxt.setLayoutData(EclipseUiUtils.fillWidth()); + + // final ServerPushSession pushSession = new ServerPushSession(); + delayedText.addDelayedModifyListener(null, new ModifyListener() { + private static final long serialVersionUID = 5003010530960334977L; + + public void modifyText(ModifyEvent event) { + delayedText.getText().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + refreshFilteredList(); + } + }); + // pushSession.stop(); + } + }); + + // Jump to the first item of the list using the down arrow + filterTxt.addKeyListener(new KeyListener() { + private static final long serialVersionUID = -4523394262771183968L; + + @Override + public void keyReleased(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + // boolean shiftPressed = (e.stateMask & SWT.SHIFT) != 0; + // boolean altPressed = (e.stateMask & SWT.ALT) != 0; + if (e.keyCode == SWT.ARROW_DOWN || e.keyCode == SWT.TAB) { + Object first = entityViewer.getElementAt(0); + if (first != null) { + entityViewer.getTable().setFocus(); + entityViewer.setSelection(new StructuredSelection(first), true); + } + e.doit = false; + } + } + }); + } + + protected TableViewer createListPart(Composite parent, ILabelProvider labelProvider) { + parent.setLayout(new GridLayout()); + + Composite tableComposite = new Composite(parent, SWT.NONE); + GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_VERTICAL + | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); + tableComposite.setLayoutData(gd); + + TableViewer v = new TableViewer(tableComposite); + v.setLabelProvider(labelProvider); + + TableColumn singleColumn = new TableColumn(v.getTable(), SWT.V_SCROLL); + TableColumnLayout tableColumnLayout = new TableColumnLayout(); + tableColumnLayout.setColumnData(singleColumn, new ColumnWeightData(85)); + tableComposite.setLayout(tableColumnLayout); + + // Corresponding table & style + Table table = v.getTable(); + table.setLinesVisible(true); + table.setHeaderVisible(false); + CmsUtils.markup(table); + CmsUtils.setItemHeight(table, 26); + + v.setContentProvider(new BasicNodeListContentProvider()); + v.addDoubleClickListener(new JcrViewerDClickListener(systemWorkbenchService)); + v.addSelectionChangedListener(new ISelectionChangedListener() { + public void selectionChanged(SelectionChangedEvent event) { + IStructuredSelection selection = (IStructuredSelection) event.getSelection(); + List lst = selection.toList(); + if (lst != null && !lst.isEmpty()) + selectionService.setSelection(selection.toList()); + else + selectionService.setSelection(null); + } + }); + return v; + } + + @PreDestroy + public void dispose() { + JcrUtils.logoutQuietly(session); + } + + @Focus + public void setFocus() { + refreshFilteredList(); + filterTxt.setFocus(); + } + + @Override + public void forceRefresh(Object object) { + refreshFilteredList(); + } + + protected void refreshFilteredList() { + try { + String filter = filterTxt.getText(); + // Prevents the query on the full repository + // if (isEmpty(filter)) { + // entityViewer.setInput(null); + // return; + // } + + // XPATH Query + String xpathQueryStr = "//element(*, " + ConnectTypes.CONNECT_ENTITY + ")"; + String xpathFilter = XPathUtils.getFreeTextConstraint(filter); + if (notEmpty(xpathFilter)) + xpathQueryStr += "[" + xpathFilter + "]"; + + // boolean doOrder = orderResultsBtn != null + // && !(orderResultsBtn.isDisposed()) + // && orderResultsBtn.getSelection(); + // if (doOrder) { + // xpathQueryStr += " order by jcr:title"; + // } + + long begin = System.currentTimeMillis(); + // session.refresh(false); + Query xpathQuery = XPathUtils.createQuery(session, xpathQueryStr); + + xpathQuery.setLimit(ConnectUiConstants.SEARCH_DEFAULT_LIMIT); + QueryResult result = xpathQuery.execute(); + + NodeIterator nit = result.getNodes(); + entityViewer.setInput(JcrUtils.nodeIteratorToList(nit)); + if (log.isTraceEnabled()) { + long end = System.currentTimeMillis(); + log.trace("Quick Search - Found: " + nit.getSize() + " in " + (end - begin) + + " ms by executing XPath query (" + xpathQueryStr + ")."); + } + } catch (RepositoryException e) { + throw new ConnectException("Unable to list entities", e); + } + } + + // public void setRepository(Repository repository) { + // this.repository = repository; + // } + // + // public void setResourcesService(ResourcesService resourcesService) { + // this.resourcesService = resourcesService; + // } + // + // public void setActivitiesService(ActivitiesService activitiesService) { + // this.activitiesService = activitiesService; + // } + // + // public void setPeopleService(PeopleService peopleService) { + // this.peopleService = peopleService; + // } + // + // public void setSystemWorkbenchService(SystemWorkbenchService + // systemWorkbenchService) { + // this.systemWorkbenchService = systemWorkbenchService; + // } +} diff --git a/org.argeo.suite.standard/.classpath b/org.argeo.suite.standard/.classpath new file mode 100644 index 0000000..eca7bdb --- /dev/null +++ b/org.argeo.suite.standard/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.suite.standard/.gitignore b/org.argeo.suite.standard/.gitignore new file mode 100644 index 0000000..e0e1cc4 --- /dev/null +++ b/org.argeo.suite.standard/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target diff --git a/org.argeo.suite.standard/.project b/org.argeo.suite.standard/.project new file mode 100644 index 0000000..22ed203 --- /dev/null +++ b/org.argeo.suite.standard/.project @@ -0,0 +1,28 @@ + + + org.argeo.suite.standard + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.argeo.suite.standard/META-INF/.gitignore b/org.argeo.suite.standard/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.suite.standard/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/org.argeo.suite.standard/OSGI-INF/l10n/bundle.properties b/org.argeo.suite.standard/OSGI-INF/l10n/bundle.properties new file mode 100644 index 0000000..d58cc68 --- /dev/null +++ b/org.argeo.suite.standard/OSGI-INF/l10n/bundle.properties @@ -0,0 +1,7 @@ +# New entities +newTask=New task +newPerson=New person +newOrganisation=New organisation + +# Perspectives +folders=Folders diff --git a/org.argeo.suite.standard/OSGI-INF/l10n/bundle_ar.properties b/org.argeo.suite.standard/OSGI-INF/l10n/bundle_ar.properties new file mode 100644 index 0000000..b768c4a --- /dev/null +++ b/org.argeo.suite.standard/OSGI-INF/l10n/bundle_ar.properties @@ -0,0 +1,7 @@ +# New entities +newTask=\u0645\u0647\u0645\u0629 \u062C\u062F\u064A\u062F\u0629 +newPerson=\u0634\u062E\u0635 \u062C\u062F\u064A\u062F +newOrganisation=\u0645\u0646\u0638\u0645\u0629 \u062C\u062F\u064A\u062F\u0629 + +# Perspectives +folders=\u0645\u0644\u0641\u0627\u062A diff --git a/org.argeo.suite.standard/OSGI-INF/l10n/bundle_de.properties b/org.argeo.suite.standard/OSGI-INF/l10n/bundle_de.properties new file mode 100644 index 0000000..e76c1de --- /dev/null +++ b/org.argeo.suite.standard/OSGI-INF/l10n/bundle_de.properties @@ -0,0 +1,7 @@ +# New entities +newTask=Neue Aufgabe +newPerson=Neue Personne +newOrganisation=Neue Organisation + +# Perspectives +folders=Ordner diff --git a/org.argeo.suite.standard/OSGI-INF/l10n/bundle_fr.properties b/org.argeo.suite.standard/OSGI-INF/l10n/bundle_fr.properties new file mode 100644 index 0000000..76b98e8 --- /dev/null +++ b/org.argeo.suite.standard/OSGI-INF/l10n/bundle_fr.properties @@ -0,0 +1,4 @@ +# New entities +newTask=Nouvelle tâche +newPerson=Nouvelle personne +newOrganisation=Nouvelle organisation diff --git a/org.argeo.suite.standard/bnd.bnd b/org.argeo.suite.standard/bnd.bnd new file mode 100644 index 0000000..e2dbcd2 --- /dev/null +++ b/org.argeo.suite.standard/bnd.bnd @@ -0,0 +1,2 @@ +Bundle-SymbolicName: org.argeo.suite.standard;singleton:=true +Bundle-ActivationPolicy: lazy diff --git a/org.argeo.suite.standard/build.properties b/org.argeo.suite.standard/build.properties new file mode 100644 index 0000000..34d2e4d --- /dev/null +++ b/org.argeo.suite.standard/build.properties @@ -0,0 +1,4 @@ +source.. = src/ +output.. = bin/ +bin.includes = META-INF/,\ + . diff --git a/org.argeo.suite.standard/e4xmi/standard-toolbars.e4xmi b/org.argeo.suite.standard/e4xmi/standard-toolbars.e4xmi new file mode 100644 index 0000000..c88a7ba --- /dev/null +++ b/org.argeo.suite.standard/e4xmi/standard-toolbars.e4xmi @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.argeo.suite.standard/plugin.xml b/org.argeo.suite.standard/plugin.xml new file mode 100644 index 0000000..c4d9794 --- /dev/null +++ b/org.argeo.suite.standard/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/org.argeo.suite.standard/pom.xml b/org.argeo.suite.standard/pom.xml new file mode 100644 index 0000000..d9a252f --- /dev/null +++ b/org.argeo.suite.standard/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.1.14-SNAPSHOT + .. + + org.argeo.suite.standard + Standard Suite + jar + + + org.argeo.suite + org.argeo.suite.e4 + 2.1.14-SNAPSHOT + + + diff --git a/org.argeo.suite.tracker/.classpath b/org.argeo.suite.tracker/.classpath new file mode 100644 index 0000000..eca7bdb --- /dev/null +++ b/org.argeo.suite.tracker/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.suite.tracker/.gitignore b/org.argeo.suite.tracker/.gitignore new file mode 100644 index 0000000..09e3bc9 --- /dev/null +++ b/org.argeo.suite.tracker/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/org.argeo.suite.tracker/.project b/org.argeo.suite.tracker/.project new file mode 100644 index 0000000..e22cda3 --- /dev/null +++ b/org.argeo.suite.tracker/.project @@ -0,0 +1,28 @@ + + + org.argeo.suite.tracker + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.argeo.suite.tracker/.settings/org.eclipse.jdt.core.prefs b/org.argeo.suite.tracker/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..0c68a61 --- /dev/null +++ b/org.argeo.suite.tracker/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/org.argeo.suite.tracker/.settings/org.eclipse.pde.core.prefs b/org.argeo.suite.tracker/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 0000000..f29e940 --- /dev/null +++ b/org.argeo.suite.tracker/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/org.argeo.suite.tracker/META-INF/.gitignore b/org.argeo.suite.tracker/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.suite.tracker/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/org.argeo.suite.tracker/OSGI-INF/l10n/bundle.properties b/org.argeo.suite.tracker/OSGI-INF/l10n/bundle.properties new file mode 100644 index 0000000..b5a3127 --- /dev/null +++ b/org.argeo.suite.tracker/OSGI-INF/l10n/bundle.properties @@ -0,0 +1,3 @@ +newProjectTask=New project task +newMilestone=New milestone +newProject=New project diff --git a/org.argeo.suite.tracker/OSGI-INF/l10n/bundle_ar.properties b/org.argeo.suite.tracker/OSGI-INF/l10n/bundle_ar.properties new file mode 100644 index 0000000..799f9de --- /dev/null +++ b/org.argeo.suite.tracker/OSGI-INF/l10n/bundle_ar.properties @@ -0,0 +1,3 @@ +newProjectTask=\u0645\u0647\u0645\u0629 \u0645\u0634\u0631\u0648\u0639 \u062C\u062F\u064A\u062F +newMilestone=\u0645\u0639\u0644\u0645 \u062C\u062F\u064A\u062F +newProject=\u0645\u0634\u0631\u0648\u0639 \u062C\u062F\u064A\u062F diff --git a/org.argeo.suite.tracker/OSGI-INF/l10n/bundle_de.properties b/org.argeo.suite.tracker/OSGI-INF/l10n/bundle_de.properties new file mode 100644 index 0000000..d8c0482 --- /dev/null +++ b/org.argeo.suite.tracker/OSGI-INF/l10n/bundle_de.properties @@ -0,0 +1,3 @@ +newProjectTask=Neue Projektaufgabe +newMilestone=Neuer Meilenstein +newProject=Neues Projekt diff --git a/org.argeo.suite.tracker/OSGI-INF/l10n/bundle_fr.properties b/org.argeo.suite.tracker/OSGI-INF/l10n/bundle_fr.properties new file mode 100644 index 0000000..f1f61d5 --- /dev/null +++ b/org.argeo.suite.tracker/OSGI-INF/l10n/bundle_fr.properties @@ -0,0 +1,3 @@ +newProjectTask=Nouvelle tâche projet +newMilestone=Nouvelle étape +newProject=Nouveau projet diff --git a/org.argeo.suite.tracker/OSGI-INF/trackerE4Service.xml b/org.argeo.suite.tracker/OSGI-INF/trackerE4Service.xml new file mode 100644 index 0000000..f79ea3e --- /dev/null +++ b/org.argeo.suite.tracker/OSGI-INF/trackerE4Service.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/org.argeo.suite.tracker/OSGI-INF/trackerMaintenanceService.xml b/org.argeo.suite.tracker/OSGI-INF/trackerMaintenanceService.xml new file mode 100644 index 0000000..669f9c3 --- /dev/null +++ b/org.argeo.suite.tracker/OSGI-INF/trackerMaintenanceService.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/org.argeo.suite.tracker/OSGI-INF/trackerService.xml b/org.argeo.suite.tracker/OSGI-INF/trackerService.xml new file mode 100644 index 0000000..9cb2a0d --- /dev/null +++ b/org.argeo.suite.tracker/OSGI-INF/trackerService.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/org.argeo.suite.tracker/bnd.bnd b/org.argeo.suite.tracker/bnd.bnd new file mode 100644 index 0000000..17336a4 --- /dev/null +++ b/org.argeo.suite.tracker/bnd.bnd @@ -0,0 +1,14 @@ +Bundle-SymbolicName: org.argeo.suite.tracker;singleton:=true +Bundle-ActivationPolicy: lazy + +Service-Component: OSGI-INF/trackerService.xml,\ +OSGI-INF/trackerMaintenanceService.xml,\ +OSGI-INF/trackerE4Service.xml + +Import-Package: javax.jcr,\ +org.argeo.connect,\ +org.argeo.activities,\ +org.argeo.tracker,\ +org.argeo.tracker.core,\ +org.argeo.tracker.e4,\ +* diff --git a/org.argeo.suite.tracker/build.properties b/org.argeo.suite.tracker/build.properties new file mode 100644 index 0000000..995c040 --- /dev/null +++ b/org.argeo.suite.tracker/build.properties @@ -0,0 +1,6 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + e4xmi/,\ + plugin.xml +source.. = src/ diff --git a/org.argeo.suite.tracker/e4xmi/tracker-toolbars.e4xmi b/org.argeo.suite.tracker/e4xmi/tracker-toolbars.e4xmi new file mode 100644 index 0000000..b4bc319 --- /dev/null +++ b/org.argeo.suite.tracker/e4xmi/tracker-toolbars.e4xmi @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/org.argeo.suite.tracker/plugin.xml b/org.argeo.suite.tracker/plugin.xml new file mode 100644 index 0000000..96b3a7c --- /dev/null +++ b/org.argeo.suite.tracker/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/org.argeo.suite.tracker/pom.xml b/org.argeo.suite.tracker/pom.xml new file mode 100644 index 0000000..25409ea --- /dev/null +++ b/org.argeo.suite.tracker/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.1.14-SNAPSHOT + .. + + org.argeo.suite.tracker + Tracker + jar + + + org.argeo.suite + org.argeo.suite.e4 + 2.1.14-SNAPSHOT + + + diff --git a/org.argeo.suite.web/.classpath b/org.argeo.suite.web/.classpath new file mode 100644 index 0000000..191b71a --- /dev/null +++ b/org.argeo.suite.web/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.suite.web/.gitignore b/org.argeo.suite.web/.gitignore new file mode 100644 index 0000000..016bb39 --- /dev/null +++ b/org.argeo.suite.web/.gitignore @@ -0,0 +1,3 @@ +/target +/*.target +/bin/ diff --git a/org.argeo.suite.web/.project b/org.argeo.suite.web/.project new file mode 100644 index 0000000..69a0922 --- /dev/null +++ b/org.argeo.suite.web/.project @@ -0,0 +1,25 @@ + + + org.argeo.suite.web + + + + + + org.eclipse.jdt.core.javabuilder + + + + org.eclipse.pde.ManifestBuilder + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + diff --git a/org.argeo.suite.web/META-INF/.gitignore b/org.argeo.suite.web/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.suite.web/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/org.argeo.suite.web/bnd.bnd b/org.argeo.suite.web/bnd.bnd new file mode 100644 index 0000000..70d5711 --- /dev/null +++ b/org.argeo.suite.web/bnd.bnd @@ -0,0 +1,7 @@ +Import-Package:\ +javax.jcr.nodetype,\ +org.argeo.connect,\ +org.argeo.node,\ +javax.jcr.security,\ +org.eclipse.swt,\ +* diff --git a/org.argeo.suite.web/build.properties b/org.argeo.suite.web/build.properties new file mode 100644 index 0000000..3166058 --- /dev/null +++ b/org.argeo.suite.web/build.properties @@ -0,0 +1,3 @@ +source.. = src/ +output.. = bin/ + diff --git a/org.argeo.suite.web/pom.xml b/org.argeo.suite.web/pom.xml new file mode 100644 index 0000000..39f48a9 --- /dev/null +++ b/org.argeo.suite.web/pom.xml @@ -0,0 +1,29 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.1.14-SNAPSHOT + .. + + org.argeo.suite.web + Web UI + jar + + + org.argeo.connect + org.argeo.people.web + ${version.argeo-connect} + + + + org.argeo.tp + argeo-tp-rap-e4 + ${version.argeo-tp} + pom + provided + + + + diff --git a/org.argeo.suite.web/src/org/argeo/suite/web/DefaultDashboard.java b/org.argeo.suite.web/src/org/argeo/suite/web/DefaultDashboard.java new file mode 100644 index 0000000..d3692fd --- /dev/null +++ b/org.argeo.suite.web/src/org/argeo/suite/web/DefaultDashboard.java @@ -0,0 +1,99 @@ +package org.argeo.suite.web; + +import java.util.Map; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.ui.CmsUiProvider; +import org.argeo.cms.util.CmsUtils; +import org.argeo.connect.resources.ResourcesService; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.people.PeopleException; +import org.argeo.people.PeopleService; +import org.argeo.people.web.parts.PeopleSearchCmp; +import org.eclipse.jface.viewers.DoubleClickEvent; +import org.eclipse.jface.viewers.IDoubleClickListener; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.SashForm; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; + +/** Default dashboard layout for Argeo Suite */ +public class DefaultDashboard implements CmsUiProvider { + + private ResourcesService resourceService; + private PeopleService peopleService; + private Map peopleIconPaths; + + // Local UI Providers + // private CmsUiProvider orgPage; + + public DefaultDashboard(ResourcesService resourceService, PeopleService peopleService, Map peopleIconPaths) { + this.resourceService = resourceService; + this.peopleService = peopleService; + this.peopleIconPaths = peopleIconPaths; + + // orgPage = new OrgPage(peopleService); + } + + @Override + public Control createUi(Composite parent, Node context) throws RepositoryException { + parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); + SashForm form = new SashForm(parent, SWT.HORIZONTAL); + form.setLayoutData(EclipseUiUtils.fillAll()); + Composite leftPannelCmp = new Composite(form, SWT.NO_FOCUS); + Composite rightPannelCmp = new Composite(form, SWT.NO_FOCUS); + form.setWeights(new int[] { 2, 5 }); + + // A search on the left and the display on the right + populateSearch(leftPannelCmp, context, rightPannelCmp); + populateDefaultDisplay(rightPannelCmp, context); + + return form; + } + + public Viewer populateSearch(Composite parent, Node context, final Composite targetComposite) + throws RepositoryException { + parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); + Composite titleCmp = new Composite(parent, SWT.NO_FOCUS); + titleCmp.setLayoutData(EclipseUiUtils.fillWidth()); + titleCmp.setLayout(new GridLayout()); + Label titleLbl = new Label(titleCmp, SWT.CENTER); + titleLbl.setLayoutData(EclipseUiUtils.fillWidth()); + titleLbl.setText("My Tasks"); + titleLbl.setFont(EclipseUiUtils.getBoldFont(titleCmp)); + + PeopleSearchCmp searchComp = new PeopleSearchCmp(parent, SWT.NO_FOCUS, resourceService, peopleService, peopleIconPaths); + searchComp.populate(context, true); + searchComp.setLayoutData(EclipseUiUtils.fillAll()); + + TableViewer viewer = searchComp.getViewer(); + viewer.addDoubleClickListener(new IDoubleClickListener() { + @Override + public void doubleClick(DoubleClickEvent event) { + Object firstObj = ((IStructuredSelection) event.getSelection()).getFirstElement(); + try { + Node node = (Node) firstObj; + String path = node.getPath(); + CmsUtils.getCmsView().navigateTo(path); + } catch (RepositoryException e) { + throw new PeopleException("Unable to refresh display for " + context, e); + } + } + }); + return null; + } + + public Control populateDefaultDisplay(Composite parent, Node context) throws RepositoryException { + parent.setLayout(new GridLayout()); + Label lbl = new Label(parent, SWT.NONE); + lbl.setText("Implement a default display"); + return lbl; + } +} diff --git a/org.argeo.suite.web/src/org/argeo/suite/web/DefaultMainPage.java b/org.argeo.suite.web/src/org/argeo/suite/web/DefaultMainPage.java new file mode 100644 index 0000000..b84a653 --- /dev/null +++ b/org.argeo.suite.web/src/org/argeo/suite/web/DefaultMainPage.java @@ -0,0 +1,148 @@ +package org.argeo.suite.web; + +import java.nio.file.spi.FileSystemProvider; +import java.util.Locale; +import java.util.Map; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.nodetype.NodeType; + +import org.argeo.cms.CmsMsg; +import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.ui.CmsUiProvider; +import org.argeo.cms.ui.CmsView; +import org.argeo.cms.ui.LifeCycleUiProvider; +import org.argeo.cms.util.CmsUtils; +import org.argeo.cms.widgets.auth.CmsLogin; +import org.argeo.connect.AppMaintenanceService; +import org.argeo.connect.ConnectTypes; +import org.argeo.connect.resources.ResourcesService; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.people.PeopleService; +import org.argeo.people.PeopleTypes; +import org.argeo.people.web.pages.PeopleDefaultPage; +import org.argeo.suite.web.fs.MyFilesBrowserPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; + +/** + * Default entry point for the Argeo Suite CMS. Forwards the request to the + * relevant CmsUiProvider + */ +public class DefaultMainPage implements LifeCycleUiProvider { + + private CmsUiProvider dashboardPage; + private CmsUiProvider peoplePage; + private CmsUiProvider fsBrowserPage; + + /* DEPENDENCY INJECTION */ + private ResourcesService resourcesService; + private PeopleService peopleService; + private FileSystemProvider nodeFileSystemProvider; + private Map peopleIconPaths; + + public DefaultMainPage() { + } + + @Override + public void init(Session adminSession) throws RepositoryException { + dashboardPage = new DefaultDashboard(resourcesService, peopleService, peopleIconPaths); + peoplePage = new PeopleDefaultPage(resourcesService, peopleService, peopleIconPaths); + fsBrowserPage = new MyFilesBrowserPage(nodeFileSystemProvider); + } + + @Override + public Control createUi(Composite parent, Node context) throws RepositoryException { + if (CurrentUser.isAnonymous()) + return createAnonymousUi(parent, context); + + if (context.isNodeType(ConnectTypes.CONNECT_ENTITY)) + return peoplePage.createUi(parent, context); + else if (("/" + peopleService.getBaseRelPath(PeopleTypes.PEOPLE_PERSON)).equals(context.getPath())) + return peoplePage.createUi(parent, context); + else if (context.isNodeType(NodeType.NT_FOLDER) || context.isNodeType(NodeType.NT_FILE)) + return fsBrowserPage.createUi(parent, context); + else + return dashboardPage.createUi(parent, context); + } + + public Control createAnonymousUi(Composite parent, Node context) throws RepositoryException { + parent.setLayout(new GridLayout()); + Composite body = new Composite(parent, SWT.NO_FOCUS); + body.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true)); + body.setLayout(new GridLayout()); + + Composite loginCmp = new Composite(body, SWT.NO_FOCUS); + loginCmp.setLayout(EclipseUiUtils.noSpaceGridLayout()); + loginCmp.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true)); + + CmsLogin login = new MyCmsLogin(CmsUtils.getCmsView()); + // Composite credBlockCmp = + login.createCredentialsBlock(loginCmp); + // Use a custom style that has no border, among other + // CmsUtils.style(loginCmp, ArgeoStyles.LOGIN_INLINE_CREDBLOCK); + + Label anonymousLbl = new Label(body, SWT.WRAP); + anonymousLbl.setText("You should login or register to access your private dashboard"); + + return body; + + } + + private class MyCmsLogin extends CmsLogin { + + public MyCmsLogin(CmsView cmsView) { + super(cmsView); + } + + @Override + protected boolean login() { + boolean result = super.login(); + return result; + } + + @Override + protected void extendsCredentialsBlock(Composite credentialsBlock, Locale selectedLocale, + SelectionListener loginSelectionListener) { + Button loginBtn = new Button(credentialsBlock, SWT.PUSH); + loginBtn.setText(CmsMsg.login.lead(selectedLocale)); + loginBtn.setLayoutData(CmsUtils.fillWidth()); + loginBtn.addSelectionListener(loginSelectionListener); + // CmsUtils.style(loginBtn, ArgeoStyles.LOGIN_SIGNIN_BTN); + } + } + + @Override + public void destroy() { + } + + /* DEPENDENCY INJECTION */ + public void setResourcesService(ResourcesService resourcesService) { + this.resourcesService = resourcesService; + } + + public void setPeopleService(PeopleService peopleService) { + this.peopleService = peopleService; + } + + public void setNodeFileSystemProvider(FileSystemProvider nodeFileSystemProvider) { + this.nodeFileSystemProvider = nodeFileSystemProvider; + } + + public void setPeopleIconPaths(Map peopleIconPaths) { + this.peopleIconPaths = peopleIconPaths; + } + + // Only used has a blocker. + public void setSuiteMaintenanceService(AppMaintenanceService suiteMaintenanceService) { + } + +} diff --git a/org.argeo.suite.web/src/org/argeo/suite/web/DynamicHeader.java b/org.argeo.suite.web/src/org/argeo/suite/web/DynamicHeader.java new file mode 100644 index 0000000..775a63d --- /dev/null +++ b/org.argeo.suite.web/src/org/argeo/suite/web/DynamicHeader.java @@ -0,0 +1,35 @@ +package org.argeo.suite.web; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.ui.CmsUiProvider; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +/** + * Choose between possible headers depending on the client logged-in status and + * display type. + */ +public class DynamicHeader implements CmsUiProvider { + + private CmsUiProvider publicHeaderProvider; + private CmsUiProvider privateHeaderProvider; + + @Override + public Control createUi(Composite parent, Node context) throws RepositoryException { + if (CurrentUser.isAnonymous()) + return publicHeaderProvider.createUi(parent, context); + else + return privateHeaderProvider.createUi(parent, context); + } + + public void setPrivateHeaderProvider(CmsUiProvider privateHeaderProvider) { + this.privateHeaderProvider = privateHeaderProvider; + } + + public void setPublicHeaderProvider(CmsUiProvider publicHeaderProvider) { + this.publicHeaderProvider = publicHeaderProvider; + } +} diff --git a/org.argeo.suite.web/src/org/argeo/suite/web/fs/MyFilesBrowserPage.java b/org.argeo.suite.web/src/org/argeo/suite/web/fs/MyFilesBrowserPage.java new file mode 100644 index 0000000..cb4bdba --- /dev/null +++ b/org.argeo.suite.web/src/org/argeo/suite/web/fs/MyFilesBrowserPage.java @@ -0,0 +1,40 @@ +package org.argeo.suite.web.fs; + +import java.nio.file.spi.FileSystemProvider; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; + +import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.ui.CmsUiProvider; +import org.argeo.cms.ui.fs.CmsFsBrowser; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; + +/** Default file browser page for the CMS */ +public class MyFilesBrowserPage implements CmsUiProvider { + + private FileSystemProvider nodeFileSystemProvider; + + public MyFilesBrowserPage(FileSystemProvider nodeFileSystemProvider) { + this.nodeFileSystemProvider = nodeFileSystemProvider; + } + + @Override + public Control createUi(Composite parent, Node context) throws RepositoryException { + parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); + + if (CurrentUser.isAnonymous()) + // TODO implement public file display + return null; + + CmsFsBrowser browser = new CmsFsBrowser(parent, SWT.NO_FOCUS, context, nodeFileSystemProvider); + browser.setLayoutData(EclipseUiUtils.fillAll()); + + // TODO set input on the default home folder parent for one user's + // files + return browser; + } +} diff --git a/org.argeo.suite.workbench.rap/.classpath b/org.argeo.suite.workbench.rap/.classpath new file mode 100644 index 0000000..1ef7358 --- /dev/null +++ b/org.argeo.suite.workbench.rap/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.argeo.suite.workbench.rap/.gitignore b/org.argeo.suite.workbench.rap/.gitignore new file mode 100644 index 0000000..09e3bc9 --- /dev/null +++ b/org.argeo.suite.workbench.rap/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/org.argeo.suite.workbench.rap/.project b/org.argeo.suite.workbench.rap/.project new file mode 100644 index 0000000..4c4c4ff --- /dev/null +++ b/org.argeo.suite.workbench.rap/.project @@ -0,0 +1,28 @@ + + + org.argeo.suite.workbench.rap + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + + diff --git a/org.argeo.suite.workbench.rap/META-INF/.gitignore b/org.argeo.suite.workbench.rap/META-INF/.gitignore new file mode 100644 index 0000000..4854a41 --- /dev/null +++ b/org.argeo.suite.workbench.rap/META-INF/.gitignore @@ -0,0 +1 @@ +/MANIFEST.MF diff --git a/org.argeo.suite.workbench.rap/META-INF/spring/osgi.xml b/org.argeo.suite.workbench.rap/META-INF/spring/osgi.xml new file mode 100644 index 0000000..8f2cd1b --- /dev/null +++ b/org.argeo.suite.workbench.rap/META-INF/spring/osgi.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + diff --git a/org.argeo.suite.workbench.rap/META-INF/spring/parts.xml b/org.argeo.suite.workbench.rap/META-INF/spring/parts.xml new file mode 100644 index 0000000..d67695a --- /dev/null +++ b/org.argeo.suite.workbench.rap/META-INF/spring/parts.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.argeo.suite.workbench.rap/OSGI-INF/l10n/bundle.properties b/org.argeo.suite.workbench.rap/OSGI-INF/l10n/bundle.properties new file mode 100644 index 0000000..8c4ac22 --- /dev/null +++ b/org.argeo.suite.workbench.rap/OSGI-INF/l10n/bundle.properties @@ -0,0 +1 @@ +search=Search \ No newline at end of file diff --git a/org.argeo.suite.workbench.rap/OSGI-INF/l10n/bundle_de.properties b/org.argeo.suite.workbench.rap/OSGI-INF/l10n/bundle_de.properties new file mode 100644 index 0000000..3ec4305 --- /dev/null +++ b/org.argeo.suite.workbench.rap/OSGI-INF/l10n/bundle_de.properties @@ -0,0 +1 @@ +search=Finden \ No newline at end of file diff --git a/org.argeo.suite.workbench.rap/bnd.bnd b/org.argeo.suite.workbench.rap/bnd.bnd new file mode 100644 index 0000000..07ba246 --- /dev/null +++ b/org.argeo.suite.workbench.rap/bnd.bnd @@ -0,0 +1,39 @@ +Bundle-Activator: org.argeo.suite.workbench.AsUiPlugin +Bundle-SymbolicName: org.argeo.suite.workbench.rap;singleton:=true +#Require-Bundle: org.eclipse.core.runtime,\ +# org.eclipse.rap.ui,\ +# org.eclipse.rap.ui.workbench +Require-Bundle: org.eclipse.core.runtime,\ +org.eclipse.core.commands + +Bundle-ActivationPolicy: lazy + +Import-Package:\ +javax.jcr.nodetype,\ +javax.jcr.security,\ +org.eclipse.core.runtime.jobs,\ +org.eclipse.jface.window,\ +org.eclipse.jface.dialogs,\ +org.eclipse.swt,\ +org.eclipse.swt.widgets,\ +org.eclipse.ui.services,\ +org.argeo.activities,\ +org.argeo.activities.workbench.parts,\ +org.argeo.cms,\ +org.argeo.cms.ui.workbench,\ +org.argeo.cms.ui.workbench.jcr,\ +org.argeo.connect,\ +org.argeo.connect.resources,\ +org.argeo.connect.ui,\ +org.argeo.connect.ui.widgets,\ +org.argeo.connect.workbench.commands,\ +org.argeo.connect.workbench,\ +org.argeo.connect.workbench.util,\ +org.argeo.documents.workbench.parts,\ +org.argeo.eclipse.spring,\ +org.argeo.people.workbench.rap.parts,\ +org.argeo.node,\ +org.argeo.util,\ +jxl.*;resolution:=optional,\ +org.argeo.cms.ui.workbench.rap;resolution:=optional,\ +* \ No newline at end of file diff --git a/org.argeo.suite.workbench.rap/css/headerExt.css b/org.argeo.suite.workbench.rap/css/headerExt.css new file mode 100644 index 0000000..0ddeccb --- /dev/null +++ b/org.argeo.suite.workbench.rap/css/headerExt.css @@ -0,0 +1,15 @@ +/****************************************** +** Argeo Suite additional header ** +******************************************/ + +/* Force the addition of global styles to the application header */ + +/*** Override default links **/ +a:link { + color: #333333; + text-decoration:none; +} + +a:hover { + text-decoration:underline; +} diff --git a/org.argeo.suite.workbench.rap/icons/more.gif b/org.argeo.suite.workbench.rap/icons/more.gif new file mode 100644 index 0000000..57ad089 Binary files /dev/null and b/org.argeo.suite.workbench.rap/icons/more.gif differ diff --git a/org.argeo.suite.workbench.rap/icons/upload.gif b/org.argeo.suite.workbench.rap/icons/upload.gif new file mode 100644 index 0000000..d38085a Binary files /dev/null and b/org.argeo.suite.workbench.rap/icons/upload.gif differ diff --git a/org.argeo.suite.workbench.rap/img/favicon.ico b/org.argeo.suite.workbench.rap/img/favicon.ico new file mode 100644 index 0000000..6e6a050 Binary files /dev/null and b/org.argeo.suite.workbench.rap/img/favicon.ico differ diff --git a/org.argeo.suite.workbench.rap/img/logo-argeo.png b/org.argeo.suite.workbench.rap/img/logo-argeo.png new file mode 100644 index 0000000..f107230 Binary files /dev/null and b/org.argeo.suite.workbench.rap/img/logo-argeo.png differ diff --git a/org.argeo.suite.workbench.rap/js/Chart.min.js b/org.argeo.suite.workbench.rap/js/Chart.min.js new file mode 100644 index 0000000..090a9bd --- /dev/null +++ b/org.argeo.suite.workbench.rap/js/Chart.min.js @@ -0,0 +1,14 @@ +/*! + * Chart.js + * http://chartjs.org/ + * Version: 2.5.0 + * + * Copyright 2017 Nick Downie + * Released under the MIT license + * https://github.com/chartjs/Chart.js/blob/master/LICENSE.md + */ +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Chart=t()}}(function(){return function t(e,a,i){function n(r,s){if(!a[r]){if(!e[r]){var l="function"==typeof require&&require;if(!s&&l)return l(r,!0);if(o)return o(r,!0);var u=new Error("Cannot find module '"+r+"'");throw u.code="MODULE_NOT_FOUND",u}var d=a[r]={exports:{}};e[r][0].call(d.exports,function(t){var a=e[r][1][t];return n(a?a:t)},d,d.exports,t,e,a,i)}return a[r].exports}for(var o="function"==typeof require&&require,r=0;ra?(e+.05)/(a+.05):(a+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb,e=(299*t[0]+587*t[1]+114*t[2])/1e3;return e<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,a=(e[0]+t)%360;return e[0]=a<0?360+a:a,this.setValues("hsl",e),this},mix:function(t,e){var a=this,i=t,n=void 0===e?.5:e,o=2*n-1,r=a.alpha()-i.alpha(),s=((o*r===-1?o:(o+r)/(1+o*r))+1)/2,l=1-s;return this.rgb(s*a.red()+l*i.red(),s*a.green()+l*i.green(),s*a.blue()+l*i.blue()).alpha(a.alpha()*n+i.alpha()*(1-n))},toJSON:function(){return this.rgb()},clone:function(){var t,e,a=new o,i=this.values,n=a.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],e={}.toString.call(t),"[object Array]"===e?n[r]=t.slice(0):"[object Number]"===e?n[r]=t:console.error("unexpected color value:",t));return a}},o.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},o.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},o.prototype.getValues=function(t){for(var e=this.values,a={},i=0;i.04045?Math.pow((e+.055)/1.055,2.4):e/12.92,a=a>.04045?Math.pow((a+.055)/1.055,2.4):a/12.92,i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92;var n=.4124*e+.3576*a+.1805*i,o=.2126*e+.7152*a+.0722*i,r=.0193*e+.1192*a+.9505*i;return[100*n,100*o,100*r]}function d(t){var e,a,i,n=u(t),o=n[0],r=n[1],s=n[2];return o/=95.047,r/=100,s/=108.883,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,s=s>.008856?Math.pow(s,1/3):7.787*s+16/116,e=116*r-16,a=500*(o-r),i=200*(r-s),[e,a,i]}function c(t){return z(d(t))}function h(t){var e,a,i,n,o,r=t[0]/360,s=t[1]/100,l=t[2]/100;if(0==s)return o=255*l,[o,o,o];a=l<.5?l*(1+s):l+s-l*s,e=2*l-a,n=[0,0,0];for(var u=0;u<3;u++)i=r+1/3*-(u-1),i<0&&i++,i>1&&i--,o=6*i<1?e+6*(a-e)*i:2*i<1?a:3*i<2?e+(a-e)*(2/3-i)*6:e,n[u]=255*o;return n}function f(t){var e,a,i=t[0],n=t[1]/100,o=t[2]/100;return 0===o?[0,0,0]:(o*=2,n*=o<=1?o:2-o,a=(o+n)/2,e=2*n/(o+n),[i,100*e,100*a])}function p(t){return o(h(t))}function m(t){return s(h(t))}function v(t){return l(h(t))}function x(t){var e=t[0]/60,a=t[1]/100,i=t[2]/100,n=Math.floor(e)%6,o=e-Math.floor(e),r=255*i*(1-a),s=255*i*(1-a*o),l=255*i*(1-a*(1-o)),i=255*i;switch(n){case 0:return[i,l,r];case 1:return[s,i,r];case 2:return[r,i,l];case 3:return[r,s,i];case 4:return[l,r,i];case 5:return[i,r,s]}}function y(t){var e,a,i=t[0],n=t[1]/100,o=t[2]/100;return a=(2-n)*o,e=n*o,e/=a<=1?a:2-a,e=e||0,a/=2,[i,100*e,100*a]}function k(t){return o(x(t))}function S(t){return s(x(t))}function M(t){return l(x(t))}function w(t){var e,a,i,n,o=t[0]/360,s=t[1]/100,l=t[2]/100,u=s+l;switch(u>1&&(s/=u,l/=u),e=Math.floor(6*o),a=1-l,i=6*o-e,0!=(1&e)&&(i=1-i),n=s+i*(a-s),e){default:case 6:case 0:r=a,g=n,b=s;break;case 1:r=n,g=a,b=s;break;case 2:r=s,g=a,b=n;break;case 3:r=s,g=n,b=a;break;case 4:r=n,g=s,b=a;break;case 5:r=a,g=s,b=n}return[255*r,255*g,255*b]}function C(t){return i(w(t))}function I(t){return n(w(t))}function D(t){return s(w(t))}function A(t){return l(w(t))}function T(t){var e,a,i,n=t[0]/100,o=t[1]/100,r=t[2]/100,s=t[3]/100;return e=1-Math.min(1,n*(1-s)+s),a=1-Math.min(1,o*(1-s)+s),i=1-Math.min(1,r*(1-s)+s),[255*e,255*a,255*i]}function P(t){return i(T(t))}function _(t){return n(T(t))}function F(t){return o(T(t))}function V(t){return l(T(t))}function R(t){var e,a,i,n=t[0]/100,o=t[1]/100,r=t[2]/100;return e=3.2406*n+o*-1.5372+r*-.4986,a=n*-.9689+1.8758*o+.0415*r,i=.0557*n+o*-.204+1.057*r,e=e>.0031308?1.055*Math.pow(e,1/2.4)-.055:e*=12.92,a=a>.0031308?1.055*Math.pow(a,1/2.4)-.055:a*=12.92,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:i*=12.92,e=Math.min(Math.max(0,e),1),a=Math.min(Math.max(0,a),1),i=Math.min(Math.max(0,i),1),[255*e,255*a,255*i]}function O(t){var e,a,i,n=t[0],o=t[1],r=t[2];return n/=95.047,o/=100,r/=108.883,n=n>.008856?Math.pow(n,1/3):7.787*n+16/116,o=o>.008856?Math.pow(o,1/3):7.787*o+16/116,r=r>.008856?Math.pow(r,1/3):7.787*r+16/116,e=116*o-16,a=500*(n-o),i=200*(o-r),[e,a,i]}function L(t){return z(O(t))}function B(t){var e,a,i,n,o=t[0],r=t[1],s=t[2];return o<=8?(a=100*o/903.3,n=7.787*(a/100)+16/116):(a=100*Math.pow((o+16)/116,3),n=Math.pow(a/100,1/3)),e=e/95.047<=.008856?e=95.047*(r/500+n-16/116)/7.787:95.047*Math.pow(r/500+n,3),i=i/108.883<=.008859?i=108.883*(n-s/200-16/116)/7.787:108.883*Math.pow(n-s/200,3),[e,a,i]}function z(t){var e,a,i,n=t[0],o=t[1],r=t[2];return e=Math.atan2(r,o),a=360*e/2/Math.PI,a<0&&(a+=360),i=Math.sqrt(o*o+r*r),[n,i,a]}function W(t){return R(B(t))}function N(t){var e,a,i,n=t[0],o=t[1],r=t[2];return i=r/360*2*Math.PI,e=o*Math.cos(i),a=o*Math.sin(i),[n,e,a]}function E(t){return B(N(t))}function H(t){return W(N(t))}function j(t){return G[t]}function U(t){return i(j(t))}function q(t){return n(j(t))}function Y(t){return o(j(t))}function X(t){return s(j(t))}function K(t){return d(j(t))}function J(t){return u(j(t))}e.exports={rgb2hsl:i,rgb2hsv:n,rgb2hwb:o,rgb2cmyk:s,rgb2keyword:l,rgb2xyz:u,rgb2lab:d,rgb2lch:c,hsl2rgb:h,hsl2hsv:f,hsl2hwb:p,hsl2cmyk:m,hsl2keyword:v,hsv2rgb:x,hsv2hsl:y,hsv2hwb:k,hsv2cmyk:S,hsv2keyword:M,hwb2rgb:w,hwb2hsl:C,hwb2hsv:I,hwb2cmyk:D,hwb2keyword:A,cmyk2rgb:T,cmyk2hsl:P,cmyk2hsv:_,cmyk2hwb:F,cmyk2keyword:V,keyword2rgb:j,keyword2hsl:U,keyword2hsv:q,keyword2hwb:Y,keyword2cmyk:X,keyword2lab:K,keyword2xyz:J,xyz2rgb:R,xyz2lab:O,xyz2lch:L,lab2xyz:B,lab2rgb:W,lab2lch:z,lch2lab:N,lch2xyz:E,lch2rgb:H};var G={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},Z={};for(var Q in G)Z[JSON.stringify(G[Q])]=Q},{}],5:[function(t,e,a){var i=t(4),n=function(){return new u};for(var o in i){n[o+"Raw"]=function(t){return function(e){return"number"==typeof e&&(e=Array.prototype.slice.call(arguments)),i[t](e)}}(o);var r=/(\w+)2(\w+)/.exec(o),s=r[1],l=r[2];n[s]=n[s]||{},n[s][l]=n[o]=function(t){return function(e){"number"==typeof e&&(e=Array.prototype.slice.call(arguments));var a=i[t](e);if("string"==typeof a||void 0===a)return a;for(var n=0;n0&&(t[0].yLabel?a=t[0].yLabel:e.labels.length>0&&t[0].index');var a=t.data,i=a.datasets,n=a.labels;if(i.length)for(var o=0;o'),n[o]&&e.push(n[o]),e.push("");return e.push(""),e.join("")},legend:{labels:{generateLabels:function(t){var a=t.data;return a.labels.length&&a.datasets.length?a.labels.map(function(i,n){var o=t.getDatasetMeta(0),r=a.datasets[0],s=o.data[n],l=s&&s.custom||{},u=e.getValueAtIndexOrDefault,d=t.options.elements.arc,c=l.backgroundColor?l.backgroundColor:u(r.backgroundColor,n,d.backgroundColor),h=l.borderColor?l.borderColor:u(r.borderColor,n,d.borderColor),f=l.borderWidth?l.borderWidth:u(r.borderWidth,n,d.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(r.data[n])||o.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var a,i,n,o=e.index,r=this.chart;for(a=0,i=(r.data.datasets||[]).length;a=Math.PI?-1:g<-Math.PI?1:0);var p=g+f,m={x:Math.cos(g),y:Math.sin(g)},v={x:Math.cos(p),y:Math.sin(p)},b=g<=0&&0<=p||g<=2*Math.PI&&2*Math.PI<=p,x=g<=.5*Math.PI&&.5*Math.PI<=p||g<=2.5*Math.PI&&2.5*Math.PI<=p,y=g<=-Math.PI&&-Math.PI<=p||g<=Math.PI&&Math.PI<=p,k=g<=.5*-Math.PI&&.5*-Math.PI<=p||g<=1.5*Math.PI&&1.5*Math.PI<=p,S=h/100,M={x:y?-1:Math.min(m.x*(m.x<0?1:S),v.x*(v.x<0?1:S)),y:k?-1:Math.min(m.y*(m.y<0?1:S),v.y*(v.y<0?1:S))},w={x:b?1:Math.max(m.x*(m.x>0?1:S),v.x*(v.x>0?1:S)),y:x?1:Math.max(m.y*(m.y>0?1:S),v.y*(v.y>0?1:S))},C={width:.5*(w.x-M.x),height:.5*(w.y-M.y)};u=Math.min(s/C.width,l/C.height),d={x:(w.x+M.x)*-.5,y:(w.y+M.y)*-.5}}i.borderWidth=a.getMaxBorderWidth(c.data),i.outerRadius=Math.max((u-i.borderWidth)/2,0),i.innerRadius=Math.max(h?i.outerRadius/100*h:0,0),i.radiusLength=(i.outerRadius-i.innerRadius)/i.getVisibleDatasetCount(),i.offsetX=d.x*i.outerRadius,i.offsetY=d.y*i.outerRadius,c.total=a.calculateTotal(),a.outerRadius=i.outerRadius-i.radiusLength*a.getRingIndex(a.index),a.innerRadius=Math.max(a.outerRadius-i.radiusLength,0),e.each(c.data,function(e,i){a.updateElement(e,i,t)})},updateElement:function(t,a,i){var n=this,o=n.chart,r=o.chartArea,s=o.options,l=s.animation,u=(r.left+r.right)/2,d=(r.top+r.bottom)/2,c=s.rotation,h=s.rotation,f=n.getDataset(),g=i&&l.animateRotate?0:t.hidden?0:n.calculateCircumference(f.data[a])*(s.circumference/(2*Math.PI)),p=i&&l.animateScale?0:n.innerRadius,m=i&&l.animateScale?0:n.outerRadius,v=e.getValueAtIndexOrDefault;e.extend(t,{_datasetIndex:n.index,_index:a,_model:{x:u+o.offsetX,y:d+o.offsetY,startAngle:c,endAngle:h,circumference:g,outerRadius:m,innerRadius:p,label:v(f.label,a,o.data.labels[a])}});var b=t._model;this.removeHoverStyle(t),i&&l.animateRotate||(0===a?b.startAngle=s.rotation:b.startAngle=n.getMeta().data[a-1]._model.endAngle,b.endAngle=b.startAngle+b.circumference),t.pivot()},removeHoverStyle:function(e){t.DatasetController.prototype.removeHoverStyle.call(this,e,this.chart.options.elements.arc)},calculateTotal:function(){var t,a=this.getDataset(),i=this.getMeta(),n=0;return e.each(i.data,function(e,i){t=a.data[i],isNaN(t)||e.hidden||(n+=Math.abs(t))}),n},calculateCircumference:function(t){var e=this.getMeta().total;return e>0&&!isNaN(t)?2*Math.PI*(t/e):0},getMaxBorderWidth:function(t){for(var e,a,i=0,n=this.index,o=t.length,r=0;ri?e:i,i=a>i?a:i;return i}})}},{}],18:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){return a.getValueOrDefault(t.showLine,e.showLines)}var a=t.helpers;t.defaults.line={showLines:!0,spanGaps:!1,hover:{mode:"label"},scales:{xAxes:[{type:"category",id:"x-axis-0"}],yAxes:[{type:"linear",id:"y-axis-0"}]}},t.controllers.line=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,update:function(t){var i,n,o,r=this,s=r.getMeta(),l=s.dataset,u=s.data||[],d=r.chart.options,c=d.elements.line,h=r.getScaleForId(s.yAxisID),f=r.getDataset(),g=e(f,d);for(g&&(o=l.custom||{},void 0!==f.tension&&void 0===f.lineTension&&(f.lineTension=f.tension),l._scale=h,l._datasetIndex=r.index,l._children=u,l._model={spanGaps:f.spanGaps?f.spanGaps:d.spanGaps,tension:o.tension?o.tension:a.getValueOrDefault(f.lineTension,c.tension),backgroundColor:o.backgroundColor?o.backgroundColor:f.backgroundColor||c.backgroundColor,borderWidth:o.borderWidth?o.borderWidth:f.borderWidth||c.borderWidth,borderColor:o.borderColor?o.borderColor:f.borderColor||c.borderColor,borderCapStyle:o.borderCapStyle?o.borderCapStyle:f.borderCapStyle||c.borderCapStyle,borderDash:o.borderDash?o.borderDash:f.borderDash||c.borderDash,borderDashOffset:o.borderDashOffset?o.borderDashOffset:f.borderDashOffset||c.borderDashOffset,borderJoinStyle:o.borderJoinStyle?o.borderJoinStyle:f.borderJoinStyle||c.borderJoinStyle,fill:o.fill?o.fill:void 0!==f.fill?f.fill:c.fill,steppedLine:o.steppedLine?o.steppedLine:a.getValueOrDefault(f.steppedLine,c.stepped),cubicInterpolationMode:o.cubicInterpolationMode?o.cubicInterpolationMode:a.getValueOrDefault(f.cubicInterpolationMode,c.cubicInterpolationMode),scaleTop:h.top,scaleBottom:h.bottom,scaleZero:h.getBasePixel()},l.pivot()),i=0,n=u.length;i');var a=t.data,i=a.datasets,n=a.labels;if(i.length)for(var o=0;o'),n[o]&&e.push(n[o]),e.push("");return e.push(""),e.join("")},legend:{labels:{generateLabels:function(t){var a=t.data;return a.labels.length&&a.datasets.length?a.labels.map(function(i,n){var o=t.getDatasetMeta(0),r=a.datasets[0],s=o.data[n],l=s.custom||{},u=e.getValueAtIndexOrDefault,d=t.options.elements.arc,c=l.backgroundColor?l.backgroundColor:u(r.backgroundColor,n,d.backgroundColor),h=l.borderColor?l.borderColor:u(r.borderColor,n,d.borderColor),f=l.borderWidth?l.borderWidth:u(r.borderWidth,n,d.borderWidth);return{text:i,fillStyle:c,strokeStyle:h,lineWidth:f,hidden:isNaN(r.data[n])||o.data[n].hidden,index:n}}):[]}},onClick:function(t,e){var a,i,n,o=e.index,r=this.chart;for(a=0,i=(r.data.datasets||[]).length;a0&&!isNaN(t)?2*Math.PI/e:0}})}},{}],20:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.radar={aspectRatio:1,scale:{type:"radialLinear"},elements:{line:{tension:0}}},t.controllers.radar=t.DatasetController.extend({datasetElementType:t.elements.Line,dataElementType:t.elements.Point,linkScales:e.noop,update:function(t){var a=this,i=a.getMeta(),n=i.dataset,o=i.data,r=n.custom||{},s=a.getDataset(),l=a.chart.options.elements.line,u=a.chart.scale;void 0!==s.tension&&void 0===s.lineTension&&(s.lineTension=s.tension),e.extend(i.dataset,{_datasetIndex:a.index,_children:o,_loop:!0,_model:{tension:r.tension?r.tension:e.getValueOrDefault(s.lineTension,l.tension),backgroundColor:r.backgroundColor?r.backgroundColor:s.backgroundColor||l.backgroundColor,borderWidth:r.borderWidth?r.borderWidth:s.borderWidth||l.borderWidth,borderColor:r.borderColor?r.borderColor:s.borderColor||l.borderColor,fill:r.fill?r.fill:void 0!==s.fill?s.fill:l.fill,borderCapStyle:r.borderCapStyle?r.borderCapStyle:s.borderCapStyle||l.borderCapStyle,borderDash:r.borderDash?r.borderDash:s.borderDash||l.borderDash,borderDashOffset:r.borderDashOffset?r.borderDashOffset:s.borderDashOffset||l.borderDashOffset,borderJoinStyle:r.borderJoinStyle?r.borderJoinStyle:s.borderJoinStyle||l.borderJoinStyle,scaleTop:u.top,scaleBottom:u.bottom,scaleZero:u.getBasePosition()}}),i.dataset.pivot(),e.each(o,function(e,i){a.updateElement(e,i,t)},a),a.updateBezierControlPoints()},updateElement:function(t,a,i){var n=this,o=t.custom||{},r=n.getDataset(),s=n.chart.scale,l=n.chart.options.elements.point,u=s.getPointPositionForValue(a,r.data[a]);e.extend(t,{_datasetIndex:n.index,_index:a,_scale:s,_model:{x:i?s.xCenter:u.x,y:i?s.yCenter:u.y,tension:o.tension?o.tension:e.getValueOrDefault(r.lineTension,n.chart.options.elements.line.tension),radius:o.radius?o.radius:e.getValueAtIndexOrDefault(r.pointRadius,a,l.radius),backgroundColor:o.backgroundColor?o.backgroundColor:e.getValueAtIndexOrDefault(r.pointBackgroundColor,a,l.backgroundColor),borderColor:o.borderColor?o.borderColor:e.getValueAtIndexOrDefault(r.pointBorderColor,a,l.borderColor),borderWidth:o.borderWidth?o.borderWidth:e.getValueAtIndexOrDefault(r.pointBorderWidth,a,l.borderWidth),pointStyle:o.pointStyle?o.pointStyle:e.getValueAtIndexOrDefault(r.pointStyle,a,l.pointStyle),hitRadius:o.hitRadius?o.hitRadius:e.getValueAtIndexOrDefault(r.hitRadius,a,l.hitRadius)}}),t._model.skip=o.skip?o.skip:isNaN(t._model.x)||isNaN(t._model.y)},updateBezierControlPoints:function(){var t=this.chart.chartArea,a=this.getMeta();e.each(a.data,function(i,n){var o=i._model,r=e.splineCurve(e.previousItem(a.data,n,!0)._model,o,e.nextItem(a.data,n,!0)._model,o.tension);o.controlPointPreviousX=Math.max(Math.min(r.previous.x,t.right),t.left),o.controlPointPreviousY=Math.max(Math.min(r.previous.y,t.bottom),t.top),o.controlPointNextX=Math.max(Math.min(r.next.x,t.right),t.left),o.controlPointNextY=Math.max(Math.min(r.next.y,t.bottom),t.top),i.pivot()})},draw:function(t){var a=this.getMeta(),i=t||1;e.each(a.data,function(t){t.transition(i)}),a.dataset.transition(i).draw(),e.each(a.data,function(t){t.draw()})},setHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,o=t._model;o.radius=i.hoverRadius?i.hoverRadius:e.getValueAtIndexOrDefault(a.pointHoverRadius,n,this.chart.options.elements.point.hoverRadius),o.backgroundColor=i.hoverBackgroundColor?i.hoverBackgroundColor:e.getValueAtIndexOrDefault(a.pointHoverBackgroundColor,n,e.getHoverColor(o.backgroundColor)),o.borderColor=i.hoverBorderColor?i.hoverBorderColor:e.getValueAtIndexOrDefault(a.pointHoverBorderColor,n,e.getHoverColor(o.borderColor)),o.borderWidth=i.hoverBorderWidth?i.hoverBorderWidth:e.getValueAtIndexOrDefault(a.pointHoverBorderWidth,n,o.borderWidth)},removeHoverStyle:function(t){var a=this.chart.data.datasets[t._datasetIndex],i=t.custom||{},n=t._index,o=t._model,r=this.chart.options.elements.point;o.radius=i.radius?i.radius:e.getValueAtIndexOrDefault(a.radius,n,r.radius),o.backgroundColor=i.backgroundColor?i.backgroundColor:e.getValueAtIndexOrDefault(a.pointBackgroundColor,n,r.backgroundColor),o.borderColor=i.borderColor?i.borderColor:e.getValueAtIndexOrDefault(a.pointBorderColor,n,r.borderColor),o.borderWidth=i.borderWidth?i.borderWidth:e.getValueAtIndexOrDefault(a.pointBorderWidth,n,r.borderWidth)}})}},{}],21:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.animation={duration:1e3,easing:"easeOutQuart",onProgress:e.noop,onComplete:e.noop},t.Animation=t.Element.extend({currentStep:null,numSteps:60,easing:"",render:null,onAnimationProgress:null,onAnimationComplete:null}),t.animationService={frameDuration:17,animations:[],dropFrames:0,request:null,addAnimation:function(t,e,a,i){var n=this;i||(t.animating=!0);for(var o=0;o1&&(a=Math.floor(t.dropFrames),t.dropFrames=t.dropFrames%1);for(var i=0;it.animations[i].animationObject.numSteps&&(t.animations[i].animationObject.currentStep=t.animations[i].animationObject.numSteps),t.animations[i].animationObject.render(t.animations[i].chartInstance,t.animations[i].animationObject),t.animations[i].animationObject.onAnimationProgress&&t.animations[i].animationObject.onAnimationProgress.call&&t.animations[i].animationObject.onAnimationProgress.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].animationObject.currentStep===t.animations[i].animationObject.numSteps?(t.animations[i].animationObject.onAnimationComplete&&t.animations[i].animationObject.onAnimationComplete.call&&t.animations[i].animationObject.onAnimationComplete.call(t.animations[i].chartInstance,t.animations[i]),t.animations[i].chartInstance.animating=!1,t.animations.splice(i,1)):++i;var n=Date.now(),o=(n-e)/t.frameDuration;t.dropFrames+=o,t.animations.length>0&&t.requestAnimationFrame()}}}},{}],22:[function(t,e,a){"use strict";e.exports=function(t){var e=t.canvasHelpers={};e.drawPoint=function(e,a,i,n,o){var r,s,l,u,d,c;if("object"==typeof a&&(r=a.toString(),"[object HTMLImageElement]"===r||"[object HTMLCanvasElement]"===r))return void e.drawImage(a,n-a.width/2,o-a.height/2);if(!(isNaN(i)||i<=0)){switch(a){default:e.beginPath(),e.arc(n,o,i,0,2*Math.PI),e.closePath(),e.fill();break;case"triangle":e.beginPath(),s=3*i/Math.sqrt(3),d=s*Math.sqrt(3)/2,e.moveTo(n-s/2,o+d/3),e.lineTo(n+s/2,o+d/3),e.lineTo(n,o-2*d/3),e.closePath(),e.fill();break;case"rect":c=1/Math.SQRT2*i,e.beginPath(),e.fillRect(n-c,o-c,2*c,2*c),e.strokeRect(n-c,o-c,2*c,2*c);break;case"rectRounded":var h=i/Math.SQRT2,f=n-h,g=o-h,p=Math.SQRT2*i;t.helpers.drawRoundedRectangle(e,f,g,p,p,i/2),e.fill();break;case"rectRot":c=1/Math.SQRT2*i,e.beginPath(),e.moveTo(n-c,o),e.lineTo(n,o+c),e.lineTo(n+c,o),e.lineTo(n,o-c),e.closePath(),e.fill();break;case"cross":e.beginPath(),e.moveTo(n,o+i),e.lineTo(n,o-i),e.moveTo(n-i,o),e.lineTo(n+i,o),e.closePath();break;case"crossRot":e.beginPath(),l=Math.cos(Math.PI/4)*i,u=Math.sin(Math.PI/4)*i,e.moveTo(n-l,o-u),e.lineTo(n+l,o+u),e.moveTo(n-l,o+u),e.lineTo(n+l,o-u),e.closePath();break;case"star":e.beginPath(),e.moveTo(n,o+i),e.lineTo(n,o-i),e.moveTo(n-i,o),e.lineTo(n+i,o),l=Math.cos(Math.PI/4)*i,u=Math.sin(Math.PI/4)*i,e.moveTo(n-l,o-u),e.lineTo(n+l,o+u),e.moveTo(n-l,o+u),e.lineTo(n+l,o-u),e.closePath();break;case"line":e.beginPath(),e.moveTo(n-i,o),e.lineTo(n+i,o),e.closePath();break;case"dash":e.beginPath(),e.moveTo(n,o),e.lineTo(n+i,o),e.closePath()}e.stroke()}},e.clipArea=function(t,e){t.save(),t.beginPath(),t.rect(e.left,e.top,e.right-e.left,e.bottom-e.top),t.clip()},e.unclipArea=function(t){t.restore()}}},{}],23:[function(t,e,a){"use strict";e.exports=function(t){function e(e){e=e||{};var a=e.data=e.data||{};return a.datasets=a.datasets||[],a.labels=a.labels||[],e.options=i.configMerge(t.defaults.global,t.defaults[e.type],e.options||{}),e}function a(t){var e=t.options;e.scale?t.scale.options=e.scale:e.scales&&e.scales.xAxes.concat(e.scales.yAxes).forEach(function(e){t.scales[e.id].options=e}),t.tooltip._options=e.tooltips}var i=t.helpers,n=t.plugins,o=t.platform;t.types={},t.instances={},t.controllers={},t.Controller=function(a,n,r){var s=this;n=e(n);var l=o.acquireContext(a,n),u=l&&l.canvas,d=u&&u.height,c=u&&u.width;return r.ctx=l,r.canvas=u,r.config=n,r.width=c,r.height=d,r.aspectRatio=d?c/d:null,s.id=i.uid(),s.chart=r,s.config=n,s.options=n.options,s._bufferedRender=!1,t.instances[s.id]=s,Object.defineProperty(s,"data",{get:function(){return s.config.data}}),l&&u?(s.initialize(),s.update(),s):(console.error("Failed to create chart: can't acquire context from the given item"),s)},i.extend(t.Controller.prototype,{initialize:function(){var t=this;return n.notify(t,"beforeInit"),i.retinaScale(t.chart),t.bindEvents(),t.options.responsive&&t.resize(!0),t.ensureScalesHaveIDs(),t.buildScales(),t.initToolTip(),n.notify(t,"afterInit"),t},clear:function(){return i.clear(this.chart),this},stop:function(){return t.animationService.cancelAnimation(this),this},resize:function(t){var e=this,a=e.chart,o=e.options,r=a.canvas,s=o.maintainAspectRatio&&a.aspectRatio||null,l=Math.floor(i.getMaximumWidth(r)),u=Math.floor(s?l/s:i.getMaximumHeight(r));if((a.width!==l||a.height!==u)&&(r.width=a.width=l,r.height=a.height=u,r.style.width=l+"px",r.style.height=u+"px",i.retinaScale(a),!t)){var d={width:l,height:u};n.notify(e,"resize",[d]),e.options.onResize&&e.options.onResize(e,d),e.stop(),e.update(e.options.responsiveAnimationDuration)}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},a=t.scale;i.each(e.xAxes,function(t,e){t.id=t.id||"x-axis-"+e}),i.each(e.yAxes,function(t,e){t.id=t.id||"y-axis-"+e}),a&&(a.id=a.id||"scale")},buildScales:function(){var e=this,a=e.options,n=e.scales={},o=[];a.scales&&(o=o.concat((a.scales.xAxes||[]).map(function(t){return{options:t,dtype:"category"}}),(a.scales.yAxes||[]).map(function(t){return{options:t,dtype:"linear"}}))),a.scale&&o.push({options:a.scale,dtype:"radialLinear",isDefault:!0}),i.each(o,function(a){var o=a.options,r=i.getValueOrDefault(o.type,a.dtype),s=t.scaleService.getScaleConstructor(r);if(s){var l=new s({id:o.id,options:o,ctx:e.chart.ctx,chart:e});n[l.id]=l,a.isDefault&&(e.scale=l)}}),t.scaleService.addScalesToLayout(this)},buildOrUpdateControllers:function(){var e=this,a=[],n=[];if(i.each(e.data.datasets,function(i,o){var r=e.getDatasetMeta(o);r.type||(r.type=i.type||e.config.type),a.push(r.type),r.controller?r.controller.updateIndex(o):(r.controller=new t.controllers[r.type](e,o),n.push(r.controller))},e),a.length>1)for(var o=1;o0||(n.forEach(function(e){delete t[e]}),delete t._chartjs)}}var i=t.helpers,n=["push","pop","shift","splice","unshift"];t.DatasetController=function(t,e){this.initialize(t,e)},i.extend(t.DatasetController.prototype,{datasetElementType:null,dataElementType:null,initialize:function(t,e){var a=this;a.chart=t,a.index=e,a.linkScales(),a.addElements()},updateIndex:function(t){this.index=t},linkScales:function(){var t=this,e=t.getMeta(),a=t.getDataset();null===e.xAxisID&&(e.xAxisID=a.xAxisID||t.chart.options.scales.xAxes[0].id),null===e.yAxisID&&(e.yAxisID=a.yAxisID||t.chart.options.scales.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},reset:function(){this.update(!0)},destroy:function(){this._data&&a(this._data,this)},createMetaDataset:function(){var t=this,e=t.datasetElementType;return e&&new e({_chart:t.chart.chart,_datasetIndex:t.index})},createMetaData:function(t){var e=this,a=e.dataElementType;return a&&new a({_chart:e.chart.chart,_datasetIndex:e.index,_index:t})},addElements:function(){var t,e,a=this,i=a.getMeta(),n=a.getDataset().data||[],o=i.data;for(t=0,e=n.length;ti&&t.insertElements(i,n-i)},insertElements:function(t,e){for(var a=0;a=0;n--)e.call(a,t[n],n);else for(n=0;n=i[a].length||!i[a][n].type?i[a].push(o.configMerge(s,e)):e.type&&e.type!==i[a][n].type?i[a][n]=o.configMerge(i[a][n],s,e):i[a][n]=o.configMerge(i[a][n],e)}):(i[a]=[],o.each(e,function(e){var n=o.getValueOrDefault(e.type,"xAxes"===a?"category":"linear");i[a].push(o.configMerge(t.scaleService.getScaleDefaults(n),e))})):i.hasOwnProperty(a)&&"object"==typeof i[a]&&null!==i[a]&&"object"==typeof e?i[a]=o.configMerge(i[a],e):i[a]=e}),i},o.getValueAtIndexOrDefault=function(t,e,a){return void 0===t||null===t?a:o.isArray(t)?e=0;i--){var n=t[i];if(e(n))return n}},o.inherits=function(t){var e=this,a=t&&t.hasOwnProperty("constructor")?t.constructor:function(){return e.apply(this,arguments)},i=function(){this.constructor=a};return i.prototype=e.prototype,a.prototype=new i,a.extend=o.inherits,t&&o.extend(a.prototype,t),a.__super__=e.prototype,a},o.noop=function(){},o.uid=function(){var t=0;return function(){return t++}}(),o.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},o.almostEquals=function(t,e,a){return Math.abs(t-e)t},o.max=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.max(t,e)},Number.NEGATIVE_INFINITY)},o.min=function(t){return t.reduce(function(t,e){return isNaN(e)?t:Math.min(t,e)},Number.POSITIVE_INFINITY)},o.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return t=+t,0===t||isNaN(t)?t:t>0?1:-1},o.log10=Math.log10?function(t){return Math.log10(t)}:function(t){return Math.log(t)/Math.LN10},o.toRadians=function(t){return t*(Math.PI/180)},o.toDegrees=function(t){return t*(180/Math.PI)},o.getAngleFromPoint=function(t,e){var a=e.x-t.x,i=e.y-t.y,n=Math.sqrt(a*a+i*i),o=Math.atan2(i,a);return o<-.5*Math.PI&&(o+=2*Math.PI),{angle:o,distance:n}},o.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},o.aliasPixel=function(t){return t%2===0?0:.5},o.splineCurve=function(t,e,a,i){var n=t.skip?e:t,o=e,r=a.skip?e:a,s=Math.sqrt(Math.pow(o.x-n.x,2)+Math.pow(o.y-n.y,2)),l=Math.sqrt(Math.pow(r.x-o.x,2)+Math.pow(r.y-o.y,2)),u=s/(s+l),d=l/(s+l);u=isNaN(u)?0:u,d=isNaN(d)?0:d;var c=i*u,h=i*d;return{previous:{x:o.x-c*(r.x-n.x),y:o.y-c*(r.y-n.y)},next:{x:o.x+h*(r.x-n.x),y:o.y+h*(r.y-n.y)}}},o.EPSILON=Number.EPSILON||1e-14,o.splineCurveMonotone=function(t){var e,a,i,n,r=(t||[]).map(function(t){return{model:t._model,deltaK:0,mK:0}}),s=r.length;for(e=0;e0?r[e-1]:null,n=e0?r[e-1]:null,n=e=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},o.previousItem=function(t,e,a){return a?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},o.niceNum=function(t,e){var a,i=Math.floor(o.log10(t)),n=t/Math.pow(10,i);return a=e?n<1.5?1:n<3?2:n<7?5:10:n<=1?1:n<=2?2:n<=5?5:10,a*Math.pow(10,i)};var r=o.easingEffects={linear:function(t){return t},easeInQuad:function(t){return t*t},easeOutQuad:function(t){return-1*t*(t-2)},easeInOutQuad:function(t){return(t/=.5)<1?.5*t*t:-.5*(--t*(t-2)-1)},easeInCubic:function(t){return t*t*t},easeOutCubic:function(t){return 1*((t=t/1-1)*t*t+1)},easeInOutCubic:function(t){return(t/=.5)<1?.5*t*t*t:.5*((t-=2)*t*t+2)},easeInQuart:function(t){return t*t*t*t},easeOutQuart:function(t){return-1*((t=t/1-1)*t*t*t-1)},easeInOutQuart:function(t){return(t/=.5)<1?.5*t*t*t*t:-.5*((t-=2)*t*t*t-2)},easeInQuint:function(t){return 1*(t/=1)*t*t*t*t},easeOutQuint:function(t){return 1*((t=t/1-1)*t*t*t*t+1)},easeInOutQuint:function(t){return(t/=.5)<1?.5*t*t*t*t*t:.5*((t-=2)*t*t*t*t+2)},easeInSine:function(t){return-1*Math.cos(t/1*(Math.PI/2))+1},easeOutSine:function(t){return 1*Math.sin(t/1*(Math.PI/2))},easeInOutSine:function(t){return-.5*(Math.cos(Math.PI*t/1)-1)},easeInExpo:function(t){return 0===t?1:1*Math.pow(2,10*(t/1-1))},easeOutExpo:function(t){return 1===t?1:1*(-Math.pow(2,-10*t/1)+1)},easeInOutExpo:function(t){return 0===t?0:1===t?1:(t/=.5)<1?.5*Math.pow(2,10*(t-1)):.5*(-Math.pow(2,-10*--t)+2)},easeInCirc:function(t){return t>=1?t:-1*(Math.sqrt(1-(t/=1)*t)-1)},easeOutCirc:function(t){return 1*Math.sqrt(1-(t=t/1-1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,a=0,i=1;return 0===t?0:1===(t/=1)?1:(a||(a=.3),i0?(a=l[0].clientX,i=l[0].clientY):(a=n.clientX,i=n.clientY);var u=parseFloat(o.getStyle(r,"padding-left")),d=parseFloat(o.getStyle(r,"padding-top")),c=parseFloat(o.getStyle(r,"padding-right")),h=parseFloat(o.getStyle(r,"padding-bottom")),f=s.right-s.left-u-c,g=s.bottom-s.top-d-h;return a=Math.round((a-s.left-u)/f*r.width/e.currentDevicePixelRatio),i=Math.round((i-s.top-d)/g*r.height/e.currentDevicePixelRatio),{x:a,y:i}},o.addEvent=function(t,e,a){t.addEventListener?t.addEventListener(e,a):t.attachEvent?t.attachEvent("on"+e,a):t["on"+e]=a},o.removeEvent=function(t,e,a){t.removeEventListener?t.removeEventListener(e,a,!1):t.detachEvent?t.detachEvent("on"+e,a):t["on"+e]=o.noop},o.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},o.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},o.getMaximumWidth=function(t){var e=t.parentNode,a=parseInt(o.getStyle(e,"padding-left"),10),i=parseInt(o.getStyle(e,"padding-right"),10),n=e.clientWidth-a-i,r=o.getConstraintWidth(t);return isNaN(r)?n:Math.min(n,r)},o.getMaximumHeight=function(t){var e=t.parentNode,a=parseInt(o.getStyle(e,"padding-top"),10),i=parseInt(o.getStyle(e,"padding-bottom"),10),n=e.clientHeight-a-i,r=o.getConstraintHeight(t);return isNaN(r)?n:Math.min(n,r)},o.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},o.retinaScale=function(t){var e=t.currentDevicePixelRatio=window.devicePixelRatio||1;if(1!==e){var a=t.canvas,i=t.height,n=t.width;a.height=i*e,a.width=n*e,t.ctx.scale(e,e),a.style.height=i+"px",a.style.width=n+"px"}},o.clear=function(t){t.ctx.clearRect(0,0,t.width,t.height)},o.fontString=function(t,e,a){return e+" "+t+"px "+a},o.longestText=function(t,e,a,i){i=i||{};var n=i.data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(n=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var s=0;o.each(a,function(e){void 0!==e&&null!==e&&o.isArray(e)!==!0?s=o.measureText(t,n,r,s,e):o.isArray(e)&&o.each(e,function(e){void 0===e||null===e||o.isArray(e)||(s=o.measureText(t,n,r,s,e))})});var l=r.length/2;if(l>a.length){for(var u=0;ui&&(i=o),i},o.numberOfLabelLines=function(t){var e=1;return o.each(t,function(t){o.isArray(t)&&t.length>e&&(e=t.length)}),e},o.drawRoundedRectangle=function(t,e,a,i,n,o){t.beginPath(),t.moveTo(e+o,a),t.lineTo(e+i-o,a),t.quadraticCurveTo(e+i,a,e+i,a+o),t.lineTo(e+i,a+n-o),t.quadraticCurveTo(e+i,a+n,e+i-o,a+n),t.lineTo(e+o,a+n),t.quadraticCurveTo(e,a+n,e,a+n-o),t.lineTo(e,a+o),t.quadraticCurveTo(e,a,e+o,a),t.closePath()},o.color=function(e){return i?i(e instanceof CanvasGradient?t.defaults.global.defaultColor:e):(console.error("Color.js not found!"),e)},o.isArray=Array.isArray?function(t){return Array.isArray(t)}:function(t){return"[object Array]"===Object.prototype.toString.call(t)},o.arrayEquals=function(t,e){var a,i,n,r;if(!t||!e||t.length!==e.length)return!1;for(a=0,i=t.length;a0&&(s=t.getDatasetMeta(s[0]._datasetIndex).data),s},"x-axis":function(t,e){return o(t,e,!0)},point:function(t,a){var n=e(a,t.chart);return i(t,n)},nearest:function(t,a,i){var o=e(a,t.chart),r=n(t,o,i.intersect);return r.length>1&&r.sort(function(t,e){var a=t.getArea(),i=e.getArea(),n=a-i;return 0===n&&(n=t._datasetIndex-e._datasetIndex),n}),r.slice(0,1)},x:function(t,i,n){var o=e(i,t.chart),r=[],s=!1;return a(t,function(t){t.inXRange(o.x)&&r.push(t),t.inRange(o.x,o.y)&&(s=!0)}),n.intersect&&!s&&(r=[]),r},y:function(t,i,n){var o=e(i,t.chart),r=[],s=!1;return a(t,function(t){t.inYRange(o.y)&&r.push(t),t.inRange(o.x,o.y)&&(s=!0)}),n.intersect&&!s&&(r=[]),r}}}}},{}],28:[function(t,e,a){"use strict";e.exports=function(){var t=function(e,a){return this.controller=new t.Controller(e,a,this),this.controller};return t.defaults={global:{responsive:!0,responsiveAnimationDuration:0,maintainAspectRatio:!0,events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,defaultColor:"rgba(0,0,0,0.1)",defaultFontColor:"#666",defaultFontFamily:"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",defaultFontSize:12,defaultFontStyle:"normal",showLines:!0,elements:{},legendCallback:function(t){var e=[];e.push('
    ');for(var a=0;a'),t.data.datasets[a].label&&e.push(t.data.datasets[a].label),e.push("");return e.push("
"),e.join("")}}},t.Chart=t,t}},{}],29:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.layoutService={defaults:{},addBox:function(t,e){t.boxes||(t.boxes=[]),t.boxes.push(e)},removeBox:function(t,e){t.boxes&&t.boxes.splice(t.boxes.indexOf(e),1)},update:function(t,a,i){function n(t){var e,a=t.isHorizontal();a?(e=t.update(t.options.fullWidth?x:C,w),I-=e.height):(e=t.update(M,S),C-=e.width),D.push({horizontal:a,minSize:e,box:t})}function o(t){var a=e.findNextWhere(D,function(e){return e.box===t});if(a)if(t.isHorizontal()){var i={left:Math.max(F,A),right:Math.max(V,T),top:0,bottom:0};t.update(t.options.fullWidth?x:C,y/2,i)}else t.update(a.minSize.width,I)}function r(t){var a=e.findNextWhere(D,function(e){return e.box===t}),i={left:0,right:0,top:R,bottom:O};a&&t.update(a.minSize.width,I,i)}function s(t){t.isHorizontal()?(t.left=t.options.fullWidth?d:F,t.right=t.options.fullWidth?a-c:F+C,t.top=E,t.bottom=E+t.height,E=t.bottom):(t.left=N,t.right=N+t.width,t.top=R,t.bottom=R+I,N=t.right)}if(t){var l=t.options.layout,u=l?l.padding:null,d=0,c=0,h=0,f=0;isNaN(u)?(d=u.left||0,c=u.right||0,h=u.top||0,f=u.bottom||0):(d=u,c=u,h=u,f=u);var g=e.where(t.boxes,function(t){return"left"===t.options.position}),p=e.where(t.boxes,function(t){return"right"===t.options.position}),m=e.where(t.boxes,function(t){return"top"===t.options.position}),v=e.where(t.boxes,function(t){return"bottom"===t.options.position}),b=e.where(t.boxes,function(t){return"chartArea"===t.options.position});m.sort(function(t,e){return(e.options.fullWidth?1:0)-(t.options.fullWidth?1:0)}),v.sort(function(t,e){return(t.options.fullWidth?1:0)-(e.options.fullWidth?1:0)});var x=a-d-c,y=i-h-f,k=x/2,S=y/2,M=(a-k)/(g.length+p.length),w=(i-S)/(m.length+v.length),C=x,I=y,D=[];e.each(g.concat(p,m,v),n);var A=0,T=0,P=0,_=0;e.each(m.concat(v),function(t){if(t.getPadding){var e=t.getPadding();A=Math.max(A,e.left),T=Math.max(T,e.right)}}),e.each(g.concat(p),function(t){if(t.getPadding){var e=t.getPadding();P=Math.max(P,e.top),_=Math.max(_,e.bottom)}});var F=d,V=c,R=h,O=f;e.each(g.concat(p),o),e.each(g,function(t){F+=t.width}),e.each(p,function(t){V+=t.width}),e.each(m.concat(v),o),e.each(m,function(t){R+=t.height}),e.each(v,function(t){O+=t.height}),e.each(g.concat(p),r),F=d,V=c,R=h,O=f,e.each(g,function(t){F+=t.width}),e.each(p,function(t){V+=t.width}),e.each(m,function(t){R+=t.height}),e.each(v,function(t){O+=t.height});var L=Math.max(A-F,0);F+=L,V+=Math.max(T-V,0);var B=Math.max(P-R,0);R+=B,O+=Math.max(_-O,0);var z=i-R-O,W=a-F-V;W===C&&z===I||(e.each(g,function(t){t.height=z}),e.each(p,function(t){t.height=z}),e.each(m,function(t){t.options.fullWidth||(t.width=W)}),e.each(v,function(t){t.options.fullWidth||(t.width=W)}),I=z,C=W);var N=d+L,E=h+B;e.each(g.concat(m),s),N+=C,E+=I,e.each(p,s),e.each(v,s),t.chartArea={left:F,top:R,right:F+C,bottom:R+I},e.each(b,function(e){e.left=t.chartArea.left,e.top=t.chartArea.top,e.right=t.chartArea.right,e.bottom=t.chartArea.bottom,e.update(C,I)})}}}}},{}],30:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){return t.usePointStyle?e*Math.SQRT2:t.boxWidth}function a(e,a){var i=new t.Legend({ctx:e.chart.ctx,options:a,chart:e});e.legend=i,t.layoutService.addBox(e,i)}var i=t.helpers,n=i.noop;t.defaults.global.legend={display:!0,position:"top",fullWidth:!0,reverse:!1,onClick:function(t,e){var a=e.datasetIndex,i=this.chart,n=i.getDatasetMeta(a);n.hidden=null===n.hidden?!i.data.datasets[a].hidden:null,i.update()},onHover:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data;return i.isArray(e.datasets)?e.datasets.map(function(e,a){return{text:e.label,fillStyle:i.isArray(e.backgroundColor)?e.backgroundColor[0]:e.backgroundColor,hidden:!t.isDatasetVisible(a),lineCap:e.borderCapStyle,lineDash:e.borderDash,lineDashOffset:e.borderDashOffset,lineJoin:e.borderJoinStyle,lineWidth:e.borderWidth,strokeStyle:e.borderColor,pointStyle:e.pointStyle,datasetIndex:a}},this):[]}}},t.Legend=t.Element.extend({initialize:function(t){i.extend(this,t),this.legendHitBoxes=[],this.doughnutMode=!1},beforeUpdate:n,update:function(t,e,a){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=a,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:n,beforeSetDimensions:n,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:n,beforeBuildLabels:n,buildLabels:function(){var t=this,e=t.options.labels,a=e.generateLabels.call(t,t.chart);e.filter&&(a=a.filter(function(a){return e.filter(a,t.chart.data)})),t.options.reverse&&a.reverse(),t.legendItems=a},afterBuildLabels:n,beforeFit:n,fit:function(){var a=this,n=a.options,o=n.labels,r=n.display,s=a.ctx,l=t.defaults.global,u=i.getValueOrDefault,d=u(o.fontSize,l.defaultFontSize),c=u(o.fontStyle,l.defaultFontStyle),h=u(o.fontFamily,l.defaultFontFamily),f=i.fontString(d,c,h),g=a.legendHitBoxes=[],p=a.minSize,m=a.isHorizontal();if(m?(p.width=a.maxWidth,p.height=r?10:0):(p.width=r?10:0,p.height=a.maxHeight),r)if(s.font=f,m){var v=a.lineWidths=[0],b=a.legendItems.length?d+o.padding:0;s.textAlign="left",s.textBaseline="top",i.each(a.legendItems,function(t,i){var n=e(o,d),r=n+d/2+s.measureText(t.text).width;v[v.length-1]+r+o.padding>=a.width&&(b+=d+o.padding,v[v.length]=a.left),g[i]={left:0,top:0,width:r,height:d},v[v.length-1]+=r+o.padding}),p.height+=b}else{var x=o.padding,y=a.columnWidths=[],k=o.padding,S=0,M=0,w=d+x;i.each(a.legendItems,function(t,a){var i=e(o,d),n=i+d/2+s.measureText(t.text).width;M+w>p.height&&(k+=S+o.padding,y.push(S),S=0,M=0),S=Math.max(S,n),M+=w,g[a]={left:0,top:0,width:n,height:d}}),k+=S,y.push(S),p.width+=k}a.width=p.width,a.height=p.height},afterFit:n,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var a=this,n=a.options,o=n.labels,r=t.defaults.global,s=r.elements.line,l=a.width,u=a.lineWidths;if(n.display){var d,c=a.ctx,h=i.getValueOrDefault,f=h(o.fontColor,r.defaultFontColor),g=h(o.fontSize,r.defaultFontSize),p=h(o.fontStyle,r.defaultFontStyle),m=h(o.fontFamily,r.defaultFontFamily),v=i.fontString(g,p,m);c.textAlign="left",c.textBaseline="top",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=v;var b=e(o,g),x=a.legendHitBoxes,y=function(e,a,i){if(!(isNaN(b)||b<=0)){c.save(),c.fillStyle=h(i.fillStyle,r.defaultColor),c.lineCap=h(i.lineCap,s.borderCapStyle),c.lineDashOffset=h(i.lineDashOffset,s.borderDashOffset),c.lineJoin=h(i.lineJoin,s.borderJoinStyle),c.lineWidth=h(i.lineWidth,s.borderWidth),c.strokeStyle=h(i.strokeStyle,r.defaultColor);var o=0===h(i.lineWidth,s.borderWidth);if(c.setLineDash&&c.setLineDash(h(i.lineDash,s.borderDash)),n.labels&&n.labels.usePointStyle){var l=g*Math.SQRT2/2,u=l/Math.SQRT2,d=e+u,f=a+u;t.canvasHelpers.drawPoint(c,i.pointStyle,l,d,f)}else o||c.strokeRect(e,a,b,g),c.fillRect(e,a,b,g);c.restore()}},k=function(t,e,a,i){c.fillText(a.text,b+g/2+t,e),a.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(b+g/2+t,e+g/2),c.lineTo(b+g/2+t+i,e+g/2),c.stroke())},S=a.isHorizontal();d=S?{x:a.left+(l-u[0])/2,y:a.top+o.padding,line:0}:{x:a.left+o.padding,y:a.top+o.padding,line:0};var M=g+o.padding;i.each(a.legendItems,function(t,e){var i=c.measureText(t.text).width,n=b+g/2+i,r=d.x,s=d.y;S?r+n>=l&&(s=d.y+=M,d.line++,r=d.x=a.left+(l-u[d.line])/2):s+M>a.bottom&&(r=d.x=r+a.columnWidths[d.line]+o.padding,s=d.y=a.top+o.padding,d.line++),y(r,s,t),x[e].left=r,x[e].top=s,k(r,s,t,i),S?d.x+=n+o.padding:d.y+=M})}},handleEvent:function(t){var e=this,a=e.options,i="mouseup"===t.type?"click":t.type,n=!1;if("mousemove"===i){if(!a.onHover)return}else{if("click"!==i)return;if(!a.onClick)return}var o=t.x,r=t.y;if(o>=e.left&&o<=e.right&&r>=e.top&&r<=e.bottom)for(var s=e.legendHitBoxes,l=0;l=u.left&&o<=u.left+u.width&&r>=u.top&&r<=u.top+u.height){if("click"===i){a.onClick.call(e,t.native,e.legendItems[l]),n=!0;break}if("mousemove"===i){a.onHover.call(e,t.native,e.legendItems[l]),n=!0;break}}}return n}}),t.plugins.register({beforeInit:function(t){var e=t.options.legend;e&&a(t,e)},beforeUpdate:function(e){var n=e.options.legend;n?(n=i.configMerge(t.defaults.global.legend,n),e.legend?e.legend.options=n:a(e,n)):(t.layoutService.removeBox(e,e.legend),delete e.legend)},afterEvent:function(t,e){var a=t.legend;a&&a.handleEvent(e)}})}},{}],31:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers;t.defaults.global.plugins={},t.plugins={_plugins:[],_cacheId:0,register:function(t){var e=this._plugins;[].concat(t).forEach(function(t){e.indexOf(t)===-1&&e.push(t)}),this._cacheId++},unregister:function(t){var e=this._plugins;[].concat(t).forEach(function(t){var a=e.indexOf(t);a!==-1&&e.splice(a,1)}),this._cacheId++},clear:function(){this._plugins=[],this._cacheId++},count:function(){return this._plugins.length; +},getAll:function(){return this._plugins},notify:function(t,e,a){var i,n,o,r,s,l=this.descriptors(t),u=l.length;for(i=0;ic&&rt.maxHeight){r--;break}r++,d=s*u}t.labelRotation=r},afterCalculateTickRotation:function(){i.callCallback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){i.callCallback(this.options.beforeFit,[this])},fit:function(){var t=this,n=t.minSize={width:0,height:0},o=t.options,r=o.ticks,s=o.scaleLabel,l=o.gridLines,u=o.display,d=t.isHorizontal(),c=a(r),h=1.5*a(s).size,f=o.gridLines.tickMarkLength;if(d?n.width=t.isFullWidth()?t.maxWidth-t.margins.left-t.margins.right:t.maxWidth:n.width=u&&l.drawTicks?f:0,d?n.height=u&&l.drawTicks?f:0:n.height=t.maxHeight,s.display&&u&&(d?n.height+=h:n.width+=h),r.display&&u){var g=i.longestText(t.ctx,c.font,t.ticks,t.longestTextCache),p=i.numberOfLabelLines(t.ticks),m=.5*c.size;if(d){t.longestLabelWidth=g;var v=i.toRadians(t.labelRotation),b=Math.cos(v),x=Math.sin(v),y=x*g+c.size*p+m*p;n.height=Math.min(t.maxHeight,n.height+y),t.ctx.font=c.font;var k=t.ticks[0],S=e(t.ctx,k,c.font),M=t.ticks[t.ticks.length-1],w=e(t.ctx,M,c.font);0!==t.labelRotation?(t.paddingLeft="bottom"===o.position?b*S+3:b*m+3,t.paddingRight="bottom"===o.position?b*m+3:b*w+3):(t.paddingLeft=S/2+3,t.paddingRight=w/2+3)}else r.mirror?g=0:g+=t.options.ticks.padding,n.width+=g,t.paddingTop=c.size/2,t.paddingBottom=c.size/2}t.handleMargins(),t.width=n.width,t.height=n.height},handleMargins:function(){var t=this;t.margins&&(t.paddingLeft=Math.max(t.paddingLeft-t.margins.left,0),t.paddingTop=Math.max(t.paddingTop-t.margins.top,0),t.paddingRight=Math.max(t.paddingRight-t.margins.right,0),t.paddingBottom=Math.max(t.paddingBottom-t.margins.bottom,0))},afterFit:function(){i.callCallback(this.options.afterFit,[this])},isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){return null===t||"undefined"==typeof t?NaN:"number"!=typeof t||isFinite(t)?"object"==typeof t?t instanceof Date||t.isValid?t:this.getRightValue(this.isHorizontal()?t.x:t.y):t:NaN},getLabelForIndex:i.noop,getPixelForValue:i.noop,getValueForPixel:i.noop,getPixelForTick:function(t,e){var a=this;if(a.isHorizontal()){var i=a.width-(a.paddingLeft+a.paddingRight),n=i/Math.max(a.ticks.length-(a.options.gridLines.offsetGridLines?0:1),1),o=n*t+a.paddingLeft;e&&(o+=n/2);var r=a.left+Math.round(o);return r+=a.isFullWidth()?a.margins.left:0}var s=a.height-(a.paddingTop+a.paddingBottom);return a.top+t*(s/(a.ticks.length-1))},getPixelForDecimal:function(t){var e=this;if(e.isHorizontal()){var a=e.width-(e.paddingLeft+e.paddingRight),i=a*t+e.paddingLeft,n=e.left+Math.round(i);return n+=e.isFullWidth()?e.margins.left:0}return e.top+t*e.height},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this,e=t.min,a=t.max;return t.beginAtZero?0:e<0&&a<0?a:e>0&&a>0?e:0},draw:function(e){var n=this,o=n.options;if(o.display){var r,s,l=n.ctx,u=t.defaults.global,d=o.ticks,c=o.gridLines,h=o.scaleLabel,f=0!==n.labelRotation,g=d.autoSkip,p=n.isHorizontal();d.maxTicksLimit&&(s=d.maxTicksLimit);var m=i.getValueOrDefault(d.fontColor,u.defaultFontColor),v=a(d),b=c.drawTicks?c.tickMarkLength:0,x=i.getValueOrDefault(c.borderDash,u.borderDash),y=i.getValueOrDefault(c.borderDashOffset,u.borderDashOffset),k=i.getValueOrDefault(h.fontColor,u.defaultFontColor),S=a(h),M=i.toRadians(n.labelRotation),w=Math.cos(M),C=n.longestLabelWidth*w;l.fillStyle=m;var I=[];if(p){if(r=!1,f&&(C/=2),(C+d.autoSkipPadding)*n.ticks.length>n.width-(n.paddingLeft+n.paddingRight)&&(r=1+Math.floor((C+d.autoSkipPadding)*n.ticks.length/(n.width-(n.paddingLeft+n.paddingRight)))),s&&n.ticks.length>s)for(;!r||n.ticks.length/(r||1)>s;)r||(r=1),r+=1;g||(r=!1)}var D="right"===o.position?n.left:n.right-b,A="right"===o.position?n.left+b:n.right,T="bottom"===o.position?n.top:n.bottom-b,P="bottom"===o.position?n.top+b:n.bottom;if(i.each(n.ticks,function(t,a){if(void 0!==t&&null!==t){var s=n.ticks.length===a+1,l=r>1&&a%r>0||a%r===0&&a+r>=n.ticks.length;if((!l||s)&&void 0!==t&&null!==t){var u,h;a===("undefined"!=typeof n.zeroLineIndex?n.zeroLineIndex:0)?(u=c.zeroLineWidth,h=c.zeroLineColor):(u=i.getValueAtIndexOrDefault(c.lineWidth,a),h=i.getValueAtIndexOrDefault(c.color,a));var g,m,v,k,S,w,C,_,F,V,R="middle",O="middle";if(p){"bottom"===o.position?(O=f?"middle":"top",R=f?"right":"center",V=n.top+b):(O=f?"middle":"bottom",R=f?"left":"center",V=n.bottom-b);var L=n.getPixelForTick(a)+i.aliasPixel(u);F=n.getPixelForTick(a,c.offsetGridLines)+d.labelOffset,g=v=S=C=L,m=T,k=P,w=e.top,_=e.bottom}else{var B,z="left"===o.position,W=d.padding;d.mirror?(R=z?"left":"right",B=W):(R=z?"right":"left",B=b+W),F=z?n.right-B:n.left+B;var N=n.getPixelForTick(a);N+=i.aliasPixel(u),V=n.getPixelForTick(a,c.offsetGridLines),g=D,v=A,S=e.left,C=e.right,m=k=w=_=N}I.push({tx1:g,ty1:m,tx2:v,ty2:k,x1:S,y1:w,x2:C,y2:_,labelX:F,labelY:V,glWidth:u,glColor:h,glBorderDash:x,glBorderDashOffset:y,rotation:-1*M,label:t,textBaseline:O,textAlign:R})}}}),i.each(I,function(t){if(c.display&&(l.save(),l.lineWidth=t.glWidth,l.strokeStyle=t.glColor,l.setLineDash&&(l.setLineDash(t.glBorderDash),l.lineDashOffset=t.glBorderDashOffset),l.beginPath(),c.drawTicks&&(l.moveTo(t.tx1,t.ty1),l.lineTo(t.tx2,t.ty2)),c.drawOnChartArea&&(l.moveTo(t.x1,t.y1),l.lineTo(t.x2,t.y2)),l.stroke(),l.restore()),d.display){l.save(),l.translate(t.labelX,t.labelY),l.rotate(t.rotation),l.font=v.font,l.textBaseline=t.textBaseline,l.textAlign=t.textAlign;var e=t.label;if(i.isArray(e))for(var a=0,n=0;a0)i=t.stepSize;else{var o=e.niceNum(a.max-a.min,!1);i=e.niceNum(o/(t.maxTicks-1),!0)}var r=Math.floor(a.min/i)*i,s=Math.ceil(a.max/i)*i;t.min&&t.max&&t.stepSize&&e.almostWhole((t.max-t.min)/t.stepSize,i/1e3)&&(r=t.min,s=t.max);var l=(s-r)/i;l=e.almostEquals(l,Math.round(l),i/1e3)?Math.round(l):Math.ceil(l),n.push(void 0!==t.min?t.min:r);for(var u=1;u3?i[2]-i[1]:i[1]-i[0];Math.abs(n)>1&&t!==Math.floor(t)&&(n=t-Math.floor(t));var o=e.log10(Math.abs(n)),r="";if(0!==t){var s=-1*Math.floor(o);s=Math.max(Math.min(s,20),0),r=t.toFixed(s)}else r="0";return r},logarithmic:function(t,a,i){var n=t/Math.pow(10,Math.floor(e.log10(t)));return 0===t?"0":1===n||2===n||5===n||0===a||a===i.length-1?t.toExponential():""}}}}},{}],35:[function(t,e,a){"use strict";e.exports=function(t){function e(e,a){var i=new t.Title({ctx:e.chart.ctx,options:a,chart:e});e.titleBlock=i,t.layoutService.addBox(e,i)}var a=t.helpers;t.defaults.global.title={display:!1,position:"top",fullWidth:!0,fontStyle:"bold",padding:10,text:""};var i=a.noop;t.Title=t.Element.extend({initialize:function(t){var e=this;a.extend(e,t),e.legendHitBoxes=[]},beforeUpdate:i,update:function(t,e,a){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=a,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:i,beforeSetDimensions:i,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:i,beforeBuildLabels:i,buildLabels:i,afterBuildLabels:i,beforeFit:i,fit:function(){var e=this,i=a.getValueOrDefault,n=e.options,o=t.defaults.global,r=n.display,s=i(n.fontSize,o.defaultFontSize),l=e.minSize;e.isHorizontal()?(l.width=e.maxWidth,l.height=r?s+2*n.padding:0):(l.width=r?s+2*n.padding:0,l.height=e.maxHeight),e.width=l.width,e.height=l.height},afterFit:i,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var e=this,i=e.ctx,n=a.getValueOrDefault,o=e.options,r=t.defaults.global;if(o.display){var s,l,u,d=n(o.fontSize,r.defaultFontSize),c=n(o.fontStyle,r.defaultFontStyle),h=n(o.fontFamily,r.defaultFontFamily),f=a.fontString(d,c,h),g=0,p=e.top,m=e.left,v=e.bottom,b=e.right;i.fillStyle=n(o.fontColor,r.defaultFontColor),i.font=f,e.isHorizontal()?(s=m+(b-m)/2,l=p+(v-p)/2,u=b-m):(s="left"===o.position?m+d/2:b-d/2,l=p+(v-p)/2,u=v-p,g=Math.PI*("left"===o.position?-.5:.5)),i.save(),i.translate(s,l),i.rotate(g),i.textAlign="center",i.textBaseline="middle",i.fillText(o.text,0,0,u),i.restore()}}}),t.plugins.register({beforeInit:function(t){var a=t.options.title;a&&e(t,a)},beforeUpdate:function(i){var n=i.options.title;n?(n=a.configMerge(t.defaults.global.title,n),i.titleBlock?i.titleBlock.options=n:e(i,n)):(t.layoutService.removeBox(i,i.titleBlock),delete i.titleBlock)}})}},{}],36:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){var a=l.color(t);return a.alpha(e*a.alpha()).rgbaString()}function a(t,e){return e&&(l.isArray(e)?Array.prototype.push.apply(t,e):t.push(e)),t}function i(t){var e=t._xScale,a=t._yScale||t._scale,i=t._index,n=t._datasetIndex;return{xLabel:e?e.getLabelForIndex(i,n):"",yLabel:a?a.getLabelForIndex(i,n):"",index:i,datasetIndex:n,x:t._model.x,y:t._model.y}}function n(e){var a=t.defaults.global,i=l.getValueOrDefault;return{xPadding:e.xPadding,yPadding:e.yPadding,xAlign:e.xAlign,yAlign:e.yAlign,bodyFontColor:e.bodyFontColor,_bodyFontFamily:i(e.bodyFontFamily,a.defaultFontFamily),_bodyFontStyle:i(e.bodyFontStyle,a.defaultFontStyle),_bodyAlign:e.bodyAlign,bodyFontSize:i(e.bodyFontSize,a.defaultFontSize),bodySpacing:e.bodySpacing,titleFontColor:e.titleFontColor,_titleFontFamily:i(e.titleFontFamily,a.defaultFontFamily),_titleFontStyle:i(e.titleFontStyle,a.defaultFontStyle),titleFontSize:i(e.titleFontSize,a.defaultFontSize),_titleAlign:e.titleAlign,titleSpacing:e.titleSpacing,titleMarginBottom:e.titleMarginBottom,footerFontColor:e.footerFontColor,_footerFontFamily:i(e.footerFontFamily,a.defaultFontFamily),_footerFontStyle:i(e.footerFontStyle,a.defaultFontStyle),footerFontSize:i(e.footerFontSize,a.defaultFontSize),_footerAlign:e.footerAlign,footerSpacing:e.footerSpacing,footerMarginTop:e.footerMarginTop,caretSize:e.caretSize,cornerRadius:e.cornerRadius,backgroundColor:e.backgroundColor,opacity:0,legendColorBackground:e.multiKeyBackground,displayColors:e.displayColors}}function o(t,e){var a=t._chart.ctx,i=2*e.yPadding,n=0,o=e.body,r=o.reduce(function(t,e){return t+e.before.length+e.lines.length+e.after.length},0);r+=e.beforeBody.length+e.afterBody.length;var s=e.title.length,u=e.footer.length,d=e.titleFontSize,c=e.bodyFontSize,h=e.footerFontSize;i+=s*d,i+=s?(s-1)*e.titleSpacing:0,i+=s?e.titleMarginBottom:0,i+=r*c,i+=r?(r-1)*e.bodySpacing:0,i+=u?e.footerMarginTop:0,i+=u*h,i+=u?(u-1)*e.footerSpacing:0;var f=0,g=function(t){n=Math.max(n,a.measureText(t).width+f)};return a.font=l.fontString(d,e._titleFontStyle,e._titleFontFamily),l.each(e.title,g),a.font=l.fontString(c,e._bodyFontStyle,e._bodyFontFamily),l.each(e.beforeBody.concat(e.afterBody),g),f=e.displayColors?c+2:0,l.each(o,function(t){l.each(t.before,g),l.each(t.lines,g),l.each(t.after,g)}),f=0,a.font=l.fontString(h,e._footerFontStyle,e._footerFontFamily),l.each(e.footer,g),n+=2*e.xPadding,{width:n,height:i}}function r(t,e){var a=t._model,i=t._chart,n=t._chartInstance.chartArea,o="center",r="center";a.yi.height-e.height&&(r="bottom");var s,l,u,d,c,h=(n.left+n.right)/2,f=(n.top+n.bottom)/2;"center"===r?(s=function(t){return t<=h},l=function(t){return t>h}):(s=function(t){return t<=e.width/2},l=function(t){return t>=i.width-e.width/2}),u=function(t){return t+e.width>i.width},d=function(t){return t-e.width<0},c=function(t){return t<=f?"top":"bottom"},s(a.x)?(o="left",u(a.x)&&(o="center",r=c(a.y))):l(a.x)&&(o="right",d(a.x)&&(o="center",r=c(a.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:o,yAlign:g.yAlign?g.yAlign:r}}function s(t,e,a){var i=t.x,n=t.y,o=t.caretSize,r=t.caretPadding,s=t.cornerRadius,l=a.xAlign,u=a.yAlign,d=o+r,c=s+r;return"right"===l?i-=e.width:"center"===l&&(i-=e.width/2),"top"===u?n+=d:n-="bottom"===u?e.height+d:e.height/2,"center"===u?"left"===l?i+=d:"right"===l&&(i-=d):"left"===l?i-=c:"right"===l&&(i+=c),{x:i,y:n}}var l=t.helpers;t.defaults.global.tooltips={enabled:!0,custom:null,mode:"nearest",position:"average",intersect:!0,backgroundColor:"rgba(0,0,0,0.8)",titleFontStyle:"bold",titleSpacing:2,titleMarginBottom:6,titleFontColor:"#fff",titleAlign:"left",bodySpacing:2,bodyFontColor:"#fff",bodyAlign:"left",footerFontStyle:"bold",footerSpacing:2,footerMarginTop:6,footerFontColor:"#fff",footerAlign:"left",yPadding:6,xPadding:6,caretSize:5,cornerRadius:6,multiKeyBackground:"#fff",displayColors:!0,callbacks:{beforeTitle:l.noop,title:function(t,e){var a="",i=e.labels,n=i?i.length:0;if(t.length>0){var o=t[0];o.xLabel?a=o.xLabel:n>0&&o.indexl;)o-=2*Math.PI;for(;o=s&&o<=l,d=r>=i.innerRadius&&r<=i.outerRadius;return u&&d}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,a=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*a,y:t.y+Math.sin(e)*a}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,a=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*a,y:t.y+Math.sin(e)*a}},draw:function(){var t=this._chart.ctx,e=this._view,a=e.startAngle,i=e.endAngle;t.beginPath(),t.arc(e.x,e.y,e.outerRadius,a,i),t.arc(e.x,e.y,e.innerRadius,i,a,!0),t.closePath(),t.strokeStyle=e.borderColor,t.lineWidth=e.borderWidth,t.fillStyle=e.backgroundColor,t.fill(),t.lineJoin="bevel",e.borderWidth&&t.stroke()}})}},{}],38:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=t.defaults.global;t.defaults.global.elements.line={tension:.4,backgroundColor:a.defaultColor,borderWidth:3,borderColor:a.defaultColor,borderCapStyle:"butt",borderDash:[],borderDashOffset:0,borderJoinStyle:"miter",capBezierPoints:!0,fill:!0},t.elements.Line=t.Element.extend({draw:function(){function t(t,e){var a=e._view;e._view.steppedLine===!0?(l.lineTo(a.x,t._view.y),l.lineTo(a.x,a.y)):0===e._view.tension?l.lineTo(a.x,a.y):l.bezierCurveTo(t._view.controlPointNextX,t._view.controlPointNextY,a.controlPointPreviousX,a.controlPointPreviousY,a.x,a.y)}var i=this,n=i._view,o=n.spanGaps,r=n.scaleZero,s=i._loop;s||("top"===n.fill?r=n.scaleTop:"bottom"===n.fill&&(r=n.scaleBottom));var l=i._chart.ctx;l.save();var u=i._children.slice(),d=-1;s&&u.length&&u.push(u[0]);var c,h,f,g;if(u.length&&n.fill){for(l.beginPath(),c=0;ce?1:-1,r=1,s=u.borderSkipped||"left"):(e=u.x-u.width/2,a=u.x+u.width/2,i=u.y,n=u.base,o=1,r=n>i?1:-1,s=u.borderSkipped||"bottom"),d){var c=Math.min(Math.abs(e-a),Math.abs(i-n));d=d>c?c:d;var h=d/2,f=e+("left"!==s?h*o:0),g=a+("right"!==s?-h*o:0),p=i+("top"!==s?h*r:0),m=n+("bottom"!==s?-h*r:0);f!==g&&(i=p,n=m),p!==m&&(e=f,a=g)}l.beginPath(),l.fillStyle=u.backgroundColor,l.strokeStyle=u.borderColor,l.lineWidth=d;var v=[[e,n],[e,i],[a,i],[a,n]],b=["bottom","left","top","right"],x=b.indexOf(s,0);x===-1&&(x=0);var y=t(0);l.moveTo(y[0],y[1]);for(var k=1;k<4;k++)y=t(k),l.lineTo(y[0],y[1]);l.fill(),d&&l.stroke()},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){var i=!1;if(this._view){var n=a(this);i=t>=n.left&&t<=n.right&&e>=n.top&&e<=n.bottom}return i},inLabelRange:function(t,i){var n=this;if(!n._view)return!1;var o=!1,r=a(n);return o=e(n)?t>=r.left&&t<=r.right:i>=r.top&&i<=r.bottom},inXRange:function(t){var e=a(this);return t>=e.left&&t<=e.right},inYRange:function(t){var e=a(this);return t>=e.top&&t<=e.bottom},getCenterPoint:function(){var t,a,i=this._view;return e(this)?(t=i.x,a=(i.y+i.base)/2):(t=(i.x+i.base)/2,a=i.y),{x:t,y:a}},getArea:function(){var t=this._view;return t.width*Math.abs(t.y-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}})}},{}],41:[function(t,e,a){"use strict";e.exports=function(t){function e(t,e){var a=l.getStyle(t,e),i=a&&a.match(/(\d+)px/);return i?Number(i[1]):void 0}function a(t,a){var i=t.style,n=t.getAttribute("height"),o=t.getAttribute("width");if(t._chartjs={initial:{height:n,width:o,style:{display:i.display,height:i.height,width:i.width}}},i.display=i.display||"block",null===o||""===o){var r=e(t,"width");void 0!==r&&(t.width=r)}if(null===n||""===n)if(""===t.style.height)t.height=t.width/(a.options.aspectRatio||2);else{var s=e(t,"height");void 0!==r&&(t.height=s)}return t}function i(t,e,a,i,n){return{type:t,chart:e,native:n||null,x:void 0!==a?a:null,y:void 0!==i?i:null}}function n(t,e){ +var a=u[t.type]||t.type,n=l.getRelativePosition(t,e);return i(a,e,n.x,n.y,t)}function o(t){var e=document.createElement("iframe");return e.className="chartjs-hidden-iframe",e.style.cssText="display:block;overflow:hidden;border:0;margin:0;top:0;left:0;bottom:0;right:0;height:100%;width:100%;position:absolute;pointer-events:none;z-index:-1;",e.tabIndex=-1,l.addEvent(e,"load",function(){l.addEvent(e.contentWindow||e,"resize",t),t()}),e}function r(t,e,a){var n=t._chartjs={ticking:!1},r=function(){n.ticking||(n.ticking=!0,l.requestAnimFrame.call(window,function(){if(n.resizer)return n.ticking=!1,e(i("resize",a))}))};n.resizer=o(r),t.insertBefore(n.resizer,t.firstChild)}function s(t){if(t&&t._chartjs){var e=t._chartjs.resizer;e&&(e.parentNode.removeChild(e),t._chartjs.resizer=null),delete t._chartjs}}var l=t.helpers,u={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};return{acquireContext:function(t,e){if("string"==typeof t?t=document.getElementById(t):t.length&&(t=t[0]),t&&t.canvas&&(t=t.canvas),t instanceof HTMLCanvasElement){var i=t.getContext&&t.getContext("2d");if(i instanceof CanvasRenderingContext2D)return a(t,e),i}return null},releaseContext:function(t){var e=t.canvas;if(e._chartjs){var a=e._chartjs.initial;["height","width"].forEach(function(t){var i=a[t];void 0===i||null===i?e.removeAttribute(t):e.setAttribute(t,i)}),l.each(a.style||{},function(t,a){e.style[a]=t}),e.width=e.width,delete e._chartjs}},addEventListener:function(t,e,a){var i=t.chart.canvas;if("resize"===e)return void r(i.parentNode,a,t.chart);var o=a._chartjs||(a._chartjs={}),s=o.proxies||(o.proxies={}),u=s[t.id+"_"+e]=function(e){a(n(e,t.chart))};l.addEvent(i,e,u)},removeEventListener:function(t,e,a){var i=t.chart.canvas;if("resize"===e)return void s(i.parentNode,a);var n=a._chartjs||{},o=n.proxies||{},r=o[t.id+"_"+e];r&&l.removeEvent(i,e,r)}}}},{}],42:[function(t,e,a){"use strict";var i=t(41);e.exports=function(t){t.platform={acquireContext:function(){},releaseContext:function(){},addEventListener:function(){},removeEventListener:function(){}},t.helpers.extend(t.platform,i(t))}},{41:41}],43:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"bottom"},i=t.Scale.extend({getLabels:function(){var t=this.chart.data;return(this.isHorizontal()?t.xLabels:t.yLabels)||t.labels},determineDataLimits:function(){var t=this,a=t.getLabels();t.minIndex=0,t.maxIndex=a.length-1;var i;void 0!==t.options.ticks.min&&(i=e.indexOf(a,t.options.ticks.min),t.minIndex=i!==-1?i:t.minIndex),void 0!==t.options.ticks.max&&(i=e.indexOf(a,t.options.ticks.max),t.maxIndex=i!==-1?i:t.maxIndex),t.min=a[t.minIndex],t.max=a[t.maxIndex]},buildTicks:function(){var t=this,e=t.getLabels();t.ticks=0===t.minIndex&&t.maxIndex===e.length-1?e:e.slice(t.minIndex,t.maxIndex+1)},getLabelForIndex:function(t,e){var a=this,i=a.chart.data,n=a.isHorizontal();return i.yLabels&&!n?a.getRightValue(i.datasets[e].data[t]):a.ticks[t-a.minIndex]},getPixelForValue:function(t,e,a,i){var n=this,o=Math.max(n.maxIndex+1-n.minIndex-(n.options.gridLines.offsetGridLines?0:1),1);if(void 0!==t&&isNaN(e)){var r=n.getLabels(),s=r.indexOf(t);e=s!==-1?s:e}if(n.isHorizontal()){var l=n.width/o,u=l*(e-n.minIndex);return(n.options.gridLines.offsetGridLines&&i||n.maxIndex===n.minIndex&&i)&&(u+=l/2),n.left+Math.round(u)}var d=n.height/o,c=d*(e-n.minIndex);return n.options.gridLines.offsetGridLines&&i&&(c+=d/2),n.top+Math.round(c)},getPixelForTick:function(t,e){return this.getPixelForValue(this.ticks[t],t+this.minIndex,null,e)},getValueForPixel:function(t){var e,a=this,i=Math.max(a.ticks.length-(a.options.gridLines.offsetGridLines?0:1),1),n=a.isHorizontal(),o=(n?a.width:a.height)/i;return t-=n?a.left:a.top,a.options.gridLines.offsetGridLines&&(t-=o/2),e=t<=0?0:Math.round(t/o)},getBasePixel:function(){return this.bottom}});t.scaleService.registerScaleType("category",i,a)}},{}],44:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"left",ticks:{callback:t.Ticks.formatters.linear}},i=t.LinearScaleBase.extend({determineDataLimits:function(){function t(t){return s?t.xAxisID===a.id:t.yAxisID===a.id}var a=this,i=a.options,n=a.chart,o=n.data,r=o.datasets,s=a.isHorizontal();a.min=null,a.max=null;var l=i.stacked;if(void 0===l&&e.each(r,function(e,a){if(!l){var i=n.getDatasetMeta(a);n.isDatasetVisible(a)&&t(i)&&void 0!==i.stack&&(l=!0)}}),i.stacked||l){var u={};e.each(r,function(o,r){var s=n.getDatasetMeta(r),l=[s.type,void 0===i.stacked&&void 0===s.stack?r:"",s.stack].join(".");void 0===u[l]&&(u[l]={positiveValues:[],negativeValues:[]});var d=u[l].positiveValues,c=u[l].negativeValues;n.isDatasetVisible(r)&&t(s)&&e.each(o.data,function(t,e){var n=+a.getRightValue(t);isNaN(n)||s.data[e].hidden||(d[e]=d[e]||0,c[e]=c[e]||0,i.relativePoints?d[e]=100:n<0?c[e]+=n:d[e]+=n)})}),e.each(u,function(t){var i=t.positiveValues.concat(t.negativeValues),n=e.min(i),o=e.max(i);a.min=null===a.min?n:Math.min(a.min,n),a.max=null===a.max?o:Math.max(a.max,o)})}else e.each(r,function(i,o){var r=n.getDatasetMeta(o);n.isDatasetVisible(o)&&t(r)&&e.each(i.data,function(t,e){var i=+a.getRightValue(t);isNaN(i)||r.data[e].hidden||(null===a.min?a.min=i:ia.max&&(a.max=i))})});this.handleTickRangeOptions()},getTickLimit:function(){var a,i=this,n=i.options.ticks;if(i.isHorizontal())a=Math.min(n.maxTicksLimit?n.maxTicksLimit:11,Math.ceil(i.width/50));else{var o=e.getValueOrDefault(n.fontSize,t.defaults.global.defaultFontSize);a=Math.min(n.maxTicksLimit?n.maxTicksLimit:11,Math.ceil(i.height/(2*o)))}return a},handleDirectionalChanges:function(){this.isHorizontal()||this.ticks.reverse()},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},getPixelForValue:function(t){var e,a=this,i=a.start,n=+a.getRightValue(t),o=a.end-i;return a.isHorizontal()?(e=a.left+a.width/o*(n-i),Math.round(e)):(e=a.bottom-a.height/o*(n-i),Math.round(e))},getValueForPixel:function(t){var e=this,a=e.isHorizontal(),i=a?e.width:e.height,n=(a?t-e.left:e.bottom-t)/i;return e.start+(e.end-e.start)*n},getPixelForTick:function(t){return this.getPixelForValue(this.ticksAsNumbers[t])}});t.scaleService.registerScaleType("linear",i,a)}},{}],45:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a=e.noop;t.LinearScaleBase=t.Scale.extend({handleTickRangeOptions:function(){var t=this,a=t.options,i=a.ticks;if(i.beginAtZero){var n=e.sign(t.min),o=e.sign(t.max);n<0&&o<0?t.max=0:n>0&&o>0&&(t.min=0)}void 0!==i.min?t.min=i.min:void 0!==i.suggestedMin&&(t.min=Math.min(t.min,i.suggestedMin)),void 0!==i.max?t.max=i.max:void 0!==i.suggestedMax&&(t.max=Math.max(t.max,i.suggestedMax)),t.min===t.max&&(t.max++,i.beginAtZero||t.min--)},getTickLimit:a,handleDirectionalChanges:a,buildTicks:function(){var a=this,i=a.options,n=i.ticks,o=a.getTickLimit();o=Math.max(2,o);var r={maxTicks:o,min:n.min,max:n.max,stepSize:e.getValueOrDefault(n.fixedStepSize,n.stepSize)},s=a.ticks=t.Ticks.generators.linear(r,a);a.handleDirectionalChanges(),a.max=e.max(s),a.min=e.min(s),n.reverse?(s.reverse(),a.start=a.max,a.end=a.min):(a.start=a.min,a.end=a.max)},convertTicksToLabels:function(){var e=this;e.ticksAsNumbers=e.ticks.slice(),e.zeroLineIndex=e.ticks.indexOf(0),t.Scale.prototype.convertTicksToLabels.call(e)}})}},{}],46:[function(t,e,a){"use strict";e.exports=function(t){var e=t.helpers,a={position:"left",ticks:{callback:t.Ticks.formatters.logarithmic}},i=t.Scale.extend({determineDataLimits:function(){function t(t){return u?t.xAxisID===a.id:t.yAxisID===a.id}var a=this,i=a.options,n=i.ticks,o=a.chart,r=o.data,s=r.datasets,l=e.getValueOrDefault,u=a.isHorizontal();a.min=null,a.max=null,a.minNotZero=null;var d=i.stacked;if(void 0===d&&e.each(s,function(e,a){if(!d){var i=o.getDatasetMeta(a);o.isDatasetVisible(a)&&t(i)&&void 0!==i.stack&&(d=!0)}}),i.stacked||d){var c={};e.each(s,function(n,r){var s=o.getDatasetMeta(r),l=[s.type,void 0===i.stacked&&void 0===s.stack?r:"",s.stack].join(".");o.isDatasetVisible(r)&&t(s)&&(void 0===c[l]&&(c[l]=[]),e.each(n.data,function(t,e){var n=c[l],o=+a.getRightValue(t);isNaN(o)||s.data[e].hidden||(n[e]=n[e]||0,i.relativePoints?n[e]=100:n[e]+=o)}))}),e.each(c,function(t){var i=e.min(t),n=e.max(t);a.min=null===a.min?i:Math.min(a.min,i),a.max=null===a.max?n:Math.max(a.max,n)})}else e.each(s,function(i,n){var r=o.getDatasetMeta(n);o.isDatasetVisible(n)&&t(r)&&e.each(i.data,function(t,e){var i=+a.getRightValue(t);isNaN(i)||r.data[e].hidden||(null===a.min?a.min=i:ia.max&&(a.max=i),0!==i&&(null===a.minNotZero||in?{start:e-a-5,end:e}:{start:e,end:e+a+5}}function o(t){var o,r,s,l=a(t),u=Math.min(t.height/2,t.width/2),d={l:t.width,r:0,t:t.height,b:0},c={};t.ctx.font=l.font,t._pointLabelSizes=[];var h=e(t);for(o=0;od.r&&(d.r=m.end,c.r=g),v.startd.b&&(d.b=v.end,c.b=g)}t.setReductions(u,d,c)}function r(t){var e=Math.min(t.height/2,t.width/2);t.drawingArea=Math.round(e),t.setCenterPoint(0,0,0,0)}function s(t){return 0===t||180===t?"center":t<180?"left":"right"}function l(t,e,a,i){if(f.isArray(e))for(var n=a.y,o=1.5*i,r=0;r270||t<90)&&(a.y-=e.h)}function d(t){var i=t.ctx,n=f.getValueOrDefault,o=t.options,r=o.angleLines,d=o.pointLabels;i.lineWidth=r.lineWidth,i.strokeStyle=r.color;var c=t.getDistanceFromCenterForValue(o.reverse?t.min:t.max),h=a(t);i.textBaseline="top";for(var p=e(t)-1;p>=0;p--){if(r.display){var m=t.getPointPosition(p,c);i.beginPath(),i.moveTo(t.xCenter,t.yCenter),i.lineTo(m.x,m.y),i.stroke(),i.closePath()}var v=t.getPointPosition(p,c+5),b=n(d.fontColor,g.defaultFontColor);i.font=h.font,i.fillStyle=b;var x=t.getIndexAngle(p),y=f.toDegrees(x);i.textAlign=s(y),u(y,t._pointLabelSizes[p],v),l(i,t.pointLabels[p]||"",v,h.size)}}function c(t,a,i,n){var o=t.ctx;if(o.strokeStyle=f.getValueAtIndexOrDefault(a.color,n-1),o.lineWidth=f.getValueAtIndexOrDefault(a.lineWidth,n-1),t.options.lineArc)o.beginPath(),o.arc(t.xCenter,t.yCenter,i,0,2*Math.PI),o.closePath(),o.stroke();else{var r=e(t);if(0===r)return;o.beginPath();var s=t.getPointPosition(0,i);o.moveTo(s.x,s.y);for(var l=1;l0&&a>0?e:0)},draw:function(){var t=this,e=t.options,a=e.gridLines,i=e.ticks,n=f.getValueOrDefault;if(e.display){var o=t.ctx,r=n(i.fontSize,g.defaultFontSize),s=n(i.fontStyle,g.defaultFontStyle),l=n(i.fontFamily,g.defaultFontFamily),u=f.fontString(r,s,l);f.each(t.ticks,function(s,l){if(l>0||e.reverse){var d=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),h=t.yCenter-d;if(a.display&&0!==l&&c(t,a,d,l),i.display){var f=n(i.fontColor,g.defaultFontColor);if(o.font=u,i.showLabelBackdrop){var p=o.measureText(s).width;o.fillStyle=i.backdropColor,o.fillRect(t.xCenter-p/2-i.backdropPaddingX,h-r/2-i.backdropPaddingY,p+2*i.backdropPaddingX,r+2*i.backdropPaddingY)}o.textAlign="center",o.textBaseline="middle",o.fillStyle=f,o.fillText(s,t.xCenter,h)}}}),e.lineArc||d(t)}}});t.scaleService.registerScaleType("radialLinear",m,p)}},{}],48:[function(t,e,a){"use strict";var i=t(1);i="function"==typeof i?i:window.moment,e.exports=function(t){var e=t.helpers,a={units:[{name:"millisecond",steps:[1,2,5,10,20,50,100,250,500]},{name:"second",steps:[1,2,5,10,30]},{name:"minute",steps:[1,2,5,10,30]},{name:"hour",steps:[1,2,3,6,12]},{name:"day",steps:[1,2,5]},{name:"week",maxStep:4},{name:"month",maxStep:3},{name:"quarter",maxStep:4},{name:"year",maxStep:!1}]},n={position:"bottom",time:{parser:!1,format:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm:ss a",hour:"MMM D, hA",day:"ll",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"}},ticks:{autoSkip:!1}},o=t.Scale.extend({initialize:function(){if(!i)throw new Error("Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com");t.Scale.prototype.initialize.call(this)},getLabelMoment:function(t,e){return null===t||null===e?null:"undefined"!=typeof this.labelMoments[t]?this.labelMoments[t][e]:null},getLabelDiff:function(t,e){var a=this;return null===t||null===e?null:(void 0===a.labelDiffs&&a.buildLabelDiffs(),"undefined"!=typeof a.labelDiffs[t]?a.labelDiffs[t][e]:null)},getMomentStartOf:function(t){var e=this;return"week"===e.options.time.unit&&e.options.time.isoWeekday!==!1?t.clone().startOf("isoWeek").isoWeekday(e.options.time.isoWeekday):t.clone().startOf(e.tickUnit)},determineDataLimits:function(){var t=this;t.labelMoments=[];var a=[];t.chart.data.labels&&t.chart.data.labels.length>0?(e.each(t.chart.data.labels,function(e){var i=t.parseTime(e);i.isValid()&&(t.options.time.round&&i.startOf(t.options.time.round),a.push(i))},t),t.firstTick=i.min.call(t,a),t.lastTick=i.max.call(t,a)):(t.firstTick=null,t.lastTick=null),e.each(t.chart.data.datasets,function(n,o){var r=[],s=t.chart.isDatasetVisible(o);"object"==typeof n.data[0]&&null!==n.data[0]?e.each(n.data,function(e){var a=t.parseTime(t.getRightValue(e));a.isValid()&&(t.options.time.round&&a.startOf(t.options.time.round),r.push(a),s&&(t.firstTick=null!==t.firstTick?i.min(t.firstTick,a):a,t.lastTick=null!==t.lastTick?i.max(t.lastTick,a):a))},t):r=a,t.labelMoments.push(r)},t),t.options.time.min&&(t.firstTick=t.parseTime(t.options.time.min)),t.options.time.max&&(t.lastTick=t.parseTime(t.options.time.max)),t.firstTick=(t.firstTick||i()).clone(),t.lastTick=(t.lastTick||i()).clone()},buildLabelDiffs:function(){var t=this;t.labelDiffs=[];var a=[];t.chart.data.labels&&t.chart.data.labels.length>0&&e.each(t.chart.data.labels,function(e){var i=t.parseTime(e);i.isValid()&&(t.options.time.round&&i.startOf(t.options.time.round),a.push(i.diff(t.firstTick,t.tickUnit,!0)))},t),e.each(t.chart.data.datasets,function(i){var n=[];"object"==typeof i.data[0]&&null!==i.data[0]?e.each(i.data,function(e){var a=t.parseTime(t.getRightValue(e));a.isValid()&&(t.options.time.round&&a.startOf(t.options.time.round),n.push(a.diff(t.firstTick,t.tickUnit,!0)))},t):n=a,t.labelDiffs.push(n)},t)},buildTicks:function(){var i=this;i.ctx.save();var n=e.getValueOrDefault(i.options.ticks.fontSize,t.defaults.global.defaultFontSize),o=e.getValueOrDefault(i.options.ticks.fontStyle,t.defaults.global.defaultFontStyle),r=e.getValueOrDefault(i.options.ticks.fontFamily,t.defaults.global.defaultFontFamily),s=e.fontString(n,o,r);if(i.ctx.font=s,i.ticks=[],i.unitScale=1,i.scaleSizeInUnits=0,i.options.time.unit)i.tickUnit=i.options.time.unit||"day",i.displayFormat=i.options.time.displayFormats[i.tickUnit],i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0),i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,1);else{var l=i.isHorizontal()?i.width:i.height,u=i.tickFormatFunction(i.firstTick,0,[]),d=i.ctx.measureText(u).width,c=Math.cos(e.toRadians(i.options.ticks.maxRotation)),h=Math.sin(e.toRadians(i.options.ticks.maxRotation));d=d*c+n*h;var f=l/d;i.tickUnit=i.options.time.minUnit,i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0),i.displayFormat=i.options.time.displayFormats[i.tickUnit];for(var g=0,p=a.units[g];g=Math.ceil(i.scaleSizeInUnits/f)){i.unitScale=e.getValueOrDefault(i.options.time.unitStepSize,p.steps[m]);break}break}if(p.maxStep===!1||Math.ceil(i.scaleSizeInUnits/f)=0&&(i.lastTick=y),i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0)}i.options.time.displayFormat&&(i.displayFormat=i.options.time.displayFormat),i.ticks.push(i.firstTick.clone());for(var S=i.unitScale;S<=i.scaleSizeInUnits;S+=i.unitScale){var M=x.clone().add(S,i.tickUnit);if(i.options.time.max&&M.diff(i.lastTick,i.tickUnit,!0)>=0)break;i.ticks.push(M)}var w=i.ticks[i.ticks.length-1].diff(i.lastTick,i.tickUnit);0===w&&0!==i.scaleSizeInUnits||(i.options.time.max?(i.ticks.push(i.lastTick.clone()),i.scaleSizeInUnits=i.lastTick.diff(i.ticks[0],i.tickUnit,!0)):(i.ticks.push(i.lastTick.clone()),i.scaleSizeInUnits=i.lastTick.diff(i.firstTick,i.tickUnit,!0))),i.ctx.restore(),i.labelDiffs=void 0},getLabelForIndex:function(t,e){var a=this,i=a.chart.data.labels&&t svg, +.leaflet-pane > canvas, +.leaflet-zoom-box, +.leaflet-image-layer, +.leaflet-layer { + position: absolute; + left: 0; + top: 0; + } +.leaflet-container { + overflow: hidden; + } +.leaflet-tile, +.leaflet-marker-icon, +.leaflet-marker-shadow { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + -webkit-user-drag: none; + } +/* Safari renders non-retina tile on retina better with this, but Chrome is worse */ +.leaflet-safari .leaflet-tile { + image-rendering: -webkit-optimize-contrast; + } +/* hack that prevents hw layers "stretching" when loading new tiles */ +.leaflet-safari .leaflet-tile-container { + width: 1600px; + height: 1600px; + -webkit-transform-origin: 0 0; + } +.leaflet-marker-icon, +.leaflet-marker-shadow { + display: block; + } +/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */ +/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */ +.leaflet-container .leaflet-overlay-pane svg, +.leaflet-container .leaflet-marker-pane img, +.leaflet-container .leaflet-shadow-pane img, +.leaflet-container .leaflet-tile-pane img, +.leaflet-container img.leaflet-image-layer { + max-width: none !important; + } + +.leaflet-container.leaflet-touch-zoom { + -ms-touch-action: pan-x pan-y; + touch-action: pan-x pan-y; + } +.leaflet-container.leaflet-touch-drag { + -ms-touch-action: pinch-zoom; + } +.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom { + -ms-touch-action: none; + touch-action: none; +} +.leaflet-tile { + filter: inherit; + visibility: hidden; + } +.leaflet-tile-loaded { + visibility: inherit; + } +.leaflet-zoom-box { + width: 0; + height: 0; + -moz-box-sizing: border-box; + box-sizing: border-box; + z-index: 800; + } +/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */ +.leaflet-overlay-pane svg { + -moz-user-select: none; + } + +.leaflet-pane { z-index: 400; } + +.leaflet-tile-pane { z-index: 200; } +.leaflet-overlay-pane { z-index: 400; } +.leaflet-shadow-pane { z-index: 500; } +.leaflet-marker-pane { z-index: 600; } +.leaflet-tooltip-pane { z-index: 650; } +.leaflet-popup-pane { z-index: 700; } + +.leaflet-map-pane canvas { z-index: 100; } +.leaflet-map-pane svg { z-index: 200; } + +.leaflet-vml-shape { + width: 1px; + height: 1px; + } +.lvml { + behavior: url(#default#VML); + display: inline-block; + position: absolute; + } + + +/* control positioning */ + +.leaflet-control { + position: relative; + z-index: 800; + pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ + pointer-events: auto; + } +.leaflet-top, +.leaflet-bottom { + position: absolute; + z-index: 1000; + pointer-events: none; + } +.leaflet-top { + top: 0; + } +.leaflet-right { + right: 0; + } +.leaflet-bottom { + bottom: 0; + } +.leaflet-left { + left: 0; + } +.leaflet-control { + float: left; + clear: both; + } +.leaflet-right .leaflet-control { + float: right; + } +.leaflet-top .leaflet-control { + margin-top: 10px; + } +.leaflet-bottom .leaflet-control { + margin-bottom: 10px; + } +.leaflet-left .leaflet-control { + margin-left: 10px; + } +.leaflet-right .leaflet-control { + margin-right: 10px; + } + + +/* zoom and fade animations */ + +.leaflet-fade-anim .leaflet-tile { + will-change: opacity; + } +.leaflet-fade-anim .leaflet-popup { + opacity: 0; + -webkit-transition: opacity 0.2s linear; + -moz-transition: opacity 0.2s linear; + -o-transition: opacity 0.2s linear; + transition: opacity 0.2s linear; + } +.leaflet-fade-anim .leaflet-map-pane .leaflet-popup { + opacity: 1; + } +.leaflet-zoom-animated { + -webkit-transform-origin: 0 0; + -ms-transform-origin: 0 0; + transform-origin: 0 0; + } +.leaflet-zoom-anim .leaflet-zoom-animated { + will-change: transform; + } +.leaflet-zoom-anim .leaflet-zoom-animated { + -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1); + -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1); + -o-transition: -o-transform 0.25s cubic-bezier(0,0,0.25,1); + transition: transform 0.25s cubic-bezier(0,0,0.25,1); + } +.leaflet-zoom-anim .leaflet-tile, +.leaflet-pan-anim .leaflet-tile { + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; + } + +.leaflet-zoom-anim .leaflet-zoom-hide { + visibility: hidden; + } + + +/* cursors */ + +.leaflet-interactive { + cursor: pointer; + } +.leaflet-grab { + cursor: -webkit-grab; + cursor: -moz-grab; + } +.leaflet-crosshair, +.leaflet-crosshair .leaflet-interactive { + cursor: crosshair; + } +.leaflet-popup-pane, +.leaflet-control { + cursor: auto; + } +.leaflet-dragging .leaflet-grab, +.leaflet-dragging .leaflet-grab .leaflet-interactive, +.leaflet-dragging .leaflet-marker-draggable { + cursor: move; + cursor: -webkit-grabbing; + cursor: -moz-grabbing; + } + +/* marker & overlays interactivity */ +.leaflet-marker-icon, +.leaflet-marker-shadow, +.leaflet-image-layer, +.leaflet-pane > svg path, +.leaflet-tile-container { + pointer-events: none; + } + +.leaflet-marker-icon.leaflet-interactive, +.leaflet-image-layer.leaflet-interactive, +.leaflet-pane > svg path.leaflet-interactive { + pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ + pointer-events: auto; + } + +/* visual tweaks */ + +.leaflet-container { + background: #ddd; + outline: 0; + } +.leaflet-container a { + color: #0078A8; + } +.leaflet-container a.leaflet-active { + outline: 2px solid orange; + } +.leaflet-zoom-box { + border: 2px dotted #38f; + background: rgba(255,255,255,0.5); + } + + +/* general typography */ +.leaflet-container { + font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif; + } + + +/* general toolbar styles */ + +.leaflet-bar { + box-shadow: 0 1px 5px rgba(0,0,0,0.65); + border-radius: 4px; + } +.leaflet-bar a, +.leaflet-bar a:hover { + background-color: #fff; + border-bottom: 1px solid #ccc; + width: 26px; + height: 26px; + line-height: 26px; + display: block; + text-align: center; + text-decoration: none; + color: black; + } +.leaflet-bar a, +.leaflet-control-layers-toggle { + background-position: 50% 50%; + background-repeat: no-repeat; + display: block; + } +.leaflet-bar a:hover { + background-color: #f4f4f4; + } +.leaflet-bar a:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; + } +.leaflet-bar a:last-child { + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + border-bottom: none; + } +.leaflet-bar a.leaflet-disabled { + cursor: default; + background-color: #f4f4f4; + color: #bbb; + } + +.leaflet-touch .leaflet-bar a { + width: 30px; + height: 30px; + line-height: 30px; + } + + +/* zoom control */ + +.leaflet-control-zoom-in, +.leaflet-control-zoom-out { + font: bold 18px 'Lucida Console', Monaco, monospace; + text-indent: 1px; + } +.leaflet-control-zoom-out { + font-size: 20px; + } + +.leaflet-touch .leaflet-control-zoom-in { + font-size: 22px; + } +.leaflet-touch .leaflet-control-zoom-out { + font-size: 24px; + } + + +/* layers control */ + +.leaflet-control-layers { + box-shadow: 0 1px 5px rgba(0,0,0,0.4); + background: #fff; + border-radius: 5px; + } +.leaflet-control-layers-toggle { + background-image: url(images/layers.png); + width: 36px; + height: 36px; + } +.leaflet-retina .leaflet-control-layers-toggle { + background-image: url(images/layers-2x.png); + background-size: 26px 26px; + } +.leaflet-touch .leaflet-control-layers-toggle { + width: 44px; + height: 44px; + } +.leaflet-control-layers .leaflet-control-layers-list, +.leaflet-control-layers-expanded .leaflet-control-layers-toggle { + display: none; + } +.leaflet-control-layers-expanded .leaflet-control-layers-list { + display: block; + position: relative; + } +.leaflet-control-layers-expanded { + padding: 6px 10px 6px 6px; + color: #333; + background: #fff; + } +.leaflet-control-layers-scrollbar { + overflow-y: scroll; + padding-right: 5px; + } +.leaflet-control-layers-selector { + margin-top: 2px; + position: relative; + top: 1px; + } +.leaflet-control-layers label { + display: block; + } +.leaflet-control-layers-separator { + height: 0; + border-top: 1px solid #ddd; + margin: 5px -10px 5px -6px; + } + +/* Default icon URLs */ +.leaflet-default-icon-path { + background-image: url(images/marker-icon.png); + } + + +/* attribution and scale controls */ + +.leaflet-container .leaflet-control-attribution { + background: #fff; + background: rgba(255, 255, 255, 0.7); + margin: 0; + } +.leaflet-control-attribution, +.leaflet-control-scale-line { + padding: 0 5px; + color: #333; + } +.leaflet-control-attribution a { + text-decoration: none; + } +.leaflet-control-attribution a:hover { + text-decoration: underline; + } +.leaflet-container .leaflet-control-attribution, +.leaflet-container .leaflet-control-scale { + font-size: 11px; + } +.leaflet-left .leaflet-control-scale { + margin-left: 5px; + } +.leaflet-bottom .leaflet-control-scale { + margin-bottom: 5px; + } +.leaflet-control-scale-line { + border: 2px solid #777; + border-top: none; + line-height: 1.1; + padding: 2px 5px 1px; + font-size: 11px; + white-space: nowrap; + overflow: hidden; + -moz-box-sizing: border-box; + box-sizing: border-box; + + background: #fff; + background: rgba(255, 255, 255, 0.5); + } +.leaflet-control-scale-line:not(:first-child) { + border-top: 2px solid #777; + border-bottom: none; + margin-top: -2px; + } +.leaflet-control-scale-line:not(:first-child):not(:last-child) { + border-bottom: 2px solid #777; + } + +.leaflet-touch .leaflet-control-attribution, +.leaflet-touch .leaflet-control-layers, +.leaflet-touch .leaflet-bar { + box-shadow: none; + } +.leaflet-touch .leaflet-control-layers, +.leaflet-touch .leaflet-bar { + border: 2px solid rgba(0,0,0,0.2); + background-clip: padding-box; + } + + +/* popup */ + +.leaflet-popup { + position: absolute; + text-align: center; + margin-bottom: 20px; + } +.leaflet-popup-content-wrapper { + padding: 1px; + text-align: left; + border-radius: 12px; + } +.leaflet-popup-content { + margin: 13px 19px; + line-height: 1.4; + } +.leaflet-popup-content p { + margin: 18px 0; + } +.leaflet-popup-tip-container { + width: 40px; + height: 20px; + position: absolute; + left: 50%; + margin-left: -20px; + overflow: hidden; + pointer-events: none; + } +.leaflet-popup-tip { + width: 17px; + height: 17px; + padding: 1px; + + margin: -10px auto 0; + + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); + } +.leaflet-popup-content-wrapper, +.leaflet-popup-tip { + background: white; + color: #333; + box-shadow: 0 3px 14px rgba(0,0,0,0.4); + } +.leaflet-container a.leaflet-popup-close-button { + position: absolute; + top: 0; + right: 0; + padding: 4px 4px 0 0; + border: none; + text-align: center; + width: 18px; + height: 14px; + font: 16px/14px Tahoma, Verdana, sans-serif; + color: #c3c3c3; + text-decoration: none; + font-weight: bold; + background: transparent; + } +.leaflet-container a.leaflet-popup-close-button:hover { + color: #999; + } +.leaflet-popup-scrolled { + overflow: auto; + border-bottom: 1px solid #ddd; + border-top: 1px solid #ddd; + } + +.leaflet-oldie .leaflet-popup-content-wrapper { + zoom: 1; + } +.leaflet-oldie .leaflet-popup-tip { + width: 24px; + margin: 0 auto; + + -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; + filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); + } +.leaflet-oldie .leaflet-popup-tip-container { + margin-top: -1px; + } + +.leaflet-oldie .leaflet-control-zoom, +.leaflet-oldie .leaflet-control-layers, +.leaflet-oldie .leaflet-popup-content-wrapper, +.leaflet-oldie .leaflet-popup-tip { + border: 1px solid #999; + } + + +/* div icon */ + +.leaflet-div-icon { + background: #fff; + border: 1px solid #666; + } + + +/* Tooltip */ +/* Base styles for the element that has a tooltip */ +.leaflet-tooltip { + position: absolute; + padding: 6px; + background-color: #fff; + border: 1px solid #fff; + border-radius: 3px; + color: #222; + white-space: nowrap; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + pointer-events: none; + box-shadow: 0 1px 3px rgba(0,0,0,0.4); + } +.leaflet-tooltip.leaflet-clickable { + cursor: pointer; + pointer-events: auto; + } +.leaflet-tooltip-top:before, +.leaflet-tooltip-bottom:before, +.leaflet-tooltip-left:before, +.leaflet-tooltip-right:before { + position: absolute; + pointer-events: none; + border: 6px solid transparent; + background: transparent; + content: ""; + } + +/* Directions */ + +.leaflet-tooltip-bottom { + margin-top: 6px; +} +.leaflet-tooltip-top { + margin-top: -6px; +} +.leaflet-tooltip-bottom:before, +.leaflet-tooltip-top:before { + left: 50%; + margin-left: -6px; + } +.leaflet-tooltip-top:before { + bottom: 0; + margin-bottom: -12px; + border-top-color: #fff; + } +.leaflet-tooltip-bottom:before { + top: 0; + margin-top: -12px; + margin-left: -6px; + border-bottom-color: #fff; + } +.leaflet-tooltip-left { + margin-left: -6px; +} +.leaflet-tooltip-right { + margin-left: 6px; +} +.leaflet-tooltip-left:before, +.leaflet-tooltip-right:before { + top: 50%; + margin-top: -6px; + } +.leaflet-tooltip-left:before { + right: 0; + margin-right: -12px; + border-left-color: #fff; + } +.leaflet-tooltip-right:before { + left: 0; + margin-left: -12px; + border-right-color: #fff; + } diff --git a/org.argeo.suite.workbench.rap/js/leaflet.js b/org.argeo.suite.workbench.rap/js/leaflet.js new file mode 100644 index 0000000..24042d1 --- /dev/null +++ b/org.argeo.suite.workbench.rap/js/leaflet.js @@ -0,0 +1,9 @@ +/* + Leaflet 1.0.3+ed36a04, a JS library for interactive maps. http://leafletjs.com + (c) 2010-2016 Vladimir Agafonkin, (c) 2010-2011 CloudMade +*/ +!function(t,e,i){function n(){var e=t.L;o.noConflict=function(){return t.L=e,this},t.L=o}var o={version:"1.0.3+ed36a04"};"object"==typeof module&&"object"==typeof module.exports?module.exports=o:"function"==typeof define&&define.amd&&define(o),"undefined"!=typeof t&&n(),o.Util={extend:function(t){var e,i,n,o;for(i=1,n=arguments.length;i1}}(),o.Point=function(t,e,i){this.x=i?Math.round(t):t,this.y=i?Math.round(e):e},o.Point.prototype={clone:function(){return new o.Point(this.x,this.y)},add:function(t){return this.clone()._add(o.point(t))},_add:function(t){return this.x+=t.x,this.y+=t.y,this},subtract:function(t){return this.clone()._subtract(o.point(t))},_subtract:function(t){return this.x-=t.x,this.y-=t.y,this},divideBy:function(t){return this.clone()._divideBy(t)},_divideBy:function(t){return this.x/=t,this.y/=t,this},multiplyBy:function(t){return this.clone()._multiplyBy(t)},_multiplyBy:function(t){return this.x*=t,this.y*=t,this},scaleBy:function(t){return new o.Point(this.x*t.x,this.y*t.y)},unscaleBy:function(t){return new o.Point(this.x/t.x,this.y/t.y)},round:function(){return this.clone()._round()},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},floor:function(){return this.clone()._floor()},_floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this},ceil:function(){return this.clone()._ceil()},_ceil:function(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this},distanceTo:function(t){t=o.point(t);var e=t.x-this.x,i=t.y-this.y;return Math.sqrt(e*e+i*i)},equals:function(t){return t=o.point(t),t.x===this.x&&t.y===this.y},contains:function(t){return t=o.point(t),Math.abs(t.x)<=Math.abs(this.x)&&Math.abs(t.y)<=Math.abs(this.y)},toString:function(){return"Point("+o.Util.formatNum(this.x)+", "+o.Util.formatNum(this.y)+")"}},o.point=function(t,e,n){return t instanceof o.Point?t:o.Util.isArray(t)?new o.Point(t[0],t[1]):t===i||null===t?t:"object"==typeof t&&"x"in t&&"y"in t?new o.Point(t.x,t.y):new o.Point(t,e,n)},o.Bounds=function(t,e){if(t)for(var i=e?[t,e]:t,n=0,o=i.length;n=this.min.x&&i.x<=this.max.x&&e.y>=this.min.y&&i.y<=this.max.y},intersects:function(t){t=o.bounds(t);var e=this.min,i=this.max,n=t.min,s=t.max,r=s.x>=e.x&&n.x<=i.x,a=s.y>=e.y&&n.y<=i.y;return r&&a},overlaps:function(t){t=o.bounds(t);var e=this.min,i=this.max,n=t.min,s=t.max,r=s.x>e.x&&n.xe.y&&n.y0&&new RegExp("(^|\\s)"+e+"(\\s|$)").test(n)},addClass:function(t,e){if(t.classList!==i)for(var n=o.Util.splitWords(e),s=0,r=n.length;s=n.lat&&i.lat<=s.lat&&e.lng>=n.lng&&i.lng<=s.lng},intersects:function(t){t=o.latLngBounds(t);var e=this._southWest,i=this._northEast,n=t.getSouthWest(),s=t.getNorthEast(),r=s.lat>=e.lat&&n.lat<=i.lat,a=s.lng>=e.lng&&n.lng<=i.lng;return r&&a},overlaps:function(t){t=o.latLngBounds(t);var e=this._southWest,i=this._northEast,n=t.getSouthWest(),s=t.getNorthEast(),r=s.lat>e.lat&&n.late.lng&&n.lngthis.options.maxZoom?this.setZoom(t):this},panInsideBounds:function(t,e){this._enforcingBounds=!0;var i=this.getCenter(),n=this._limitCenter(i,this._zoom,o.latLngBounds(t));return i.equals(n)||this.panTo(n,e),this._enforcingBounds=!1,this},invalidateSize:function(t){if(!this._loaded)return this;t=o.extend({animate:!1,pan:!0},t===!0?{animate:!0}:t);var e=this.getSize();this._sizeChanged=!0,this._lastCenter=null;var i=this.getSize(),n=e.divideBy(2).round(),s=i.divideBy(2).round(),r=n.subtract(s);return r.x||r.y?(t.animate&&t.pan?this.panBy(r):(t.pan&&this._rawPanBy(r),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(o.bind(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:e,newSize:i})):this},stop:function(){return this.setZoom(this._limitZoom(this._zoom)),this.options.zoomSnap||this.fire("viewreset"),this._stop()},locate:function(t){if(t=this._locateOptions=o.extend({timeout:1e4,watch:!1},t),!("geolocation"in navigator))return this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this;var e=o.bind(this._handleGeolocationResponse,this),i=o.bind(this._handleGeolocationError,this);return t.watch?this._locationWatchId=navigator.geolocation.watchPosition(e,i,t):navigator.geolocation.getCurrentPosition(e,i,t),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(t){var e=t.code,i=t.message||(1===e?"permission denied":2===e?"position unavailable":"timeout");this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:e,message:"Geolocation error: "+i+"."})},_handleGeolocationResponse:function(t){var e=t.coords.latitude,i=t.coords.longitude,n=new o.LatLng(e,i),s=n.toBounds(t.coords.accuracy),r=this._locateOptions;if(r.setView){var a=this.getBoundsZoom(s);this.setView(n,r.maxZoom?Math.min(a,r.maxZoom):a)}var h={latlng:n,bounds:s,timestamp:t.timestamp};for(var l in t.coords)"number"==typeof t.coords[l]&&(h[l]=t.coords[l]);this.fire("locationfound",h)},addHandler:function(t,e){if(!e)return this;var i=this[t]=new e(this);return this._handlers.push(i),this.options[t]&&i.enable(),this},remove:function(){if(this._initEvents(!0),this._containerId!==this._container._leaflet_id)throw new Error("Map container is being reused by another instance");try{delete this._container._leaflet_id,delete this._containerId}catch(t){this._container._leaflet_id=i,this._containerId=i}o.DomUtil.remove(this._mapPane),this._clearControlPos&&this._clearControlPos(),this._clearHandlers(),this._loaded&&this.fire("unload");for(var t in this._layers)this._layers[t].remove();return this},createPane:function(t,e){var i="leaflet-pane"+(t?" leaflet-"+t.replace("Pane","")+"-pane":""),n=o.DomUtil.create("div",i,e||this._mapPane);return t&&(this._panes[t]=n),n},getCenter:function(){return this._checkIfLoaded(),this._lastCenter&&!this._moved()?this._lastCenter:this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds(),e=this.unproject(t.getBottomLeft()),i=this.unproject(t.getTopRight());return new o.LatLngBounds(e,i)},getMinZoom:function(){return this.options.minZoom===i?this._layersMinZoom||0:this.options.minZoom},getMaxZoom:function(){return this.options.maxZoom===i?this._layersMaxZoom===i?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(t,e,i){t=o.latLngBounds(t),i=o.point(i||[0,0]);var n=this.getZoom()||0,s=this.getMinZoom(),r=this.getMaxZoom(),a=t.getNorthWest(),h=t.getSouthEast(),l=this.getSize().subtract(i),u=o.bounds(this.project(h,n),this.project(a,n)).getSize(),c=o.Browser.any3d?this.options.zoomSnap:1,d=Math.min(l.x/u.x,l.y/u.y);return n=this.getScaleZoom(d,n),c&&(n=Math.round(n/(c/100))*(c/100),n=e?Math.ceil(n/c)*c:Math.floor(n/c)*c),Math.max(s,Math.min(r,n))},getSize:function(){return this._size&&!this._sizeChanged||(this._size=new o.Point(this._container.clientWidth||0,this._container.clientHeight||0),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(t,e){var i=this._getTopLeftPoint(t,e);return new o.Bounds(i,i.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._pixelOrigin},getPixelWorldBounds:function(t){return this.options.crs.getProjectedBounds(t===i?this.getZoom():t)},getPane:function(t){return"string"==typeof t?this._panes[t]:t},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(t,e){var n=this.options.crs;return e=e===i?this._zoom:e,n.scale(t)/n.scale(e)},getScaleZoom:function(t,e){var n=this.options.crs;e=e===i?this._zoom:e;var o=n.zoom(t*n.scale(e));return isNaN(o)?1/0:o},project:function(t,e){return e=e===i?this._zoom:e,this.options.crs.latLngToPoint(o.latLng(t),e)},unproject:function(t,e){return e=e===i?this._zoom:e,this.options.crs.pointToLatLng(o.point(t),e)},layerPointToLatLng:function(t){var e=o.point(t).add(this.getPixelOrigin());return this.unproject(e)},latLngToLayerPoint:function(t){var e=this.project(o.latLng(t))._round();return e._subtract(this.getPixelOrigin())},wrapLatLng:function(t){return this.options.crs.wrapLatLng(o.latLng(t))},wrapLatLngBounds:function(t){return this.options.crs.wrapLatLngBounds(o.latLngBounds(t))},distance:function(t,e){return this.options.crs.distance(o.latLng(t),o.latLng(e))},containerPointToLayerPoint:function(t){return o.point(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return o.point(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){var e=this.containerPointToLayerPoint(o.point(t));return this.layerPointToLatLng(e)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(o.latLng(t)))},mouseEventToContainerPoint:function(t){return o.DomEvent.getMousePosition(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){var e=this._container=o.DomUtil.get(t);if(!e)throw new Error("Map container not found.");if(e._leaflet_id)throw new Error("Map container is already initialized.");o.DomEvent.addListener(e,"scroll",this._onScroll,this),this._containerId=o.Util.stamp(e)},_initLayout:function(){var t=this._container;this._fadeAnimated=this.options.fadeAnimation&&o.Browser.any3d, +o.DomUtil.addClass(t,"leaflet-container"+(o.Browser.touch?" leaflet-touch":"")+(o.Browser.retina?" leaflet-retina":"")+(o.Browser.ielt9?" leaflet-oldie":"")+(o.Browser.safari?" leaflet-safari":"")+(this._fadeAnimated?" leaflet-fade-anim":""));var e=o.DomUtil.getStyle(t,"position");"absolute"!==e&&"relative"!==e&&"fixed"!==e&&(t.style.position="relative"),this._initPanes(),this._initControlPos&&this._initControlPos()},_initPanes:function(){var t=this._panes={};this._paneRenderers={},this._mapPane=this.createPane("mapPane",this._container),o.DomUtil.setPosition(this._mapPane,new o.Point(0,0)),this.createPane("tilePane"),this.createPane("shadowPane"),this.createPane("overlayPane"),this.createPane("markerPane"),this.createPane("tooltipPane"),this.createPane("popupPane"),this.options.markerZoomAnimation||(o.DomUtil.addClass(t.markerPane,"leaflet-zoom-hide"),o.DomUtil.addClass(t.shadowPane,"leaflet-zoom-hide"))},_resetView:function(t,e){o.DomUtil.setPosition(this._mapPane,new o.Point(0,0));var i=!this._loaded;this._loaded=!0,e=this._limitZoom(e),this.fire("viewprereset");var n=this._zoom!==e;this._moveStart(n)._move(t,e)._moveEnd(n),this.fire("viewreset"),i&&this.fire("load")},_moveStart:function(t){return t&&this.fire("zoomstart"),this.fire("movestart")},_move:function(t,e,n){e===i&&(e=this._zoom);var o=this._zoom!==e;return this._zoom=e,this._lastCenter=t,this._pixelOrigin=this._getNewPixelOrigin(t),(o||n&&n.pinch)&&this.fire("zoom",n),this.fire("move",n)},_moveEnd:function(t){return t&&this.fire("zoomend"),this.fire("moveend")},_stop:function(){return o.Util.cancelAnimFrame(this._flyToFrame),this._panAnim&&this._panAnim.stop(),this},_rawPanBy:function(t){o.DomUtil.setPosition(this._mapPane,this._getMapPanePos().subtract(t))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_panInsideMaxBounds:function(){this._enforcingBounds||this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw new Error("Set map center and zoom first.")},_initEvents:function(e){if(o.DomEvent){this._targets={},this._targets[o.stamp(this._container)]=this;var i=e?"off":"on";o.DomEvent[i](this._container,"click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu keypress",this._handleDOMEvent,this),this.options.trackResize&&o.DomEvent[i](t,"resize",this._onResize,this),o.Browser.any3d&&this.options.transform3DLimit&&this[i]("moveend",this._onMoveEnd)}},_onResize:function(){o.Util.cancelAnimFrame(this._resizeRequest),this._resizeRequest=o.Util.requestAnimFrame(function(){this.invalidateSize({debounceMoveend:!0})},this)},_onScroll:function(){this._container.scrollTop=0,this._container.scrollLeft=0},_onMoveEnd:function(){var t=this._getMapPanePos();Math.max(Math.abs(t.x),Math.abs(t.y))>=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(t,e){for(var i,n=[],s="mouseout"===e||"mouseover"===e,r=t.target||t.srcElement,a=!1;r;){if(i=this._targets[o.stamp(r)],i&&("click"===e||"preclick"===e)&&!t._simulated&&this._draggableMoved(i)){a=!0;break}if(i&&i.listens(e,!0)){if(s&&!o.DomEvent._isExternalTarget(r,t))break;if(n.push(i),s)break}if(r===this._container)break;r=r.parentNode}return n.length||a||s||!o.DomEvent._isExternalTarget(r,t)||(n=[this]),n},_handleDOMEvent:function(t){if(this._loaded&&!o.DomEvent._skipped(t)){var e="keypress"===t.type&&13===t.keyCode?"click":t.type;"mousedown"===e&&o.DomUtil.preventOutline(t.target||t.srcElement),this._fireDOMEvent(t,e)}},_fireDOMEvent:function(t,e,i){if("click"===t.type){var n=o.Util.extend({},t);n.type="preclick",this._fireDOMEvent(n,n.type,i)}if(!t._stopped&&(i=(i||[]).concat(this._findEventTargets(t,e)),i.length)){var s=i[0];"contextmenu"===e&&s.listens(e,!0)&&o.DomEvent.preventDefault(t);var r={originalEvent:t};if("keypress"!==t.type){var a=s instanceof o.Marker;r.containerPoint=a?this.latLngToContainerPoint(s.getLatLng()):this.mouseEventToContainerPoint(t),r.layerPoint=this.containerPointToLayerPoint(r.containerPoint),r.latlng=a?s.getLatLng():this.layerPointToLatLng(r.layerPoint)}for(var h=0;h0?Math.round(t-e)/2:Math.max(0,Math.ceil(t))-Math.max(0,Math.floor(e))},_limitZoom:function(t){var e=this.getMinZoom(),i=this.getMaxZoom(),n=o.Browser.any3d?this.options.zoomSnap:1;return n&&(t=Math.round(t/n)*n),Math.max(e,Math.min(i,t))},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){o.DomUtil.removeClass(this._mapPane,"leaflet-pan-anim"),this.fire("moveend")},_tryAnimatedPan:function(t,e){var i=this._getCenterOffset(t)._floor();return!((e&&e.animate)!==!0&&!this.getSize().contains(i))&&(this.panBy(i,e),!0)},_createAnimProxy:function(){var t=this._proxy=o.DomUtil.create("div","leaflet-proxy leaflet-zoom-animated");this._panes.mapPane.appendChild(t),this.on("zoomanim",function(e){var i=o.DomUtil.TRANSFORM,n=t.style[i];o.DomUtil.setTransform(t,this.project(e.center,e.zoom),this.getZoomScale(e.zoom,1)),n===t.style[i]&&this._animatingZoom&&this._onZoomTransitionEnd()},this),this.on("load moveend",function(){var e=this.getCenter(),i=this.getZoom();o.DomUtil.setTransform(t,this.project(e,i),this.getZoomScale(i,1))},this)},_catchTransitionEnd:function(t){this._animatingZoom&&t.propertyName.indexOf("transform")>=0&&this._onZoomTransitionEnd()},_nothingToAnimate:function(){return!this._container.getElementsByClassName("leaflet-zoom-animated").length},_tryAnimatedZoom:function(t,e,i){if(this._animatingZoom)return!0;if(i=i||{},!this._zoomAnimated||i.animate===!1||this._nothingToAnimate()||Math.abs(e-this._zoom)>this.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(e),s=this._getCenterOffset(t)._divideBy(1-1/n);return!(i.animate!==!0&&!this.getSize().contains(s))&&(o.Util.requestAnimFrame(function(){this._moveStart(!0)._animateZoom(t,e,!0)},this),!0)},_animateZoom:function(t,e,i,n){i&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=e,o.DomUtil.addClass(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:e,noUpdate:n}),setTimeout(o.bind(this._onZoomTransitionEnd,this),250)},_onZoomTransitionEnd:function(){this._animatingZoom&&(o.DomUtil.removeClass(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom),o.Util.requestAnimFrame(function(){this._moveEnd(!0)},this))}}),o.map=function(t,e){return new o.Map(t,e)},o.Layer=o.Evented.extend({options:{pane:"overlayPane",nonBubblingEvents:[],attribution:null},addTo:function(t){return t.addLayer(this),this},remove:function(){return this.removeFrom(this._map||this._mapToAdd)},removeFrom:function(t){return t&&t.removeLayer(this),this},getPane:function(t){return this._map.getPane(t?this.options[t]||t:this.options.pane)},addInteractiveTarget:function(t){return this._map._targets[o.stamp(t)]=this,this},removeInteractiveTarget:function(t){return delete this._map._targets[o.stamp(t)],this},getAttribution:function(){return this.options.attribution},_layerAdd:function(t){var e=t.target;if(e.hasLayer(this)){if(this._map=e,this._zoomAnimated=e._zoomAnimated,this.getEvents){var i=this.getEvents();e.on(i,this),this.once("remove",function(){e.off(i,this)},this)}this.onAdd(e),this.getAttribution&&e.attributionControl&&e.attributionControl.addAttribution(this.getAttribution()),this.fire("add"),e.fire("layeradd",{layer:this})}}}),o.Map.include({addLayer:function(t){var e=o.stamp(t);return this._layers[e]?this:(this._layers[e]=t,t._mapToAdd=this,t.beforeAdd&&t.beforeAdd(this),this.whenReady(t._layerAdd,t),this)},removeLayer:function(t){var e=o.stamp(t);return this._layers[e]?(this._loaded&&t.onRemove(this),t.getAttribution&&this.attributionControl&&this.attributionControl.removeAttribution(t.getAttribution()),delete this._layers[e],this._loaded&&(this.fire("layerremove",{layer:t}),t.fire("remove")),t._map=t._mapToAdd=null,this):this},hasLayer:function(t){return!!t&&o.stamp(t)in this._layers},eachLayer:function(t,e){for(var i in this._layers)t.call(e,this._layers[i]);return this},_addLayers:function(t){t=t?o.Util.isArray(t)?t:[t]:[];for(var e=0,i=t.length;ethis._layersMaxZoom&&this.setZoom(this._layersMaxZoom),this.options.minZoom===i&&this._layersMinZoom&&this.getZoom()100&&n<500||t.target._simulatedClick&&!t._simulated?void o.DomEvent.stop(t):(o.DomEvent._lastClick=i,void e(t))}},o.DomEvent.addListener=o.DomEvent.on,o.DomEvent.removeListener=o.DomEvent.off,o.PosAnimation=o.Evented.extend({run:function(t,e,i,n){this.stop(),this._el=t,this._inProgress=!0,this._duration=i||.25,this._easeOutPower=1/Math.max(n||.5,.2),this._startPos=o.DomUtil.getPosition(t),this._offset=e.subtract(this._startPos),this._startTime=+new Date,this.fire("start"),this._animate()},stop:function(){this._inProgress&&(this._step(!0),this._complete())},_animate:function(){this._animId=o.Util.requestAnimFrame(this._animate,this),this._step()},_step:function(t){var e=+new Date-this._startTime,i=1e3*this._duration;e1e-7;l++)e=r*Math.sin(h),e=Math.pow((1-e)/(1+e),r/2),u=Math.PI/2-2*Math.atan(a*e)-h,h+=u;return new o.LatLng(h*i,t.x*i/n)}},o.CRS.EPSG3395=o.extend({},o.CRS.Earth,{code:"EPSG:3395",projection:o.Projection.Mercator,transformation:function(){var t=.5/(Math.PI*o.Projection.Mercator.R);return new o.Transformation(t,.5,-t,.5)}()}),o.GridLayer=o.Layer.extend({options:{tileSize:256,opacity:1,updateWhenIdle:o.Browser.mobile,updateWhenZooming:!0,updateInterval:200,zIndex:1,bounds:null,minZoom:0,maxZoom:i,noWrap:!1,pane:"tilePane",className:"",keepBuffer:2},initialize:function(t){o.setOptions(this,t)},onAdd:function(){this._initContainer(),this._levels={},this._tiles={},this._resetView(),this._update()},beforeAdd:function(t){t._addZoomLimit(this)},onRemove:function(t){this._removeAllTiles(),o.DomUtil.remove(this._container),t._removeZoomLimit(this),this._container=null,this._tileZoom=null},bringToFront:function(){return this._map&&(o.DomUtil.toFront(this._container),this._setAutoZIndex(Math.max)),this},bringToBack:function(){return this._map&&(o.DomUtil.toBack(this._container),this._setAutoZIndex(Math.min)),this},getContainer:function(){return this._container},setOpacity:function(t){return this.options.opacity=t,this._updateOpacity(),this},setZIndex:function(t){return this.options.zIndex=t,this._updateZIndex(),this},isLoading:function(){return this._loading},redraw:function(){return this._map&&(this._removeAllTiles(),this._update()),this},getEvents:function(){var t={viewprereset:this._invalidateAll,viewreset:this._resetView,zoom:this._resetView,moveend:this._onMoveEnd};return this.options.updateWhenIdle||(this._onMove||(this._onMove=o.Util.throttle(this._onMoveEnd,this.options.updateInterval,this)),t.move=this._onMove),this._zoomAnimated&&(t.zoomanim=this._animateZoom),t},createTile:function(){return e.createElement("div")},getTileSize:function(){var t=this.options.tileSize;return t instanceof o.Point?t:new o.Point(t,t)},_updateZIndex:function(){this._container&&this.options.zIndex!==i&&null!==this.options.zIndex&&(this._container.style.zIndex=this.options.zIndex)},_setAutoZIndex:function(t){for(var e,i=this.getPane().children,n=-t(-(1/0),1/0),o=0,s=i.length;othis.options.maxZoom||in&&this._retainParent(s,r,a,n))},_retainChildren:function(t,e,i,n){for(var s=2*t;s<2*t+2;s++)for(var r=2*e;r<2*e+2;r++){var a=new o.Point(s,r);a.z=i+1;var h=this._tileCoordsToKey(a),l=this._tiles[h];l&&l.active?l.retain=!0:(l&&l.loaded&&(l.retain=!0),i+1this.options.maxZoom||this.options.minZoom!==i&&s1)return void this._setView(t,s);for(var m=a.min.y;m<=a.max.y;m++)for(var p=a.min.x;p<=a.max.x;p++){var f=new o.Point(p,m);if(f.z=this._tileZoom,this._isValidTile(f)){var g=this._tiles[this._tileCoordsToKey(f)];g?g.current=!0:l.push(f)}}if(l.sort(function(t,e){return t.distanceTo(h)-e.distanceTo(h)}),0!==l.length){this._loading||(this._loading=!0,this.fire("loading"));var v=e.createDocumentFragment();for(p=0;pi.max.x)||!e.wrapLat&&(t.yi.max.y))return!1}if(!this.options.bounds)return!0;var n=this._tileCoordsToBounds(t);return o.latLngBounds(this.options.bounds).overlaps(n)},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToBounds:function(t){var e=this._map,i=this.getTileSize(),n=t.scaleBy(i),s=n.add(i),r=e.unproject(n,t.z),a=e.unproject(s,t.z),h=new o.LatLngBounds(r,a);return this.options.noWrap||e.wrapLatLngBounds(h),h},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var e=t.split(":"),i=new o.Point(+e[0],+e[1]);return i.z=+e[2],i},_removeTile:function(t){var e=this._tiles[t];e&&(o.DomUtil.remove(e.el),delete this._tiles[t],this.fire("tileunload",{tile:e.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){o.DomUtil.addClass(t,"leaflet-tile");var e=this.getTileSize();t.style.width=e.x+"px",t.style.height=e.y+"px",t.onselectstart=o.Util.falseFn,t.onmousemove=o.Util.falseFn,o.Browser.ielt9&&this.options.opacity<1&&o.DomUtil.setOpacity(t,this.options.opacity),o.Browser.android&&!o.Browser.android23&&(t.style.WebkitBackfaceVisibility="hidden")},_addTile:function(t,e){var i=this._getTilePos(t),n=this._tileCoordsToKey(t),s=this.createTile(this._wrapCoords(t),o.bind(this._tileReady,this,t));this._initTile(s),this.createTile.length<2&&o.Util.requestAnimFrame(o.bind(this._tileReady,this,t,null,s)),o.DomUtil.setPosition(s,i),this._tiles[n]={el:s,coords:t,current:!0},e.appendChild(s),this.fire("tileloadstart",{tile:s,coords:t})},_tileReady:function(t,e,i){if(this._map){e&&this.fire("tileerror",{error:e,tile:i,coords:t});var n=this._tileCoordsToKey(t);i=this._tiles[n],i&&(i.loaded=+new Date,this._map._fadeAnimated?(o.DomUtil.setOpacity(i.el,0),o.Util.cancelAnimFrame(this._fadeFrame),this._fadeFrame=o.Util.requestAnimFrame(this._updateOpacity,this)):(i.active=!0,this._pruneTiles()),e||(o.DomUtil.addClass(i.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:i.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),o.Browser.ielt9||!this._map._fadeAnimated?o.Util.requestAnimFrame(this._pruneTiles,this):setTimeout(o.bind(this._pruneTiles,this),250)))}},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var e=new o.Point(this._wrapX?o.Util.wrapNum(t.x,this._wrapX):t.x,this._wrapY?o.Util.wrapNum(t.y,this._wrapY):t.y);return e.z=t.z,e},_pxBoundsToTileRange:function(t){var e=this.getTileSize();return new o.Bounds(t.min.unscaleBy(e).floor(),t.max.unscaleBy(e).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}}),o.gridLayer=function(t){return new o.GridLayer(t)},o.TileLayer=o.GridLayer.extend({options:{minZoom:0,maxZoom:18,maxNativeZoom:null,minNativeZoom:null,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1},initialize:function(t,e){this._url=t,e=o.setOptions(this,e),e.detectRetina&&o.Browser.retina&&e.maxZoom>0&&(e.tileSize=Math.floor(e.tileSize/2),e.zoomReverse?(e.zoomOffset--,e.minZoom++):(e.zoomOffset++,e.maxZoom--),e.minZoom=Math.max(0,e.minZoom)),"string"==typeof e.subdomains&&(e.subdomains=e.subdomains.split("")),o.Browser.android||this.on("tileunload",this._onTileRemove)},setUrl:function(t,e){return this._url=t,e||this.redraw(),this},createTile:function(t,i){var n=e.createElement("img");return o.DomEvent.on(n,"load",o.bind(this._tileOnLoad,this,i,n)),o.DomEvent.on(n,"error",o.bind(this._tileOnError,this,i,n)),this.options.crossOrigin&&(n.crossOrigin=""),n.alt="",n.setAttribute("role","presentation"),n.src=this.getTileUrl(t),n},getTileUrl:function(t){var e={r:o.Browser.retina?"@2x":"",s:this._getSubdomain(t),x:t.x,y:t.y,z:this._getZoomForUrl()};if(this._map&&!this._map.options.crs.infinite){var i=this._globalTileRange.max.y-t.y;this.options.tms&&(e.y=i),e["-y"]=i}return o.Util.template(this._url,o.extend(e,this.options))},_tileOnLoad:function(t,e){o.Browser.ielt9?setTimeout(o.bind(t,this,null,e),0):t(null,e)},_tileOnError:function(t,e,i){var n=this.options.errorTileUrl;n&&e.src!==n&&(e.src=n),t(i,e)},getTileSize:function(){var t=this._map,e=o.GridLayer.prototype.getTileSize.call(this),i=this._tileZoom+this.options.zoomOffset,n=this.options.minNativeZoom,s=this.options.maxNativeZoom;return null!==n&&is?e.divideBy(t.getZoomScale(s,i)).round():e},_onTileRemove:function(t){t.tile.onload=null},_getZoomForUrl:function(){var t=this._tileZoom,e=this.options.maxZoom,i=this.options.zoomReverse,n=this.options.zoomOffset,o=this.options.minNativeZoom,s=this.options.maxNativeZoom;return i&&(t=e-t),t+=n,null!==o&&ts?s:t},_getSubdomain:function(t){var e=Math.abs(t.x+t.y)%this.options.subdomains.length;return this.options.subdomains[e]},_abortLoading:function(){var t,e;for(t in this._tiles)this._tiles[t].coords.z!==this._tileZoom&&(e=this._tiles[t].el,e.onload=o.Util.falseFn,e.onerror=o.Util.falseFn,e.complete||(e.src=o.Util.emptyImageUrl,o.DomUtil.remove(e)))}}),o.tileLayer=function(t,e){return new o.TileLayer(t,e)},o.TileLayer.WMS=o.TileLayer.extend({defaultWmsParams:{service:"WMS",request:"GetMap",layers:"",styles:"",format:"image/jpeg",transparent:!1,version:"1.1.1"},options:{crs:null,uppercase:!1},initialize:function(t,e){this._url=t;var i=o.extend({},this.defaultWmsParams);for(var n in e)n in this.options||(i[n]=e[n]);e=o.setOptions(this,e),i.width=i.height=e.tileSize*(e.detectRetina&&o.Browser.retina?2:1),this.wmsParams=i},onAdd:function(t){this._crs=this.options.crs||t.options.crs,this._wmsVersion=parseFloat(this.wmsParams.version);var e=this._wmsVersion>=1.3?"crs":"srs";this.wmsParams[e]=this._crs.code,o.TileLayer.prototype.onAdd.call(this,t)},getTileUrl:function(t){var e=this._tileCoordsToBounds(t),i=this._crs.project(e.getNorthWest()),n=this._crs.project(e.getSouthEast()),s=(this._wmsVersion>=1.3&&this._crs===o.CRS.EPSG4326?[n.y,i.x,i.y,n.x]:[i.x,n.y,n.x,i.y]).join(","),r=o.TileLayer.prototype.getTileUrl.call(this,t);return r+o.Util.getParamString(this.wmsParams,r,this.options.uppercase)+(this.options.uppercase?"&BBOX=":"&bbox=")+s},setParams:function(t,e){return o.extend(this.wmsParams,t),e||this.redraw(),this}}),o.tileLayer.wms=function(t,e){return new o.TileLayer.WMS(t,e)},o.ImageOverlay=o.Layer.extend({options:{opacity:1,alt:"",interactive:!1,crossOrigin:!1},initialize:function(t,e,i){this._url=t,this._bounds=o.latLngBounds(e),o.setOptions(this,i)},onAdd:function(){this._image||(this._initImage(),this.options.opacity<1&&this._updateOpacity()),this.options.interactive&&(o.DomUtil.addClass(this._image,"leaflet-interactive"),this.addInteractiveTarget(this._image)),this.getPane().appendChild(this._image),this._reset()},onRemove:function(){o.DomUtil.remove(this._image),this.options.interactive&&this.removeInteractiveTarget(this._image)},setOpacity:function(t){return this.options.opacity=t,this._image&&this._updateOpacity(),this},setStyle:function(t){return t.opacity&&this.setOpacity(t.opacity),this},bringToFront:function(){return this._map&&o.DomUtil.toFront(this._image),this},bringToBack:function(){return this._map&&o.DomUtil.toBack(this._image),this},setUrl:function(t){return this._url=t,this._image&&(this._image.src=t),this},setBounds:function(t){return this._bounds=t,this._map&&this._reset(),this},getEvents:function(){var t={zoom:this._reset,viewreset:this._reset};return this._zoomAnimated&&(t.zoomanim=this._animateZoom),t},getBounds:function(){return this._bounds},getElement:function(){return this._image},_initImage:function(){var t=this._image=o.DomUtil.create("img","leaflet-image-layer "+(this._zoomAnimated?"leaflet-zoom-animated":""));t.onselectstart=o.Util.falseFn,t.onmousemove=o.Util.falseFn,t.onload=o.bind(this.fire,this,"load"),this.options.crossOrigin&&(t.crossOrigin=""),t.src=this._url,t.alt=this.options.alt},_animateZoom:function(t){var e=this._map.getZoomScale(t.zoom),i=this._map._latLngBoundsToNewLayerBounds(this._bounds,t.zoom,t.center).min; +o.DomUtil.setTransform(this._image,i,e)},_reset:function(){var t=this._image,e=new o.Bounds(this._map.latLngToLayerPoint(this._bounds.getNorthWest()),this._map.latLngToLayerPoint(this._bounds.getSouthEast())),i=e.getSize();o.DomUtil.setPosition(t,e.min),t.style.width=i.x+"px",t.style.height=i.y+"px"},_updateOpacity:function(){o.DomUtil.setOpacity(this._image,this.options.opacity)}}),o.imageOverlay=function(t,e,i){return new o.ImageOverlay(t,e,i)},o.Icon=o.Class.extend({initialize:function(t){o.setOptions(this,t)},createIcon:function(t){return this._createIcon("icon",t)},createShadow:function(t){return this._createIcon("shadow",t)},_createIcon:function(t,e){var i=this._getIconUrl(t);if(!i){if("icon"===t)throw new Error("iconUrl not set in Icon options (see the docs).");return null}var n=this._createImg(i,e&&"IMG"===e.tagName?e:null);return this._setIconStyles(n,t),n},_setIconStyles:function(t,e){var i=this.options,n=i[e+"Size"];"number"==typeof n&&(n=[n,n]);var s=o.point(n),r=o.point("shadow"===e&&i.shadowAnchor||i.iconAnchor||s&&s.divideBy(2,!0));t.className="leaflet-marker-"+e+" "+(i.className||""),r&&(t.style.marginLeft=-r.x+"px",t.style.marginTop=-r.y+"px"),s&&(t.style.width=s.x+"px",t.style.height=s.y+"px")},_createImg:function(t,i){return i=i||e.createElement("img"),i.src=t,i},_getIconUrl:function(t){return o.Browser.retina&&this.options[t+"RetinaUrl"]||this.options[t+"Url"]}}),o.icon=function(t){return new o.Icon(t)},o.Icon.Default=o.Icon.extend({options:{iconUrl:"marker-icon.png",iconRetinaUrl:"marker-icon-2x.png",shadowUrl:"marker-shadow.png",iconSize:[25,41],iconAnchor:[12,41],popupAnchor:[1,-34],tooltipAnchor:[16,-28],shadowSize:[41,41]},_getIconUrl:function(t){return o.Icon.Default.imagePath||(o.Icon.Default.imagePath=this._detectIconPath()),(this.options.imagePath||o.Icon.Default.imagePath)+o.Icon.prototype._getIconUrl.call(this,t)},_detectIconPath:function(){var t=o.DomUtil.create("div","leaflet-default-icon-path",e.body),i=o.DomUtil.getStyle(t,"background-image")||o.DomUtil.getStyle(t,"backgroundImage");return e.body.removeChild(t),0===i.indexOf("url")?i.replace(/^url\([\"\']?/,"").replace(/marker-icon\.png[\"\']?\)$/,""):""}}),o.Marker=o.Layer.extend({options:{icon:new o.Icon.Default,interactive:!0,draggable:!1,keyboard:!0,title:"",alt:"",zIndexOffset:0,opacity:1,riseOnHover:!1,riseOffset:250,pane:"markerPane",nonBubblingEvents:["click","dblclick","mouseover","mouseout","contextmenu"]},initialize:function(t,e){o.setOptions(this,e),this._latlng=o.latLng(t)},onAdd:function(t){this._zoomAnimated=this._zoomAnimated&&t.options.markerZoomAnimation,this._zoomAnimated&&t.on("zoomanim",this._animateZoom,this),this._initIcon(),this.update()},onRemove:function(t){this.dragging&&this.dragging.enabled()&&(this.options.draggable=!0,this.dragging.removeHooks()),this._zoomAnimated&&t.off("zoomanim",this._animateZoom,this),this._removeIcon(),this._removeShadow()},getEvents:function(){return{zoom:this.update,viewreset:this.update}},getLatLng:function(){return this._latlng},setLatLng:function(t){var e=this._latlng;return this._latlng=o.latLng(t),this.update(),this.fire("move",{oldLatLng:e,latlng:this._latlng})},setZIndexOffset:function(t){return this.options.zIndexOffset=t,this.update()},setIcon:function(t){return this.options.icon=t,this._map&&(this._initIcon(),this.update()),this._popup&&this.bindPopup(this._popup,this._popup.options),this},getElement:function(){return this._icon},update:function(){if(this._icon){var t=this._map.latLngToLayerPoint(this._latlng).round();this._setPos(t)}return this},_initIcon:function(){var t=this.options,e="leaflet-zoom-"+(this._zoomAnimated?"animated":"hide"),i=t.icon.createIcon(this._icon),n=!1;i!==this._icon&&(this._icon&&this._removeIcon(),n=!0,t.title&&(i.title=t.title),t.alt&&(i.alt=t.alt)),o.DomUtil.addClass(i,e),t.keyboard&&(i.tabIndex="0"),this._icon=i,t.riseOnHover&&this.on({mouseover:this._bringToFront,mouseout:this._resetZIndex});var s=t.icon.createShadow(this._shadow),r=!1;s!==this._shadow&&(this._removeShadow(),r=!0),s&&(o.DomUtil.addClass(s,e),s.alt=""),this._shadow=s,t.opacity<1&&this._updateOpacity(),n&&this.getPane().appendChild(this._icon),this._initInteraction(),s&&r&&this.getPane("shadowPane").appendChild(this._shadow)},_removeIcon:function(){this.options.riseOnHover&&this.off({mouseover:this._bringToFront,mouseout:this._resetZIndex}),o.DomUtil.remove(this._icon),this.removeInteractiveTarget(this._icon),this._icon=null},_removeShadow:function(){this._shadow&&o.DomUtil.remove(this._shadow),this._shadow=null},_setPos:function(t){o.DomUtil.setPosition(this._icon,t),this._shadow&&o.DomUtil.setPosition(this._shadow,t),this._zIndex=t.y+this.options.zIndexOffset,this._resetZIndex()},_updateZIndex:function(t){this._icon.style.zIndex=this._zIndex+t},_animateZoom:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center).round();this._setPos(e)},_initInteraction:function(){if(this.options.interactive&&(o.DomUtil.addClass(this._icon,"leaflet-interactive"),this.addInteractiveTarget(this._icon),o.Handler.MarkerDrag)){var t=this.options.draggable;this.dragging&&(t=this.dragging.enabled(),this.dragging.disable()),this.dragging=new o.Handler.MarkerDrag(this),t&&this.dragging.enable()}},setOpacity:function(t){return this.options.opacity=t,this._map&&this._updateOpacity(),this},_updateOpacity:function(){var t=this.options.opacity;o.DomUtil.setOpacity(this._icon,t),this._shadow&&o.DomUtil.setOpacity(this._shadow,t)},_bringToFront:function(){this._updateZIndex(this.options.riseOffset)},_resetZIndex:function(){this._updateZIndex(0)},_getPopupAnchor:function(){return this.options.icon.options.popupAnchor||[0,0]},_getTooltipAnchor:function(){return this.options.icon.options.tooltipAnchor||[0,0]}}),o.marker=function(t,e){return new o.Marker(t,e)},o.DivIcon=o.Icon.extend({options:{iconSize:[12,12],html:!1,bgPos:null,className:"leaflet-div-icon"},createIcon:function(t){var i=t&&"DIV"===t.tagName?t:e.createElement("div"),n=this.options;if(i.innerHTML=n.html!==!1?n.html:"",n.bgPos){var s=o.point(n.bgPos);i.style.backgroundPosition=-s.x+"px "+-s.y+"px"}return this._setIconStyles(i,"icon"),i},createShadow:function(){return null}}),o.divIcon=function(t){return new o.DivIcon(t)},o.DivOverlay=o.Layer.extend({options:{offset:[0,7],className:"",pane:"popupPane"},initialize:function(t,e){o.setOptions(this,t),this._source=e},onAdd:function(t){this._zoomAnimated=t._zoomAnimated,this._container||this._initLayout(),t._fadeAnimated&&o.DomUtil.setOpacity(this._container,0),clearTimeout(this._removeTimeout),this.getPane().appendChild(this._container),this.update(),t._fadeAnimated&&o.DomUtil.setOpacity(this._container,1),this.bringToFront()},onRemove:function(t){t._fadeAnimated?(o.DomUtil.setOpacity(this._container,0),this._removeTimeout=setTimeout(o.bind(o.DomUtil.remove,o.DomUtil,this._container),200)):o.DomUtil.remove(this._container)},getLatLng:function(){return this._latlng},setLatLng:function(t){return this._latlng=o.latLng(t),this._map&&(this._updatePosition(),this._adjustPan()),this},getContent:function(){return this._content},setContent:function(t){return this._content=t,this.update(),this},getElement:function(){return this._container},update:function(){this._map&&(this._container.style.visibility="hidden",this._updateContent(),this._updateLayout(),this._updatePosition(),this._container.style.visibility="",this._adjustPan())},getEvents:function(){var t={zoom:this._updatePosition,viewreset:this._updatePosition};return this._zoomAnimated&&(t.zoomanim=this._animateZoom),t},isOpen:function(){return!!this._map&&this._map.hasLayer(this)},bringToFront:function(){return this._map&&o.DomUtil.toFront(this._container),this},bringToBack:function(){return this._map&&o.DomUtil.toBack(this._container),this},_updateContent:function(){if(this._content){var t=this._contentNode,e="function"==typeof this._content?this._content(this._source||this):this._content;if("string"==typeof e)t.innerHTML=e;else{for(;t.hasChildNodes();)t.removeChild(t.firstChild);t.appendChild(e)}this.fire("contentupdate")}},_updatePosition:function(){if(this._map){var t=this._map.latLngToLayerPoint(this._latlng),e=o.point(this.options.offset),i=this._getAnchor();this._zoomAnimated?o.DomUtil.setPosition(this._container,t.add(i)):e=e.add(t).add(i);var n=this._containerBottom=-e.y,s=this._containerLeft=-Math.round(this._containerWidth/2)+e.x;this._container.style.bottom=n+"px",this._container.style.left=s+"px"}},_getAnchor:function(){return[0,0]}}),o.Popup=o.DivOverlay.extend({options:{maxWidth:300,minWidth:50,maxHeight:null,autoPan:!0,autoPanPaddingTopLeft:null,autoPanPaddingBottomRight:null,autoPanPadding:[5,5],keepInView:!1,closeButton:!0,autoClose:!0,className:""},openOn:function(t){return t.openPopup(this),this},onAdd:function(t){o.DivOverlay.prototype.onAdd.call(this,t),t.fire("popupopen",{popup:this}),this._source&&(this._source.fire("popupopen",{popup:this},!0),this._source instanceof o.Path||this._source.on("preclick",o.DomEvent.stopPropagation))},onRemove:function(t){o.DivOverlay.prototype.onRemove.call(this,t),t.fire("popupclose",{popup:this}),this._source&&(this._source.fire("popupclose",{popup:this},!0),this._source instanceof o.Path||this._source.off("preclick",o.DomEvent.stopPropagation))},getEvents:function(){var t=o.DivOverlay.prototype.getEvents.call(this);return("closeOnClick"in this.options?this.options.closeOnClick:this._map.options.closePopupOnClick)&&(t.preclick=this._close),this.options.keepInView&&(t.moveend=this._adjustPan),t},_close:function(){this._map&&this._map.closePopup(this)},_initLayout:function(){var t="leaflet-popup",e=this._container=o.DomUtil.create("div",t+" "+(this.options.className||"")+" leaflet-zoom-animated");if(this.options.closeButton){var i=this._closeButton=o.DomUtil.create("a",t+"-close-button",e);i.href="#close",i.innerHTML="×",o.DomEvent.on(i,"click",this._onCloseButtonClick,this)}var n=this._wrapper=o.DomUtil.create("div",t+"-content-wrapper",e);this._contentNode=o.DomUtil.create("div",t+"-content",n),o.DomEvent.disableClickPropagation(n).disableScrollPropagation(this._contentNode).on(n,"contextmenu",o.DomEvent.stopPropagation),this._tipContainer=o.DomUtil.create("div",t+"-tip-container",e),this._tip=o.DomUtil.create("div",t+"-tip",this._tipContainer)},_updateLayout:function(){var t=this._contentNode,e=t.style;e.width="",e.whiteSpace="nowrap";var i=t.offsetWidth;i=Math.min(i,this.options.maxWidth),i=Math.max(i,this.options.minWidth),e.width=i+1+"px",e.whiteSpace="",e.height="";var n=t.offsetHeight,s=this.options.maxHeight,r="leaflet-popup-scrolled";s&&n>s?(e.height=s+"px",o.DomUtil.addClass(t,r)):o.DomUtil.removeClass(t,r),this._containerWidth=this._container.offsetWidth},_animateZoom:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center),i=this._getAnchor();o.DomUtil.setPosition(this._container,e.add(i))},_adjustPan:function(){if(!(!this.options.autoPan||this._map._panAnim&&this._map._panAnim._inProgress)){var t=this._map,e=parseInt(o.DomUtil.getStyle(this._container,"marginBottom"),10)||0,i=this._container.offsetHeight+e,n=this._containerWidth,s=new o.Point(this._containerLeft,-i-this._containerBottom);s._add(o.DomUtil.getPosition(this._container));var r=t.layerPointToContainerPoint(s),a=o.point(this.options.autoPanPadding),h=o.point(this.options.autoPanPaddingTopLeft||a),l=o.point(this.options.autoPanPaddingBottomRight||a),u=t.getSize(),c=0,d=0;r.x+n+l.x>u.x&&(c=r.x+n-u.x+l.x),r.x-c-h.x<0&&(c=r.x-h.x),r.y+i+l.y>u.y&&(d=r.y+i-u.y+l.y),r.y-d-h.y<0&&(d=r.y-h.y),(c||d)&&t.fire("autopanstart").panBy([c,d])}},_onCloseButtonClick:function(t){this._close(),o.DomEvent.stop(t)},_getAnchor:function(){return o.point(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}}),o.popup=function(t,e){return new o.Popup(t,e)},o.Map.mergeOptions({closePopupOnClick:!0}),o.Map.include({openPopup:function(t,e,i){return t instanceof o.Popup||(t=new o.Popup(i).setContent(t)),e&&t.setLatLng(e),this.hasLayer(t)?this:(this._popup&&this._popup.options.autoClose&&this.closePopup(),this._popup=t,this.addLayer(t))},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&this.removeLayer(t),this}}),o.Layer.include({bindPopup:function(t,e){return t instanceof o.Popup?(o.setOptions(t,e),this._popup=t,t._source=this):(this._popup&&!e||(this._popup=new o.Popup(e,this)),this._popup.setContent(t)),this._popupHandlersAdded||(this.on({click:this._openPopup,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this.off({click:this._openPopup,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!1,this._popup=null),this},openPopup:function(t,e){if(t instanceof o.Layer||(e=t,t=this),t instanceof o.FeatureGroup)for(var i in this._layers){t=this._layers[i];break}return e||(e=t.getCenter?t.getCenter():t.getLatLng()),this._popup&&this._map&&(this._popup._source=t,this._popup.update(),this._map.openPopup(this._popup,e)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(t){return this._popup&&(this._popup._map?this.closePopup():this.openPopup(t)),this},isPopupOpen:function(){return!!this._popup&&this._popup.isOpen()},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},getPopup:function(){return this._popup},_openPopup:function(t){var e=t.layer||t.target;if(this._popup&&this._map)return o.DomEvent.stop(t),e instanceof o.Path?void this.openPopup(t.layer||t.target,t.latlng):void(this._map.hasLayer(this._popup)&&this._popup._source===e?this.closePopup():this.openPopup(e,t.latlng))},_movePopup:function(t){this._popup.setLatLng(t.latlng)}}),o.Tooltip=o.DivOverlay.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,interactive:!1,opacity:.9},onAdd:function(t){o.DivOverlay.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&this._source.fire("tooltipopen",{tooltip:this},!0)},onRemove:function(t){o.DivOverlay.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&this._source.fire("tooltipclose",{tooltip:this},!0)},getEvents:function(){var t=o.DivOverlay.prototype.getEvents.call(this);return o.Browser.touch&&!this.options.permanent&&(t.preclick=this._close),t},_close:function(){this._map&&this._map.closeTooltip(this)},_initLayout:function(){var t="leaflet-tooltip",e=t+" "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=o.DomUtil.create("div",e)},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var e=this._map,i=this._container,n=e.latLngToContainerPoint(e.getCenter()),s=e.layerPointToContainerPoint(t),r=this.options.direction,a=i.offsetWidth,h=i.offsetHeight,l=o.point(this.options.offset),u=this._getAnchor();"top"===r?t=t.add(o.point(-a/2+l.x,-h+l.y+u.y,!0)):"bottom"===r?t=t.subtract(o.point(a/2-l.x,-l.y,!0)):"center"===r?t=t.subtract(o.point(a/2+l.x,h/2-u.y+l.y,!0)):"right"===r||"auto"===r&&s.xh&&(s=r,h=a);h>i&&(e[s]=1,this._simplifyDPStep(t,e,i,n,s),this._simplifyDPStep(t,e,i,s,o))},_reducePoints:function(t,e){for(var i=[t[0]],n=1,o=0,s=t.length;ne&&(i.push(t[n]),o=n);return oe.max.x&&(i|=2),t.ye.max.y&&(i|=8),i},_sqDist:function(t,e){var i=e.x-t.x,n=e.y-t.y;return i*i+n*n},_sqClosestPointOnSegment:function(t,e,i,n){var s,r=e.x,a=e.y,h=i.x-r,l=i.y-a,u=h*h+l*l;return u>0&&(s=((t.x-r)*h+(t.y-a)*l)/u,s>1?(r=i.x,a=i.y):s>0&&(r+=h*s,a+=l*s)),h=t.x-r,l=t.y-a,n?h*h+l*l:new o.Point(r,a)}},o.Polyline=o.Path.extend({options:{smoothFactor:1,noClip:!1},initialize:function(t,e){o.setOptions(this,e),this._setLatLngs(t)},getLatLngs:function(){return this._latlngs},setLatLngs:function(t){return this._setLatLngs(t),this.redraw()},isEmpty:function(){return!this._latlngs.length},closestLayerPoint:function(t){for(var e,i,n=1/0,s=null,r=o.LineUtil._sqClosestPointOnSegment,a=0,h=this._parts.length;ae)return r=(n-e)/i,this._map.layerPointToLatLng([s.x-r*(s.x-o.x),s.y-r*(s.y-o.y)])},getBounds:function(){return this._bounds},addLatLng:function(t,e){return e=e||this._defaultShape(),t=o.latLng(t),e.push(t),this._bounds.extend(t),this.redraw()},_setLatLngs:function(t){this._bounds=new o.LatLngBounds,this._latlngs=this._convertLatLngs(t)},_defaultShape:function(){return o.Polyline._flat(this._latlngs)?this._latlngs:this._latlngs[0]},_convertLatLngs:function(t){for(var e=[],i=o.Polyline._flat(t),n=0,s=t.length;n=2&&e[0]instanceof o.LatLng&&e[0].equals(e[i-1])&&e.pop(),e},_setLatLngs:function(t){o.Polyline.prototype._setLatLngs.call(this,t),o.Polyline._flat(this._latlngs)&&(this._latlngs=[this._latlngs])},_defaultShape:function(){return o.Polyline._flat(this._latlngs[0])?this._latlngs[0]:this._latlngs[0][0]},_clipPoints:function(){var t=this._renderer._bounds,e=this.options.weight,i=new o.Point(e,e);if(t=new o.Bounds(t.min.subtract(i),t.max.add(i)),this._parts=[],this._pxBounds&&this._pxBounds.intersects(t)){if(this.options.noClip)return void(this._parts=this._rings);for(var n,s=0,r=this._rings.length;s';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(t){return!1}}(),o.SVG.include(o.Browser.vml?{_initContainer:function(){this._container=o.DomUtil.create("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(o.Renderer.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var e=t._container=o.SVG.create("shape");o.DomUtil.addClass(e,"leaflet-vml-shape "+(this.options.className||"")),e.coordsize="1 1",t._path=o.SVG.create("path"),e.appendChild(t._path),this._updateStyle(t),this._layers[o.stamp(t)]=t},_addPath:function(t){var e=t._container;this._container.appendChild(e),t.options.interactive&&t.addInteractiveTarget(e)},_removePath:function(t){var e=t._container;o.DomUtil.remove(e),t.removeInteractiveTarget(e),delete this._layers[o.stamp(t)]},_updateStyle:function(t){var e=t._stroke,i=t._fill,n=t.options,s=t._container;s.stroked=!!n.stroke,s.filled=!!n.fill,n.stroke?(e||(e=t._stroke=o.SVG.create("stroke")),s.appendChild(e),e.weight=n.weight+"px",e.color=n.color,e.opacity=n.opacity,n.dashArray?e.dashStyle=o.Util.isArray(n.dashArray)?n.dashArray.join(" "):n.dashArray.replace(/( *, *)/g," "):e.dashStyle="",e.endcap=n.lineCap.replace("butt","flat"),e.joinstyle=n.lineJoin):e&&(s.removeChild(e),t._stroke=null),n.fill?(i||(i=t._fill=o.SVG.create("fill")),s.appendChild(i),i.color=n.fillColor||n.color,i.opacity=n.fillOpacity):i&&(s.removeChild(i),t._fill=null)},_updateCircle:function(t){var e=t._point.round(),i=Math.round(t._radius),n=Math.round(t._radiusY||i);this._setPath(t,t._empty()?"M0 0":"AL "+e.x+","+e.y+" "+i+","+n+" 0,23592600")},_setPath:function(t,e){t._path.v=e},_bringToFront:function(t){o.DomUtil.toFront(t._container)},_bringToBack:function(t){o.DomUtil.toBack(t._container)}}:{}),o.Browser.vml&&(o.SVG.create=function(){try{return e.namespaces.add("lvml","urn:schemas-microsoft-com:vml"),function(t){return e.createElement("')}}catch(t){return function(t){return e.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}()),o.Canvas=o.Renderer.extend({getEvents:function(){var t=o.Renderer.prototype.getEvents.call(this);return t.viewprereset=this._onViewPreReset,t},_onViewPreReset:function(){this._postponeUpdatePaths=!0},onAdd:function(){o.Renderer.prototype.onAdd.call(this),this._draw()},_initContainer:function(){var t=this._container=e.createElement("canvas");o.DomEvent.on(t,"mousemove",o.Util.throttle(this._onMouseMove,32,this),this).on(t,"click dblclick mousedown mouseup contextmenu",this._onClick,this).on(t,"mouseout",this._handleMouseOut,this),this._ctx=t.getContext("2d")},_updatePaths:function(){if(!this._postponeUpdatePaths){var t;this._redrawBounds=null;for(var e in this._layers)t=this._layers[e],t._update();this._redraw()}},_update:function(){if(!this._map._animatingZoom||!this._bounds){this._drawnLayers={},o.Renderer.prototype._update.call(this);var t=this._bounds,e=this._container,i=t.getSize(),n=o.Browser.retina?2:1;o.DomUtil.setPosition(e,t.min),e.width=n*i.x,e.height=n*i.y,e.style.width=i.x+"px",e.style.height=i.y+"px",o.Browser.retina&&this._ctx.scale(2,2),this._ctx.translate(-t.min.x,-t.min.y),this.fire("update")}},_reset:function(){o.Renderer.prototype._reset.call(this),this._postponeUpdatePaths&&(this._postponeUpdatePaths=!1,this._updatePaths())},_initPath:function(t){this._updateDashArray(t),this._layers[o.stamp(t)]=t;var e=t._order={layer:t,prev:this._drawLast,next:null};this._drawLast&&(this._drawLast.next=e),this._drawLast=e,this._drawFirst=this._drawFirst||this._drawLast},_addPath:function(t){this._requestRedraw(t)},_removePath:function(t){var e=t._order,i=e.next,n=e.prev;i?i.prev=n:this._drawLast=n,n?n.next=i:this._drawFirst=i,delete t._order,delete this._layers[o.stamp(t)],this._requestRedraw(t)},_updatePath:function(t){this._extendRedrawBounds(t),t._project(),t._update(),this._requestRedraw(t)},_updateStyle:function(t){this._updateDashArray(t),this._requestRedraw(t)},_updateDashArray:function(t){if(t.options.dashArray){var e,i=t.options.dashArray.split(","),n=[];for(e=0;et.y!=n.y>t.y&&t.x<(n.x-i.x)*(t.y-i.y)/(n.y-i.y)+i.x&&(u=!u);return u||o.Polyline.prototype._containsPoint.call(this,t,!0)},o.CircleMarker.prototype._containsPoint=function(t){return t.distanceTo(this._point)<=this._radius+this._clickTolerance()},o.GeoJSON=o.FeatureGroup.extend({initialize:function(t,e){o.setOptions(this,e),this._layers={},t&&this.addData(t)},addData:function(t){var e,i,n,s=o.Util.isArray(t)?t:t.features;if(s){for(e=0,i=s.length;e1)return void(this._moved=!0);var n=i.touches&&1===i.touches.length?i.touches[0]:i,s=new o.Point(n.clientX,n.clientY),r=s.subtract(this._startPoint);(r.x||r.y)&&(Math.abs(r.x)+Math.abs(r.y)50&&(this._positions.shift(),this._times.shift())}this._map.fire("move",t).fire("drag",t)},_onZoomEnd:function(){var t=this._map.getSize().divideBy(2),e=this._map.latLngToLayerPoint([0,0]);this._initialWorldOffset=e.subtract(t).x,this._worldWidth=this._map.getPixelWorldBounds().getSize().x},_viscousLimit:function(t,e){return t-(t-e)*this._viscosity},_onPreDragLimit:function(){if(this._viscosity&&this._offsetLimit){var t=this._draggable._newPos.subtract(this._draggable._startPos),e=this._offsetLimit;t.xe.max.x&&(t.x=this._viscousLimit(t.x,e.max.x)),t.y>e.max.y&&(t.y=this._viscousLimit(t.y,e.max.y)),this._draggable._newPos=this._draggable._startPos.add(t)}},_onPreDragWrap:function(){var t=this._worldWidth,e=Math.round(t/2),i=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-e+i)%t+e-i,s=(n+e+i)%t-e-i,r=Math.abs(o+i)0?s:-s))-e;this._delta=0,this._startTime=null,r&&("center"===t.options.scrollWheelZoom?t.setZoom(e+r):t.setZoomAround(this._lastMousePos,e+r))}}),o.Map.addInitHook("addHandler","scrollWheelZoom",o.Map.ScrollWheelZoom),o.extend(o.DomEvent,{_touchstart:o.Browser.msPointer?"MSPointerDown":o.Browser.pointer?"pointerdown":"touchstart",_touchend:o.Browser.msPointer?"MSPointerUp":o.Browser.pointer?"pointerup":"touchend",addDoubleTapListener:function(t,e,i){function n(t){var e;if(o.Browser.pointer){if(!o.Browser.edge||"mouse"===t.pointerType)return;e=o.DomEvent._pointersCount}else e=t.touches.length;if(!(e>1)){var i=Date.now(),n=i-(r||i);a=t.touches?t.touches[0]:t,h=n>0&&n<=l,r=i}}function s(t){if(h&&!a.cancelBubble){if(o.Browser.pointer){if(!o.Browser.edge||"mouse"===t.pointerType)return;var i,n,s={};for(n in a)i=a[n],s[n]=i&&i.bind?i.bind(a):i;a=s}a.type="dblclick",e(a),r=null}}var r,a,h=!1,l=250,u="_leaflet_",c=this._touchstart,d=this._touchend;return t[u+c+i]=n,t[u+d+i]=s,t[u+"dblclick"+i]=e,t.addEventListener(c,n,!1),t.addEventListener(d,s,!1),t.addEventListener("dblclick",e,!1),this},removeDoubleTapListener:function(t,e){var i="_leaflet_",n=t[i+this._touchstart+e],s=t[i+this._touchend+e],r=t[i+"dblclick"+e];return t.removeEventListener(this._touchstart,n,!1),t.removeEventListener(this._touchend,s,!1),o.Browser.edge||t.removeEventListener("dblclick",r,!1),this}}),o.extend(o.DomEvent,{POINTER_DOWN:o.Browser.msPointer?"MSPointerDown":"pointerdown",POINTER_MOVE:o.Browser.msPointer?"MSPointerMove":"pointermove",POINTER_UP:o.Browser.msPointer?"MSPointerUp":"pointerup",POINTER_CANCEL:o.Browser.msPointer?"MSPointerCancel":"pointercancel",TAG_WHITE_LIST:["INPUT","SELECT","OPTION"],_pointers:{},_pointersCount:0,addPointerListener:function(t,e,i,n){return"touchstart"===e?this._addPointerStart(t,i,n):"touchmove"===e?this._addPointerMove(t,i,n):"touchend"===e&&this._addPointerEnd(t,i,n),this},removePointerListener:function(t,e,i){var n=t["_leaflet_"+e+i];return"touchstart"===e?t.removeEventListener(this.POINTER_DOWN,n,!1):"touchmove"===e?t.removeEventListener(this.POINTER_MOVE,n,!1):"touchend"===e&&(t.removeEventListener(this.POINTER_UP,n,!1),t.removeEventListener(this.POINTER_CANCEL,n,!1)),this},_addPointerStart:function(t,i,n){var s=o.bind(function(t){if("mouse"!==t.pointerType&&t.MSPOINTER_TYPE_MOUSE&&t.pointerType!==t.MSPOINTER_TYPE_MOUSE){if(!(this.TAG_WHITE_LIST.indexOf(t.target.tagName)<0))return;o.DomEvent.preventDefault(t)}this._handlePointer(t,i)},this);if(t["_leaflet_touchstart"+n]=s,t.addEventListener(this.POINTER_DOWN,s,!1),!this._pointerDocListener){var r=o.bind(this._globalPointerUp,this);e.documentElement.addEventListener(this.POINTER_DOWN,o.bind(this._globalPointerDown,this),!0),e.documentElement.addEventListener(this.POINTER_MOVE,o.bind(this._globalPointerMove,this),!0),e.documentElement.addEventListener(this.POINTER_UP,r,!0),e.documentElement.addEventListener(this.POINTER_CANCEL,r,!0),this._pointerDocListener=!0}},_globalPointerDown:function(t){this._pointers[t.pointerId]=t,this._pointersCount++},_globalPointerMove:function(t){this._pointers[t.pointerId]&&(this._pointers[t.pointerId]=t)},_globalPointerUp:function(t){delete this._pointers[t.pointerId],this._pointersCount--},_handlePointer:function(t,e){t.touches=[];for(var i in this._pointers)t.touches.push(this._pointers[i]);t.changedTouches=[t],e(t)},_addPointerMove:function(t,e,i){var n=o.bind(function(t){(t.pointerType!==t.MSPOINTER_TYPE_MOUSE&&"mouse"!==t.pointerType||0!==t.buttons)&&this._handlePointer(t,e)},this);t["_leaflet_touchmove"+i]=n,t.addEventListener(this.POINTER_MOVE,n,!1)},_addPointerEnd:function(t,e,i){var n=o.bind(function(t){this._handlePointer(t,e)},this);t["_leaflet_touchend"+i]=n,t.addEventListener(this.POINTER_UP,n,!1),t.addEventListener(this.POINTER_CANCEL,n,!1)}}),o.Map.mergeOptions({touchZoom:o.Browser.touch&&!o.Browser.android23,bounceAtZoomLimits:!0}),o.Map.TouchZoom=o.Handler.extend({addHooks:function(){o.DomUtil.addClass(this._map._container,"leaflet-touch-zoom"),o.DomEvent.on(this._map._container,"touchstart",this._onTouchStart,this)},removeHooks:function(){o.DomUtil.removeClass(this._map._container,"leaflet-touch-zoom"),o.DomEvent.off(this._map._container,"touchstart",this._onTouchStart,this)},_onTouchStart:function(t){var i=this._map;if(t.touches&&2===t.touches.length&&!i._animatingZoom&&!this._zooming){var n=i.mouseEventToContainerPoint(t.touches[0]),s=i.mouseEventToContainerPoint(t.touches[1]);this._centerPoint=i.getSize()._divideBy(2),this._startLatLng=i.containerPointToLatLng(this._centerPoint),"center"!==i.options.touchZoom&&(this._pinchStartLatLng=i.containerPointToLatLng(n.add(s)._divideBy(2))),this._startDist=n.distanceTo(s),this._startZoom=i.getZoom(),this._moved=!1,this._zooming=!0,i._stop(),o.DomEvent.on(e,"touchmove",this._onTouchMove,this).on(e,"touchend",this._onTouchEnd,this),o.DomEvent.preventDefault(t)}},_onTouchMove:function(t){if(t.touches&&2===t.touches.length&&this._zooming){var e=this._map,i=e.mouseEventToContainerPoint(t.touches[0]),n=e.mouseEventToContainerPoint(t.touches[1]),s=i.distanceTo(n)/this._startDist;if(this._zoom=e.getScaleZoom(s,this._startZoom),!e.options.bounceAtZoomLimits&&(this._zoome.getMaxZoom()&&s>1)&&(this._zoom=e._limitZoom(this._zoom)),"center"===e.options.touchZoom){if(this._center=this._startLatLng,1===s)return}else{var r=i._add(n)._divideBy(2)._subtract(this._centerPoint);if(1===s&&0===r.x&&0===r.y)return;this._center=e.unproject(e.project(this._pinchStartLatLng,this._zoom).subtract(r),this._zoom)}this._moved||(e._moveStart(!0),this._moved=!0),o.Util.cancelAnimFrame(this._animRequest);var a=o.bind(e._move,e,this._center,this._zoom,{pinch:!0,round:!1});this._animRequest=o.Util.requestAnimFrame(a,this,!0),o.DomEvent.preventDefault(t)}},_onTouchEnd:function(){return this._moved&&this._zooming?(this._zooming=!1,o.Util.cancelAnimFrame(this._animRequest),o.DomEvent.off(e,"touchmove",this._onTouchMove).off(e,"touchend",this._onTouchEnd),void(this._map.options.zoomAnimation?this._map._animateZoom(this._center,this._map._limitZoom(this._zoom),!0,this._map.options.zoomSnap):this._map._resetView(this._center,this._map._limitZoom(this._zoom)))):void(this._zooming=!1)}}),o.Map.addInitHook("addHandler","touchZoom",o.Map.TouchZoom),o.Map.mergeOptions({tap:!0,tapTolerance:15}),o.Map.Tap=o.Handler.extend({addHooks:function(){o.DomEvent.on(this._map._container,"touchstart",this._onDown,this)},removeHooks:function(){o.DomEvent.off(this._map._container,"touchstart",this._onDown,this)},_onDown:function(t){if(t.touches){if(o.DomEvent.preventDefault(t),this._fireClick=!0,t.touches.length>1)return this._fireClick=!1,void clearTimeout(this._holdTimeout);var i=t.touches[0],n=i.target;this._startPos=this._newPos=new o.Point(i.clientX,i.clientY),n.tagName&&"a"===n.tagName.toLowerCase()&&o.DomUtil.addClass(n,"leaflet-active"),this._holdTimeout=setTimeout(o.bind(function(){this._isTapValid()&&(this._fireClick=!1,this._onUp(),this._simulateEvent("contextmenu",i))},this),1e3),this._simulateEvent("mousedown",i),o.DomEvent.on(e,{touchmove:this._onMove,touchend:this._onUp},this)}},_onUp:function(t){if(clearTimeout(this._holdTimeout),o.DomEvent.off(e,{touchmove:this._onMove,touchend:this._onUp},this),this._fireClick&&t&&t.changedTouches){var i=t.changedTouches[0],n=i.target;n&&n.tagName&&"a"===n.tagName.toLowerCase()&&o.DomUtil.removeClass(n,"leaflet-active"),this._simulateEvent("mouseup",i), +this._isTapValid()&&this._simulateEvent("click",i)}},_isTapValid:function(){return this._newPos.distanceTo(this._startPos)<=this._map.options.tapTolerance},_onMove:function(t){var e=t.touches[0];this._newPos=new o.Point(e.clientX,e.clientY),this._simulateEvent("mousemove",e)},_simulateEvent:function(i,n){var o=e.createEvent("MouseEvents");o._simulated=!0,n.target._simulatedClick=!0,o.initMouseEvent(i,!0,!0,t,1,n.screenX,n.screenY,n.clientX,n.clientY,!1,!1,!1,!1,0,null),n.target.dispatchEvent(o)}}),o.Browser.touch&&!o.Browser.pointer&&o.Map.addInitHook("addHandler","tap",o.Map.Tap),o.Map.mergeOptions({boxZoom:!0}),o.Map.BoxZoom=o.Handler.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane},addHooks:function(){o.DomEvent.on(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){o.DomEvent.off(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_resetState:function(){this._moved=!1},_onMouseDown:function(t){return!(!t.shiftKey||1!==t.which&&1!==t.button)&&(this._resetState(),o.DomUtil.disableTextSelection(),o.DomUtil.disableImageDrag(),this._startPoint=this._map.mouseEventToContainerPoint(t),void o.DomEvent.on(e,{contextmenu:o.DomEvent.stop,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this))},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=o.DomUtil.create("div","leaflet-zoom-box",this._container),o.DomUtil.addClass(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var e=new o.Bounds(this._point,this._startPoint),i=e.getSize();o.DomUtil.setPosition(this._box,e.min),this._box.style.width=i.x+"px",this._box.style.height=i.y+"px"},_finish:function(){this._moved&&(o.DomUtil.remove(this._box),o.DomUtil.removeClass(this._container,"leaflet-crosshair")),o.DomUtil.enableTextSelection(),o.DomUtil.enableImageDrag(),o.DomEvent.off(e,{contextmenu:o.DomEvent.stop,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){if((1===t.which||1===t.button)&&(this._finish(),this._moved)){setTimeout(o.bind(this._resetState,this),0);var e=new o.LatLngBounds(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point));this._map.fitBounds(e).fire("boxzoomend",{boxZoomBounds:e})}},_onKeyDown:function(t){27===t.keyCode&&this._finish()}}),o.Map.addInitHook("addHandler","boxZoom",o.Map.BoxZoom),o.Map.mergeOptions({keyboard:!0,keyboardPanDelta:80}),o.Map.Keyboard=o.Handler.extend({keyCodes:{left:[37],right:[39],down:[40],up:[38],zoomIn:[187,107,61,171],zoomOut:[189,109,54,173]},initialize:function(t){this._map=t,this._setPanDelta(t.options.keyboardPanDelta),this._setZoomDelta(t.options.zoomDelta)},addHooks:function(){var t=this._map._container;t.tabIndex<=0&&(t.tabIndex="0"),o.DomEvent.on(t,{focus:this._onFocus,blur:this._onBlur,mousedown:this._onMouseDown},this),this._map.on({focus:this._addHooks,blur:this._removeHooks},this)},removeHooks:function(){this._removeHooks(),o.DomEvent.off(this._map._container,{focus:this._onFocus,blur:this._onBlur,mousedown:this._onMouseDown},this),this._map.off({focus:this._addHooks,blur:this._removeHooks},this)},_onMouseDown:function(){if(!this._focused){var i=e.body,n=e.documentElement,o=i.scrollTop||n.scrollTop,s=i.scrollLeft||n.scrollLeft;this._map._container.focus(),t.scrollTo(s,o)}},_onFocus:function(){this._focused=!0,this._map.fire("focus")},_onBlur:function(){this._focused=!1,this._map.fire("blur")},_setPanDelta:function(t){var e,i,n=this._panKeys={},o=this.keyCodes;for(e=0,i=o.left.length;e0&&t.screenY>0&&this._map.getContainer().focus()}}),o.control=function(t){return new o.Control(t)},o.Map.include({addControl:function(t){return t.addTo(this),this},removeControl:function(t){return t.remove(),this},_initControlPos:function(){function t(t,s){var r=i+t+" "+i+s;e[t+s]=o.DomUtil.create("div",r,n)}var e=this._controlCorners={},i="leaflet-",n=this._controlContainer=o.DomUtil.create("div",i+"control-container",this._container);t("top","left"),t("top","right"),t("bottom","left"),t("bottom","right")},_clearControlPos:function(){o.DomUtil.remove(this._controlContainer)}}),o.Control.Zoom=o.Control.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"-",zoomOutTitle:"Zoom out"},onAdd:function(t){var e="leaflet-control-zoom",i=o.DomUtil.create("div",e+" leaflet-bar"),n=this.options;return this._zoomInButton=this._createButton(n.zoomInText,n.zoomInTitle,e+"-in",i,this._zoomIn),this._zoomOutButton=this._createButton(n.zoomOutText,n.zoomOutTitle,e+"-out",i,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),i},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(t){!this._disabled&&this._map._zoomthis._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(t.shiftKey?3:1))},_createButton:function(t,e,i,n,s){var r=o.DomUtil.create("a",i,n);return r.innerHTML=t,r.href="#",r.title=e,r.setAttribute("role","button"),r.setAttribute("aria-label",e),o.DomEvent.on(r,"mousedown dblclick",o.DomEvent.stopPropagation).on(r,"click",o.DomEvent.stop).on(r,"click",s,this).on(r,"click",this._refocusOnMap,this),r},_updateDisabled:function(){var t=this._map,e="leaflet-disabled";o.DomUtil.removeClass(this._zoomInButton,e),o.DomUtil.removeClass(this._zoomOutButton,e),(this._disabled||t._zoom===t.getMinZoom())&&o.DomUtil.addClass(this._zoomOutButton,e),(this._disabled||t._zoom===t.getMaxZoom())&&o.DomUtil.addClass(this._zoomInButton,e)}}),o.Map.mergeOptions({zoomControl:!0}),o.Map.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new o.Control.Zoom,this.addControl(this.zoomControl))}),o.control.zoom=function(t){return new o.Control.Zoom(t)},o.Control.Attribution=o.Control.extend({options:{position:"bottomright",prefix:'Leaflet'},initialize:function(t){o.setOptions(this,t),this._attributions={}},onAdd:function(t){t.attributionControl=this,this._container=o.DomUtil.create("div","leaflet-control-attribution"),o.DomEvent&&o.DomEvent.disableClickPropagation(this._container);for(var e in t._layers)t._layers[e].getAttribution&&this.addAttribution(t._layers[e].getAttribution());return this._update(),this._container},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t?(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update(),this):this},removeAttribution:function(t){return t?(this._attributions[t]&&(this._attributions[t]--,this._update()),this):this},_update:function(){if(this._map){var t=[];for(var e in this._attributions)this._attributions[e]&&t.push(e);var i=[];this.options.prefix&&i.push(this.options.prefix),t.length&&i.push(t.join(", ")),this._container.innerHTML=i.join(" | ")}}}),o.Map.mergeOptions({attributionControl:!0}),o.Map.addInitHook(function(){this.options.attributionControl&&(new o.Control.Attribution).addTo(this)}),o.control.attribution=function(t){return new o.Control.Attribution(t)},o.Control.Scale=o.Control.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var e="leaflet-control-scale",i=o.DomUtil.create("div",e),n=this.options;return this._addScales(n,e+"-line",i),t.on(n.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,e,i){t.metric&&(this._mScale=o.DomUtil.create("div",e,i)),t.imperial&&(this._iScale=o.DomUtil.create("div",e,i))},_update:function(){var t=this._map,e=t.getSize().y/2,i=t.distance(t.containerPointToLatLng([0,e]),t.containerPointToLatLng([this.options.maxWidth,e]));this._updateScales(i)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var e=this._getRoundNum(t),i=e<1e3?e+" m":e/1e3+" km";this._updateScale(this._mScale,i,e/t)},_updateImperial:function(t){var e,i,n,o=3.2808399*t;o>5280?(e=o/5280,i=this._getRoundNum(e),this._updateScale(this._iScale,i+" mi",i/e)):(n=this._getRoundNum(o),this._updateScale(this._iScale,n+" ft",n/o))},_updateScale:function(t,e,i){t.style.width=Math.round(this.options.maxWidth*i)+"px",t.innerHTML=e},_getRoundNum:function(t){var e=Math.pow(10,(Math.floor(t)+"").length-1),i=t/e;return i=i>=10?10:i>=5?5:i>=3?3:i>=2?2:1,e*i}}),o.control.scale=function(t){return new o.Control.Scale(t)},o.Control.Layers=o.Control.extend({options:{collapsed:!0,position:"topright",autoZIndex:!0,hideSingleBase:!1,sortLayers:!1,sortFunction:function(t,e,i,n){return i1,this._baseLayersList.style.display=t?"":"none"),this._separator.style.display=e&&t?"":"none",this},_onLayerChange:function(t){this._handlingClick||this._update();var e=this._getLayer(o.stamp(t.target)),i=e.overlay?"add"===t.type?"overlayadd":"overlayremove":"add"===t.type?"baselayerchange":null;i&&this._map.fire(i,e)},_createRadioElement:function(t,i){var n='",o=e.createElement("div");return o.innerHTML=n,o.firstChild},_addItem:function(t){var i,n=e.createElement("label"),s=this._map.hasLayer(t.layer);t.overlay?(i=e.createElement("input"),i.type="checkbox",i.className="leaflet-control-layers-selector",i.defaultChecked=s):i=this._createRadioElement("leaflet-base-layers",s),i.layerId=o.stamp(t.layer),o.DomEvent.on(i,"click",this._onInputClick,this);var r=e.createElement("span");r.innerHTML=" "+t.name;var a=e.createElement("div");n.appendChild(a),a.appendChild(i),a.appendChild(r);var h=t.overlay?this._overlaysList:this._baseLayersList;return h.appendChild(n),this._checkDisabledLayers(),n},_onInputClick:function(){var t,e,i,n=this._form.getElementsByTagName("input"),o=[],s=[];this._handlingClick=!0;for(var r=n.length-1;r>=0;r--)t=n[r],e=this._getLayer(t.layerId).layer,i=this._map.hasLayer(e),t.checked&&!i?o.push(e):!t.checked&&i&&s.push(e);for(r=0;r=0;s--)t=n[s],e=this._getLayer(t.layerId).layer,t.disabled=e.options.minZoom!==i&&oe.options.maxZoom},_expand:function(){return this.expand()},_collapse:function(){return this.collapse()}}),o.control.layers=function(t,e,i){return new o.Control.Layers(t,e,i)}}(window,document); \ No newline at end of file diff --git a/org.argeo.suite.workbench.rap/plugin.xml b/org.argeo.suite.workbench.rap/plugin.xml new file mode 100644 index 0000000..981c361 --- /dev/null +++ b/org.argeo.suite.workbench.rap/plugin.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.argeo.suite.workbench.rap/pom.xml b/org.argeo.suite.workbench.rap/pom.xml new file mode 100644 index 0000000..ebd3090 --- /dev/null +++ b/org.argeo.suite.workbench.rap/pom.xml @@ -0,0 +1,39 @@ + + + 4.0.0 + + org.argeo.suite + argeo-suite + 2.1.14-SNAPSHOT + .. + + org.argeo.suite.workbench.rap + RAP Workbench + jar + + + org.argeo.connect + org.argeo.documents + ${version.argeo-connect} + + + org.argeo.connect + org.argeo.tracker + ${version.argeo-connect} + + + org.argeo.connect + org.argeo.people.workbench.rap + ${version.argeo-connect} + + + + org.argeo.tp + argeo-tp-rap-e3 + ${version.argeo-tp} + pom + provided + + + + diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/AsUiPlugin.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/AsUiPlugin.java new file mode 100644 index 0000000..7cb1885 --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/AsUiPlugin.java @@ -0,0 +1,73 @@ +package org.argeo.suite.workbench; + +import java.net.URL; + +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.resource.ImageRegistry; +import org.eclipse.swt.graphics.Image; +import org.eclipse.ui.plugin.AbstractUIPlugin; +import org.osgi.framework.BundleContext; + +/** The activator class controls the plug-in life cycle */ +public class AsUiPlugin extends AbstractUIPlugin { + + public static final String PLUGIN_ID = "org.argeo.suite.workbench.rap"; + + // The shared instance + private static AsUiPlugin plugin; + + private BundleContext bundleContext; + + /** Default constructor */ + public AsUiPlugin() { + } + + public void start(BundleContext context) throws Exception { + super.start(context); + this.bundleContext = context; + plugin = this; + } + + public void stop(BundleContext context) throws Exception { + plugin = null; + super.stop(context); + } + + /** + * Returns the shared instance + * + * @return the shared instance + */ + public static AsUiPlugin getDefault() { + return plugin; + } + + /** Creates the image */ + public static Image img(String path) { + return getImageDescriptor(path).createImage(); + } + + /** + * Returns an image descriptor for the image file at the given plug-in + * relative path + * + * @param path + * the path + * @return the image descriptor + */ + public static ImageDescriptor getImageDescriptor(String path) { + return imageDescriptorFromPlugin(PLUGIN_ID, path); + } + + public URL imageUrl(String path) { + return bundleContext.getBundle().getResource(path); + } + + @Override + protected void initializeImageRegistry(ImageRegistry reg) { + } + + public BundleContext getBundleContext() { + return bundleContext; + } +} diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/DashboardPerspective.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/DashboardPerspective.java new file mode 100644 index 0000000..765de22 --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/DashboardPerspective.java @@ -0,0 +1,21 @@ +package org.argeo.suite.workbench; + +import org.argeo.documents.workbench.parts.MyFilesView; +import org.argeo.suite.workbench.parts.QuickSearchView; +import org.eclipse.ui.IFolderLayout; +import org.eclipse.ui.IPageLayout; +import org.eclipse.ui.IPerspectiveFactory; + +/** Default Argeo Suite Dashboard perspective */ +public class DashboardPerspective implements IPerspectiveFactory { + + public void createInitialLayout(IPageLayout layout) { + String editorArea = layout.getEditorArea(); + layout.setEditorAreaVisible(true); + layout.setFixed(false); + IFolderLayout left = layout.createFolder("left", IPageLayout.LEFT, 0.25f, editorArea); + left.addView(MyFilesView.ID); + left.addView(QuickSearchView.ID); + // left.addView(MyTodoListView.ID); + } +} diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/SuiteWorkbenchException.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/SuiteWorkbenchException.java new file mode 100644 index 0000000..dbc3333 --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/SuiteWorkbenchException.java @@ -0,0 +1,17 @@ +package org.argeo.suite.workbench; + +public class SuiteWorkbenchException extends RuntimeException { + private static final long serialVersionUID = 5276857785523513563L; + + public SuiteWorkbenchException(String message) { + super(message); + } + + public SuiteWorkbenchException(Throwable cause) { + super(cause); + } + + public SuiteWorkbenchException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/commands/ImportEntities.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/commands/ImportEntities.java new file mode 100644 index 0000000..b9906e9 --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/commands/ImportEntities.java @@ -0,0 +1,670 @@ +package org.argeo.suite.workbench.commands; + +import static org.argeo.eclipse.ui.EclipseUiUtils.notEmpty; +import static org.argeo.suite.workbench.commands.JxlUtils.getStringValue; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.activities.ActivitiesNames; +import org.argeo.connect.ConnectConstants; +import org.argeo.connect.ConnectNames; +import org.argeo.connect.resources.ResourcesNames; +import org.argeo.connect.resources.ResourcesService; +import org.argeo.connect.util.ConnectJcrUtils; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.jcr.JcrUtils; +import org.argeo.people.ContactValueCatalogs; +import org.argeo.people.PeopleException; +import org.argeo.people.PeopleNames; +import org.argeo.people.PeopleService; +import org.argeo.people.PeopleTypes; +import org.argeo.people.util.PeopleJcrUtils; +import org.argeo.people.util.PersonJcrUtils; +import org.argeo.suite.workbench.SuiteWorkbenchException; +import org.argeo.suite.workbench.AsUiPlugin; +import org.eclipse.core.commands.AbstractHandler; +import org.eclipse.core.commands.ExecutionEvent; +import org.eclipse.core.commands.ExecutionException; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.rap.fileupload.FileDetails; +import org.eclipse.rap.fileupload.FileUploadEvent; +import org.eclipse.rap.fileupload.FileUploadHandler; +import org.eclipse.rap.fileupload.FileUploadListener; +import org.eclipse.rap.fileupload.FileUploadReceiver; +import org.eclipse.rap.rwt.service.ServerPushSession; +import org.eclipse.rap.rwt.widgets.FileUpload; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.handlers.HandlerUtil; + +import jxl.Sheet; +import jxl.Workbook; + +/** Open a one page wizard to import an EXCEL 2003 legacy organisation file */ +public class ImportEntities extends AbstractHandler implements PeopleNames { + private final static Log log = LogFactory.getLog(ImportEntities.class); + + public final static String ID = AsUiPlugin.PLUGIN_ID + ".importEntities"; + + // public final static String PARAM_NODE_TYPE = "param.nodeType"; + + private static final Map KNOWN_TEMPLATES; + static { + Map tmpMap = new HashMap(); + tmpMap.put("Organisations", PeopleTypes.PEOPLE_ORG); + tmpMap.put("Persons", PeopleTypes.PEOPLE_PERSON); + KNOWN_TEMPLATES = Collections.unmodifiableMap(tmpMap); + } + + // TODO make this configurable + private final static String IMPORT_ENCODING = "ISO-8859-1";// "UTF-8"; + + /* DEPENDENCY INJECTION */ + private Repository repository; + private ResourcesService resourcesService; + private PeopleService peopleService; + + public Object execute(final ExecutionEvent event) throws ExecutionException { + // String jcrId = event.getParameter(PARAM_NODE_TYPE); + + Wizard wizard = new ImportMappingFileWizard(HandlerUtil.getActiveShell(event), + "Upload legacy contact via Excel file import"); + WizardDialog dialog = new WizardDialog(HandlerUtil.getActiveShell(event), wizard); + dialog.open(); + return null; + } + + /** One page wizard to import a EXCEL 2003 Mapping files */ + private class ImportMappingFileWizard extends Wizard { + + // Various UI Objects + private UserInputPage userInputPage; + private Combo resourceTypeCombo; + + // File upload + private FileUpload fileUpload; + private Label fileNameLabel; + private ServerPushSession pushSession; + private File file; + + public ImportMappingFileWizard(Shell parentShell, String title) { + setWindowTitle(title); + } + + @Override + public void addPages() { + try { + userInputPage = new UserInputPage("User input page"); + addPage(userInputPage); + } catch (Exception e) { + throw new SuiteWorkbenchException("Cannot add page to wizard", e); + } + } + + /** Performs the real import. */ + @Override + public boolean performFinish() { + String templateName = resourceTypeCombo.getItem(resourceTypeCombo.getSelectionIndex()); + String type = KNOWN_TEMPLATES.get(templateName); + InputStream in = null; + try { + in = new FileInputStream(file); + if (PeopleTypes.PEOPLE_ORG.equals(type)) + importDefaultOrgFile(in); + else if (PeopleTypes.PEOPLE_PERSON.equals(type)) + importDefaultPersonFile(in); + } catch (IOException e) { + throw new SuiteWorkbenchException("Cannot import mapping file", e); + } finally { + IOUtils.closeQuietly(in); + } + return true; + } + + @Override + public boolean performCancel() { + return true; + } + + @Override + public boolean canFinish() { + if (resourceTypeCombo.getSelectionIndex() < 0) { + userInputPage.setErrorMessage("Please choose an entity type"); + return false; + } else if (file == null) { + userInputPage.setErrorMessage("Please upload a file"); + return false; + } else { + userInputPage.setErrorMessage(null); + return true; + } + } + + private class UserInputPage extends WizardPage { + private static final long serialVersionUID = 1L; + + public UserInputPage(String pageName) { + super(pageName); + setTitle("Upload an Excel 2003 file (.xls)"); + } + + public void createControl(Composite parent) { + parent.setLayout(new GridLayout(1, false)); + Composite composite = new Composite(parent, SWT.NONE); + composite.setLayout(new GridLayout(2, false)); + composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + // Import type + resourceTypeCombo = createLC(composite, "Type"); + resourceTypeCombo.addModifyListener(new ModifyListener() { + private static final long serialVersionUID = 1L; + + @Override + public void modifyText(ModifyEvent event) { + getWizard().getContainer().updateButtons(); + } + }); + resourceTypeCombo.setItems(KNOWN_TEMPLATES.keySet().toArray(new String[0])); + resourceTypeCombo.select(0); + + // File upload + Label lbl = new Label(composite, SWT.NONE); + lbl.setText("Chosen file"); + lbl.setFont(EclipseUiUtils.getBoldFont(composite)); + Composite uploadCmp = new Composite(composite, SWT.NONE); + uploadCmp.setLayoutData(EclipseUiUtils.fillWidth()); + createFileUploadArea(uploadCmp); + setControl(composite); + } + } + + private Control createFileUploadArea(Composite parent) { + GridLayout gl = EclipseUiUtils.noSpaceGridLayout(new GridLayout(2, false)); + gl.horizontalSpacing = 5; + parent.setLayout(gl); + + fileNameLabel = new Label(parent, SWT.NONE | SWT.BEGINNING); + fileNameLabel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + + fileUpload = new FileUpload(parent, SWT.NONE); + fileUpload.setText("Browse..."); + fileUpload.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); + + final String url = startUploadReceiver(); + pushSession = new ServerPushSession(); + + fileUpload.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = 1L; + + @Override + public void widgetSelected(SelectionEvent e) { + String fileName = fileUpload.getFileName(); + fileNameLabel.setText(fileName == null ? "" : fileName); + pushSession.start(); + fileUpload.submit(url); + } + }); + return parent; + } + + private String startUploadReceiver() { + MyFileUploadReceiver receiver = new MyFileUploadReceiver(); + FileUploadHandler uploadHandler = new FileUploadHandler(receiver); + uploadHandler.addUploadListener(new FileUploadListener() { + + public void uploadProgress(FileUploadEvent event) { + // handle upload progress + } + + public void uploadFailed(FileUploadEvent event) { + ImportMappingFileWizard.this.userInputPage + .setErrorMessage("upload failed: " + event.getException()); + } + + public void uploadFinished(FileUploadEvent event) { + fileNameLabel.getDisplay().asyncExec(new Runnable() { + public void run() { + ImportMappingFileWizard.this.getContainer().updateButtons(); + pushSession.stop(); + } + }); + } + }); + return uploadHandler.getUploadUrl(); + } + + private class MyFileUploadReceiver extends FileUploadReceiver { + + private static final String TEMP_FILE_PREFIX = "fileupload_"; + + @Override + public void receive(InputStream dataStream, FileDetails details) throws IOException { + File result = File.createTempFile(TEMP_FILE_PREFIX, ""); + FileOutputStream outputStream = new FileOutputStream(result); + try { + copy(dataStream, outputStream); + } finally { + dataStream.close(); + outputStream.close(); + } + if (file != null) + file.delete(); + file = result; + } + } + + private void copy(InputStream inputStream, OutputStream outputStream) throws IOException { + byte[] buffer = new byte[8192]; + boolean finished = false; + while (!finished) { + int bytesRead = inputStream.read(buffer); + if (bytesRead != -1) { + outputStream.write(buffer, 0, bytesRead); + } else { + finished = true; + } + } + } + + /** Creates label and Combo. */ + protected Combo createLC(Composite parent, String label) { + Label lbl = new Label(parent, SWT.RIGHT); + lbl.setText(label); + lbl.setFont(EclipseUiUtils.getBoldFont(parent)); + lbl.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false)); + Combo combo = new Combo(parent, SWT.READ_ONLY); + combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); + return combo; + } + } + + private Node importDefaultOrgFile(InputStream in) throws IOException { + // TODO make this configurable + int displayNameIndex = 0; + int legalNameIndex = 1; + int legalFormIndex = 2; + int urlsIndex = 3; + int streetIndex = 4; + int postalCodeIndex = 5; + int lIndex = 6; + int stIndex = 7; + int cIndex = 8; + int mobileIndex = 9; + int telephoneNumberIndex = 10; + int mailIndex = 11; + int contactsIndex = 12; + int descriptionIndex = 13; + int tagsIndex = 14; + + Session session = null; + int i = 0; + try { + Workbook wb = JxlUtils.toWorkbook(in, IMPORT_ENCODING); + session = repository.login(); + String basePath = "/" + peopleService.getBaseRelPath(PeopleTypes.PEOPLE_ORG); + Node targetParent = session.getNode(basePath); + Sheet sheet = wb.getSheet(0); + + Node tmpParent = peopleService.getDraftParent(session); + + int rowNb = sheet.getRows(); + for (i = 1; i < rowNb - 1; i++) { + + Node tmpOrg = createDraftNode(tmpParent, PeopleTypes.PEOPLE_ORG); + + String dName = JxlUtils.getStringValue(sheet, displayNameIndex, i); + if (notEmpty(dName)) + tmpOrg.setProperty(PeopleNames.PEOPLE_DISPLAY_NAME, dName); + String lName = getStringValue(sheet, legalNameIndex, i); + if (notEmpty(lName)) + tmpOrg.setProperty(PeopleNames.PEOPLE_LEGAL_NAME, lName); + String lForm = getStringValue(sheet, legalFormIndex, i); + if (notEmpty(lForm)) + tmpOrg.setProperty(PeopleNames.PEOPLE_LEGAL_FORM, lForm); + String urlStr = getStringValue(sheet, urlsIndex, i); + if (notEmpty(urlStr)) + importUrls(tmpOrg, urlStr); + String mailStr = getStringValue(sheet, mailIndex, i); + if (notEmpty(mailStr)) + importMails(tmpOrg, mailStr); + String streetStr = getStringValue(sheet, streetIndex, i); + String pcStr = getStringValue(sheet, postalCodeIndex, i); + String lStr = getStringValue(sheet, lIndex, i); + String stStr = getStringValue(sheet, stIndex, i); + String cStr = getStringValue(sheet, cIndex, i); + if (notEmpty(streetStr) || notEmpty(pcStr) || notEmpty(lStr) || notEmpty(stStr) || notEmpty(cStr)) + PeopleJcrUtils.createAddress(resourcesService, peopleService, tmpOrg, streetStr, null, pcStr, lStr, + stStr, cStr, true, ContactValueCatalogs.CONTACT_CAT_MAIN, null); + String mobileStr = getStringValue(sheet, mobileIndex, i); + if (notEmpty(mobileStr)) + PeopleJcrUtils.createPhone(resourcesService, peopleService, tmpOrg, mobileStr, true, null, null); + String phoneStr = getStringValue(sheet, telephoneNumberIndex, i); + if (notEmpty(phoneStr)) + PeopleJcrUtils.createPhone(resourcesService, peopleService, tmpOrg, phoneStr, true, + ContactValueCatalogs.CONTACT_CAT_DIRECT, null); + String descStr = getStringValue(sheet, descriptionIndex, i); + if (notEmpty(descStr)) + tmpOrg.setProperty(Property.JCR_DESCRIPTION, descStr); + String tagsStr = getStringValue(sheet, tagsIndex, i); + if (notEmpty(tagsStr)) + tmpOrg.setProperty(ResourcesNames.CONNECT_TAGS, ConnectJcrUtils.parseAndClean(tagsStr, ",", true)); + + Node newOrgNode = peopleService.publishEntity(targetParent, PeopleTypes.PEOPLE_ORG, tmpOrg); + // Save the newly created entity without creating a base version + newOrgNode = peopleService.saveEntity(newOrgNode, false); + + String contactsStr = getStringValue(sheet, contactsIndex, i); + if (notEmpty(contactsStr)) + importOrgEmployees(tmpParent, targetParent, newOrgNode, contactsStr); + } + + // Refresh tags and mailing list + Node tagParent = resourcesService.getTagLikeResourceParent(session, ConnectConstants.RESOURCE_TAG); + resourcesService.refreshKnownTags(tagParent); + + // Create Mailing lists + Node mlParent = resourcesService.getTagLikeResourceParent(session, PeopleTypes.PEOPLE_MAILING_LIST); + resourcesService.refreshKnownTags(mlParent); + + } catch (PeopleException | RepositoryException e) { + throw new SuiteWorkbenchException("Cannot import mapping file, error at line: " + (i + 1), e); + } finally { + JcrUtils.logoutQuietly(session); + } + + return null; + } + + private Map initialiseHeaders(Sheet sheet, List validHeaders) { + Map headers = new HashMap<>(); + int length = sheet.getColumns(); + for (int i = 0; i < length; i++) { + String value = JxlUtils.getStringValue(sheet, i, 0); + if (validHeaders.contains(value)) + headers.put(value, i); + else + log.warn(value + " (column [" + i + "]) is not a valid header"); + } + return headers; + } + + private Node importDefaultPersonFile(InputStream in) throws IOException { + // Local shortcut + String JCR_DESC = ConnectJcrUtils.getLocalJcrItemName(Property.JCR_DESCRIPTION); + + // Map headers = new HashMap<>(); + // headers.put(PeopleNames.PEOPLE_FIRST_NAME, 0); + // headers.put(PEOPLE_LAST_NAME, 1); + // headers.put(PEOPLE_SALUTATION, 2); + // headers.put(PEOPLE_HONORIFIC_TITLE, 3); + // headers.put(PEOPLE_NICKNAME, 4); + // headers.put(PEOPLE_NAME_SUFFIX, 5); + // headers.put(PEOPLE_MAIDEN_NAME, 6); + // headers.put(PEOPLE_PMOBILE, 7); + // headers.put(PEOPLE_PTELEPHONE_NUMBER, 8); + // headers.put(PEOPLE_SPOKEN_LANGUAGES, 9); + // headers.put(ResourcesNames.CONNECT_TAGS, 10); + // headers.put(PEOPLE_MAILING_LISTS, 11); + // headers.put(PEOPLE_BIRTH_DATE, 12); + // headers.put(PEOPLE_PMAIL, 13); + // headers.put("people:emailAddressOther", 14); + // headers.put("people:org", 15); + // headers.put(PEOPLE_ROLE, 16); + // headers.put(PEOPLE_DEPARTMENT, 17); + // headers.put("people:facebook", 18); + // headers.put(JCR_DESC, 19); + // headers.put(ActivitiesNames.ACTIVITIES_FROM_IP, 20); + + List validHeaders = Arrays.asList(PeopleNames.PEOPLE_FIRST_NAME, PEOPLE_LAST_NAME, PEOPLE_SALUTATION, + PEOPLE_HONORIFIC_TITLE, PEOPLE_NICKNAME, PEOPLE_NAME_SUFFIX, PEOPLE_MAIDEN_NAME, PEOPLE_PMOBILE, + PEOPLE_PTELEPHONE_NUMBER, PEOPLE_SPOKEN_LANGUAGES, ResourcesNames.CONNECT_TAGS, PEOPLE_MAILING_LISTS, + PEOPLE_BIRTH_DATE, PEOPLE_PMAIL, "people:emailAddressOther", "people:org", PEOPLE_ROLE, + PEOPLE_DEPARTMENT, "people:facebook", JCR_DESC, ActivitiesNames.ACTIVITIES_FROM_IP, PEOPLE_STREET, + PEOPLE_ZIP_CODE, PEOPLE_CITY, PEOPLE_STATE, PEOPLE_COUNTRY); + + String[] basicInfo = { PEOPLE_FIRST_NAME, PEOPLE_LAST_NAME, PEOPLE_SALUTATION, PEOPLE_HONORIFIC_TITLE, + PEOPLE_NICKNAME, PEOPLE_NAME_SUFFIX, PEOPLE_MAIDEN_NAME, PEOPLE_BIRTH_DATE, JCR_DESC }; + + Map primaryContacts = new HashMap<>(); + primaryContacts.put(PEOPLE_PMOBILE, PeopleTypes.PEOPLE_MOBILE); + primaryContacts.put(PEOPLE_PTELEPHONE_NUMBER, PeopleTypes.PEOPLE_TELEPHONE_NUMBER); + primaryContacts.put(PEOPLE_PURL, PeopleTypes.PEOPLE_URL); + primaryContacts.put(PEOPLE_PMAIL, PeopleTypes.PEOPLE_MAIL); + + String[] multiProps = { PEOPLE_SPOKEN_LANGUAGES, ResourcesNames.CONNECT_TAGS, PEOPLE_MAILING_LISTS, }; + + Session session = null; + int i = 0; + try { + Workbook wb = JxlUtils.toWorkbook(in, IMPORT_ENCODING); + session = repository.login(); + String basePath = "/" + peopleService.getBaseRelPath(PeopleTypes.PEOPLE_PERSON); + Node targetParent = session.getNode(basePath); + Sheet sheet = wb.getSheet(0); + + Map headers = initialiseHeaders(sheet, validHeaders); + + Node tmpParent = peopleService.getDraftParent(session); + + int rowNb = sheet.getRows(); + for (i = 1; i < rowNb; i++) { + Node tmpPerson = createDraftNode(tmpParent, PeopleTypes.PEOPLE_PERSON); + + for (String propName : basicInfo) { + if (headers.containsKey(propName)) { + String value = JxlUtils.getStringValue(sheet, headers.get(propName), i); + if (notEmpty(value)) + tmpPerson.setProperty(propName, value); + } + } + + for (String propName : multiProps) { + if (headers.containsKey(propName)) { + String value = JxlUtils.getStringValue(sheet, headers.get(propName), i); + if (notEmpty(value)) + tmpPerson.setProperty(propName, ConnectJcrUtils.parseAndClean(value, ",", true)); + } + } + + for (String propName : primaryContacts.keySet()) { + if (headers.containsKey(propName)) { + String value = JxlUtils.getStringValue(sheet, headers.get(propName), i); + if (notEmpty(value)) { + PeopleJcrUtils.createContact(resourcesService, peopleService, tmpPerson, + primaryContacts.get(propName), value, true, + ContactValueCatalogs.CONTACT_CAT_MAIN, null); + } + } + } + + // Specific values + String propName = "people:emailAddressOther"; + if (headers.containsKey(propName)) { + String value = JxlUtils.getStringValue(sheet, headers.get(propName), i); + if (notEmpty(value)) { + PeopleJcrUtils.createContact(resourcesService, peopleService, tmpPerson, + PeopleTypes.PEOPLE_MAIL, value, false, ContactValueCatalogs.CONTACT_CAT_MAIN, + null); + } + } + + propName = "people:facebook"; + if (headers.containsKey(propName)) { + String value = JxlUtils.getStringValue(sheet, headers.get(propName), i); + if (notEmpty(value)) { + PeopleJcrUtils.createContact(resourcesService, peopleService, tmpPerson, + PeopleTypes.PEOPLE_SOCIAL_MEDIA, value, false, + ContactValueCatalogs.CONTACT_CAT_FACEBOOK, null); + } + } + + String street = null, zip = null, city = null, state = null, country = null; + if (headers.containsKey(PEOPLE_STREET)) + street = JxlUtils.getStringValue(sheet, headers.get(PEOPLE_STREET), i); + if (headers.containsKey(PEOPLE_ZIP_CODE)) + zip = JxlUtils.getStringValue(sheet, headers.get(PEOPLE_ZIP_CODE), i); + if (headers.containsKey(PEOPLE_CITY)) + city = JxlUtils.getStringValue(sheet, headers.get(PEOPLE_CITY), i); + if (headers.containsKey(PEOPLE_STATE)) + state = JxlUtils.getStringValue(sheet, headers.get(PEOPLE_STATE), i); + if (headers.containsKey(PEOPLE_COUNTRY)) + country = JxlUtils.getStringValue(sheet, headers.get(PEOPLE_COUNTRY), i); + + if (notEmpty(street) || notEmpty(zip) || notEmpty(city) || notEmpty(state) || notEmpty(country)) { + PeopleJcrUtils.createAddress(resourcesService, peopleService, tmpPerson, street, null, zip, city, + state, country, true, ContactValueCatalogs.CONTACT_CAT_MAIN, null); + } + + // TODO Experimental connection activity to store info about the + // IP from where a person has registered himself in the system + // propName = ActivitiesNames.ACTIVITIES_FROM_IP; + + // TODO create a job and possibly the related organisation + + Node newPersonNode = peopleService.publishEntity(targetParent, PeopleTypes.PEOPLE_PERSON, tmpPerson); + // Save the newly created entity without creating a base version + newPersonNode = peopleService.saveEntity(newPersonNode, false); + } + + // Refresh tags and mailing list + Node tagParent = resourcesService.getTagLikeResourceParent(session, ConnectConstants.RESOURCE_TAG); + resourcesService.refreshKnownTags(tagParent); + + // Create Mailing lists + Node mlParent = resourcesService.getTagLikeResourceParent(session, PeopleTypes.PEOPLE_MAILING_LIST); + resourcesService.refreshKnownTags(mlParent); + } catch (PeopleException | RepositoryException e) { + String message = "Cannot import mapping file, error at line: " + (i + 1); + // TODO Check why the error is swallowed. + log.error(message, e); + throw new SuiteWorkbenchException(message, e); + } finally { + JcrUtils.logoutQuietly(session); + } + return null; + } + + private Node createDraftNode(Node parent, String mainMixin) throws RepositoryException { + String uuid = UUID.randomUUID().toString(); + Node tmpNode = parent.addNode(uuid); + tmpNode.addMixin(mainMixin); + tmpNode.setProperty(ConnectNames.CONNECT_UID, uuid); + return tmpNode; + } + + private void importOrgEmployees(Node tmpParent, Node targetParent, Node newOrgNode, String coworkersStr) + throws RepositoryException { + String[] coworkers = coworkersStr.split("\\n"); + loop: for (String line : coworkers) { + if (EclipseUiUtils.isEmpty(line)) + continue loop; + line = line.trim(); + int index = line.indexOf(' '); + String firstName = null; + String lastName = null; + String position = null; + if (index == -1) + firstName = line; + else { + firstName = line.substring(0, index); + line = line.substring(index); + + index = line.indexOf('('); + if (index == -1) + lastName = line; + else { + lastName = line.substring(0, index).trim(); + position = line.substring(index + 1, line.length() - 1); + } + } + Node tmpPerson = createDraftNode(tmpParent, PeopleTypes.PEOPLE_PERSON); + tmpPerson.setProperty(PEOPLE_FIRST_NAME, firstName); + if (EclipseUiUtils.notEmpty(lastName)) + tmpPerson.setProperty(PEOPLE_LAST_NAME, lastName); + Node newPersonNode = peopleService.publishEntity(targetParent, PeopleTypes.PEOPLE_PERSON, tmpPerson); + // if (EclipseUiUtils.notEmpty(position)) + PersonJcrUtils.addJob(resourcesService, peopleService, newPersonNode, newOrgNode, position, true); + // Save the newly created entity without creating a base version + newPersonNode = peopleService.saveEntity(newPersonNode, false); + + } + } + + private void importUrls(Node contactable, String urlStr) throws RepositoryException { + String[] urls = urlStr.split("\\n"); + boolean hasPrimary = false; + boolean hasPrimaryFacebook = false; + + loop: for (String line : urls) { + if (EclipseUiUtils.isEmpty(line)) + continue loop; + line = line.trim(); + + if (line.startsWith("https://www.facebook.com")) { + PeopleJcrUtils.createSocialMedia(resourcesService, peopleService, contactable, line, + !hasPrimaryFacebook, ContactValueCatalogs.CONTACT_CAT_FACEBOOK, null); + hasPrimaryFacebook = true; + } else { + PeopleJcrUtils.createWebsite(resourcesService, peopleService, contactable, line, !hasPrimary, null); + hasPrimary = true; + } + } + } + + private void importMails(Node contactable, String mailStr) throws RepositoryException { + String[] urls = mailStr.split("\\n"); + boolean hasPrimary = false; + loop: for (String line : urls) { + if (EclipseUiUtils.isEmpty(line)) + continue loop; + line = line.trim(); + PeopleJcrUtils.createEmail(resourcesService, peopleService, contactable, line, !hasPrimary, null, null); + hasPrimary = true; + } + } + + /* DEPENDENCY INJECTION */ + public void setRepository(Repository repository) { + this.repository = repository; + } + + public void setResourcesService(ResourcesService resourcesService) { + this.resourcesService = resourcesService; + } + + public void setPeopleService(PeopleService peopleService) { + this.peopleService = peopleService; + } +} diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/commands/JxlUtils.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/commands/JxlUtils.java new file mode 100644 index 0000000..8be4fa4 --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/commands/JxlUtils.java @@ -0,0 +1,82 @@ +package org.argeo.suite.workbench.commands; + +import java.io.IOException; +import java.io.InputStream; + +import org.argeo.connect.ConnectException; +import org.argeo.eclipse.ui.EclipseUiUtils; + +import jxl.Cell; +import jxl.CellType; +import jxl.JXLException; +import jxl.Sheet; +import jxl.Workbook; +import jxl.WorkbookSettings; + +/** Centralise useful methods to simplify development with JXL library */ +class JxlUtils { + + public static boolean isEmptyCell(Sheet sheet, int x, int y) { + Cell cell = sheet.getCell(x, y); + CellType type = cell.getType(); + return type == CellType.EMPTY; + } + + public static String getStringValue(Sheet sheet, int x, int y) { + Cell cell = sheet.getCell(x, y); + CellType type = cell.getType(); + String stringValue = null; + if (type == CellType.LABEL || type == CellType.NUMBER) + stringValue = cell.getContents(); + return stringValue; + } + + public static String getCompulsoryStringValue(Sheet sheet, int x, int y) { + Cell cell = sheet.getCell(x, y); + CellType type = cell.getType(); + String stringValue = null; + if (type == CellType.LABEL) + stringValue = cell.getContents(); + else if (type == CellType.NUMBER) + stringValue = cell.getContents(); + if (EclipseUiUtils.isEmpty(stringValue)) + throw new ConnectException("No name defined at [" + x + "," + y + "], cannot parse indicator file"); + return stringValue; + } + + public static Double getNumberValue(Sheet sheet, int x, int y) { + Cell cell = sheet.getCell(x, y); + CellType type = cell.getType(); + if (type == CellType.NUMBER) + return new Double(cell.getContents()); + else if (type == CellType.EMPTY) + return null; + else + throw new ConnectException("Not a number at [" + x + "," + y + "]: " + type.toString()); + } + + public static Sheet getOnlySheet(InputStream in, String encoding) throws IOException { + Workbook wkb = toWorkbook(in, encoding); + Sheet sheet = wkb.getSheet(0); + return sheet; + } + + public static Sheet getSheet(InputStream in, String encoding, int index) throws IOException { + Workbook wkb = toWorkbook(in, encoding); + return wkb.getSheet(index); + } + + public static Workbook toWorkbook(InputStream in, String encoding) throws IOException { + try { + WorkbookSettings ws = new WorkbookSettings(); + ws.setEncoding(encoding); + return Workbook.getWorkbook(in, ws); + } catch (JXLException e) { + throw new ConnectException("Unable to open XLS file", e); + } + } + + // Prevents instantiation + private JxlUtils() { + } +} diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/internal/EntitySingleColumnLabelProvider.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/internal/EntitySingleColumnLabelProvider.java new file mode 100644 index 0000000..49c39a5 --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/internal/EntitySingleColumnLabelProvider.java @@ -0,0 +1,88 @@ +package org.argeo.suite.workbench.internal; + +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.RepositoryException; +import javax.jcr.nodetype.NodeType; + +import org.argeo.activities.ActivitiesService; +import org.argeo.activities.ActivitiesTypes; +import org.argeo.activities.ui.ActivityListLabelProvider; +import org.argeo.connect.resources.ResourcesService; +import org.argeo.connect.ui.ConnectUiConstants; +import org.argeo.connect.ui.SystemWorkbenchService; +import org.argeo.connect.ui.util.TagLabelProvider; +import org.argeo.connect.util.ConnectUtils; +import org.argeo.people.PeopleException; +import org.argeo.people.PeopleNames; +import org.argeo.people.PeopleService; +import org.argeo.people.PeopleTypes; +import org.argeo.people.ui.providers.GroupLabelProvider; +import org.argeo.people.ui.providers.OrgListLabelProvider; +import org.argeo.people.ui.providers.PersonListLabelProvider; +import org.argeo.tracker.TrackerTypes; +import org.argeo.tracker.ui.TrackerSingleColLP; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.swt.graphics.Image; + +/** + * Provide a single column label provider for entity lists. Icon and displayed + * text vary with the element node type + */ +public class EntitySingleColumnLabelProvider extends LabelProvider implements PeopleNames { + private static final long serialVersionUID = 3111885324210673320L; + + private SystemWorkbenchService systemWorkbenchService; + + private ActivityListLabelProvider activityLP; + private TrackerSingleColLP trackerLP; + private OrgListLabelProvider orgLp; + private PersonListLabelProvider personLp; + private GroupLabelProvider groupLp = new GroupLabelProvider(ConnectUiConstants.LIST_TYPE_SMALL); + private TagLabelProvider mlInstanceLp; + + public EntitySingleColumnLabelProvider(ResourcesService resourceService, ActivitiesService activitiesService, + PeopleService peopleService, SystemWorkbenchService systemWorkbenchService) { + this.systemWorkbenchService = systemWorkbenchService; + activityLP = new ActivityListLabelProvider(activitiesService); + trackerLP = new TrackerSingleColLP(activitiesService); + personLp = new PersonListLabelProvider(peopleService); + orgLp = new OrgListLabelProvider(resourceService, peopleService); + mlInstanceLp = new TagLabelProvider(resourceService, ConnectUiConstants.LIST_TYPE_SMALL); + } + + @Override + public String getText(Object element) { + try { + Node entity = (Node) element; + String result; + + if (entity.isNodeType(TrackerTypes.TRACKER_TASK) || entity.isNodeType(TrackerTypes.TRACKER_PROJECT) + || entity.isNodeType(TrackerTypes.TRACKER_MILESTONE)) + result = trackerLP.getText(element); + else if (entity.isNodeType(ActivitiesTypes.ACTIVITIES_ACTIVITY)) + result = activityLP.getText(element); + else if (entity.isNodeType(PeopleTypes.PEOPLE_PERSON)) + result = personLp.getText(element); + else if (entity.isNodeType(PeopleTypes.PEOPLE_ORG)) + result = orgLp.getText(element); + else if (entity.isNodeType(PeopleTypes.PEOPLE_MAILING_LIST)) + result = mlInstanceLp.getText(element); + else if (entity.isNodeType(PeopleTypes.PEOPLE_GROUP)) + result = groupLp.getText(element); + else if (entity.isNodeType(NodeType.MIX_TITLE) && entity.hasProperty(Property.JCR_TITLE)) + result = entity.getProperty(Property.JCR_TITLE).getString(); + else + result = ""; + return ConnectUtils.replaceAmpersand(result); + } catch (RepositoryException re) { + throw new PeopleException("Unable to get formatted value for node", re); + } + } + + /** Overwrite this method to provide project specific images */ + @Override + public Image getImage(Object element) { + return systemWorkbenchService.getIconForType((Node) element); + } +} diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/AbstractSuiteDashboard.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/AbstractSuiteDashboard.java new file mode 100644 index 0000000..42a7de4 --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/AbstractSuiteDashboard.java @@ -0,0 +1,190 @@ +package org.argeo.suite.workbench.parts; + +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.Session; + +import org.argeo.cms.util.CmsUtils; +import org.argeo.connect.SystemAppService; +import org.argeo.connect.resources.ResourcesService; +import org.argeo.connect.ui.AppWorkbenchService; +import org.argeo.connect.ui.ConnectUiStyles; +import org.argeo.connect.ui.SystemWorkbenchService; +import org.argeo.connect.util.ConnectJcrUtils; +import org.argeo.connect.workbench.util.EntityEditorInput; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.jcr.JcrUtils; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.forms.widgets.FormToolkit; +import org.eclipse.ui.part.EditorPart; + +/** Generic dashboard for Argeo Suite applications */ +public abstract class AbstractSuiteDashboard extends EditorPart { + + // DEPENDENCY INJECTION + private Repository repository; + private ResourcesService resourcesService; + private SystemAppService systemAppService; + private SystemWorkbenchService systemWorkbenchService; + + private Session session; + + // UI Objects + private FormToolkit toolkit; + + @Override + public void init(IEditorSite site, IEditorInput input) throws PartInitException { + setSite(site); + setInput(input); + + session = ConnectJcrUtils.login(repository); + updateTooltip(input); + } + + private void updateTooltip(IEditorInput input) { + if (input instanceof EntityEditorInput) { + EntityEditorInput sei = (EntityEditorInput) input; + sei.setTooltipText("My Dashboard"); + } + } + + /** + * Implementing classes must call super in order to create the correct form + * toolkit + */ + @Override + public void createPartControl(Composite parent) { + toolkit = new FormToolkit(getSite().getShell().getDisplay()); + } + + // UTILS + protected Composite createGadgetCmp(Composite parent, int widthHint, int heightHint) { + Composite gadgetCmp = toolkit.createComposite(parent, SWT.BORDER); + GridData gd = new GridData(SWT.CENTER, SWT.CENTER, false, false); + gd.widthHint = widthHint; + gd.heightHint = heightHint; + gadgetCmp.setLayoutData(gd); + CmsUtils.style(gadgetCmp, ConnectUiStyles.GADGET_BOX); + return gadgetCmp; + } + + protected Composite createGadgetTitleCmp(Composite parent, String title) { + Composite titleCmp = toolkit.createComposite(parent, SWT.BACKGROUND | SWT.INHERIT_NONE); + CmsUtils.style(titleCmp, ConnectUiStyles.GADGET_HEADER); + titleCmp.setBackground(null); + GridData gd = new GridData(SWT.FILL, SWT.TOP, true, false); + titleCmp.setLayoutData(gd); + titleCmp.setLayout(new GridLayout()); + + Label titleLbl = toolkit.createLabel(titleCmp, title + " ", SWT.BOLD); + CmsUtils.style(titleLbl, ConnectUiStyles.GADGET_HEADER); + titleLbl.setBackground(null); + return titleCmp; + } + + protected Composite createGadgetBodyCmp(Composite parent) { + Composite bodyCmp = toolkit.createComposite(parent, SWT.BACKGROUND | SWT.INHERIT_NONE); + bodyCmp.setLayoutData(EclipseUiUtils.fillAll()); + bodyCmp.setLayout(new GridLayout()); + return bodyCmp; + } + + protected Link createOpenEntityEditorLink(final AppWorkbenchService peopleUiService, Composite parent, + final String label, final Node entity) { + Link link = new Link(parent, SWT.NONE); + link.setText("" + label + ""); + link.setLayoutData(EclipseUiUtils.fillWidth()); + link.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = 1L; + + @Override + public void widgetSelected(final SelectionEvent event) { + // Map params = new HashMap(); + // params.put(ConnectEditor.PARAM_JCR_ID, + // ConnectJcrUtils.getIdentifier(entity)); + // CommandUtils.callCommand(peopleUiService.getOpenEntityEditorCmdId(), params); + peopleUiService.openEntityEditor(entity); + } + }); + return link; + } + + // Life cycle + @Override + public void dispose() { + JcrUtils.logoutQuietly(session); + super.dispose(); + } + + @Override + public void doSave(IProgressMonitor monitor) { + } + + @Override + public void doSaveAs() { + } + + @Override + public boolean isDirty() { + return false; + } + + @Override + public boolean isSaveAsAllowed() { + return false; + } + + @Override + public void setFocus() { + // Do nothing + } + + // Expose to implementing classes + protected Session getSession() { + return session; + } + + public ResourcesService getResourcesService() { + return resourcesService; + } + + protected SystemAppService getSystemAppService() { + return systemAppService; + } + + protected SystemWorkbenchService getSystemWorkbenchService() { + return systemWorkbenchService; + } + + protected FormToolkit getFormToolkit() { + return toolkit; + } + + /* DEPENDENCY INJECTION */ + public void setRepository(Repository repository) { + this.repository = repository; + } + + public void setResourcesService(ResourcesService resourcesService) { + this.resourcesService = resourcesService; + } + + public void setSystemAppService(SystemAppService systemAppService) { + this.systemAppService = systemAppService; + } + + public void setSystemWorkbenchService(SystemWorkbenchService systemWorkbenchService) { + this.systemWorkbenchService = systemWorkbenchService; + } +} diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/DefaultDashboardEditor.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/DefaultDashboardEditor.java new file mode 100644 index 0000000..3ad7dfa --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/DefaultDashboardEditor.java @@ -0,0 +1,407 @@ +package org.argeo.suite.workbench.parts; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.List; + +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.Property; +import javax.jcr.RepositoryException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.activities.ActivitiesNames; +import org.argeo.activities.ActivitiesService; +import org.argeo.activities.ui.TaskViewerContextMenu; +import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.util.CmsUtils; +import org.argeo.connect.ConnectNames; +import org.argeo.connect.ui.ConnectWorkbenchUtils; +import org.argeo.connect.ui.Refreshable; +import org.argeo.connect.util.ConnectJcrUtils; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.jcr.JcrUtils; +import org.argeo.node.NodeUtils; +import org.argeo.suite.workbench.AsUiPlugin; +import org.argeo.suite.workbench.SuiteWorkbenchException; +import org.argeo.tracker.TrackerNames; +import org.argeo.tracker.TrackerService; +import org.argeo.tracker.TrackerTypes; +import org.argeo.tracker.core.TrackerUtils; +import org.argeo.tracker.ui.TaskListLabelProvider; +import org.argeo.tracker.ui.TaskVirtualListComposite; +import org.eclipse.jface.viewers.ColumnLabelProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.MouseAdapter; +import org.eclipse.swt.events.MouseEvent; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Link; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorSite; +import org.eclipse.ui.PartInitException; + +/** Argeo Suite Default Dashboard */ +public class DefaultDashboardEditor extends AbstractSuiteDashboard implements Refreshable { + final static Log log = LogFactory.getLog(DefaultDashboardEditor.class); + public final static String ID = AsUiPlugin.PLUGIN_ID + ".defaultDashboardEditor"; + + private ActivitiesService activitiesService; + private TrackerService trackerService; + + private String datePattern = "dd MMM yyyy"; + + private Composite headerCmp; + private Composite taskListCmp; + private TaskVirtualListComposite tvlc; + + @Override + public void init(IEditorSite site, IEditorInput input) throws PartInitException { + super.init(site, input); + } + + @Override + public void createPartControl(Composite parent) { + super.createPartControl(parent); + parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); + Composite bodyCmp = new Composite(parent, SWT.NO_FOCUS); + bodyCmp.setLayoutData(EclipseUiUtils.fillAll()); + bodyCmp.setLayout(new GridLayout()); + + headerCmp = new Composite(bodyCmp, SWT.NO_FOCUS); + headerCmp.setLayoutData(EclipseUiUtils.fillWidth()); + + taskListCmp = new Composite(bodyCmp, SWT.NO_FOCUS); + taskListCmp.setLayoutData(EclipseUiUtils.fillAll()); + forceRefresh(null); + } + + @Override + public void forceRefresh(Object object) { + CmsUtils.clear(headerCmp); + populateHeaderPart(headerCmp, NodeUtils.getUserHome(getSession())); + + CmsUtils.clear(taskListCmp); + populateTaskListCmp(taskListCmp); + + headerCmp.getParent().layout(true, true); + } + + private void populateTaskListCmp(Composite parent) { + parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); + NodeIterator nit = activitiesService.getMyTasks(getSession(), true); + if (!nit.hasNext()) { + Composite noTaskCmp = new Composite(parent, SWT.NO_FOCUS); + noTaskCmp.setLayoutData(EclipseUiUtils.fillAll()); + noTaskCmp.setLayout(new GridLayout()); + + Label noTaskLbl = new Label(noTaskCmp, SWT.CENTER); + noTaskLbl.setText(" You have no pending Task. "); + CmsUtils.markup(noTaskLbl); + noTaskLbl.setLayoutData(new GridData(SWT.CENTER, SWT.BOTTOM, true, true)); + + final Link createTaskLk = new Link(noTaskCmp, SWT.CENTER); + createTaskLk.setText(" Create a task "); + createTaskLk.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, true)); + + createTaskLk.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = -9028457805156989935L; + + @Override + public void widgetSelected(SelectionEvent e) { + String mainMixin = TrackerTypes.TRACKER_TASK; + String pathCreated = ConnectWorkbenchUtils.createAndConfigureEntity(createTaskLk.getShell(), + getSession(), getSystemAppService(), getSystemWorkbenchService(), mainMixin); + if (EclipseUiUtils.notEmpty(pathCreated)) + forceRefresh(null); + } + }); + + } else { + TaskListLabelProvider labelProvider = new TaskListLabelProvider(getSystemAppService()); + tvlc = new TaskVirtualListComposite(parent, SWT.NO_FOCUS, labelProvider, 54); + tvlc.setLayoutData(EclipseUiUtils.fillAll()); + final TableViewer viewer = tvlc.getTableViewer(); + viewer.setInput(JcrUtils.nodeIteratorToList(nit).toArray()); + final TaskViewerContextMenu contextMenu = new TaskViewerContextMenu(viewer, getSession(), + activitiesService) { + @Override + public boolean performAction(String actionId) { + boolean hasChanged = super.performAction(actionId); + if (hasChanged) { + viewer.getTable().setFocus(); + forceRefresh(null); + // NodeIterator nit = + // activitiesService.getMyTasks(getSession(), true); + // viewer.setInput(JcrUtils.nodeIteratorToList(nit).toArray()); + } + return hasChanged; + } + }; + viewer.getTable().addMouseListener(new MouseAdapter() { + private static final long serialVersionUID = 6737579410648595940L; + + @Override + public void mouseDown(MouseEvent e) { + if (e.button == 3) { + // contextMenu.setCurrFolderPath(currDisplayedFolder); + contextMenu.show(viewer.getTable(), new Point(e.x, e.y), + (IStructuredSelection) viewer.getSelection()); + } + } + }); + + } + } + + private boolean isOverdue(Node node, String propName) { + try { + Calendar now = GregorianCalendar.getInstance(); + return node.hasProperty(propName) && node.getProperty(propName).getDate().before(now); + } catch (RepositoryException e) { + throw new SuiteWorkbenchException("Cannot check overdue status with property " + propName + " on " + node, + e); + } + } + + private void populateHeaderPart(Composite bodyCmp, Node context) { + bodyCmp.setLayout(EclipseUiUtils.noSpaceGridLayout(new GridLayout(2, true))); + + Composite leftCmp = new Composite(bodyCmp, SWT.NO_FOCUS); + leftCmp.setLayout(new GridLayout()); + leftCmp.setLayoutData(EclipseUiUtils.fillWidth()); + Composite rightCmp = new Composite(bodyCmp, SWT.NO_FOCUS); + rightCmp.setLayout(new GridLayout()); + rightCmp.setLayoutData(EclipseUiUtils.fillWidth()); + + // Title + Label titleLbl = new Label(leftCmp, SWT.WRAP | SWT.LEAD); + CmsUtils.markup(titleLbl); + String titleStr = " Hello " + CurrentUser.getDisplayName() + " "; + titleLbl.setText(titleStr); + GridData gd = new GridData(SWT.TOP, SWT.BOTTOM, false, false); + gd.verticalIndent = 5; + gd.horizontalIndent = 10; + titleLbl.setLayoutData(gd); + + NodeIterator nit = activitiesService.getMyTasks(getSession(), true); + if (nit.hasNext()) { + List overdueTasks = new ArrayList<>(); + while (nit.hasNext()) { + Node currNode = nit.nextNode(); + if (isOverdue(currNode, ActivitiesNames.ACTIVITIES_DUE_DATE)) + overdueTasks.add(currNode); + } + if (!overdueTasks.isEmpty()) { + Composite overdueCmp = new Composite(leftCmp, SWT.NO_FOCUS); + long size = overdueTasks.size(); + String overdueStr = "You have " + size + " overdue task" + (size > 1 ? "s" : "") + ": "; + populateMuliValueClickableList(overdueCmp, overdueTasks.toArray(new Node[0]), new TaskLp(), overdueStr); + } + } + + nit = trackerService.getMyMilestones(getSession(), true); + List openMilestones = new ArrayList<>(); + + if (nit.hasNext()) { + List overdueMilestones = new ArrayList<>(); + while (nit.hasNext()) { + Node currNode = nit.nextNode(); + openMilestones.add(currNode); + if (isOverdue(currNode, TrackerNames.TRACKER_TARGET_DATE)) + overdueMilestones.add(currNode); + } + if (!overdueMilestones.isEmpty()) { + Composite overdueCmp = new Composite(leftCmp, SWT.NO_FOCUS); + long size = overdueMilestones.size(); + String overdueStr = "You have " + size + " overdue milestone" + (size > 1 ? "s" : "") + ": "; + populateMuliValueClickableList(overdueCmp, overdueMilestones.toArray(new Node[0]), new MilestoneLp(), + overdueStr); + } + } + + // My projects + List openProjects = JcrUtils.nodeIteratorToList(trackerService.getMyProjects(getSession(), true)); + if (!openProjects.isEmpty()) { + Group myProjectsGp = new Group(rightCmp, SWT.NO_FOCUS); + myProjectsGp.setText("My open projects"); + myProjectsGp.setLayoutData(EclipseUiUtils.fillWidth()); + populateMuliValueClickableList(myProjectsGp, openProjects.toArray(new Node[0]), new ProjectLp(), null); + } + + // My Milestones + if (!openMilestones.isEmpty()) { + Group myMilestoneGp = new Group(rightCmp, SWT.NO_FOCUS); + myMilestoneGp.setText("My open milestones"); + myMilestoneGp.setLayoutData(EclipseUiUtils.fillWidth()); + populateMuliValueClickableList(myMilestoneGp, openMilestones.toArray(new Node[0]), new MilestoneLp(), null); + } + } + + private class ProjectLp extends ColumnLabelProvider { + private static final long serialVersionUID = 7231233932794865555L; + + @Override + public String getText(Object element) { + Node project = (Node) element; + + String percent; + NodeIterator nit = TrackerUtils.getIssues(project, null, null, null, true); + long openNb = nit.getSize(); + + nit = TrackerUtils.getIssues(project, null, null, null, false); + long allNb = nit.getSize(); + + if (allNb < 1) + percent = "empty"; + else { + double num = allNb - openNb; + double result = num / allNb * 100; + percent = String.format("%.1f", result) + "% done"; + } + StringBuilder builder = new StringBuilder(); + builder.append("").append(ConnectJcrUtils.get(project, Property.JCR_TITLE)).append(""); + builder.append(" (").append(percent).append(")"); + + return builder.toString(); + } + } + + private class MilestoneLp extends ColumnLabelProvider { + private static final long serialVersionUID = 7231233932794865555L; + + @Override + public String getText(Object element) { + Node milestone = (Node) element; + Node project = TrackerUtils.getRelatedProject(trackerService, milestone); + String dueDate = ConnectJcrUtils.getDateFormattedAsString(milestone, TrackerNames.TRACKER_TARGET_DATE, + datePattern); + + String percent; + String propName = TrackerNames.TRACKER_MILESTONE_UID; + String muid = ConnectJcrUtils.get(milestone, ConnectNames.CONNECT_UID); + NodeIterator nit = TrackerUtils.getIssues(project, null, propName, muid, true); + long openNb = nit.getSize(); + + nit = TrackerUtils.getIssues(project, null, propName, muid, false); + long allNb = nit.getSize(); + + if (allNb < 1) + percent = "empty"; + else { + double num = allNb - openNb; + double result = num / allNb * 100; + percent = String.format("%.1f", result) + "% done"; + } + StringBuilder builder = new StringBuilder(); + builder.append("").append(ConnectJcrUtils.get(milestone, Property.JCR_TITLE)).append(""); + builder.append(" ("); + if (EclipseUiUtils.notEmpty(dueDate)) + builder.append("due to ").append(dueDate).append(", "); + + builder.append(percent).append(")"); + return builder.toString(); + } + + @Override + public Color getForeground(Object element) { + Node milestone = (Node) element; + Calendar dueDate = ConnectJcrUtils.getDateValue(milestone, TrackerNames.TRACKER_TARGET_DATE); + if (dueDate != null && dueDate.before(Calendar.getInstance())) + return Display.getCurrent().getSystemColor(SWT.COLOR_RED); + return null; + } + } + + private class TaskLp extends ColumnLabelProvider { + private static final long serialVersionUID = 7231233932794865555L; + + @Override + public String getText(Object element) { + Node task = (Node) element; + String dueDate = ConnectJcrUtils.getDateFormattedAsString(task, ActivitiesNames.ACTIVITIES_DUE_DATE, + datePattern); + + StringBuilder builder = new StringBuilder(); + builder.append("").append(ConnectJcrUtils.get(task, Property.JCR_TITLE)).append(""); + if (EclipseUiUtils.notEmpty(dueDate)) + builder.append(" (").append("due to ").append(dueDate).append(")"); + return builder.toString(); + } + + @Override + public Color getForeground(Object element) { + Node milestone = (Node) element; + Calendar dueDate = ConnectJcrUtils.getDateValue(milestone, TrackerNames.TRACKER_TARGET_DATE); + if (dueDate != null && dueDate.before(Calendar.getInstance())) + return Display.getCurrent().getSystemColor(SWT.COLOR_RED); + return null; + } + } + + @Override + public void setFocus() { + // refreshDocListGadget(); + } + + public void setActivitiesService(ActivitiesService activitiesService) { + this.activitiesService = activitiesService; + } + + public void setTrackerService(TrackerService trackerService) { + this.trackerService = trackerService; + } + + // LOCAL HELPERS + private void populateMuliValueClickableList(Composite parent, Node[] nodes, ColumnLabelProvider lp, + String listLabel) { + CmsUtils.clear(parent); + RowLayout rl = new RowLayout(SWT.HORIZONTAL | SWT.WRAP); + rl.wrap = true; + rl.marginLeft = rl.marginTop = rl.marginBottom = 0; + rl.marginRight = 8; + parent.setLayout(rl); + + if (EclipseUiUtils.notEmpty(listLabel)) { + Link link = new Link(parent, SWT.NONE); + link.setText(listLabel); + link.setFont(EclipseUiUtils.getBoldFont(parent)); + } + + int i = 1; + for (Node node : nodes) { + Link link = new Link(parent, SWT.NONE); + CmsUtils.markup(link); + link.setText(lp.getText(node) + (i != nodes.length ? ", " : "")); + i++; + // Color fc = lp.getForeground(node); + // if (fc != null) + // link.setForeground(fc); + + link.addSelectionListener(new SelectionAdapter() { + private static final long serialVersionUID = 1L; + + @Override + public void widgetSelected(final SelectionEvent event) { + // CommandUtils.callCommand(getSystemWorkbenchService().getOpenEntityEditorCmdId(), + // ConnectEditor.PARAM_JCR_ID, ConnectJcrUtils.getIdentifier(node)); + getSystemWorkbenchService().openEntityEditor(node); + } + }); + } + } + +} diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/QuickSearchView.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/QuickSearchView.java new file mode 100644 index 0000000..c8ebdb2 --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/QuickSearchView.java @@ -0,0 +1,255 @@ +package org.argeo.suite.workbench.parts; + +import static org.argeo.eclipse.ui.EclipseUiUtils.notEmpty; + +import javax.jcr.NodeIterator; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.observation.Event; +import javax.jcr.observation.EventIterator; +import javax.jcr.observation.EventListener; +import javax.jcr.query.Query; +import javax.jcr.query.QueryResult; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.argeo.activities.ActivitiesService; +import org.argeo.cms.util.CmsUtils; +import org.argeo.connect.ConnectTypes; +import org.argeo.connect.resources.ResourcesService; +import org.argeo.connect.ui.ConnectUiConstants; +import org.argeo.connect.ui.Refreshable; +import org.argeo.connect.ui.SystemWorkbenchService; +import org.argeo.connect.ui.util.BasicNodeListContentProvider; +import org.argeo.connect.ui.util.JcrViewerDClickListener; +import org.argeo.connect.ui.widgets.DelayedText; +import org.argeo.connect.util.ConnectJcrUtils; +import org.argeo.connect.util.XPathUtils; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.jcr.JcrUtils; +import org.argeo.people.PeopleService; +import org.argeo.suite.workbench.AsUiPlugin; +import org.argeo.suite.workbench.SuiteWorkbenchException; +import org.argeo.suite.workbench.internal.EntitySingleColumnLabelProvider; +import org.eclipse.jface.layout.TableColumnLayout; +import org.eclipse.jface.viewers.ColumnWeightData; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.rap.rwt.service.ServerPushSession; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyEvent; +import org.eclipse.swt.events.KeyListener; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.Text; +import org.eclipse.ui.IViewSite; +import org.eclipse.ui.PartInitException; +import org.eclipse.ui.part.ViewPart; + +/** A table with a quick search field. */ +public class QuickSearchView extends ViewPart implements Refreshable { + private final static Log log = LogFactory.getLog(QuickSearchView.class); + public static final String ID = AsUiPlugin.PLUGIN_ID + ".quickSearchView"; + + /* DEPENDENCY INJECTION */ + private Repository repository; + private Session session; + private ResourcesService resourcesService; + private ActivitiesService activitiesService; + private PeopleService peopleService; + private SystemWorkbenchService systemWorkbenchService; + + // This page widgets + private TableViewer entityViewer; + private Text filterTxt; + + @Override + public void init(IViewSite site) throws PartInitException { + super.init(site); + } + + @Override + public void createPartControl(Composite parent) { + session = ConnectJcrUtils.login(repository); + // MainLayout + parent.setLayout(new GridLayout()); + addFilterPanel(parent); + entityViewer = createListPart(parent, new EntitySingleColumnLabelProvider(resourcesService, activitiesService, + peopleService, systemWorkbenchService)); + refreshFilteredList(); + + try { + session.getWorkspace().getObservationManager().addEventListener(new EventListener() { + + @Override + public void onEvent(EventIterator events) { + parent.getDisplay().asyncExec(() -> refreshFilteredList()); + } + }, Event.PROPERTY_CHANGED | Event.NODE_ADDED | Event.NODE_REMOVED | Event.PROPERTY_ADDED, "/", true, null, + new String[] { ConnectTypes.CONNECT_ENTITY }, true); + } catch (RepositoryException e) { + throw new SuiteWorkbenchException("Cannot add JCR observer", e); + } + + } + + public void addFilterPanel(Composite parent) { + // Use a delayed text: the query won't be done until the user stop + // typing for 800ms + int style = SWT.BORDER | SWT.SEARCH | SWT.ICON_CANCEL; + DelayedText delayedText = new DelayedText(parent, style, ConnectUiConstants.SEARCH_TEXT_DELAY); + filterTxt = delayedText.getText(); + filterTxt.setLayoutData(EclipseUiUtils.fillWidth()); + + final ServerPushSession pushSession = new ServerPushSession(); + delayedText.addDelayedModifyListener(pushSession, new ModifyListener() { + private static final long serialVersionUID = 5003010530960334977L; + + public void modifyText(ModifyEvent event) { + delayedText.getText().getDisplay().asyncExec(new Runnable() { + @Override + public void run() { + refreshFilteredList(); + } + }); + pushSession.stop(); + } + }); + + // Jump to the first item of the list using the down arrow + filterTxt.addKeyListener(new KeyListener() { + private static final long serialVersionUID = -4523394262771183968L; + + @Override + public void keyReleased(KeyEvent e) { + } + + @Override + public void keyPressed(KeyEvent e) { + // boolean shiftPressed = (e.stateMask & SWT.SHIFT) != 0; + // boolean altPressed = (e.stateMask & SWT.ALT) != 0; + if (e.keyCode == SWT.ARROW_DOWN || e.keyCode == SWT.TAB) { + Object first = entityViewer.getElementAt(0); + if (first != null) { + entityViewer.getTable().setFocus(); + entityViewer.setSelection(new StructuredSelection(first), true); + } + e.doit = false; + } + } + }); + } + + protected TableViewer createListPart(Composite parent, ILabelProvider labelProvider) { + parent.setLayout(new GridLayout()); + + Composite tableComposite = new Composite(parent, SWT.NONE); + GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_VERTICAL + | GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL); + tableComposite.setLayoutData(gd); + + TableViewer v = new TableViewer(tableComposite); + v.setLabelProvider(labelProvider); + + TableColumn singleColumn = new TableColumn(v.getTable(), SWT.V_SCROLL); + TableColumnLayout tableColumnLayout = new TableColumnLayout(); + tableColumnLayout.setColumnData(singleColumn, new ColumnWeightData(85)); + tableComposite.setLayout(tableColumnLayout); + + // Corresponding table & style + Table table = v.getTable(); + table.setLinesVisible(true); + table.setHeaderVisible(false); + CmsUtils.markup(table); + CmsUtils.setItemHeight(table, 26); + + v.setContentProvider(new BasicNodeListContentProvider()); + v.addDoubleClickListener(new JcrViewerDClickListener(systemWorkbenchService)); + return v; + } + + @Override + public void dispose() { + JcrUtils.logoutQuietly(session); + super.dispose(); + } + + @Override + public void setFocus() { + refreshFilteredList(); + filterTxt.setFocus(); + } + + @Override + public void forceRefresh(Object object) { + refreshFilteredList(); + } + + protected void refreshFilteredList() { + try { + String filter = filterTxt.getText(); + // Prevents the query on the full repository + // if (isEmpty(filter)) { + // entityViewer.setInput(null); + // return; + // } + + // XPATH Query + String xpathQueryStr = "//element(*, " + ConnectTypes.CONNECT_ENTITY + ")"; + String xpathFilter = XPathUtils.getFreeTextConstraint(filter); + if (notEmpty(xpathFilter)) + xpathQueryStr += "[" + xpathFilter + "]"; + + // boolean doOrder = orderResultsBtn != null + // && !(orderResultsBtn.isDisposed()) + // && orderResultsBtn.getSelection(); + // if (doOrder) { + // xpathQueryStr += " order by jcr:title"; + // } + + long begin = System.currentTimeMillis(); + Query xpathQuery = XPathUtils.createQuery(session, xpathQueryStr); + + xpathQuery.setLimit(ConnectUiConstants.SEARCH_DEFAULT_LIMIT); + QueryResult result = xpathQuery.execute(); + + NodeIterator nit = result.getNodes(); + entityViewer.setInput(JcrUtils.nodeIteratorToList(nit)); + if (log.isDebugEnabled()) { + long end = System.currentTimeMillis(); + log.debug("Quick Search - Found: " + nit.getSize() + " in " + (end - begin) + + " ms by executing XPath query (" + xpathQueryStr + ")."); + } + } catch (RepositoryException e) { + throw new SuiteWorkbenchException("Unable to list entities", e); + } + } + + /* DEPENDENCY INJECTION */ + public void setRepository(Repository repository) { + this.repository = repository; + } + + public void setResourcesService(ResourcesService resourcesService) { + this.resourcesService = resourcesService; + } + + public void setActivitiesService(ActivitiesService activitiesService) { + this.activitiesService = activitiesService; + } + + public void setPeopleService(PeopleService peopleService) { + this.peopleService = peopleService; + } + + public void setSystemWorkbenchService(SystemWorkbenchService systemWorkbenchService) { + this.systemWorkbenchService = systemWorkbenchService; + } +} diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/TestView.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/TestView.java new file mode 100644 index 0000000..e45cd69 --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/parts/TestView.java @@ -0,0 +1,49 @@ +package org.argeo.suite.workbench.parts; + +import javax.jcr.Repository; +import javax.jcr.Session; + +import org.argeo.connect.util.ConnectJcrUtils; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.argeo.jcr.JcrUtils; +import org.argeo.suite.workbench.AsUiPlugin; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.ui.part.ViewPart; + +/** Basic view to test plugin */ +public class TestView extends ViewPart { + public static final String ID = AsUiPlugin.PLUGIN_ID + ".testView"; + + /* DEPENDENCY INJECTION */ + private Repository repository; + private Session session; + + @Override + public void createPartControl(Composite parent) { + // Finalise initialisation + session = ConnectJcrUtils.login(repository); + + GridLayout layout = EclipseUiUtils.noSpaceGridLayout(); + layout.verticalSpacing = 5; + parent.setLayout(layout); + + new Label(parent, SWT.NONE).setText("Test view shown."); + } + + @Override + public void setFocus() { + } + + @Override + public void dispose() { + JcrUtils.logoutQuietly(session); + super.dispose(); + } + + public void setRepository(Repository repository) { + this.repository = repository; + } +} diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/rap/AsActionBarAdvisor.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/rap/AsActionBarAdvisor.java new file mode 100644 index 0000000..1b985bf --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/rap/AsActionBarAdvisor.java @@ -0,0 +1,12 @@ +package org.argeo.suite.workbench.rap; + +import org.argeo.cms.ui.workbench.rap.RapActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; + +/** Eclipse rap specific action bar advisor */ +public class AsActionBarAdvisor extends RapActionBarAdvisor { + + public AsActionBarAdvisor(IActionBarConfigurer configurer, String username) { + super(configurer, username); + } +} diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/rap/AsSecureEntryPoint.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/rap/AsSecureEntryPoint.java new file mode 100644 index 0000000..bae894d --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/rap/AsSecureEntryPoint.java @@ -0,0 +1,72 @@ +package org.argeo.suite.workbench.rap; + +import org.argeo.cms.ui.workbench.rap.RapWorkbenchAdvisor; +import org.argeo.cms.ui.workbench.rap.RapWorkbenchLogin; +import org.argeo.cms.util.CmsUtils; +import org.argeo.cms.widgets.auth.CmsLogin; +import org.argeo.eclipse.ui.EclipseUiUtils; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; + +/** + * This class controls all aspects of the application's execution and is + * contributed through the plugin.xml. + */ +public class AsSecureEntryPoint extends RapWorkbenchLogin { + + /** Override to provide an application specific workbench advisor */ + protected RapWorkbenchAdvisor createRapWorkbenchAdvisor(String username) { + return new AsWorkbenchAdvisor(username); + } + + protected void createLoginPage(Composite parent, CmsLogin login) { + parent.setLayout(EclipseUiUtils.noSpaceGridLayout()); + + // Main layout + Composite bodyCmp = new Composite(parent, SWT.NO_FOCUS); + bodyCmp.setLayoutData(EclipseUiUtils.fillAll()); + GridLayout gl = new GridLayout(); + gl.marginHeight = 25; + gl.marginWidth = 40; + bodyCmp.setLayout(gl); + + // Logo + Label headerLbl = new Label(bodyCmp, SWT.WRAP); + CmsUtils.markup(headerLbl); + // Images are declared via the resources extension point in plugin.xml + String headerStr = " " + + " " + ""; + headerLbl.setText(headerStr); + GridData gd = new GridData(SWT.LEFT, SWT.CENTER, true, false); + headerLbl.setLayoutData(gd); + + // Title + Label titleLbl = new Label(bodyCmp, SWT.WRAP | SWT.CENTER); + CmsUtils.markup(titleLbl); + String titleStr = " Please sign in to your personal dashboard"; + titleLbl.setText(titleStr); + gd = new GridData(SWT.CENTER, SWT.BOTTOM, false, false); + gd.verticalIndent = 15; + titleLbl.setLayoutData(gd); + + // Login composite + Composite loginCmp = login.createCredentialsBlock(bodyCmp); + gd = new GridData(SWT.CENTER, SWT.TOP, true, true); + gd.widthHint = 200; + gd.verticalIndent = 15; + loginCmp.setLayoutData(gd); + + // // Footer + // Label footerLbl = new Label(bodyCmp, SWT.WRAP | SWT.CENTER); + // CmsUtils.markup(footerLbl); + // String footerStr = "SDPS is a private service.
" + // + " Please contact us if you + // have any question.
"; + // footerLbl.setText(footerStr); + // footerLbl.setLayoutData(EclipseUiUtils.fillWidth()); + } +} diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/rap/AsWelcomeRedirect.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/rap/AsWelcomeRedirect.java new file mode 100644 index 0000000..d8c992e --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/rap/AsWelcomeRedirect.java @@ -0,0 +1,17 @@ +package org.argeo.suite.workbench.rap; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class AsWelcomeRedirect extends HttpServlet { + private static final long serialVersionUID = 4359084312826596812L; + + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + resp.sendRedirect(resp.encodeRedirectURL("/ui/WelcomePage")); + } +} diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/rap/AsWindowAdvisor.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/rap/AsWindowAdvisor.java new file mode 100644 index 0000000..b6ba3f9 --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/rap/AsWindowAdvisor.java @@ -0,0 +1,43 @@ +package org.argeo.suite.workbench.rap; + +import org.argeo.cms.ui.workbench.rap.RapWindowAdvisor; +import org.argeo.cms.ui.workbench.util.CommandUtils; +import org.argeo.connect.workbench.commands.OpenDefaultEditor; +import org.eclipse.ui.application.ActionBarAdvisor; +import org.eclipse.ui.application.IActionBarConfigurer; +import org.eclipse.ui.application.IWorkbenchWindowConfigurer; + +/** Eclipse RAP specific window advisor */ +public class AsWindowAdvisor extends RapWindowAdvisor { + + private String username; + + public AsWindowAdvisor(IWorkbenchWindowConfigurer configurer, String username) { + super(configurer, username); + this.username = username; + } + + @Override + public ActionBarAdvisor createActionBarAdvisor(IActionBarConfigurer configurer) { + return new AsActionBarAdvisor(configurer, username); + } + + @Override + public void preWindowOpen() { + super.preWindowOpen(); + IWorkbenchWindowConfigurer configurer = getWindowConfigurer(); + configurer.setShowStatusLine(true); + configurer.setShowPerspectiveBar(false); + configurer.setShowMenuBar(false); + } + + @Override + public void postWindowOpen() { + super.postWindowOpen(); + try { + CommandUtils.callCommand(OpenDefaultEditor.ID); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/rap/AsWorkbenchAdvisor.java b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/rap/AsWorkbenchAdvisor.java new file mode 100644 index 0000000..5f67135 --- /dev/null +++ b/org.argeo.suite.workbench.rap/src/org/argeo/suite/workbench/rap/AsWorkbenchAdvisor.java @@ -0,0 +1,38 @@ +package org.argeo.suite.workbench.rap; + +import org.argeo.cms.ui.workbench.rap.RapWorkbenchAdvisor; +import org.eclipse.ui.application.IWorkbenchWindowConfigurer; +import org.eclipse.ui.application.WorkbenchWindowAdvisor; + +/** Eclipse RAP specific workbench advisor */ +public class AsWorkbenchAdvisor extends RapWorkbenchAdvisor { + + private String username; + + @Override + public void postStartup() { + super.postStartup(); + // ExitConfirmation confirmation = RWT.getClient().getService( + // ExitConfirmation.class); + // confirmation.setMessage("Are you sure you want to leave the page? " + // + "All un-saved information will be lost."); + } + + public void postShutdown() { + super.postShutdown(); + // ExitConfirmation confirmation = RWT.getClient().getService( + // ExitConfirmation.class); + // if (confirmation != null) + // confirmation.setMessage(null); + } + + public AsWorkbenchAdvisor(String username) { + super(username); + this.username = username; + } + + public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor( + IWorkbenchWindowConfigurer configurer) { + return new AsWindowAdvisor(configurer, username); + } +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..7255909 --- /dev/null +++ b/pom.xml @@ -0,0 +1,200 @@ + + 4.0.0 + + org.argeo.commons + argeo-commons + 2.1.76-SNAPSHOT + + org.argeo.suite + argeo-suite + pom + Argeo Suite + + 2.1.14-SNAPSHOT + + /srv/rpmfactory/argeo-osgi-2-gpl/el7 + 2.1.14-SNAPSHOT + 2.1.80-SNAPSHOT + 2.1.10 + + + + + org.argeo.suite.web + org.argeo.suite.apps.web + + + org.argeo.suite.cms + org.argeo.suite.e4 + org.argeo.suite.e4.rap + org.argeo.suite.standard + + + org.argeo.suite.tracker + + + org.argeo.suite.apps + org.argeo.suite.workbench.rap + + dep + dist + + + scm:git:http://git.argeo.org/gpl/argeo-suite.git + http://git.argeo.org/?p=gpl/argeo-suite.git;a=summary + scm:git:https://code.argeo.org/git/gpl/argeo-suite.git + HEAD + + 2014 + + + GPL v3 with exception + http://www.gnu.org/licenses/gpl-3.0.txt + repo + + +Additional permission under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or combining it +with software covered by the terms of the Eclipse Public License, the +licensors of this Program grant you additional permission to convey the +resulting work. Corresponding Source for a non-source form of such a +combination shall include the source code for the parts of such software +which are used as well as that of the covered work.]]> + + + + + + mbaudier + Mathieu Baudier + + Argeo + http://www.argeo.org + + architect + developer + QA + + + + + + + org.argeo.tp.extras + argeo-tp-extras + ${version.argeo-tp-extras} + pom + import + + + + + + argeo + http://repo.argeo.org/data/java/argeo-2.1 + + true + daily + warn + + + + argeo-extras + http://repo.argeo.org/data/java/argeo-extras-2.1 + + true + daily + warn + + + + + + + maven-project-info-reports-plugin + 2.9 + + + + index + summary + license + scm + + + + + + maven-javadoc-plugin + 3.0.0 + + false + -Xdoclint:none + *.internal.*,org.eclipse.* + UTF-8 + true + + http://docs.oracle.com/javase/8/docs/api + https://osgi.org/javadoc/r5/core + https://osgi.org/javadoc/r5/enterprise + https://docs.adobe.com/docs/en/spec/javax.jcr/javadocs/jcr-2.0 + http://help.eclipse.org/oxygen/topic/org.eclipse.platform.doc.isv/reference/api + http://docs.spring.io/spring/docs/3.2.x/javadoc-api + + + + + aggregate-javadoc + false + + aggregate + + + + javadoc + + + + + + maven-jxr-plugin + 2.5 + + + aggregate-jxr + false + + aggregate + + + + jxr + + + + + + + + + staging + file:///srv/docfactory/argeo-2.1/site/argeo-suite/ + + + diff --git a/sdk/.gitignore b/sdk/.gitignore new file mode 100644 index 0000000..040ee0a --- /dev/null +++ b/sdk/.gitignore @@ -0,0 +1,2 @@ +/exec +/target diff --git a/sdk/all.policy b/sdk/all.policy new file mode 100644 index 0000000..facb613 --- /dev/null +++ b/sdk/all.policy @@ -0,0 +1,3 @@ +grant { + permission java.security.AllPermission; +}; \ No newline at end of file diff --git a/sdk/argeo-office-e4-rap.properties b/sdk/argeo-office-e4-rap.properties new file mode 100644 index 0000000..97d952c --- /dev/null +++ b/sdk/argeo-office-e4-rap.properties @@ -0,0 +1,40 @@ +argeo.osgi.start.2.node=\ +org.eclipse.equinox.http.servlet,\ +org.eclipse.equinox.http.jetty,\ +org.eclipse.equinox.metatype,\ +org.eclipse.equinox.cm,\ +org.eclipse.rap.rwt.osgi,\ +org.apache.tika.parsers + +argeo.osgi.start.3.node=\ +org.argeo.cms + +argeo.osgi.start.3.suite=\ +org.argeo.suite.cms + +argeo.osgi.start.5.suite=\ +org.argeo.suite.e4.rap + +# Local +argeo.node.repo.type=h2 +org.osgi.service.http.port=7070 +#org.osgi.service.http.port.secure=7073 + +#argeo.node.useradmin.uris=ldap://cn=Directory%20Manager:argeoargeo@localhost:10389/dc=example,dc=com + +argeo.i18n.locales=en,fr,de,ar +argeo.i18n.defaultLocale=en + +#tika.config=/home/mbaudier/dev/git/gpl/argeo-suite/sdk/exec/argeo-office-e4-rap/data/indexes/node/tika-config.xml + +# Logging +log4j.configuration=file:../../log4j.properties + +# DON'T CHANGE BELOW +org.eclipse.equinox.http.jetty.autostart=false +org.osgi.framework.bootdelegation=com.sun.jndi.ldap,\ +com.sun.jndi.ldap.sasl,\ +com.sun.security.jgss,\ +com.sun.jndi.dns,\ +com.sun.nio.file,\ +com.sun.nio.sctp diff --git a/sdk/argeo-suite-desktop.properties b/sdk/argeo-suite-desktop.properties new file mode 100644 index 0000000..80d51c5 --- /dev/null +++ b/sdk/argeo-suite-desktop.properties @@ -0,0 +1,23 @@ +argeo.osgi.start.2.node=\ +org.eclipse.equinox.http.servlet,\ +org.eclipse.equinox.http.jetty,\ +org.eclipse.equinox.metatype,\ +org.eclipse.equinox.cm,\ + +argeo.osgi.start.3.node=\ +org.argeo.cms + +applicationXMI=org.argeo.suite.e4/e4xmi/argeo-office.e4xmi +#applicationXMI=org.argeo.cms.e4.rcp/argeo-companion.e4xmi + +lifeCycleURI=bundleclass://org.argeo.cms.e4.rcp/org.argeo.cms.e4.rcp.CmsRcpLifeCycle +clearPersistedState=true +#argeo.cms.desktop.inTray=true + +org.osgi.service.http.port=7070 + +log4j.configuration=file:../../log4j.properties +argeo.node.useradmin.uris=os:/// +eclipse.application=org.argeo.cms.e4.rcp.CmsE4Application +#eclipse.application=org.eclipse.e4.ui.workbench.swt.E4Application +org.eclipse.equinox.http.jetty.autostart=false diff --git a/sdk/argeo-wm.properties b/sdk/argeo-wm.properties new file mode 100644 index 0000000..ed4fc57 --- /dev/null +++ b/sdk/argeo-wm.properties @@ -0,0 +1,20 @@ +argeo.osgi.start.2.node=\ +org.eclipse.equinox.http.servlet,\ +org.eclipse.equinox.http.jetty,\ +org.eclipse.equinox.metatype,\ +org.eclipse.equinox.cm,\ + +argeo.osgi.start.3.node=\ +org.argeo.cms + +applicationXMI=org.argeo.suite.e4/e4xmi/argeo-wm.e4xmi +lifeCycleURI=bundleclass://org.argeo.cms.e4.rcp/org.argeo.cms.e4.rcp.CmsRcpLifeCycle +clearPersistedState=true +#argeo.cms.desktop.inTray=true + +org.osgi.service.http.port=7070 + +log4j.configuration=file:../../log4j.properties +argeo.node.useradmin.uris=os:/// +eclipse.application=org.argeo.cms.e4.rcp.CmsE4Application +org.eclipse.equinox.http.jetty.autostart=false diff --git a/sdk/argeo_suite_desktop.properties b/sdk/argeo_suite_desktop.properties new file mode 100644 index 0000000..2a5f231 --- /dev/null +++ b/sdk/argeo_suite_desktop.properties @@ -0,0 +1,31 @@ +argeo.osgi.start.2.http=org.eclipse.equinox.http.servlet,org.eclipse.equinox.http.jetty,\ +org.eclipse.rap.rwt.osgi,org.eclipse.equinox.cm + +argeo.osgi.start.3.node=org.argeo.cms +argeo.osgi.start.4.apps=org.eclipse.gemini.blueprint.extender +argeo.osgi.start.5.workbench=org.eclipse.equinox.http.registry + +argeo.osgi.start.5.apps=org.argeo.suite.apps + +## Rap Workbench configuration +## Open the user admin page by default when opening the workbench +org.argeo.security.ui.initialPerspective=org.argeo.suite.workbench.rap.dashboardPerspective +# Use the WorkbenchAppService to open a default home page +org.argeo.ui.openHomeCommandId=org.argeo.connect.ui.openDefaultEditor + +## JCR BACKEND +argeo.node.repo.type=h2 + +### Jetty - test URL: http://localhost:7070 +org.osgi.service.http.port=7070 + + +log4j.configuration=file:../../log4j.properties + +# SECURITY +java.security.manager= +java.security.policy=file:../../all.policy + +# DON'T CHANGE BELOW +eclipse.application=org.argeo.cms.ui.workbench.rcp.secureUi +org.eclipse.equinox.http.jetty.autostart=false diff --git a/sdk/argeo_suite_web.properties b/sdk/argeo_suite_web.properties new file mode 100644 index 0000000..565878d --- /dev/null +++ b/sdk/argeo_suite_web.properties @@ -0,0 +1,34 @@ +argeo.osgi.start.2.http=org.eclipse.equinox.http.servlet,org.eclipse.equinox.http.jetty,\ +org.eclipse.rap.rwt.osgi,org.eclipse.equinox.cm + +argeo.osgi.start.3.node=org.argeo.cms +argeo.osgi.start.4.apps=org.eclipse.gemini.blueprint.extender +argeo.osgi.start.5.workbench=org.eclipse.equinox.http.registry + +# WEB and RAP Workbench +argeo.osgi.start.5.apps=org.argeo.suite.apps + +argeo.osgi.start.6.apps=org.argeo.suite.apps.web,\ +org.argeo.suite.workbench.rap + +## Rap Workbench configuration +org.argeo.security.ui.initialPerspective=org.argeo.suite.workbench.rap.dashboardPerspective +# Use the WorkbenchAppService to open a default home page +org.argeo.ui.openHomeCommandId=org.argeo.connect.ui.openDefaultEditor + +## JCR BACKEND +argeo.node.repo.type=h2 + +### Jetty - test URL: http://localhost:7070 +org.osgi.service.http.port=7070 + + +log4j.configuration=file:../../log4j.properties + +# SECURITY +java.security.manager= +java.security.policy=file:../../all.policy + +# DON'T CHANGE BELOW +org.eclipse.rap.workbenchAutostart=false +org.eclipse.equinox.http.jetty.autostart=false \ No newline at end of file diff --git a/sdk/log4j.properties b/sdk/log4j.properties new file mode 100644 index 0000000..4556d88 --- /dev/null +++ b/sdk/log4j.properties @@ -0,0 +1,19 @@ +#log4j.rootLogger=WARN, console +log4j.rootLogger=WARN, development + +## Levels +log4j.logger.org.argeo=DEBUG +log4j.logger.org.apache.tika=DEBUG +log4j.logger.org.apache.lucene=DEBUG +#log4j.logger.org.apache.jackrabbit.core.query=TRACE + +## Appenders +# default appender +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%d{yyyyMMdd HH:mm:ss} %-5p %m [%t] %c%n + +# development appender +log4j.appender.development=org.apache.log4j.ConsoleAppender +log4j.appender.development.layout=org.apache.log4j.PatternLayout +log4j.appender.development.layout.ConversionPattern=%d{HH:mm:ss,SSS} [%16.16t] %5p %m (%F:%L) %c%n