From 67023a200eebd16ad24dfa53e37b38e22d09dbaa Mon Sep 17 00:00:00 2001 From: Sachin Verma Date: Wed, 5 May 2021 02:01:33 +0530 Subject: [PATCH 01/10] Update README.md for adding new plugin repo detail --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d3ae1f1..34db965 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,8 @@ Add dependency to your build.gradle for > Grails 3.2.x: ``` repositories { ... - maven { url "http://dl.bintray.com/sachinverma/plugins" } + // maven { url "http://dl.bintray.com/sachinverma/plugins" } remove this as Bintray repo Services down now. + maven { url "https://softclinic.jfrog.io/artifactory/grails-plugins-release" } } dependencies { From 8c663e1ceb6864f213a3ec5ac4e53ecbe362bafb Mon Sep 17 00:00:00 2001 From: Sachin Verma Date: Fri, 15 Sep 2023 19:35:57 +0530 Subject: [PATCH 02/10] Update README.md for new repo --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 34db965..a4b759f 100644 --- a/README.md +++ b/README.md @@ -15,11 +15,13 @@ Add dependency to your build.gradle for > Grails 3.2.x: repositories { ... // maven { url "http://dl.bintray.com/sachinverma/plugins" } remove this as Bintray repo Services down now. - maven { url "https://softclinic.jfrog.io/artifactory/grails-plugins-release" } +// maven { url "https://softclinic.jfrog.io/artifactory/grails-plugins-release" } + maven { url "https://jitpack.io" } } dependencies { - compile 'org.grails.plugins:grails-localizations:0.1.3' + //compile 'org.grails.plugins:grails-localizations:0.1.3' + compile 'com.github.vsachinv:grails-localizations:0.1.3' } ``` From 1b04ff7dc9245ed924b22181af9079d395df4123 Mon Sep 17 00:00:00 2001 From: Sachin Verma Date: Fri, 15 Sep 2023 20:00:05 +0530 Subject: [PATCH 03/10] Add Github package package publish code. --- .github/workflows/gradle-publish.yml | 45 ++++++++++++++++ build.gradle | 76 ++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 .github/workflows/gradle-publish.yml diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml new file mode 100644 index 0000000..f290d41 --- /dev/null +++ b/.github/workflows/gradle-publish.yml @@ -0,0 +1,45 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. +# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created +# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle + +name: Gradle Package + +on: + release: + types: [created] + +jobs: + build: + + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 8 + uses: actions/setup-java@v3 + with: + java-version: '8' + distribution: 'zulu' + server-id: github # Value of the distributionManagement/repository/id field of the pom.xml + settings-path: ${{ github.workspace }} # location for the settings.xml file + + - name: Build with Gradle + uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0 + with: + arguments: build + + # The USERNAME and TOKEN need to correspond to the credentials environment variables used in + # the publishing section of your build.gradle + - name: Publish to GitHub Packages + uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0 + with: + arguments: publish + env: + GITHUB_USERNAME: ${{ github.actor }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/build.gradle b/build.gradle index 20ae9cb..8cf8c21 100644 --- a/build.gradle +++ b/build.gradle @@ -6,6 +6,7 @@ buildscript { dependencies { classpath "org.grails:grails-gradle-plugin:$grailsVersion" classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.8.2" + classpath "com.gorylenko.gradle-git-properties:com.gorylenko.gradle-git-properties.gradle.plugin:1.5.2" } } @@ -18,6 +19,8 @@ apply plugin: "org.grails.grails-plugin" apply plugin: "org.grails.grails-plugin-publish" apply plugin: "org.grails.grails-gsp" apply plugin: "asset-pipeline" +apply plugin: "com.gorylenko.gradle-git-properties" +apply plugin: 'maven-publish' repositories { mavenLocal() @@ -39,6 +42,45 @@ dependencies { runtime "com.bertramlabs.plugins:asset-pipeline-grails:2.8.2" } +gitProperties { + keys = ['git.branch', 'git.commit.id', 'git.commit.time', 'git.commit.id.abbrev'] + failOnNoGitDirectory = true + extProperty = 'gitProps' // git properties will be put in a map at project.ext.gitProps +} + +generateGitProperties.outputs.upToDateWhen { false } // make sure the generateGitProperties task always executes (even when git.properties is not changed) + +jar { + dependsOn generateGitProperties + manifest { + attributes("Built-By": System.getProperty("user.name")) + attributes(["Plugin-Version" : version, + "Plugin-Title" : project.name, + "Plugin-Build-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"), + "Git-Commit" : "${-> project.ext.gitProps['git.commit.id.abbrev']}", + "Git-Branch" : "${-> project.ext.gitProps['git.branch']}"]) + } + from sourceSets.main.output + exclude 'git.properties' +} + + +task sourceJar(type: Jar) { + classifier = 'sources' + from sourceSets.main.allSource +} + +task packageJavadoc(type: Jar) { + from javadoc + classifier = 'javadoc' +} + +task packageGroovydoc(type: Jar) { + from groovydoc + classifier = 'groovydoc' +} + + bootRun { jvmArgs('-Dspring.output.ansi.enabled=always') addResources = true @@ -86,3 +128,37 @@ bintray { assets { packagePlugin = true } + +publishing { + publications { + gpr(MavenPublication) { + pom.withXml { + def pomNode = asNode() + pomNode.dependencyManagement.replaceNode {} + + // simply remove dependencies without a version + // version-less dependencies are handled with dependencyManagement + // see https://github.com/spring-gradle-plugins/dependency-management-plugin/issues/8 for more complete solutions + pomNode.dependencies.dependency.findAll { + it.version.text().isEmpty() + }.each { + it.replaceNode {} + } + } + from components.java + artifact sourceJar + artifact packageJavadoc + artifact packageGroovydoc + } + } + repositories { + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/vsachinv/grails-localizations") + credentials { + username = project.findProperty("gpr.user") ?: System.getenv("GITHUB_USERNAME") + password = project.findProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN") + } + } + } +} \ No newline at end of file From fc42f45c763850041733dae72d70363495fb7cd3 Mon Sep 17 00:00:00 2001 From: Sachin Verma Date: Fri, 15 Sep 2023 20:38:29 +0530 Subject: [PATCH 04/10] Remove duplicate publication of jar. --- .github/workflows/gradle-publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index f290d41..0d44c23 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -39,7 +39,7 @@ jobs: - name: Publish to GitHub Packages uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0 with: - arguments: publish + arguments: publishGprPublicationToGitHubPackagesRepository env: GITHUB_USERNAME: ${{ github.actor }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From ecd21d5112618b41b3e65853764448086e011781 Mon Sep 17 00:00:00 2001 From: Sachin Verma Date: Tue, 7 May 2024 17:05:25 +0530 Subject: [PATCH 05/10] Upgrade Localization plugin to Grails 4.1.4 and minor refactor code for def. --- .github/workflows/gradle-publish.yml | 2 +- build.gradle | 120 ++++++++---------- gradle.properties | 8 +- gradle/wrapper/gradle-wrapper.jar | Bin 52818 -> 55190 bytes gradle/wrapper/gradle-wrapper.properties | 3 +- gradlew | 72 ++++++----- gradlew.bat | 14 +- .../LocalizationController.groovy | 46 +++---- .../plugins/localization/Localization.groovy | 77 +++++------ .../grails/localizations/BootStrap.groovy | 24 +++- .../localization/LocalizationService.groovy | 6 +- grails-wrapper.jar | Bin 5463 -> 5473 bytes grailsw | 1 + grailsw.bat | 0 .../GrailsLocalizationsGrailsPlugin.groovy | 4 +- .../LocalizationsPluginUtils.groovy | 13 +- .../LocalizationMessageSource.java | 2 + 17 files changed, 205 insertions(+), 187 deletions(-) mode change 100644 => 100755 gradlew mode change 100644 => 100755 gradlew.bat mode change 100644 => 100755 grailsw mode change 100644 => 100755 grailsw.bat diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index 0d44c23..ab1d457 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -39,7 +39,7 @@ jobs: - name: Publish to GitHub Packages uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0 with: - arguments: publishGprPublicationToGitHubPackagesRepository + arguments: publishMavenJarPublicationToGitHubPackagesRepository env: GITHUB_USERNAME: ${{ github.actor }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/build.gradle b/build.gradle index 8cf8c21..4e37ee2 100644 --- a/build.gradle +++ b/build.gradle @@ -5,20 +5,19 @@ buildscript { } dependencies { classpath "org.grails:grails-gradle-plugin:$grailsVersion" - classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.8.2" - classpath "com.gorylenko.gradle-git-properties:com.gorylenko.gradle-git-properties.gradle.plugin:1.5.2" + classpath "com.bertramlabs.plugins:asset-pipeline-gradle:3.0.10" + classpath "gradle.plugin.com.gorylenko.gradle-git-properties:gradle-git-properties:2.2.3" } } -version "0.1.3" +version "4.0-M1" group "org.grails.plugins" apply plugin: "eclipse" apply plugin: "idea" apply plugin: "org.grails.grails-plugin" -apply plugin: "org.grails.grails-plugin-publish" -apply plugin: "org.grails.grails-gsp" apply plugin: "asset-pipeline" +apply plugin: "org.grails.grails-gsp" apply plugin: "com.gorylenko.gradle-git-properties" apply plugin: 'maven-publish' @@ -27,19 +26,34 @@ repositories { maven { url "https://repo.grails.org/grails/core" } } +configurations { + developmentOnly + runtimeClasspath { + extendsFrom developmentOnly + } +} + dependencies { + developmentOnly("org.springframework.boot:spring-boot-devtools") compile "org.springframework.boot:spring-boot-starter-logging" compile "org.springframework.boot:spring-boot-autoconfigure" compile "org.grails:grails-core" - compile "org.springframework.boot:spring-boot-starter-actuator" compile "org.springframework.boot:spring-boot-starter-tomcat" - compile "org.grails:grails-dependencies" compile "org.grails:grails-web-boot" - compile "org.grails.plugins:cache" + compile "org.grails:grails-logging" + compile "org.grails:grails-plugin-databinding" + compile "org.grails:grails-plugin-i18n" + compile "org.grails:grails-plugin-services" + compile "org.grails:grails-plugin-url-mappings" + compile "org.grails.plugins:gsp" + compile "org.grails.plugins:converters:4.0.1" + compileOnly "io.micronaut:micronaut-inject-groovy" profile "org.grails.profiles:web-plugin" - provided "org.grails:grails-plugin-services" - provided "org.grails:grails-plugin-domain-class" - runtime "com.bertramlabs.plugins:asset-pipeline-grails:2.8.2" + runtime "com.bertramlabs.plugins:asset-pipeline-grails:3.0.10" + testCompile "io.micronaut:micronaut-inject-groovy" + testCompile "org.grails:grails-gorm-testing-support" + testCompile "org.mockito:mockito-core" + testCompile "org.grails:grails-web-testing-support" } gitProperties { @@ -48,7 +62,9 @@ gitProperties { extProperty = 'gitProps' // git properties will be put in a map at project.ext.gitProps } -generateGitProperties.outputs.upToDateWhen { false } // make sure the generateGitProperties task always executes (even when git.properties is not changed) +generateGitProperties.outputs.upToDateWhen { + false +} // make sure the generateGitProperties task always executes (even when git.properties is not changed) jar { dependsOn generateGitProperties @@ -64,7 +80,6 @@ jar { exclude 'git.properties' } - task sourceJar(type: Jar) { classifier = 'sources' from sourceSets.main.allSource @@ -80,77 +95,41 @@ task packageGroovydoc(type: Jar) { classifier = 'groovydoc' } - bootRun { - jvmArgs('-Dspring.output.ansi.enabled=always') - addResources = true -} -// enable if you wish to package this plugin as a standalone application -bootRepackage.enabled = false -grailsPublish { - githubSlug = 'halfbaked/grails-localizations' - license { - name = 'Apache-2.0' - } - title = "Localizations (messages) plugin" - desc = '''This plugin will pull i18n definitions from the database rather than from the standard properties files in the i18n folder for Grails 3 applications. - -It will do the following: -* Create a domain class and corresponding table called Localization -* Prepopulate the table with all the message properties it finds in the i18n folder -* Ensure Grails writes i18n messages based on what it finds in the database rather than the 118n folder - -In addtion the plugin also has these added features to help you: -* A CRUD UI to add, delete, and update i18n messages -* A cache for increased speed -* A JSONP action which can be useful in client-side templating. - -Asumptions: -* Your database supports unicode -* Your application has a layout called main -''' - developers = [sachinverma: "Sachin Verma", halfbaked: "Eamonn O'Connell"] + ignoreExitValue true + jvmArgs( + '-Dspring.output.ansi.enabled=always', + '-noverify', + '-XX:TieredStopAtLevel=1', + '-Xmx1024m') + sourceResources sourceSets.main + String springProfilesActive = 'spring.profiles.active' + systemProperty springProfilesActive, System.getProperty(springProfilesActive) } -bintray { - pkg { - name = "$project.name" - issueTrackerUrl = "https://github.com/halfbaked/$project.name/issues" - vcsUrl = "https://github.com/halfbaked/$project.name" - version { - attributes = ['grails-plugin': "$project.group:$project.name"] - name = project.version - } +tasks.withType(GroovyCompile) { + configure(groovyOptions) { + forkOptions.jvmArgs = ['-Xmx1024m'] } } - +// enable if you wish to package this plugin as a standalone application +bootJar.enabled = false assets { packagePlugin = true } publishing { + publications { - gpr(MavenPublication) { - pom.withXml { - def pomNode = asNode() - pomNode.dependencyManagement.replaceNode {} - - // simply remove dependencies without a version - // version-less dependencies are handled with dependencyManagement - // see https://github.com/spring-gradle-plugins/dependency-management-plugin/issues/8 for more complete solutions - pomNode.dependencies.dependency.findAll { - it.version.text().isEmpty() - }.each { - it.replaceNode {} - } - } + mavenJar(MavenPublication) { from components.java artifact sourceJar artifact packageJavadoc artifact packageGroovydoc } } + repositories { maven { name = "GitHubPackages" @@ -160,5 +139,14 @@ publishing { password = project.findProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN") } } + maven { + name = "NexusRepo" + credentials { + username project.findProperty("nexusUsername") ?: System.getenv("NEXUS_USERNAME") + password project.findProperty("nexusPassword") ?: System.getenv("NEXUS_PASSWORD") + } + url project.findProperty("nexusUrl") ?: System.getenv("NEXUS_URL") + } + } } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 2bdd0e1..4d79d49 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,5 @@ -grailsVersion=3.2.9 -gormVersion=6.0.12.RELEASE -gradleWrapperVersion=3.4.1 \ No newline at end of file +grailsVersion=4.1.4 +gorm.version=7.0.9 +org.gradle.daemon=true +org.gradle.parallel=true +org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xmx1024M \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index deedc7fa5e6310eac3148a7dd0b1f069b07364cb..87b738cbd051603d91cc39de6cb000dd98fe6b02 100644 GIT binary patch literal 55190 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 z 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 G#s2{UCS}q9 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ddee6fd..5028f28 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Nov 27 23:09:32 CET 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-bin.zip \ No newline at end of file diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 index 9d82f78..af6708f --- a/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env sh ############################################################################## ## @@ -6,20 +6,38 @@ ## ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m"' + # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" -warn ( ) { +warn () { echo "$*" } -die ( ) { +die () { echo echo "$*" echo @@ -30,6 +48,7 @@ die ( ) { cygwin=false msys=false darwin=false +nonstop=false case "`uname`" in CYGWIN* ) cygwin=true @@ -40,26 +59,11 @@ case "`uname`" in MINGW* ) msys=true ;; + NONSTOP* ) + nonstop=true + ;; esac -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -85,7 +89,7 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then MAX_FD_LIMIT=`ulimit -H -n` if [ $? -eq 0 ] ; then if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then @@ -150,11 +154,19 @@ if $cygwin ; then esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " } -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat old mode 100644 new mode 100755 index 8a0b282..6d57edc --- a/gradlew.bat +++ b/gradlew.bat @@ -8,14 +8,14 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome @@ -46,10 +46,9 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args :win9xME_args @rem Slurp the command line arguments. @@ -60,11 +59,6 @@ set _SKIP=2 if "x%~1" == "x" goto execute set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ :execute @rem Setup the command line diff --git a/grails-app/controllers/org/grails/plugins/localization/LocalizationController.groovy b/grails-app/controllers/org/grails/plugins/localization/LocalizationController.groovy index 07716b0..20e09a9 100644 --- a/grails-app/controllers/org/grails/plugins/localization/LocalizationController.groovy +++ b/grails-app/controllers/org/grails/plugins/localization/LocalizationController.groovy @@ -1,7 +1,7 @@ package org.grails.plugins.localization import grails.converters.JSON -import grails.transaction.Transactional +import grails.gorm.transactions.Transactional import org.springframework.context.i18n.LocaleContextHolder class LocalizationController { @@ -17,8 +17,8 @@ class LocalizationController { // them in this list! message(code: "home", default: "Home") - def max = 50 - def dflt = 20 + Integer max = 50 + Integer dflt = 20 // If the settings plugin is available, try and use it for pagination if (localizationService.hasPlugin("settings")) { @@ -36,7 +36,7 @@ class LocalizationController { params.max = (params.max && params.max.toInteger() > 0) ? Math.min(params.max.toInteger(), max) : dflt params.sort = params.sort ?: "code" - def lst + List lst if (localizationService.hasPlugin("criteria") || localizationService.hasPlugin("drilldowns")) { lst = Localization.selectList(session, params) } else { @@ -54,7 +54,7 @@ class LocalizationController { params.max = (params.max && params.max.toInteger() > 0) ? Math.min(params.max.toInteger(), 50) : 20 params.order = params.order ? params.order : (params.sort ? 'desc' : 'asc') params.sort = params.sort ?: "code" - def lst = Localization.search(params) + List lst = Localization.search(params) render(view: 'index', model: [ localizationList : lst, localizationListCount: lst.size(), @@ -88,9 +88,9 @@ class LocalizationController { @Transactional def update() { - def localization = Localization.get(params.id) + Localization localization = Localization.get(params.id) if (localization) { - def oldCode = localization.code + String oldCode = localization.code localization.properties = params if (!localization.hasErrors() && localization.save()) { Localization.resetThis(oldCode) @@ -111,14 +111,14 @@ class LocalizationController { } def create() { - def localization = new Localization() + Localization localization = new Localization() localization.properties = params return ['localization': localization] } @Transactional def save() { - def localization = new Localization(params) + Localization localization = new Localization(params) if (!localization.hasErrors() && localization.save()) { Localization.resetThis(localization.code) flash.message = "localization.created" @@ -146,10 +146,10 @@ class LocalizationController { // the property files here. message(code: "home", default: "Home") - def names = [] - def path = servletContext.getRealPath("/") + List names = [] + String path = servletContext.getRealPath("/") if (path) { - def dir = new File(new File(path).getParent(), "grails-app${File.separator}i18n") + File dir = new File(new File(path).getParent(), "grails-app${File.separator}i18n") if (dir.exists() && dir.canRead()) { def name dir.listFiles().each { @@ -167,18 +167,18 @@ class LocalizationController { @Transactional def load() { - def name = params.file + String name = params.file if (name) { name += ".properties" - def path = servletContext.getRealPath("/") + String path = servletContext.getRealPath("/") if (path) { - def dir = new File(new File(path).getParent(), "grails-app${File.separator}i18n") + File dir = new File(new File(path).getParent(), "grails-app${File.separator}i18n") if (dir.exists() && dir.canRead()) { - def file = new File(dir, name) + File file = new File(dir, name) if (file.isFile() && file.canRead()) { - def locale = Localization.getLocaleForFileName(name) + Locale locale = Localization.getLocaleForFileName(name) - def counts = Localization.loadPropertyFile(new InputStreamReader(new FileInputStream(file), "UTF-8"), locale) + Map counts = Localization.loadPropertyFile(new InputStreamReader(new FileInputStream(file), "UTF-8"), locale) flash.message = "localization.imports.counts" flash.args = [counts.imported, counts.skipped] flash.defaultMessage = "Imported ${counts.imported} key(s). Skipped ${counts.skipped} key(s)." @@ -209,9 +209,9 @@ class LocalizationController { // It is possible to limit the messages returned by providing a codeBeginsWith parameter // Currently, there is no caching. Will have to add. def jsonp = { - def currentLocale = LocaleContextHolder.getLocale() //.toString.replaceAll('_','') - def padding = params.padding ?: 'messages' //JSONP - def localizations = Localization.createCriteria().list { + Locale currentLocale = LocaleContextHolder.getLocale() //.toString.replaceAll('_','') + String padding = params.padding ?: 'messages' //JSONP + List localizations = Localization.createCriteria().list { if (params.codeBeginsWith) ilike "code", "${params.codeBeginsWith}%" or { eq "locale", "*" @@ -220,7 +220,7 @@ class LocalizationController { } order("locale") } - def localizationsMap = [:] + Map localizationsMap = [:] localizations.each { // if there are duplicate codes found, as the results are ordered by locale, the more specific should overwrite the less specific localizationsMap[it.code] = it.text @@ -229,7 +229,7 @@ class LocalizationController { } private def withLocalization(id = "id", Closure c) { - def localization = Localization.get(params[id]) + Localization localization = Localization.get(params[id]) if (localization) { c.call localization } else { diff --git a/grails-app/domain/org/grails/plugins/localization/Localization.groovy b/grails-app/domain/org/grails/plugins/localization/Localization.groovy index 8bcb114..a1c3b1a 100644 --- a/grails-app/domain/org/grails/plugins/localization/Localization.groovy +++ b/grails-app/domain/org/grails/plugins/localization/Localization.groovy @@ -1,10 +1,13 @@ package org.grails.plugins.localization import grails.localizations.LocalizationsPluginUtils -import grails.util.GrailsWebUtil +import grails.util.GrailsWebMockUtil import grails.util.Holders import grails.web.context.ServletContextHolder +import groovy.transform.CompileStatic import org.springframework.core.io.Resource +import org.springframework.web.context.WebApplicationContext +import org.springframework.web.context.request.RequestAttributes import org.springframework.web.context.request.RequestContextHolder import org.springframework.web.context.support.WebApplicationContextUtils import org.springframework.web.servlet.support.RequestContextUtils @@ -12,7 +15,7 @@ import org.springframework.web.servlet.support.RequestContextUtils class Localization implements Serializable { - private static cache = new LinkedHashMap((int) 16, (float) 0.75, (boolean) true) + private static final Map cache = new LinkedHashMap((int) 16, (float) 0.75, (boolean) true) private static long maxCacheSize = 128L * 1024L // Cache size in KB (default is 128kb) private static long currentCacheSize = 0L private static final missingValue = "\b" // an impossible value signifying that no such code exists in the database @@ -44,7 +47,7 @@ class Localization implements Serializable { text(blank: true, size: 0..2000) } - def localeAsObj() { + Locale localeAsObj() { switch (locale.size()) { case 4: return new Locale(locale[0..1], locale[2..3]) @@ -57,7 +60,7 @@ class Localization implements Serializable { static String decodeMessage(String code, Locale locale) { - def key = code + keyDelimiter + locale.getLanguage() + locale.getCountry() + String key = code + keyDelimiter + locale.getLanguage() + locale.getCountry() def msg if (maxCacheSize > 0) { synchronized (cache) { @@ -72,8 +75,8 @@ class Localization implements Serializable { if (!msg) { Localization.withNewSession { - def lst = Localization.findAll( - "from org.grails.plugins.localization.Localization as x where x.code = ? and x.locale in ('*', ?, ?) order by x.relevance desc", + List lst = Localization.findAll( + "from org.grails.plugins.localization.Localization as x where x.code = ?0 and x.locale in ('*', ?1, ?2) order by x.relevance desc", [code, locale.getLanguage(), locale.getLanguage() + locale.getCountry()]) msg = lst.size() > 0 ? lst[0].text : missingValue } @@ -107,14 +110,14 @@ class Localization implements Serializable { return (msg == missingValue) ? null : msg } - static getMessage(parameters) { - def requestAttributes = RequestContextHolder.getRequestAttributes() - def applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContextHolder.getServletContext()) + static String getMessage(Map parameters) { + RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes() + WebApplicationContext applicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContextHolder.getServletContext()) boolean unbindRequest = false // Outside of an executing request, establish a mock version if (!requestAttributes) { - requestAttributes = GrailsWebUtil.bindMockWebRequest(applicationContext) + requestAttributes = GrailsWebMockUtil.bindMockWebRequest(applicationContext) unbindRequest = true } @@ -129,11 +132,11 @@ class Localization implements Serializable { if (locale.length() >= 5) { locale = new Locale(locale[0..1], locale[3..4]) } else { - locale = new Locale(locale) + locale = new Locale(locale as String) } } - def msg = messageSource.getMessage(parameters.code, parameters.args as Object[], parameters.default, locale) + String msg = messageSource.getMessage(parameters.code as String, parameters.args as Object[], parameters.default as String, locale) if (unbindRequest) RequestContextHolder.setRequestAttributes(null) if (parameters.encodeAs) { @@ -175,6 +178,7 @@ class Localization implements Serializable { } // Repopulates the org.grails.plugins.localization table from the i18n property files + @CompileStatic static reload() { Localization.executeUpdate("delete Localization") load() @@ -187,6 +191,7 @@ class Localization implements Serializable { resetAll() } + @CompileStatic static load() { List propertiesResources = [] LocalizationsPluginUtils.i18nResources?.each { @@ -203,28 +208,29 @@ class Localization implements Serializable { def locale = getLocaleForFileName(it.filename) Localization.loadPropertyFile(new InputStreamReader(it.inputStream, "UTF-8"), locale) } - def size = Holders.config.localizations.cache.size.kb - if (size != null && size instanceof Integer && size >= 0 && size <= 1024 * 1024) { + Integer size = Holders.config.getProperty('localizations.cache.size.kb', Integer) + if (size != null && size >= 0 && size <= 1024 * 1024) { maxCacheSize = size * 1024L } } - static loadPropertyFile(InputStreamReader inputStreamReader, locale) { - def loc = locale ? locale.getLanguage() + locale.getCountry() : "*" - def props = new Properties() - def reader = new BufferedReader(inputStreamReader) + static Map loadPropertyFile(InputStreamReader inputStreamReader, locale) { + String loc = locale ? locale.getLanguage() + locale.getCountry() : "*" + Properties props = new Properties() + Reader reader = new BufferedReader(inputStreamReader) try { props.load(reader) } finally { if (reader) reader.close() } - def rec, txt - def counts = [imported: 0, skipped: 0] + Localization rec = null + String txt = null + Map counts = [imported: 0, skipped: 0] Localization.withSession { session -> props.stringPropertyNames().each { key -> - rec = Localization.findByCodeAndLocale(key, loc) - if (!rec) { + Boolean exist = !!Localization.countByCodeAndLocale(key, loc) + if (!exist) { txt = props.getProperty(key) rec = new Localization([code: key, locale: loc, text: txt]) if (rec.validate()) { @@ -238,7 +244,7 @@ class Localization implements Serializable { } } // Clear the whole cache if we actually imported any new keys - if (counts.imported > 0){ + if (counts.imported > 0) { Localization.resetAll() session.flush() } @@ -246,19 +252,19 @@ class Localization implements Serializable { return counts } - static getLocaleForFileName(String fileName) { - def locale = null - + @CompileStatic + static Locale getLocaleForFileName(String fileName) { + Locale locale = null if (fileName ==~ /.+_[a-z][a-z]_[A-Z][A-Z]\.properties$/) { locale = new Locale(fileName.substring(fileName.length() - 16, fileName.length() - 14), fileName.substring(fileName.length() - 13, fileName.length() - 11)) } else if (fileName ==~ /.+_[a-z][a-z]\.properties$/) { locale = new Locale(fileName.substring(fileName.length() - 13, fileName.length() - 11)) } - - locale + return locale } - static resetAll() { + @CompileStatic + static void resetAll() { synchronized (cache) { cache.clear() currentCacheSize = 0L @@ -267,7 +273,7 @@ class Localization implements Serializable { } } - static resetThis(String key) { + static void resetThis(String key) { key += keyDelimiter synchronized (cache) { def entries = cache.entrySet().iterator() @@ -282,8 +288,8 @@ class Localization implements Serializable { } } - static statistics() { - def stats = [:] + static Map statistics() { + Map stats = [:] synchronized (cache) { stats.max = maxCacheSize stats.size = currentCacheSize @@ -291,13 +297,12 @@ class Localization implements Serializable { stats.hits = cacheHits stats.misses = cacheMisses } - return stats } - static Object search(params) { - def expr = "%${params.q}%".toString().toLowerCase() - Localization.createCriteria().list(limit: params.max, order: params.order, sort: params.sort) { + static List search(Map params) { + String expr = "%${params.q}%".toString().toLowerCase() + return Localization.createCriteria().list(limit: params.max, order: params.order, sort: params.sort) { if (params.locale) { eq 'locale', params.locale } diff --git a/grails-app/init/grails/localizations/BootStrap.groovy b/grails-app/init/grails/localizations/BootStrap.groovy index f2d07e5..eaeb574 100644 --- a/grails-app/init/grails/localizations/BootStrap.groovy +++ b/grails-app/init/grails/localizations/BootStrap.groovy @@ -1,19 +1,31 @@ package grails.localizations +import grails.gorm.transactions.Transactional import grails.util.Holders +import groovy.util.logging.Slf4j import org.grails.plugins.localization.Localization +@Slf4j class BootStrap { def init = { servletContext -> - if (Holders.config?.grails?.plugin?.localizations?.enabled) { - if (Holders.config?.grails?.plugin?.localizations?.reloadAll) { - Localization.reload() - } else { - Localization.load() - } + if (Holders.config.getProperty('grails.plugin.localizations.enabled', Boolean, false)) { + log.info("Localization Plugin: Loading localization files to DB") + loadLocalizeDataToDB() } } + def destroy = { } + + @Transactional + void loadLocalizeDataToDB() { + if (Holders.config.getProperty('grails.plugin.localizations.reloadAll', Boolean, false)) { + log.warn("Re-Loading all localization data to db by refreshing localization table") + Localization.reload() + } else { + Localization.load() + } + } + } diff --git a/grails-app/services/org/grails/plugins/localization/LocalizationService.groovy b/grails-app/services/org/grails/plugins/localization/LocalizationService.groovy index cbb7d0c..b2a01ea 100644 --- a/grails-app/services/org/grails/plugins/localization/LocalizationService.groovy +++ b/grails-app/services/org/grails/plugins/localization/LocalizationService.groovy @@ -1,12 +1,12 @@ package org.grails.plugins.localization import grails.util.Holders +import groovy.transform.CompileStatic +@CompileStatic class LocalizationService { - boolean transactional = true - - def hasPlugin(name) { + Boolean hasPlugin(String name) { return Holders.getPluginManager()?.hasGrailsPlugin(name) } } diff --git a/grails-wrapper.jar b/grails-wrapper.jar index bc85146c130e69264ce20e079987784615201b35..6b6da64fe2dbac9d01e295cd9bdaa523cb70766c 100644 GIT binary patch delta 3452 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/dev/null` diff --git a/grailsw.bat b/grailsw.bat old mode 100644 new mode 100755 diff --git a/src/main/groovy/grails/localizations/GrailsLocalizationsGrailsPlugin.groovy b/src/main/groovy/grails/localizations/GrailsLocalizationsGrailsPlugin.groovy index 5abd5bb..b4f18b6 100644 --- a/src/main/groovy/grails/localizations/GrailsLocalizationsGrailsPlugin.groovy +++ b/src/main/groovy/grails/localizations/GrailsLocalizationsGrailsPlugin.groovy @@ -8,7 +8,7 @@ import org.grails.plugins.localization.LocalizationMessageSource class GrailsLocalizationsGrailsPlugin extends Plugin { // the version or versions of Grails the plugin is designed for - def grailsVersion = "3.2.9 > *" + def grailsVersion = "4.1.4 > *" // resources that are excluded from plugin packaging def pluginExcludes = [ "grails-app/views/error.gsp" @@ -66,7 +66,7 @@ Asumptions: Closure doWithSpring() { { -> - if(Holders.config?.grails?.plugin?.localizations?.enabled){ + if(Holders.config.getProperty('grails.plugin.localizations.enabled', Boolean, false)){ messageSource(LocalizationMessageSource) } } diff --git a/src/main/groovy/grails/localizations/LocalizationsPluginUtils.groovy b/src/main/groovy/grails/localizations/LocalizationsPluginUtils.groovy index c4e30c7..2527330 100644 --- a/src/main/groovy/grails/localizations/LocalizationsPluginUtils.groovy +++ b/src/main/groovy/grails/localizations/LocalizationsPluginUtils.groovy @@ -5,6 +5,7 @@ import grails.core.GrailsApplicationClass import grails.util.BuildSettings import grails.util.Environment import grails.util.Holders +import groovy.transform.CompileStatic import groovy.util.logging.Slf4j import org.grails.core.io.StaticResourceLoader import org.grails.core.support.internal.tools.ClassRelativeResourcePatternResolver @@ -20,7 +21,8 @@ class LocalizationsPluginUtils { static final String GRAILS_APP_I18N_PATH_COMPONENT = "/grails-app/i18n/"; static String messageBundleLocationPattern = "classpath*:*.properties"; - static List getI18nResources() { + @CompileStatic + static Resource[] getI18nResources() { Resource[] resources = [] if (Environment.isDevelopmentEnvironmentAvailable()) { File[] propertiesFiles = new File(BuildSettings.BASE_DIR, GRAILS_APP_I18N_PATH_COMPONENT).listFiles(new FilenameFilter() { @@ -32,7 +34,7 @@ class LocalizationsPluginUtils { if (propertiesFiles != null && propertiesFiles.length > 0) { List resourceList = new ArrayList(propertiesFiles.length); for (File propertiesFile : propertiesFiles) { - log.debug "Project - "+ propertiesFile.name + log.debug "Project - " + propertiesFile.name resourceList.add(new FileSystemResource(propertiesFile)); } resources = resourceList.toArray(new Resource[resourceList.size()]); @@ -54,13 +56,14 @@ class LocalizationsPluginUtils { }.reverse() } + @CompileStatic static List getAllPluginI18nResources() { List resources = [] Holders.pluginManager.allPlugins.each { if (it instanceof BinaryGrailsPlugin) { - List pluginResources = getPluginI18nResources(it) + Resource[] pluginResources = getPluginI18nResources(it) if (pluginResources) { - log.debug "Plugin - "+ it.name + log.debug "Plugin - " + it.name resources.addAll(pluginResources) } } @@ -72,7 +75,7 @@ class LocalizationsPluginUtils { } - static List getPluginI18nResources(BinaryGrailsPlugin plugin) { + static Resource[] getPluginI18nResources(BinaryGrailsPlugin plugin) { Resource url = plugin.baseResourcesResource; if (url != null) { StaticResourceLoader resourceLoader = new StaticResourceLoader(); diff --git a/src/main/groovy/org/grails/plugins/localization/LocalizationMessageSource.java b/src/main/groovy/org/grails/plugins/localization/LocalizationMessageSource.java index 69d059f..02c5551 100644 --- a/src/main/groovy/org/grails/plugins/localization/LocalizationMessageSource.java +++ b/src/main/groovy/org/grails/plugins/localization/LocalizationMessageSource.java @@ -1,5 +1,6 @@ package org.grails.plugins.localization; +import groovy.transform.CompileStatic; import org.springframework.context.ResourceLoaderAware; import org.springframework.context.support.AbstractMessageSource; import org.springframework.core.io.ResourceLoader; @@ -7,6 +8,7 @@ import java.text.MessageFormat; import java.util.Locale; +@CompileStatic public class LocalizationMessageSource extends AbstractMessageSource implements ResourceLoaderAware { private ResourceLoader resourceLoader = null; From 61561119454e62ed2cb24eace9ecc5f90c0aefd5 Mon Sep 17 00:00:00 2001 From: Sachin Verma Date: Tue, 7 May 2024 17:09:22 +0530 Subject: [PATCH 06/10] Update README.md for grails 4.x dependency support --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index a4b759f..1633524 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,19 @@ database the first time a message is requested after the plugin is installed. ##Installation +Add dependency to your build.gradle for > Grails 4.x: + +``` +repositories { + ... + maven { url "https://jitpack.io" } +} + +dependencies { + compile 'com.github.vsachinv:grails-localizations:4.0-M1' +} +``` + Add dependency to your build.gradle for > Grails 3.2.x: ``` @@ -24,6 +37,7 @@ dependencies { compile 'com.github.vsachinv:grails-localizations:0.1.3' } ``` +Source Code for Grails 3.x: https://github.com/vsachinv/grails-localizations/tree/grails3-upgrade Add dependency to your BuildConfig.groovy for Grails 2.x: From 0c007a31503e4bc19f4945f15b7ed371d598a391 Mon Sep 17 00:00:00 2001 From: Sachin Verma Date: Mon, 13 May 2024 13:50:57 +0530 Subject: [PATCH 07/10] Upgrade plugin to Grails 5.3.6 and update README.md file. --- README.md | 29 ++++++++ build.gradle | 62 ++++++++++-------- gradle.properties | 6 +- gradle/wrapper/gradle-wrapper.jar | Bin 55190 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 53 +++++++++------ gradlew.bat | 43 ++++++------ .../LocalizationController.groovy | 4 ++ .../plugins/localization/Localization.groovy | 5 +- grails-wrapper.jar | Bin 5473 -> 5507 bytes 10 files changed, 134 insertions(+), 70 deletions(-) diff --git a/README.md b/README.md index 1633524..f601f75 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,35 @@ database the first time a message is requested after the plugin is installed. ##Installation +Add dependency to your build.gradle for > Grails 5.x: + +``` +repositories { + ... + maven { url "https://jitpack.io" } +} + +dependencies { + compile 'com.github.vsachinv:grails-localizations:5.0-M1' +} +``` + +In addition if you don't want to use jitpack.io then use following github package registry: + +```groovy +repositories { + maven { + name = "GitHubPackages" + url = uri("https://maven.pkg.github.com/vsachinv/grails-localizations") + credentials { + username = project.findProperty("gpr.user") ?: System.getenv("GITHUB_USERNAME") + password = project.findProperty("gpr.key") ?: System.getenv("GITHUB_TOKEN") + } + } + } + +``` + Add dependency to your build.gradle for > Grails 4.x: ``` diff --git a/build.gradle b/build.gradle index 4e37ee2..5af6905 100644 --- a/build.gradle +++ b/build.gradle @@ -1,28 +1,30 @@ buildscript { repositories { mavenLocal() + maven { url "https://plugins.gradle.org/m2/" } maven { url "https://repo.grails.org/grails/core" } } dependencies { - classpath "org.grails:grails-gradle-plugin:$grailsVersion" - classpath "com.bertramlabs.plugins:asset-pipeline-gradle:3.0.10" - classpath "gradle.plugin.com.gorylenko.gradle-git-properties:gradle-git-properties:2.2.3" + classpath "org.grails:grails-gradle-plugin:$grailsGradlePluginVersion" + classpath "com.bertramlabs.plugins:asset-pipeline-gradle:3.3.4" + classpath "com.gorylenko.gradle-git-properties:gradle-git-properties:2.3.2" } } -version "4.0-M1" +version "5.0-M1" group "org.grails.plugins" -apply plugin: "eclipse" -apply plugin: "idea" -apply plugin: "org.grails.grails-plugin" -apply plugin: "asset-pipeline" -apply plugin: "org.grails.grails-gsp" +apply plugin:"eclipse" +apply plugin:"idea" +apply plugin:"org.grails.grails-plugin" +apply plugin:"asset-pipeline" +apply plugin:"org.grails.grails-gsp" apply plugin: "com.gorylenko.gradle-git-properties" apply plugin: 'maven-publish' repositories { mavenLocal() + mavenCentral() maven { url "https://repo.grails.org/grails/core" } } @@ -35,25 +37,29 @@ configurations { dependencies { developmentOnly("org.springframework.boot:spring-boot-devtools") - compile "org.springframework.boot:spring-boot-starter-logging" - compile "org.springframework.boot:spring-boot-autoconfigure" - compile "org.grails:grails-core" - compile "org.springframework.boot:spring-boot-starter-tomcat" - compile "org.grails:grails-web-boot" - compile "org.grails:grails-logging" - compile "org.grails:grails-plugin-databinding" - compile "org.grails:grails-plugin-i18n" - compile "org.grails:grails-plugin-services" - compile "org.grails:grails-plugin-url-mappings" - compile "org.grails.plugins:gsp" - compile "org.grails.plugins:converters:4.0.1" compileOnly "io.micronaut:micronaut-inject-groovy" + console "org.grails:grails-console" + implementation "org.springframework.boot:spring-boot-starter-logging" + implementation "org.springframework.boot:spring-boot-starter-validation" + implementation "org.springframework.boot:spring-boot-autoconfigure" + implementation "org.grails:grails-core" + implementation "org.springframework.boot:spring-boot-starter-tomcat" + implementation "org.grails:grails-web-boot" + implementation "org.grails:grails-logging" + implementation "org.grails:grails-plugin-databinding" + implementation "org.grails:grails-plugin-i18n" + implementation "org.grails:grails-plugin-services" + implementation "org.grails:grails-plugin-url-mappings" + implementation "org.grails.plugins:gsp" profile "org.grails.profiles:web-plugin" - runtime "com.bertramlabs.plugins:asset-pipeline-grails:3.0.10" - testCompile "io.micronaut:micronaut-inject-groovy" - testCompile "org.grails:grails-gorm-testing-support" - testCompile "org.mockito:mockito-core" - testCompile "org.grails:grails-web-testing-support" + runtimeOnly "com.bertramlabs.plugins:asset-pipeline-grails:3.3.4" + testImplementation "io.micronaut:micronaut-inject-groovy" + testImplementation "org.grails:grails-gorm-testing-support" + testImplementation "org.mockito:mockito-core" + testImplementation "org.grails:grails-web-testing-support" + + implementation "org.grails.plugins:converters:4.0.1" + } gitProperties { @@ -112,6 +118,10 @@ tasks.withType(GroovyCompile) { forkOptions.jvmArgs = ['-Xmx1024m'] } } + +tasks.withType(Test) { + useJUnitPlatform() +} // enable if you wish to package this plugin as a standalone application bootJar.enabled = false diff --git a/gradle.properties b/gradle.properties index 4d79d49..173fd26 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,7 @@ -grailsVersion=4.1.4 -gorm.version=7.0.9 +grailsVersion=5.3.6 +grailsGradlePluginVersion=5.3.1 +groovyVersion=3.0.11 +gorm.version=7.3.4 org.gradle.daemon=true org.gradle.parallel=true org.gradle.jvmargs=-Dfile.encoding=UTF-8 -Xmx1024M \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 87b738cbd051603d91cc39de6cb000dd98fe6b02..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f 100644 GIT binary patch delta 26193 zcmZ6yQ+S|Vu&o>0wrv|7+qP{xU&pp>+fK)}ZKK1EI!T}Z?6uCtKF>3+>b7Q$8a3;k z=?&n+bKs5iponRd%jI35ARxHlARx>siR4%*il7((1uK)8y@{J!oa(gW@(&EbVLvhOxk#E0z~5*_n$Tfk4BT1W zh~4H^yI$w!jrIW$@8~{|r_Pqh9?;*1{Rs-h$o?FVSot<3yKX_cH33Wqgy&Ugow#-- zd$AFKpvAm7vspRndDP5Y*{X$rg0EvCe9(Ow>lBeyGY!V@xQpXomHjCWwMA-rDRPSv zY@gq7;|J=t%N|R7799odG(V`K@OXpjH2q11r=-spt+w zmng+yzxXW&2lk&G)N z-h)16N@V9eFCNeZrbSiuE44@1#kS@h5wqX)wgpxfDiThLBx=5wyP_q&uT8OO)g!i} z`ony65!)LBh`yjIhNFW{%5vZka3CNsFd!fxA|N)P3^l}%ARrX~g&6-g&ji4>8oCzF zKSH<7MutdMx~SkLQ5g_)<~Gen%{ZC`NJdbH)-9$<(ppE)OUsf4+q=3xf!CmpZ`c>g z4Ys!B49{{P<@lMuM@Gi9cVK3-W&h8s0rx+luP@f0C2um4An0s{!;rApVwtHdlxBE$ zQ}-fiEaWDdk_Z{*`eS})9~03LOH#dsT^&c)G^Img%Th&3)4?O4Wq0Y&WfVC|VC zaAQwCL*mCoU593J>8NRWao@R|t#I*_etEAkj;Pnx3Px?Zvdq$zVwkChuPxdoUTJ_f z91pe6B-4rYiTj&D4-yF14*5BofspUDM3g|`#ZB$#P?p~-U9+h+Tp`mRxh*=&=&T*z2q>oXsGC%dWpshF`TNHT@_F>BTVa9G zFHYaGE;{c#SSHF=YdV#s&=@2HPVty?i1KRKnHMZOfiniPe%}^B8HFW z*bJMvi!j9I(^KSPI$-KTx8V>{A^SDH?XXHk2r zl3KMvKg}3t6q5GEn_a9c#&WLtG*Z+HlGMW<(x+DV$pO_9MbEmMd(|gjX$n1RcRRtv zDT~=Ns?nTUr{?a8bL%J`yhpBI_HJ=#J82CYL&{%*ODAh3aQ7C!&9@kuw2vTv^C5Jv zw{IBtth8_1lePLj%=eb2<|{r*Tr*eZc-3zAmND82-Y2(LCRJAYureb+>#gbkwS;}t z*dnlaO#wXPiqx378QPITyhU~VJF;i9bY&O>9`a<{Z=?tck-b5V=Ao(5iSinj^|JG0 z^Mei%8;vfT5yjl03`{X#`7o70WDu59Odv`qB&Kd4C_bQnCkPF-Z;JgZ^g{2~-?;k+ z9+d0E@fT(gQ5tY0OC?v8n)9lJ>xx!1rO|MACzpKq&HkF1K{ zFMRybn|7SN@1S0)$Tgnp%zhGmU0>jDj(qPx9cd6`;(p;9lq7up`hoX{FkphHyA0DN z5*0_8Cr`bKX4N+FM+NK)D;S+PQe|0pN`4GS%9VQJ!F@1AmvLj;s* z?5g2wVEo&)=YpSxQkAAjZU5QM2_ajp*;-oX5M*sllctPP$Cq)!W#4miWC{L-|8byZ z^iiy&Xyktx3$vQ_qG0ub{r0Drov-9Lg!p(omOcL5a7e1+=Q3+nuHS2}-`t&-(97AN zF!4V4J;ELv>Nxx#>p@srsIrMn3PoV;Fg0q~y9pFFHz~V?YR;q*bQp&>(1D%FPs zC*IM^c|*^YFd>8K!*CNjO?IyyVo0Oj58J=V+HZAg4EGQ_44PdzlAt7maXilOhlg5a01 zY;8K$cR z`?@05v}ykdXcpLFzwCu_^1Ix5oA^_#4P!q~iRGZaX}VfO>ocM-TIR_OVK|WIk=>*a zeNESLpfO2pCzrnXhvy4zVJJ|)bs@SBYiq&LgqV+kKtj0biu*n~3>Ls(AQ(f9*~_s) zl-KPHr3GJJdZbJ9z~4gno4QuCR6$+sXgnW-SR$UwdY>J(?y@VzOw-!z29BZMAa@*>cOMvu0j;NRm&a zA?dwChkQuKL|!${FHs;*>8zcvo{*&C&2uo)%+*>dx4mwK>fGN+2G`s+E+?FoDMB>o zeEk&R)YUb-)hB0btx0ZnL88NiU<4a4`*dXC&pJay_*!BvzV5L3egZfJ^3pQHC8zFj z6=tLQ9h+!XzlAle1MVUJR85LGy?b&&${lv)c!u?eR_HV5VGs~FMZC*XTEE>nWMNC4 zB-UE7S$o)*022^2SpSi8XR351W?e8S@6i^nRhZK21FxbQo=r|Xn3;a2gqkA9jC)ti z1U4zFR*N)5@{VZmvX8drmAd;H`V9VYPp)`CJ<24J3+oWFOOh|D+JrBTtRrT-UNiS+ z(J%rlp)E0cuK~b2h31^v%*?vFF%$`yaX*844h@8tiqzpL`V|45>?UdyCevybaaT+l zdZ{j2LANKlT=)%J%zpa;hj+KHasV#AP+j%_aV7mNFYy(I_e39m$ld%;hB{CR3NVHM zs?_7ryClg9%EdjJGu)cCVf%af}^xD1`=ey;xTSwvKswhL}f-h0rN zx$a-|8ICEr+~Tj|Q4jJ&D%Al!W{4)^8UYCecR(m4n1Xox7yTqZ!IweY}ynJI3 zMz}L%pqst|R9anw=H*@%l{5QYAlsH-?qK4IOT|U_%?X}+&3)yyoEsv22Yx~r!!S#D zFHjffGZQ^)k^dxFhZ09Hl^#$)1$%|>4LpawxEh+VJLRz_6n%#;LPdOiZ?-?QopPOR@$pf0U=M zotnQ+LX;pV(2mBcz5(Tq6mtI6^{nnb0ZCeqdc2jimiO)`7S5L5d*s~AL(wwRx^y_) zh#GRJ6CxyPN*6Zaw(!3)H6nkpJ5EKdx44c~YYcFRRlLrSK}q>QJLrKU+@6Erj&$a; zqseNY2DlS-f#nv2LUG7?M@oSa$z=|r!z!Vove26#Jt4%MY5?-5EAFbS6yguDs?gCE z(vc>HKlF#duyAd`Ef7JyP%dBGd}$B5LM>{YZJ8-rOT-4~#18)T(~5~bG7eBFL@D*sXp~E2b)#Kj-6#_;rKFTcZ5;~q>XBa%9qtn zh|*NK&npj)_X0e@`Q)Duq;*G(ix)9}{FJ(tBr%|Zl{%`3vm<3;ZTao!@JCy!w$Hd$ zeTsHc-QO?{AjJ$$xyVeeiaa(mIS{g>H~RWDd^7NrcuhG+n6;;IOM;Pnv9AXK%*F>l zh;aH=_~cR-sWJe&{k3#sLEJ9Q;xpFrzQ!1IA($)K6A(HHJ78{YNzs2fS9t(^@rq2; z%#zYDCmxz&BIxr`?~%}btlSLY*nUOqSIu}@IIZ6m+uae;rw{n@(ccR5i+I!DYr1e1 za(MOzHzGaa-+2Qi4lE{yhB?MQdUJSqM$cf$?F?6pb~QsYC}kb`SX9W4V`o%%*{zQJ z64`;gk{^o`6(Of^2y<*)?pbt(p*cCs&QLrs354H|(M+Bl84yFLM>{4$a^t<&uOd2( zDhK}WqM`tq3_L~#0nsJ_0U`b0qJjbbXWp&Th4scC_XtdYXp(dG5kaH82(=)@Kwe1p zNKUs;DyER`6;Dj1)k)SGNDhTGJscIq$m5B>ort=n@wBIQ$t`!x`S0)~<-(*&Y|AE0 z)a`OzqP|LRKT9XHDk!b@B{%*6j6c1Qx`5psOT1Mo>jGwg; zn#*@S7dQbm1brRiPk)Qw!Na~6#2i1!S>M_ZKFrd-N5lZxeU;03j1M7M?Pf4N8dDV?~ChR zl~dm^ZdlcjsW>`r+GpIb96^EutTZQ7HZJ;Ji9;!9fm+SDzseGRa8}V!>`vLfEA5< z^)ZQgMs(z0cl=&{{#-n$H4i7s&F>pR0-jaEn=80*K7h4_Idl}?F4O-j&+iq}!q|0u zW>KXn0n?zIbBoRPGAVPB&EzsF)TGUQQbxPlc&8)*U!LeW9DyE}^H`oU%IDjfiRxVP zcZm6`!=m@f-tdayub+@lecT1jHj$I7CX&YH9$FlZ&!uBZ_-j7{`7B}n<(LR^mFlUm zdPXw&F#ypd4Z0KNnbu6!n+YwuuibHJChS6JgbF%iJ2%OW%yroEX{36{1($2+bB-&K zC0J1^1xfhaH|c}lg(Z}>?KcTy2vs7B`wT%jT2_Co)Dt-(~ z$*7abZzyD0vyDjXlMsm7MuDfEld>A6c;^VEn_#?$SSettv}`*0^ICen24YL)KM7sp>Adr36Z)i zLZ)C~O4l-Gf7j-`wbz!yKgf7>5oT>A5&2stuDEVk(Mb*S$E|S5S*`6RXM&8_DcsVv zCK2jHYi|StkgaGR5AN&9NqFZaeIZ_hgv4iEeNG!)WAE2;tZty`kUh#rx0T{i<$L(pl}iOmk&Jn&`s#jtF66@s#y-I zrs`Ym7<%r)TW;h`wil?x%EZp6y^@4kv#)JSw#ajW_F1RVu}r@b$DP>2UqH&8hkfa) zgPn~tP`HoQzMD8L-$()v073u!X)Q$4`&f7(NRb`EPA>$p&-63+XPOTAUl+O`CVMBv zUrQ*z96r#y(>OjwsSPUDv!=|yZT$0zP51zJCqSw3{3pOd>*?-nTsY6nx@rVd9r#ph z^8SY>H;-e8C;6+TlQz|S9$*y4dPkmczn4KLYdPZkMB5YQKCyx1k zJU4XSsE4Vem=3%L+>&Z1KHvXd;|(^h;3Q!f2m$|_<7NAaA#5;^0T^^w!jQ4QL;le} z*zsm?=EF;Xc)4tMRH8y4kh-rGShhn)F}9Mo8($sHHs?z!aFY1UepV8{ZGt?)QusJ7 zzf~$ngGIL`3tXTAjsF%C+r97MR_g|>aA)^c*OI<*yVs|9XU79XL4qJI26Uk7Ijv3x zoINaggyd9a%t_q%0Ph8Ql54a^ty-n_TBVQcb?WVteFYzbIN`|xuv|=$?1TOt2d7n0 zl5X7BBE4qHiyuUa#im|F_P^ddNQq;Qd~V)7b~RAGgIK3?C-mhqFa+JRkpBJJtsb?Y z62_+%!ETHm0%1mb%*fmFd z-(YSD22!E5B|nk@2o@GOO91cOjR9JiitxXy-!;sEW|(do8;%0P&eP`;44pK7O*MhX zdlfBHfc!vIi~q{+{~Yhf~URiRcY@Pkc?o3SCkQQg}E+y{>J{{cN^5EY^KdbZj0eL(u#c~39>G3r3`=a|y(g9VG ze}!4C?0rHYoy*G-LX{VUGPp;XC>s6yOH$*fi2M)v$zDQ~Z-5?Et!K&4XKhzSA@f~# z2D4gmA=DNBUoxh8%ui`)gXJ{mzO;`Ka7Yro`3THr#>S{ih`Fm&Af_p<$IpA2`> zcde1;fXK1=Y%7#s1`@e0{)Ze>eOIs%ZAx25fAtKS2&3m==&$*)WJQuNTkc$bqb}pE z-|}i=Zhj)B^u#$9ue!%(%F|I3Z>Ea=V?a$?fMBd} ze1q9wcHuXQpXD!fBk-UaRsr3cun@5r2vH(J2asdupCZQXtO!W>%S8LAv!xe0kfu2n zjW5_uuq+)vtGwrR=+l{QqF2kBE78!W(J}GR<%hyOSa^#KW2A9#7?v-EpG}|G-ghyn z=?rspMd0U@OLxiB;Y?ZmX`qtu$BtOjBlV)!Sme@`-#+XmY|ZzS&1tu!IJe(QY_SR1 z0UV=l1SuTQ1Woeb)q8dM)^=&@D0MIY=odw=R}Ix1`s7uYSGi_ZR9?Ypz~{)8DQKuF z;;$|^>WXy8;kVBCj)zk}goNWAo+T`+Eu^`)Rq5;Orj}=OtP(k(_`S?Ia*=lu&i(!Y z6ky!UGfXJmharkF3Z=N zw|spi95hC)Z#|XXFr~?^gLGr^%K#mG*CRRdI!@8olzM+?;<` zmMBkcY<*15Y~<5?on)3RjW#`011xN|mi+U4bC%t&;oTcGP~j?Uw(l_ls= z>}ftPt(>WqU$ooRt&WD#h(kUpTahm$0)a5J z-Z=WZ(i=h)mcpDWFgE-@IdH`}B3S$|R`_jjI00_L3YJ|7a(6Hf0Ikg*&c>H}i8a<* z^1^4vKTOgld+Y*{4;&xunXo&fUk)n(nZ7>(A~0v{k}!HW8=|4a&j(!xARx)

$|c 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∨fd|u2@Kuk2 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 F_djzcFxCJ7 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5028f28..ffed3a2 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index af6708f..4f906e0 100755 --- a/gradlew +++ b/gradlew @@ -1,5 +1,21 @@ #!/usr/bin/env sh +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + ############################################################################## ## ## Gradle start up script for UN*X @@ -28,7 +44,7 @@ APP_NAME="Gradle" APP_BASE_NAME=`basename "$0"` # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m"' +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD="maximum" @@ -66,6 +82,7 @@ esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then @@ -109,10 +126,11 @@ if $darwin; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then APP_HOME=`cygpath --path --mixed "$APP_HOME"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` # We build the pattern for arguments to be converted via cygpath @@ -138,19 +156,19 @@ if $cygwin ; then else eval `echo args$i`="\"$arg\"" fi - i=$((i+1)) + i=`expr $i + 1` done case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; esac fi @@ -159,14 +177,9 @@ save () { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } -APP_ARGS=$(save "$@") +APP_ARGS=`save "$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" -fi - exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 6d57edc..107acd3 100755 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,19 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + @if "%DEBUG%" == "" @echo off @rem ########################################################################## @rem @@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if "%ERRORLEVEL%" == "0" goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,28 +64,14 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/grails-app/controllers/org/grails/plugins/localization/LocalizationController.groovy b/grails-app/controllers/org/grails/plugins/localization/LocalizationController.groovy index 20e09a9..6f7a01d 100644 --- a/grails-app/controllers/org/grails/plugins/localization/LocalizationController.groovy +++ b/grails-app/controllers/org/grails/plugins/localization/LocalizationController.groovy @@ -62,6 +62,10 @@ class LocalizationController { ]) } + def list() { + redirect(action: 'index') + } + def show() { withLocalization { localization -> return [localization: localization] diff --git a/grails-app/domain/org/grails/plugins/localization/Localization.groovy b/grails-app/domain/org/grails/plugins/localization/Localization.groovy index a1c3b1a..96eb1df 100644 --- a/grails-app/domain/org/grails/plugins/localization/Localization.groovy +++ b/grails-app/domain/org/grails/plugins/localization/Localization.groovy @@ -5,6 +5,7 @@ import grails.util.GrailsWebMockUtil import grails.util.Holders import grails.web.context.ServletContextHolder import groovy.transform.CompileStatic +import groovy.util.logging.Slf4j import org.springframework.core.io.Resource import org.springframework.web.context.WebApplicationContext import org.springframework.web.context.request.RequestAttributes @@ -12,7 +13,7 @@ import org.springframework.web.context.request.RequestContextHolder import org.springframework.web.context.support.WebApplicationContextUtils import org.springframework.web.servlet.support.RequestContextUtils - +@Slf4j class Localization implements Serializable { private static final Map cache = new LinkedHashMap((int) 16, (float) 0.75, (boolean) true) @@ -30,7 +31,7 @@ class Localization implements Serializable { Date dateCreated Date lastUpdated - static mapping = Holders.config.grails.plugin.localizations.mapping ?: { + static mapping = Holders.config.getProperty('grails.plugin.localizations.mapping',Closure) ?: { columns { code index: "localizations_idx" locale column: "loc" diff --git a/grails-wrapper.jar b/grails-wrapper.jar index 6b6da64fe2dbac9d01e295cd9bdaa523cb70766c..2cb677725e6d8d38c7a2ba03ca34b6703357dcb9 100644 GIT binary patch delta 4752 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 Date: Mon, 13 May 2024 13:56:31 +0530 Subject: [PATCH 08/10] Add default asset files provided by Grails. --- grails-app/assets/images/advancedgrails.svg | 27 + .../assets/images/apple-touch-icon-retina.png | Bin 0 -> 7038 bytes grails-app/assets/images/apple-touch-icon.png | Bin 0 -> 3077 bytes grails-app/assets/images/documentation.svg | 19 + grails-app/assets/images/favicon.ico | Bin 0 -> 5558 bytes .../images/grails-cupsonly-logo-white.svg | 26 + grails-app/assets/images/grails.svg | 13 + .../assets/images/skin/database_add.png | Bin 0 -> 658 bytes .../assets/images/skin/database_delete.png | Bin 0 -> 659 bytes .../assets/images/skin/database_edit.png | Bin 0 -> 767 bytes .../assets/images/skin/database_save.png | Bin 0 -> 755 bytes .../assets/images/skin/database_table.png | Bin 0 -> 726 bytes grails-app/assets/images/skin/exclamation.png | Bin 0 -> 701 bytes grails-app/assets/images/skin/house.png | Bin 0 -> 806 bytes grails-app/assets/images/skin/information.png | Bin 0 -> 778 bytes grails-app/assets/images/skin/sorted_asc.gif | Bin 0 -> 835 bytes grails-app/assets/images/skin/sorted_desc.gif | Bin 0 -> 834 bytes grails-app/assets/images/slack.svg | 18 + grails-app/assets/images/spinner.gif | Bin 0 -> 2037 bytes grails-app/assets/javascripts/application.js | 11 + .../assets/javascripts/bootstrap.bundle.js | 6972 ++++++++++ .../javascripts/bootstrap.bundle.js.map | 1 + .../javascripts/bootstrap.bundle.min.js | 7 + .../javascripts/bootstrap.bundle.min.js.map | 1 + grails-app/assets/javascripts/bootstrap.js | 4357 +++++++ .../assets/javascripts/bootstrap.js.map | 1 + .../assets/javascripts/bootstrap.min.js | 7 + .../assets/javascripts/bootstrap.min.js.map | 1 + grails-app/assets/javascripts/jquery-3.5.1.js | 10872 ++++++++++++++++ .../assets/javascripts/jquery-3.5.1.min.js | 2 + .../javascripts/jquery-3.5.1.min.js.map | 1 + grails-app/assets/javascripts/popper.js | 2624 ++++ grails-app/assets/javascripts/popper.min.js | 5 + .../assets/javascripts/popper.min.js.map | 1 + grails-app/assets/stylesheets/application.css | 15 + .../assets/stylesheets/bootstrap-grid.css | 3872 ++++++ .../assets/stylesheets/bootstrap-grid.css.map | 1 + .../assets/stylesheets/bootstrap-grid.min.css | 7 + .../stylesheets/bootstrap-grid.min.css.map | 1 + .../assets/stylesheets/bootstrap-reboot.css | 331 + grails-app/assets/stylesheets/bootstrap.css | 10315 +++++++++++++++ .../assets/stylesheets/bootstrap.css.map | 1 + .../assets/stylesheets/bootstrap.min.css | 7 + .../assets/stylesheets/bootstrap.min.css.map | 1 + grails-app/assets/stylesheets/errors.css | 98 + grails-app/assets/stylesheets/grails.css | 1052 ++ grails-app/assets/stylesheets/main.css | 589 + grails-app/assets/stylesheets/mobile.css | 82 + 48 files changed, 41338 insertions(+) create mode 100644 grails-app/assets/images/advancedgrails.svg create mode 100644 grails-app/assets/images/apple-touch-icon-retina.png create mode 100644 grails-app/assets/images/apple-touch-icon.png create mode 100644 grails-app/assets/images/documentation.svg create mode 100644 grails-app/assets/images/favicon.ico create mode 100644 grails-app/assets/images/grails-cupsonly-logo-white.svg create mode 100644 grails-app/assets/images/grails.svg create mode 100644 grails-app/assets/images/skin/database_add.png create mode 100644 grails-app/assets/images/skin/database_delete.png create mode 100644 grails-app/assets/images/skin/database_edit.png create mode 100644 grails-app/assets/images/skin/database_save.png create mode 100644 grails-app/assets/images/skin/database_table.png create mode 100644 grails-app/assets/images/skin/exclamation.png create mode 100644 grails-app/assets/images/skin/house.png create mode 100644 grails-app/assets/images/skin/information.png create mode 100644 grails-app/assets/images/skin/sorted_asc.gif create mode 100644 grails-app/assets/images/skin/sorted_desc.gif create mode 100644 grails-app/assets/images/slack.svg create mode 100644 grails-app/assets/images/spinner.gif create mode 100644 grails-app/assets/javascripts/application.js create mode 100644 grails-app/assets/javascripts/bootstrap.bundle.js create mode 100644 grails-app/assets/javascripts/bootstrap.bundle.js.map create mode 100644 grails-app/assets/javascripts/bootstrap.bundle.min.js create mode 100644 grails-app/assets/javascripts/bootstrap.bundle.min.js.map create mode 100644 grails-app/assets/javascripts/bootstrap.js create mode 100644 grails-app/assets/javascripts/bootstrap.js.map create mode 100644 grails-app/assets/javascripts/bootstrap.min.js create mode 100644 grails-app/assets/javascripts/bootstrap.min.js.map create mode 100644 grails-app/assets/javascripts/jquery-3.5.1.js create mode 100644 grails-app/assets/javascripts/jquery-3.5.1.min.js create mode 100644 grails-app/assets/javascripts/jquery-3.5.1.min.js.map create mode 100644 grails-app/assets/javascripts/popper.js create mode 100644 grails-app/assets/javascripts/popper.min.js create mode 100644 grails-app/assets/javascripts/popper.min.js.map create mode 100644 grails-app/assets/stylesheets/application.css create mode 100644 grails-app/assets/stylesheets/bootstrap-grid.css create mode 100644 grails-app/assets/stylesheets/bootstrap-grid.css.map create mode 100644 grails-app/assets/stylesheets/bootstrap-grid.min.css create mode 100644 grails-app/assets/stylesheets/bootstrap-grid.min.css.map create mode 100644 grails-app/assets/stylesheets/bootstrap-reboot.css create mode 100644 grails-app/assets/stylesheets/bootstrap.css create mode 100644 grails-app/assets/stylesheets/bootstrap.css.map create mode 100644 grails-app/assets/stylesheets/bootstrap.min.css create mode 100644 grails-app/assets/stylesheets/bootstrap.min.css.map create mode 100644 grails-app/assets/stylesheets/errors.css create mode 100644 grails-app/assets/stylesheets/grails.css create mode 100644 grails-app/assets/stylesheets/main.css create mode 100644 grails-app/assets/stylesheets/mobile.css diff --git a/grails-app/assets/images/advancedgrails.svg b/grails-app/assets/images/advancedgrails.svg new file mode 100644 index 0000000..8b63ec8 --- /dev/null +++ b/grails-app/assets/images/advancedgrails.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + diff --git a/grails-app/assets/images/apple-touch-icon-retina.png b/grails-app/assets/images/apple-touch-icon-retina.png new file mode 100644 index 0000000000000000000000000000000000000000..d5bc4c0da0bf34d32c86eee86f14845f1e5bf412 GIT binary patch literal 7038 zcmV-^8-e7BP)Py5I7vi7RCodHT??FD)4Bh?edZBlroEM*RKi6)f?Kb8q)LcnCT_hiqMrTTqHe32 znM_IBd#Arvq{$@JYJ*ZjdP!V@y3I@?1QkUil%j){#G{B_%!It=>~;U&x6e7V&zb!^ zXP=WZk@cH1d+oKp^{wx*-s@XyGYw*Ay4pWOX3d^NHh#P(88d>I8^DtDGkCHQKat^H zV(Nv@`5A+EUWJHmBCDHtXg4>t|DVDR!hbwiXf_LfUQhJ;VPx6IKw(EgF{2EbVM)@@ z#P31z&qKivlWjdnwDaRU;nMX<=20$ORjo*~sAVrQbP9fBpuEwBXsdDw!V52ivldEy z3^n;d{1))|nSb$utA?0niGK|*qnNZxh#+XB@K}cB|nE8)T?5$L9=JA-B?`6ZQ z;aN3`MD1%Pn=VG5)ocvaR)cW-Xkey|=#x9iqU%sgJN@7)8NNvsi5kbWs0~eLdJ2?x zU?mw(DlaH?1#xOBji0^%H5RS^rg57@k;dGSqOK<=lCh_N^Sw6>>&fN{LB2?AO{JzU z-p+h_I$7-D*eb3_vv~4oO53wh8}|<k=L}V_7Asub3ir5VMx1V|af) zn$e2oTS;MN^FnirnGw$+s{1ZaxN3DayqwR92-I}8TnN^tfxCYyCo|QC8}rilG0MGy znr8f}-2G=+73r+J^v*#u`ju)EawX}367M5!IKP}LM`cr_>1;h5gPD04%#5g{(5f{r zDD!npSZGUlJO;q&^+H>M=N`8 zMPGPEGURQZSkQOQr;!ck@~HL=NpYB%BF)nFp|q~|Zj`pMNfEa><3UrqgoZSn%wyWu zB*AAQiZlza7*4#Q6G}WN38FqJIH1g@$ka6_F-0j^k>-Jxk+h!fM{~NzCq)5C@`+~l zWvZv+_}G~%OTk-`BDE&chGkonSc(cTmK9}E-RM$kX3>f?kG3^XZ+dCm<`m7zt6=+Y z7{SR7!Y=Ud0vto|+$9fZwM8L|@smzD4yzuhW-xJx^qJVzAWKPD2{6 z%!Gqq8t0W>!c>85{TMV~<5q@Q)VdAmZ3To(JGSvluQ+4?G@{}7Vn(wyL5RKLKnzo7 zt4uK>DG|-a25>o%n`bWY!UqLox=BxA)H{*a_UwrlC`p{1hCuopf9}7$OO2M_Z_UD% z4$#q(i*sg32mHtB6E9|K`jJ} z+Ri}HT|i{{g~juq6^dLzV_QDQ#X5aKTo@@c@YC)+IJ3A1ieh~|bi?&|qE zYD!~%3Vpi)N<=f4al?ns<<&h?0sEP3P;yUxFk4W~(#bo}x^z1h&0z>;o*(u8;Zpo$ z4%*}|+kx3Xqi<=+|MBb`yxYTcEe1aw7?fNI_!D{jtpAm0^s5-{^1*IU^`{v9A>u_4 zY|bKk&AIZ9bXd4HcZ)w+XO9OhTEMw!#$D7(|^X#O=a!KJko$PTJ7qZ ze4#XjvB{~SeoHgMSTM+|Sg&yNtXXcHFu?jU8pTW8VdCeeSwAWa)Ax02t^~u|x#J+b zXJ8QZh=!RpXQM9HV?6bBykD(h7M^MPH+Py+{m5e!uj{!J$~+%~qYwDVY3~E)ujFSs z+xBEi-wFBc8#f=3IYahHcYRpe&>E?eeq*i*L*yB6*YpoUnBMe+i4bTOx9zAF1{qkh zu@zVxVE_RLFjet3ZMB(rc*pZ=Cy zv8_99fIr>09HzoAp~Qb$`#@9^TGa$kM|kRHh$@k*15&GzEz-lW7h5y-Og%N1ejPck;ODPK{5!c9Kbx3=;Aj z8~X?Z+^d0h{dLUizlXH>>!8RaFHz2-6L7g;#>OVZgN=nGMgIu9mj!5WNtGMy=>VN_EhQ>c#_)C(*KUf)$uMJ>W|Uf{flm30?w=>{o#Z{fYT3o;xAz zU@$tujU2Guh?il!xPwqnY8@|>pgSn$9p{}JQCs&y)AnRG9?wIaTIvePc#-xE;Kfhf zFu?6zfNwttOV>mTU^7Wv4?~}l!XY8jN8%p}7QKKcM(F%G6ilH*2RyD+C3)FOou+fu z0xaH&>}**9W)3KT-SS!m5%~KD2yJUNGxK1 zqY!Azd$mcxmMyV7m)ErF>d89umb*X7gWmE|6%x>?))3y&eb_d?My{oaTa;K8x(Xyh zbp&0xfePl4Mt2F^0LA)IYA`D0S1}@$$+y_&$ON$u@7P0x9}^sm9x>>{OwhouTUCsA zgkd()|Bh5Ti^Nk-IrTfYzdtnJm)GJTDlAPte0DJeLsBGl;$(4x#gC`Kwz$S=yi|(J zk1^H2_LU*Xmqo@kfWY#d*)^ZMQr=Wo*JLp`#No}{-?q2e*!My7T+Mpws`Vz)W*6*xp3)B6{(jI86)eE$vH!xPY&5;fXOz=%L6)d zE|SVNt-R`Ri~_bwQe42deUuH+B=f9lT*j2X0a3u9>I}M*V5eziGo}D0nb*|%Lz6+Y z8DL>9k1R5}a}+6eyOqPG`RH<>9h5i?l}8pC-DMQX{U#YnN~v5mJxLlXfD4=9yJDa- zvMgEQaz(*wiOC=`8CH%=FttAr`*FLK1NWf9Y13)tqE~b$I>hRO+;>_=$LX`nh<$LN zHugDXB@{YD(<+zNmeCo$K#vQQF^g(OEw`IsbeZ^wHJ@i&6p5RM%jmRkc<<%&%a}!# zqqf`2Pay9p3%ZdyVXQA<(VOK0+6`El#rX+c1joWR7QCS?gyV@`F?U0vEQr%i_&)}x zuf7j^ow=~WURQpmswW4r4>D;pPAJ0KI%H?wa;TF9cP!aqL0Y4nX`l=|@iQr`&!+%e z2dN$lAx5$F8Ce711_ycQ|F?Oy!s1B1zF`j9k5$s>qHNxr zGy9K&W01kZIC?x zgD$^_i(@ds>rps_{VT0OL92+K%thJAn(Pc!(U(rrHB6J>@luVpm)G$NW zV7I(%s~vgyR_H~K(XH#b8C{4D2$fg4Rip^#$T-H;s4$a}rZsm=IxJ6g-VL;RO;M{9 za=Qi2UY!62-v%BTWZj10xgPKd%eUI&Q3G+we(w!XqOM{IkIJj?T#SQ^foo{wq|l)l z4@Fj_B9;r~ADdOw-lcQ&n~p`3FM(n(xI*$Yza9K-a`cgm!oYeelNgIBDFln2WxE3Mt3WUPGy?r8M7$`BG6$kQ?u& z@M{y;_4r+=k=jZLPgGlbWY!?6D4ITea|ZD395XFyWQ?XYhn(p@&@3L8dynbi2{Zmm zmUSpf?*r1zqHxSMU6Xzqcb*zE+eE?jMA+)yhfo-uGne2+c^W(IZ^dThoZNDzEwOME z)wCi95HAaIbIb$Z3tx5cp$L8EyIAcQ2W9>keTofh*UM;a@1r=GyN6GbstMMCnoV*g z+95)_@Swa1PenSFCEGWvY~$iU_lRq&Tdo2@m&Z*j@Mub&CsRMBlv@o24`?_9kLy9l z0a!Ko7{~6~Y4{#j>&apPs1hfaQcybmQ_y+3kOT!jjmJf>-~D4LB&ux_Z$Rz#zAG;b zH|UrqePnkSpkF*n&nV*cOHJ35&-%ec30FZh9eM~Z0lW-#{UaEoPp8%0Ph)5Om?-JX z4I`FnC~V)MzVu&2i73FUab*76Bs7<*M3J4yut+63yqj*hNd9mL?y*vYp`Cn9?FqPT z>bX+zNLuGMMY(Io#%+o;9HkAknX7S2vXC_QXqRAN4M_a6Fu4x3>2ez1a829=Vz0b)7~b>d zY3PvU(!e9puPEaOroX9<}NKDB>pqxA>)FQ9R^$PVM;gL zQDo;N8AcyfGFBG?AYO(o(QBx#@vdT9jP{nrSwPVHSktr=t;8-t z*#P$uls3N(f(eT=OQviO7}P{u>>J>e7NIF~S8M=iE=qYeat{z>P%f9zouf$ky0?57 zx=aowy$-c!fmt%?^I=(l`Gat|(0?OMhPL1ofI9;h7aboA6%e~|{ZAlh-F6Cq(kP`# zXcHPkoZJejJSTku%ayOAvz;H8AQhIj{W{EdK_%=(i5?2Gt*N1C(=;8h^`UTX0Nci* zMtda1yOWu&?~cOAG1hL5(gqsccs%{44_A=J*un5b5)ufVW&7=Z=H(OZ<##8cPs_Vs z)t#j*&!N;G;|`1BN3*yeb$&E93Tz&Xz46;oYrZ?3&}h0Y-`ySN_Gg;w@^8_(bmms% z0yi<`@I&A*?F%@EX`3$^_E^QM#ua0L5LcY;(*cz0Uy2hnP%ILm;-JObbOR(Ev1BDW%Z zdR?wkDWhY1wLf+ai1SY+F)|3j=o1AsqDym$OJf1FrU+}Y<#Vbd=*pc#o+6!_l(^Fk zPzJw0lcsn9WcCHoHAQr+M;;;qdw|*2J079gAb%dS5G6gi(|zlepvqIE;h zjFPmTw*CBHeL;o{ebF~AECO~bVIX<&K}};G;J_E~0V5UmrxiRZuLF}N6XKzx0g7~N zP<6vJnM~bS3_57JhT6wrP4)u}xQe^9$Z-)|G{TiM+FQZ#W(k0mcIh^D2)}|Df9Xc<^pahQn!$#H$-=M8A)2 zycIcq`T~p^{F{!5dAh;0gC4?j-C>^oRO)7Jx;!HT16Kyd7DgU><+~`|>k5Oz-jz11 z_U14+04neBAfKL3td=;r@8&lRLMK*JJ`2ojL)U;>v z0s~&SY5GzSE*5H$oHk*#))SF{-9T3AQTJ<@Uuc5m!$V2JT z;qX=^H;V;%5VcLPCn-y#Ob4 zpt>jscE1KHQUSN3HZc3XJ5d}zO7UAXzTjKQQ4ru8S15@+Q9!Y-b7wTTe5lN%`l0+# z?>F%Ap_qGk#|DIgca=c^NKlj``?~K2!AM-FB9&R@E5Z=@#vAi#y8om7edGNic%>L8 zg&r2dNbX~tx46v@O=!4S$3=2xYaBj~Z!jgiiwuf&kbM*baL6It=^AENE9@_0oY`}s zMTz_frjq|fcHOOEL}jeGzlK`&eci-$;qmfUVen`n z)}zDuF}}fdQ||LkK8bYSRjlz0{Sb27#s@4g7;?LhnmSIzGj!=Ok|HHHH5Igbo(9Gd zfw>1nYNu^jhVB^l<7+sU^`U|r{j4FrTx0eH{(lZYkr$Q0x38Y?%8QBj0&~#+#Afji z-tc)@?nUA1^ z)f8sDDc+&Tg)jv?zSO+cqI|7ci9)n>sko9zj~WPzdj4`8+u+bX(oL9yn5VeIHmyI# zoGyUS%s60907!+ScuE{43URR%soXTp=s<~yKYB}86rds2oGvu`ly$W>)uDjp1;8kE zK0(HDbBV1;?RZBtoQLOmn6=(xKySi8_rc3$4nesk%FJ) zGq*z;PDTg2JZ650fTQNDCVS`ki6C<$Nm2Ag2zR;!{7~LgDpU6-gk#_>N|AyedxzM_ zt)GCVKo+?x>)85L)}AxbjK_5>fk1NxO^M zTIDfE(IyQC4Flwrc$CUcWH{lfqV1K0sFD;Z2>95UD~akxSG1W;r(1N9LI_CE={bIz z&rA?yAS!K6MRqE~K+w?0So6prY&beL6eq9lhJeQg!6g-kl6((s)o_8Bha`bBbC1D% z(7$UE_`+~NiA%Ik)GjIvIy^oxMM_q>+_kFr76_vvr5eJ(H=Fs_RD<1kXG1!iV;6*8 zcC`4(qj1>fe5}Zvfu)%`S9ICDD1`G#MyEv%Y`h3dRFRT_HhEo>Tj84uf5ldSz{opT zGFy(NFEc(g{{wLh2 z3`7>q9e*g7D9TnNvjjU$ZL3^yf-{UI9Gb}@97Ip_h41T4CruqUB;Ax2ilOX^%x389 zFyMeFoAXQA-pS&t=4WPmZ4S1@+X_wl%SCs^6q#iJhgnBc+MbP?8sBOli=>L5sCmzl z7)pt~Qw3ec6)C(qcbq;s5hKVc7!2)QL4M1Y6$JUB+5)Q?slT;bxd_-Kip(;j{pX^# zQ*imi6g0O7X2S>56V2!f;?z_U>->bL6mjIRNfqfP6gOowq{HzV|RadLGJqnDj;|TqHH&QkXzizZ*1)^b)0Wo1=Wl zRK9_U&nFs#Px=zez+vRA>d=TWgF})fHar+;0*7Ms%?-`0~9EOJm$_ltKZt^p2NB4 zoO|xM!$ZSP?(DtST6;bAUVH7w*~4@OlDs?nJUW`biEO!whzF6#<-~j*L{$<=7r>69 z+zR+Xz;^=HLKc5aT}t2PQS%O-Zk70SF_gyH1Buf2Lg5J{JWNQeVtF&MO)MXw6J94O zeVME0{i|3WQS_&5q%_T}BFW4G^U)%7%KTgX?o-WvQI35J5F+$oUI)0{3==H4|3Jq{}dy$ zC?jRv%#oC_U&HA2E=I`dq{XQ2rIa<1Z(Zju%CuNR0)C4VvYPS);jIHKEO@HvU0vF1AzkzKd&OPYq36H zQ-B)NKd_{(#1g5VvLEG_(Cz{7)6IiP4h=0Qwy;r)ak7VFV@E%4b zB}+Z}LItMneDk9Hl#!=|>@{L%8ZnAx;by$d(L0O@87b>#^)<^x6eEi_XIYqDV~a2< z)_7)XqQ|5cjoSr)OGnZMc7%gK>+j!Ur(T_lt(h0@>GQSm2L z$c4esPQV%Ck$3geX&F4!bxi?(9Xg?M0NgePZAf&@6uQv^Bq@mf5Xj6C&5WdT;BET? zg1wPV!spve15d#alwG0+Z)YUAZL+{|3Mma2Tmh=BplgR)WiT9QWnlo3W9TsVoUzri zN!hx`*zAO|H9yV=hY&+x1EyuHPl(D;SyJGyfwBbZ-v$vs_Si-gbimkZn+((wj*&ul zM9_sn%*{Bsz7j^9T?nFQe;6HWq|wN+>j}$TI^j+xk(z~~S|TQ=fk-dLk|e!r!ljy} zw`%aWob@tqd*N&I;?5>QD3KnBFqtdp#NjCk$VHnm*BJ;>a-b6_3Vncj&cf{iJs8XJHM(#gz7CCU2}knAhH(X zT=$ey&i#vH*89|WSP!TRb1`S3)|y@ftv|+bZ)B7-X{>t~`{TI*-1!!UEn<$@g9C)V zD%U~Klk(<6Lw&$AUc~|*t&%iS1Z$rh zCD^BdXJ-^nVF<@nw6En2SzFgNAC1||mUX%w#6zj6wn-Xh-r7-PRbfQ$duUhd2jJI( zN>W$F?UjvQs-NnaFTpBeC1x zLWg`9yg%{Nk==d+wuyIQB(KEjYb8cyc@93Jf^A|a7`P5?^a8CfI_Rf{PXw)k%so^? z?IzJFQoumN0$;G0e@QJrbnN zsUL4$0lFW#FqD62_<)}ab8{^AcN_U6i8koQF8xHW3@}1lVZd;gS)m**un$**{mjjo zw*O#pXF9Zd4-D)PY>RX6*Tj_e0V1-%xW*!6v}$ zYxy_yOuRNj&uzHvzgm|NB>hI8JQ+a;KflatacK9IQ3fg=Bh!_n^(P)}PJ!>vsro90 zANYD8$ScM`r=4S0)<`@;Fn1yz%ff|>mG+2AOK}|%lY}nHgUttb$WuNUetCJA`N57o zr7tVY7@2)#vC&TySB5KPsAs1=9!*K-FXKCjPk6LB1<3=4Z)vBORqXc2AN64q3B8FcoS0vXAc}&yWO@b+C+1yYpa%)_ien;rq29c6x{FuzYq>`jr@rIVPn)~S-%p8(&i|7Lp84JN01lZJA;qkRb7sT59GV`s9g0|JN&pDBMm~| z$>=kZyvZId_z)9B%leutu%W&&2*+gqLm1{j%oPfgiGVpY;A8mZ0I?i3%)AsQ|Iq=k zS2cP=e-Dr?VD!Vue6iJMBvBt?-GxaspzEkeEL5@`b{xx}p(n`0Ey#O2Q>YG?6p64B)$Qa$q- zs7>-3Y519kKzJw9vDA?C4IGbK^bXuD`m1vR*)UMw@yv`Pi#5_*H<*V&9T-vJk>;gG zob)UXr<&VP9GHMKhs1bVfrm=kAn%;a;f9LNQJfWj8yAd%ZA>s=`3oEd7g78fuBrD> zdD(GlOIMI(_cON%BID6+EaqflT?}7~afpwegJC^_keIrOy65sMNwwXCXD%Oxo{Zlx z#B|iDpp0CVU&J#|qjyJznro1A_2qJ~Q_kr(=pkdz<^LuK8mo14qx~)VzmWd}oqpOb TOgI^o00000NkvXXu0mjfLl)`& literal 0 HcmV?d00001 diff --git a/grails-app/assets/images/documentation.svg b/grails-app/assets/images/documentation.svg new file mode 100644 index 0000000..29bc9d5 --- /dev/null +++ b/grails-app/assets/images/documentation.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + diff --git a/grails-app/assets/images/favicon.ico b/grails-app/assets/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..76e4b11feda94c87ef50f4350eceeb1506e31311 GIT binary patch literal 5558 zcmds5TWB0r7@oAD-jLoD5kymO6!D=TzFEzK#d}{Q^hKedq)oD$o!QjZ7iB>ZDuT5Z zQK*!*+QLGbCUe=S#R?S^iw{!UT3ecmm$p`8F14H8xg5XmOinU8o!!i8KrnDJXU{qR z_xt7+PjCE@Rlt(vwLV=FO+C0aWg*UiUYXHhK9 zn3Z+9<$b8z{)wCwjIy!MG0t(#d~iiDT6zyu?$2577Q^;F&)edh;RIub9e91iLa?!~ z+updG!y2xo3@}K`6Fsg z9&0H>Sz~U8^;XC|F);Ud`BFoqbL@^Hv6TmA~KYha=;`uIpVVF zcXrTw3i|(+gdz2yErx~LYx+G(Mm=+;`;cx27wXA!oY>@0GSR0#P;P@y9ZlMIjSW7= znOfd(G|r^mO!u`pWu*?@QF2AODKGteSOoH%WA=;kb04}DT-abv-J>w*f7EF%eu)hZ zaz)R9v8p@X$lUUQU_3yd%RPhc!-~JNU)*X~{_%RYkLphja!uz43Bi0Zja%byQ90G; zI-KJb!*(B6{MmkS8^+G2;U^9;$VvIm;^<=Lk~DjlvOGg4_`Q3ex=Qi)9GF-R-~S>l z2G^03+!@nb2i?!5(VcorS z`5OJsTJCDt>N9EAkgvwK$(gf!+~3LkJZI>4jCrjQPop_~f4L1gaX{+8`y*mo#ZMd1 z7E$|$XC3^QG2Qk?_-W=gGOs$`;hNY`_Q%;@<$rQcRI+BZHw}K8HJO2Od)^AphyD=8 zzw*C${B4r?JvfprPTrgbJIxy0jSF?t+kv|a`5pW+{=@jI%|D1UNBF2^UP*)7%o@XT zA7vcT7oz!x7%Klte|P-J+~CxjX0X$&eQ{9Sg1mW}9MnPOU&{7cynp-=+Mef4- zLUDXq&+dukT_24tUBBzkCA@EGt8@+bA!H~^90QH_CH(Nqmp-}r{^=+d7pnUgdBdYF zsDZvm?8uh4{geNsDS2Y$9si7Bi@)dt@%xuHn5jQt1KNmZG@ngk(zj9L#On|8^H0`a zPJ{X@l0TxkBu$_EIRCo!7x`r!RjOZqrr}9iBmJHAC$OV+4>{w1jMe1&JNYh6;+q+p zjy2Zu#3Xi{FX=bm6|Q>!Xwvp7&YFGyi0YH{{-toE_XYcmY3XCr@%?Y!zoI&zU-SNn z95#aceH1n>^A2N^eT>Pud3^tj>494DKY9O-tMR}3&F>`mbRxfyH2a;TdvNM*)KBjq zUysXX`#U%`mw{Nn>Lvd@`0XX+`|nU&z6<&7x+A_u{d$RWNi{BUyN9X|!naRu{!|Fw zB{{pgLGksPQ%^DmHXlN*g*9BO=J+Hgz7L$D9CHNkyS(Ea>L?yx#CgP23aUl?og~B!g%=2 zVLI1vo-&k$ZrhX`pUkP8$M_!B#xi%C?i(0$!+p)>OUfcnFDiLCZ;NC3A@A8Iwx7O+ z`tgtXv2V~_gEKf1#V~9i-+O#1PhRZvn~kV#rBK2@zK`i8F|07iO&vmei7VNm@*@di zHA9_dWhL~G-y$e0?PmuQ$fsY`ENt)t?>7C|^JU6%8TPOf_W1?xu5X9U-$v|sQ*-do zQm-|ufmy$AH<51n|(Hp aAB7=xL9F5|-{N;0+0aiDzfp{|{l5XfK*m4- literal 0 HcmV?d00001 diff --git a/grails-app/assets/images/grails-cupsonly-logo-white.svg b/grails-app/assets/images/grails-cupsonly-logo-white.svg new file mode 100644 index 0000000..d3fe882 --- /dev/null +++ b/grails-app/assets/images/grails-cupsonly-logo-white.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/grails-app/assets/images/grails.svg b/grails-app/assets/images/grails.svg new file mode 100644 index 0000000..79f698b --- /dev/null +++ b/grails-app/assets/images/grails.svg @@ -0,0 +1,13 @@ + + + + grails + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/grails-app/assets/images/skin/database_add.png b/grails-app/assets/images/skin/database_add.png new file mode 100644 index 0000000000000000000000000000000000000000..802bd6cde02d442288490c5f278b225e192927b5 GIT binary patch literal 658 zcmV;D0&V??P)$< zN?sD2BV4j9Yl`*+fsWQD?H_4>L?~r48B=l;Spkuc)A?yA6iP)R5d;DO`2BwH_g=3D z!!XcjG|+Ch%jCP5&1Rc|$N`LEvA9yN*EyX%X^loByIQT_h>#+l_9wi@{(Z?D2RE zUDq)j4#hY2{Z&BrR!Yn$4g z^!3C0RHpz#W@n--_jThHPEAe2R834DnuV#1kUlxXv}=C^n7~&>f1RO6h@8fUuT`wRE91*{Z%LW-oO8KckjTdf s77ewwyuEar+*b)ffn+a07*qoM6N<$f>LlT?EnA( literal 0 HcmV?d00001 diff --git a/grails-app/assets/images/skin/database_delete.png b/grails-app/assets/images/skin/database_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..cce652e845cde732ac3ce9a4132b597301ad660e GIT binary patch literal 659 zcmV;E0&M+>P)ps_J1 zHhTmGl@tMUh=_=a3Fb%)BqZVTW3s!xH?UsxE?7A5@n+t<@6Gq#%m~l(@IOPFT;%il z03|#}Sa4nU2-$-Kn!4}FekQv@$S0FY$L9!N0g;c={9!m8K4zLG48uSu6aw$J+ii5a zT~sO+G#ZW9!I0fqFSvY9*@h|sR=YqL#x%oU@(yD@pz0* zr-R{eDEHX6V*RaK<|4rWl@GKt@8COeKZT>%ICBq4+h_I-+?Y*V28oxmqBc+Oz5 zc>4@kzJgDe<1lkKXYEtktsNC`FoTI)4qLaF!_1E&4qv>EKx`iUcee83)!MzalltZ# z3K)~8`*H_w9^uf5^9X)<39-6>(AOuJvu0IKc#FRkFoCa%ULtC>8v6bIR-H|{S~CWm zy|LB2yL+L!Vs5g8ONBz=aUzj0EX$JbfSV}a#vT*B_2)32Uc<0oLyzLS9V$=7hM4?~ znM@`|iEa~8)bZW?7q}d~l*7K(I`+@}grT|_=WaH**u tj~DMRZZpzVy^OjT85Vq(G=8XD@S91FH}kp`d7hyPh1 z5CCa%X>*RH50W(1GMNlqE*ChCgTvu4bCM)M5Co)BDTG2HvvyYjmSvI4<)A2v`CcxU zQ79BpEEdf*P56K_c;lUWy=bic9s#4IZm`yWps?HR<^;5uf_%3rLf1Uy7}ym7{u3SG zgQxL#;V@<+y-&7GK#MIB!!Xb^&5SuEhPoOV9{wDJpWonQN~qlHho`!h-y&cUDCjiw zot3{JSR;b3Z$U9V2&bDtVsaL$Qu?FFtIb;kXm<)qqyl<=9Kq@&_)r^^)N|OJWjH)_ za7i;6X_aj`duRB^h5&`toyKA^3V-E1_yb`=eg>PPj8Y+p^vFkpk)_tg?(s>=HO~R< zNVkfdL~{$}rBQI|9QHR{MrpYhcBg@2p$?h%pAnUsbBDUeKUv#oTc6-&EEZdf$Kwze zM&QwZLDd6D&pd?=1#1F{N2f6?Hf8gwvt`>|pf)ft5F|nm_AI~XywcT&?}K--v^WN? z_7vo-s3)9F{TXfF{hpqll^q2vdwBb}datvKg-yfc+gC^|#8-K5)%lB$rlxi}-rEGO xUZ|2A>wRp~(I5;*aZFyx-fDe3J-^%i_y?+(!m^mX(n$aS002ovPDHLkV1gwlT*CkW literal 0 HcmV?d00001 diff --git a/grails-app/assets/images/skin/database_save.png b/grails-app/assets/images/skin/database_save.png new file mode 100644 index 0000000000000000000000000000000000000000..44c06dddf19fbda14efe428b9b1793c13f46b2cf GIT binary patch literal 755 zcmV3^_07cLZBR}_>&jXObH zw2it@svr%qE?kJ(Xuudu+DSW|WWK!jNvbU^UO02#+Tt zYOko4%Vx8c4Gh!M(=Qem7g;XcE?n0Qi^XD?&*vX7@xPFCIh;%;@xMr?(;$(vo9j9i z6;riZMJyIWG#Z6r7^-I5HtO{{DwPWQ`}>&y+Y;!yjz*&a$8prX=XtO!3$0d5J>%Mz z1f8>Jnx-7^X2#7Yb#zC2VYfZ>c17@L{s)8{OuWBa3WHFfVXfhLv2t?V0V~q5R2D*D z&315l_#iF}b>Zoo?-;+7*`WOJWsMw(x3WXv`@U*s@Y-&edFEYpz0skP)dFfu zZ4wIp&Vbb!+|0+3Qa}p<*AH-eY>3q8s6?RA)zqP8W39IT5HLFG9m1F);gE|P`L7@@ zctjKsn1rA6!ZZR%R^(SjU!r=2o$yGp<$KViK~{B;AIcgvN+J+&Nvur+W(Sw&=H?z} zGMRW^U!Nl3AvWzQ3~C%Z*G*(?qLfNCq;tpg2yRW4@yl9;p3CK)O-@c8Sy))OUMiKc zQp#QYFZe-*@LZDInR^#F=Bm=!vA2i6tkEJ#i0aggzp2D%3!>h~r~3uLt(-IMoyFAT&uF!>{(iS?1OX-eX zKw9bunxR5FrF6QaYs~9>A4#zW^dwIvCpq(+cfR?U`T6-{9LHUqo16RKcDwUVr?cX4 zIN~hJDs48~aRAJ}U_2g=KAB9SP$;0;Y@*$6Ly{z<(`i^NmbL#1W@l#$wOS3;YPBOE zJ;7`?L*?Ga6XzC292wl75}>gDz`(>h?is$JPxm#0jGnotoK|nAVM5$DQ z!C*kO-aeF@+Ejy?nVHEp8V&F~k7BWicsx!aH9kHLRpcQ?L&JFBAB4i&kAaVUxVvzh z3a-EY0%m%8nhI7|SE(QpiBL#sG#VUMM9}*(0mg2(Q$Zq;z|PJNd_Euiem@;jtJN@i za|c2MmsL?PR;yKNwOUA}QuO=7;V@#c7!{~gs?J7hAlsE7U#g?$aRkhSTqLq6iuCu9 z10_j_=;?Dc?4cZ386qH0HkgHTDT|HmGR`W4V2noNQJqfLJEot)q{V_UtsW+m31cP~ zDwWEi3HYBSoF4M;T?VaIdqinn1HZ9}32qs-PdwPbCf+WI6n9jl0-8cjV3%1FB%B&r z+`mzSliyLSH0dxYE}rk&=!uCa*V>()2znj`_XYjtbt>@4FLHnJE|G`xv)Ba@oLBny z1%3K7c4fiB^4{k6E8Pif0kNy62}b@9+N#0$9Ug7g~-`rQ^qx~m@y2OU8A z#zh~=7n#Z$Z*fx-GOtDf07cgx0suCz_W(2~Y(0tf@FX@P6EPuM_dgn$vj9LucO)%W zw%HgMW>=#oL>nZ>M&NEf08>)#)k<{$fCT_r>rPi=BV=hFh6WS^qqze>C6Ek}o{M5% za|@JGowu0t{&hgNzySHZxy@LTNh);YzZ2zSp_ zl$^T&Dnc|NLb&RD_!4>pt@VHdP)ZGER%5ZmWEe$lryR&y;2u^3cOkO4#6c%-(EY6a{600000NkvXXu0mjfxS2AI literal 0 HcmV?d00001 diff --git a/grails-app/assets/images/skin/house.png b/grails-app/assets/images/skin/house.png new file mode 100644 index 0000000000000000000000000000000000000000..fed62219f57cdfb854782dbadf5123c44d056bd4 GIT binary patch literal 806 zcmV+>1KIqEP)v;U&v3%|^C`Ga3?LtY&4dQB4Oz;1v;J%z!D&%WRH@BZ?x; z3)8@IUIv@hG|@IwyHLC`l{1<4BK>wam95g|i|?Cfzt876&-Zx_0f5*l-9`IJI&mHu zE6$@xB)6N}7VeR;!X8D!TAw;;&0Bsj?A071cO>X3K0wl7WZ1;Tg!4LHyNcnzoeQ7t zNW`aSlm8WXYkek&ir$13=ngczvf zV0vnjNpCF&K8px}dunv+`LIb-sOC$_jD(;IBI$xC|7`(+9cA>Vir_V#z{?k7SX^Ah z^71m~W@q439Ycqfhi7+gp#A14n1n1!e>$EdeATG|f798Y=ggzwEKH2Q!qU2QA(Se?dwqG69%>n$6rtE z%F(845Az8c{w(XgimJg96!jLMz?zS6I1HUm2baqQx7&@nx;lhHA!r6vs2|fqJETOu zLxeu2OQ(3(au%dg>AcZsWI(zXn9XJg1cLe8k~0h0wOL=&HK}7X k{AKr*U4z7Szv)i%9gTgghwgU$Q~&?~07*qoM6N<$g31kYk^lez literal 0 HcmV?d00001 diff --git a/grails-app/assets/images/skin/information.png b/grails-app/assets/images/skin/information.png new file mode 100644 index 0000000000000000000000000000000000000000..12cd1aef900803abba99b26920337ec01ad5c267 GIT binary patch literal 778 zcmV+l1NHogP)BVme|mWaqy4$_pJm?y9KM{-*hp?1+Ey3e-CEDooTa!B;e(Q>TSF?bj>5At13y1p zriN3w3x~5SfZj{@J4M{kp{?=M_Lh2bV+5LH)Q)5W!-ePA$RgE1@5f1cyHki0Y}JyVEYZF(LD$xXlt$7A5CgE@ zpV-&l%vf;=5kZ2-2gi@Y6J&=cuwt>!vJ^#(&n|LcZyUzi6Duj$$hJ1s*HD-#;k-w@ zpdrwAuoDG_N2bvb07G$Zk*?Hc)JLtW4yqOnic_$zO7NZ#l>Fm){;fE?b$IbOaX2fe z0la4g0Dfw2xk7Wi7NapVD8YMPCZu?A1QCK*67dgsvRKBLFtrM>?$%&_lD1882mzdO zWPdw5KWw6IT`m1b_8=lS5jt8D3=RDa=&jWzR-)S@56WMslZ~mKu1)-wpXB>rNBQ>N zU#K`#1B&v|_AQK;7I~B}OdGiUT9LX>f0xm6<;LeP!=vFjPsUQF*wCJ*dO)4YBypgdiuF!=i@6Zyi7F|q#K zz?tlSZULa@t1D?$e;f@b36&N!V2mjOHw|*FMR=dr@6o0ZXGBB_+=zx3%$`cG63Jm-*84Da1I50Ew7%?y?G#+5$ UVU>wEFhP-tNtBU=gM+~u00(^_>i_@% literal 0 HcmV?d00001 diff --git a/grails-app/assets/images/skin/sorted_desc.gif b/grails-app/assets/images/skin/sorted_desc.gif new file mode 100644 index 0000000000000000000000000000000000000000..38b3a01d078418d3afcdb2765251a9f21b7995be GIT binary patch literal 834 zcmZ?wbhEHbWMg1s_|Cu}C@83_tE;D{=jG+)?d|RKCt}{bc?%XSShQ%-?%lih?%lh8 z|9*y1Fd72GGz1iXvM@3*urla?{0GVt3>@+doD32i4hNW;7z9Kl3=A9^nYh^GDt25@ NJj%i*$Hu~74FL5|8=3$B literal 0 HcmV?d00001 diff --git a/grails-app/assets/images/slack.svg b/grails-app/assets/images/slack.svg new file mode 100644 index 0000000..34fcf4c --- /dev/null +++ b/grails-app/assets/images/slack.svg @@ -0,0 +1,18 @@ + + + + slack_orange + Created with Sketch. + + + + + + + + + + + + + \ No newline at end of file diff --git a/grails-app/assets/images/spinner.gif b/grails-app/assets/images/spinner.gif new file mode 100644 index 0000000000000000000000000000000000000000..1ed786f2ece49ec5db07dee13a56ef38025b628c GIT binary patch literal 2037 zcmY*ZcTf|19{+AO8xjIZfItFCFrkL3BodGwflvety+|>T03uy{D35o<4X`9Q3=bSU zojZMs3Qw_)j=f_!)B!!mUKqwc>ezd^4c;H{$Ifr|uTTHRC8&buXgI)uM*u&6{`~Rd zM}L3+_wV1IK7G1x-@ebEKY#i1<^B8j-@bj@wr$&s7cWknII(;8?sMnPJ$(4^-Me>t z_wN1p@#D#pCr3v|A3b`6qUeJM5ANT;KRi7A^5x65YuBDSb?WNXs}mCwVPRo|gM+(v z?RxX(&Gzlv_w3no`}XavTesf4dGq@9>xT~?_VDnybm`KK8#fLfJh*P%x(gRB?AWp6 z>({T(pFdAaOMCY0SzBA%hYueT6BF;;xnpHzb@}q;O`A4(d3im4{J5Z?;ONn#0|NsW zFJ9cgfB);(ugAv5a&vP_OG`&aMz(C(^6J&A@$vBk2M!!Re*DRkCvV@rJ%9duQ&ZFC z&6|%MJC>4?a{Bb?vuDqqIdg`~z*4Ws1>(;I2=4ORL zQCC-|R4OYgD_5;rwQSk44I4IW+_=%t&(GD>Rj=1yxpHM_Xh`ytnG&0k9<5Zz%KT@c z2mnYvQ>hsF`jQ_R5(mKIydH2saldkg!Gzlvi9nFeu<gyfnCs8|SGO1R0M3N~Sp zx@MoynP5Rh(303ldPHFemMT%$+lXy}A1JR?IwL6=E`apW=@Z-0R!QO^@j_&{6#;i|5R1o$ zJ1J~xCDQ$1cs9`DW9Z!)D)^+%&Ug81908UkMXX;jkp>#b+SE}d{`0S>>Ef(`Ns6oa zB~H-LX25y1!BDgW%?nC0$RettYz8zsuz>9Z!g8TH$kU;rwYWrSTkjuYCH9utgFU6b z*wzBKaG6IjEXYSpAo5j4&c(t zwi-c(Q6YX2N-v2q(mgN`>wuCTV&XSRUA4h-f8g+uV2k_=o;2wb`7N)&+7T-C+CT_Bu4KrjWmK>x0AbH2rmR&7+q6fX+R0o&}V!t?TP+g0{x`8PSP{7CvnEPL^Hzx^T2Eus2 zi$U6ZM7}+l%$}afWn#%|+MPTsC236GKi9-ad*Z9;Ymg?jSO$L1s$w4BvDzu_kH9>z zTWC{K?jx4~H3oGGt3}I}LWNw@H)C>9GF4^|x(5n#+Va}kr_cb>{a+K%>B+@JNrC8? zJOUkD3fe*NdA-rJupqo?FfRK}k zOm!l7Dj$dsL|kS`3FL3^@^7axrU9d*@79yf!+bu3kXbziU!v&TO3p#w{y_lYG5ZPzDh;giB_lkGp((nqZ12&%LTrgm4vY= z{ffd0B$DiUKReJ9>?{#_KVrMyhiu_A8fNd!&DWTZ4+9S|1lJHkLv-^}a0IC{WI9N! zQTY-}db!%OH^;l2ZeajnA&Q6Uv=#0KZB9;^^lzMOi^0~bS~m!&K#e6hia79(ItV9M SXP~*+AU!zMlD%~Wg#Hic*k=_0 literal 0 HcmV?d00001 diff --git a/grails-app/assets/javascripts/application.js b/grails-app/assets/javascripts/application.js new file mode 100644 index 0000000..6f6ef0b --- /dev/null +++ b/grails-app/assets/javascripts/application.js @@ -0,0 +1,11 @@ +// This is a manifest file that'll be compiled into application.js. +// +// Any JavaScript file within this directory can be referenced here using a relative path. +// +// You're free to add application-wide JavaScript to this file, but it's generally better +// to create separate JavaScript files as needed. +// +//= require jquery-3.5.1.min +//= require popper.min +//= require bootstrap +//= require_self diff --git a/grails-app/assets/javascripts/bootstrap.bundle.js b/grails-app/assets/javascripts/bootstrap.bundle.js new file mode 100644 index 0000000..f2df15a --- /dev/null +++ b/grails-app/assets/javascripts/bootstrap.bundle.js @@ -0,0 +1,6972 @@ +/*! + * Bootstrap v4.6.1 (https://getbootstrap.com/) + * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('jquery')) : + typeof define === 'function' && define.amd ? define(['exports', 'jquery'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.bootstrap = {}, global.jQuery)); +})(this, (function (exports, $) { 'use strict'; + + function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } + + var $__default = /*#__PURE__*/_interopDefaultLegacy($); + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _extends$1() { + _extends$1 = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + return _extends$1.apply(this, arguments); + } + + function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + + _setPrototypeOf(subClass, superClass); + } + + function _setPrototypeOf(o, p) { + _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + + return _setPrototypeOf(o, p); + } + + /** + * -------------------------------------------------------------------------- + * Bootstrap (v4.6.1): util.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + * -------------------------------------------------------------------------- + */ + /** + * Private TransitionEnd Helpers + */ + + var TRANSITION_END = 'transitionend'; + var MAX_UID = 1000000; + var MILLISECONDS_MULTIPLIER = 1000; // Shoutout AngusCroll (https://goo.gl/pxwQGp) + + function toType(obj) { + if (obj === null || typeof obj === 'undefined') { + return "" + obj; + } + + return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase(); + } + + function getSpecialTransitionEndEvent() { + return { + bindType: TRANSITION_END, + delegateType: TRANSITION_END, + handle: function handle(event) { + if ($__default["default"](event.target).is(this)) { + return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params + } + + return undefined; + } + }; + } + + function transitionEndEmulator(duration) { + var _this = this; + + var called = false; + $__default["default"](this).one(Util.TRANSITION_END, function () { + called = true; + }); + setTimeout(function () { + if (!called) { + Util.triggerTransitionEnd(_this); + } + }, duration); + return this; + } + + function setTransitionEndSupport() { + $__default["default"].fn.emulateTransitionEnd = transitionEndEmulator; + $__default["default"].event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent(); + } + /** + * Public Util API + */ + + + var Util = { + TRANSITION_END: 'bsTransitionEnd', + getUID: function getUID(prefix) { + do { + // eslint-disable-next-line no-bitwise + prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here + } while (document.getElementById(prefix)); + + return prefix; + }, + getSelectorFromElement: function getSelectorFromElement(element) { + var selector = element.getAttribute('data-target'); + + if (!selector || selector === '#') { + var hrefAttr = element.getAttribute('href'); + selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : ''; + } + + try { + return document.querySelector(selector) ? selector : null; + } catch (_) { + return null; + } + }, + getTransitionDurationFromElement: function getTransitionDurationFromElement(element) { + if (!element) { + return 0; + } // Get transition-duration of the element + + + var transitionDuration = $__default["default"](element).css('transition-duration'); + var transitionDelay = $__default["default"](element).css('transition-delay'); + var floatTransitionDuration = parseFloat(transitionDuration); + var floatTransitionDelay = parseFloat(transitionDelay); // Return 0 if element or transition duration is not found + + if (!floatTransitionDuration && !floatTransitionDelay) { + return 0; + } // If multiple durations are defined, take the first + + + transitionDuration = transitionDuration.split(',')[0]; + transitionDelay = transitionDelay.split(',')[0]; + return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER; + }, + reflow: function reflow(element) { + return element.offsetHeight; + }, + triggerTransitionEnd: function triggerTransitionEnd(element) { + $__default["default"](element).trigger(TRANSITION_END); + }, + supportsTransitionEnd: function supportsTransitionEnd() { + return Boolean(TRANSITION_END); + }, + isElement: function isElement(obj) { + return (obj[0] || obj).nodeType; + }, + typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) { + for (var property in configTypes) { + if (Object.prototype.hasOwnProperty.call(configTypes, property)) { + var expectedTypes = configTypes[property]; + var value = config[property]; + var valueType = value && Util.isElement(value) ? 'element' : toType(value); + + if (!new RegExp(expectedTypes).test(valueType)) { + throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\".")); + } + } + } + }, + findShadowRoot: function findShadowRoot(element) { + if (!document.documentElement.attachShadow) { + return null; + } // Can find the shadow root otherwise it'll return the document + + + if (typeof element.getRootNode === 'function') { + var root = element.getRootNode(); + return root instanceof ShadowRoot ? root : null; + } + + if (element instanceof ShadowRoot) { + return element; + } // when we don't find a shadow root + + + if (!element.parentNode) { + return null; + } + + return Util.findShadowRoot(element.parentNode); + }, + jQueryDetection: function jQueryDetection() { + if (typeof $__default["default"] === 'undefined') { + throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.'); + } + + var version = $__default["default"].fn.jquery.split(' ')[0].split('.'); + var minMajor = 1; + var ltMajor = 2; + var minMinor = 9; + var minPatch = 1; + var maxMajor = 4; + + if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) { + throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0'); + } + } + }; + Util.jQueryDetection(); + setTransitionEndSupport(); + + /** + * Constants + */ + + var NAME$a = 'alert'; + var VERSION$a = '4.6.1'; + var DATA_KEY$a = 'bs.alert'; + var EVENT_KEY$a = "." + DATA_KEY$a; + var DATA_API_KEY$7 = '.data-api'; + var JQUERY_NO_CONFLICT$a = $__default["default"].fn[NAME$a]; + var CLASS_NAME_ALERT = 'alert'; + var CLASS_NAME_FADE$5 = 'fade'; + var CLASS_NAME_SHOW$7 = 'show'; + var EVENT_CLOSE = "close" + EVENT_KEY$a; + var EVENT_CLOSED = "closed" + EVENT_KEY$a; + var EVENT_CLICK_DATA_API$6 = "click" + EVENT_KEY$a + DATA_API_KEY$7; + var SELECTOR_DISMISS = '[data-dismiss="alert"]'; + /** + * Class definition + */ + + var Alert = /*#__PURE__*/function () { + function Alert(element) { + this._element = element; + } // Getters + + + var _proto = Alert.prototype; + + // Public + _proto.close = function close(element) { + var rootElement = this._element; + + if (element) { + rootElement = this._getRootElement(element); + } + + var customEvent = this._triggerCloseEvent(rootElement); + + if (customEvent.isDefaultPrevented()) { + return; + } + + this._removeElement(rootElement); + }; + + _proto.dispose = function dispose() { + $__default["default"].removeData(this._element, DATA_KEY$a); + this._element = null; + } // Private + ; + + _proto._getRootElement = function _getRootElement(element) { + var selector = Util.getSelectorFromElement(element); + var parent = false; + + if (selector) { + parent = document.querySelector(selector); + } + + if (!parent) { + parent = $__default["default"](element).closest("." + CLASS_NAME_ALERT)[0]; + } + + return parent; + }; + + _proto._triggerCloseEvent = function _triggerCloseEvent(element) { + var closeEvent = $__default["default"].Event(EVENT_CLOSE); + $__default["default"](element).trigger(closeEvent); + return closeEvent; + }; + + _proto._removeElement = function _removeElement(element) { + var _this = this; + + $__default["default"](element).removeClass(CLASS_NAME_SHOW$7); + + if (!$__default["default"](element).hasClass(CLASS_NAME_FADE$5)) { + this._destroyElement(element); + + return; + } + + var transitionDuration = Util.getTransitionDurationFromElement(element); + $__default["default"](element).one(Util.TRANSITION_END, function (event) { + return _this._destroyElement(element, event); + }).emulateTransitionEnd(transitionDuration); + }; + + _proto._destroyElement = function _destroyElement(element) { + $__default["default"](element).detach().trigger(EVENT_CLOSED).remove(); + } // Static + ; + + Alert._jQueryInterface = function _jQueryInterface(config) { + return this.each(function () { + var $element = $__default["default"](this); + var data = $element.data(DATA_KEY$a); + + if (!data) { + data = new Alert(this); + $element.data(DATA_KEY$a, data); + } + + if (config === 'close') { + data[config](this); + } + }); + }; + + Alert._handleDismiss = function _handleDismiss(alertInstance) { + return function (event) { + if (event) { + event.preventDefault(); + } + + alertInstance.close(this); + }; + }; + + _createClass(Alert, null, [{ + key: "VERSION", + get: function get() { + return VERSION$a; + } + }]); + + return Alert; + }(); + /** + * Data API implementation + */ + + + $__default["default"](document).on(EVENT_CLICK_DATA_API$6, SELECTOR_DISMISS, Alert._handleDismiss(new Alert())); + /** + * jQuery + */ + + $__default["default"].fn[NAME$a] = Alert._jQueryInterface; + $__default["default"].fn[NAME$a].Constructor = Alert; + + $__default["default"].fn[NAME$a].noConflict = function () { + $__default["default"].fn[NAME$a] = JQUERY_NO_CONFLICT$a; + return Alert._jQueryInterface; + }; + + /** + * Constants + */ + + var NAME$9 = 'button'; + var VERSION$9 = '4.6.1'; + var DATA_KEY$9 = 'bs.button'; + var EVENT_KEY$9 = "." + DATA_KEY$9; + var DATA_API_KEY$6 = '.data-api'; + var JQUERY_NO_CONFLICT$9 = $__default["default"].fn[NAME$9]; + var CLASS_NAME_ACTIVE$3 = 'active'; + var CLASS_NAME_BUTTON = 'btn'; + var CLASS_NAME_FOCUS = 'focus'; + var EVENT_CLICK_DATA_API$5 = "click" + EVENT_KEY$9 + DATA_API_KEY$6; + var EVENT_FOCUS_BLUR_DATA_API = "focus" + EVENT_KEY$9 + DATA_API_KEY$6 + " " + ("blur" + EVENT_KEY$9 + DATA_API_KEY$6); + var EVENT_LOAD_DATA_API$2 = "load" + EVENT_KEY$9 + DATA_API_KEY$6; + var SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^="button"]'; + var SELECTOR_DATA_TOGGLES = '[data-toggle="buttons"]'; + var SELECTOR_DATA_TOGGLE$4 = '[data-toggle="button"]'; + var SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle="buttons"] .btn'; + var SELECTOR_INPUT = 'input:not([type="hidden"])'; + var SELECTOR_ACTIVE$2 = '.active'; + var SELECTOR_BUTTON = '.btn'; + /** + * Class definition + */ + + var Button = /*#__PURE__*/function () { + function Button(element) { + this._element = element; + this.shouldAvoidTriggerChange = false; + } // Getters + + + var _proto = Button.prototype; + + // Public + _proto.toggle = function toggle() { + var triggerChangeEvent = true; + var addAriaPressed = true; + var rootElement = $__default["default"](this._element).closest(SELECTOR_DATA_TOGGLES)[0]; + + if (rootElement) { + var input = this._element.querySelector(SELECTOR_INPUT); + + if (input) { + if (input.type === 'radio') { + if (input.checked && this._element.classList.contains(CLASS_NAME_ACTIVE$3)) { + triggerChangeEvent = false; + } else { + var activeElement = rootElement.querySelector(SELECTOR_ACTIVE$2); + + if (activeElement) { + $__default["default"](activeElement).removeClass(CLASS_NAME_ACTIVE$3); + } + } + } + + if (triggerChangeEvent) { + // if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input + if (input.type === 'checkbox' || input.type === 'radio') { + input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE$3); + } + + if (!this.shouldAvoidTriggerChange) { + $__default["default"](input).trigger('change'); + } + } + + input.focus(); + addAriaPressed = false; + } + } + + if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) { + if (addAriaPressed) { + this._element.setAttribute('aria-pressed', !this._element.classList.contains(CLASS_NAME_ACTIVE$3)); + } + + if (triggerChangeEvent) { + $__default["default"](this._element).toggleClass(CLASS_NAME_ACTIVE$3); + } + } + }; + + _proto.dispose = function dispose() { + $__default["default"].removeData(this._element, DATA_KEY$9); + this._element = null; + } // Static + ; + + Button._jQueryInterface = function _jQueryInterface(config, avoidTriggerChange) { + return this.each(function () { + var $element = $__default["default"](this); + var data = $element.data(DATA_KEY$9); + + if (!data) { + data = new Button(this); + $element.data(DATA_KEY$9, data); + } + + data.shouldAvoidTriggerChange = avoidTriggerChange; + + if (config === 'toggle') { + data[config](); + } + }); + }; + + _createClass(Button, null, [{ + key: "VERSION", + get: function get() { + return VERSION$9; + } + }]); + + return Button; + }(); + /** + * Data API implementation + */ + + + $__default["default"](document).on(EVENT_CLICK_DATA_API$5, SELECTOR_DATA_TOGGLE_CARROT, function (event) { + var button = event.target; + var initialButton = button; + + if (!$__default["default"](button).hasClass(CLASS_NAME_BUTTON)) { + button = $__default["default"](button).closest(SELECTOR_BUTTON)[0]; + } + + if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) { + event.preventDefault(); // work around Firefox bug #1540995 + } else { + var inputBtn = button.querySelector(SELECTOR_INPUT); + + if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) { + event.preventDefault(); // work around Firefox bug #1540995 + + return; + } + + if (initialButton.tagName === 'INPUT' || button.tagName !== 'LABEL') { + Button._jQueryInterface.call($__default["default"](button), 'toggle', initialButton.tagName === 'INPUT'); + } + } + }).on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, function (event) { + var button = $__default["default"](event.target).closest(SELECTOR_BUTTON)[0]; + $__default["default"](button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type)); + }); + $__default["default"](window).on(EVENT_LOAD_DATA_API$2, function () { + // ensure correct active class is set to match the controls' actual values/states + // find all checkboxes/readio buttons inside data-toggle groups + var buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS)); + + for (var i = 0, len = buttons.length; i < len; i++) { + var button = buttons[i]; + var input = button.querySelector(SELECTOR_INPUT); + + if (input.checked || input.hasAttribute('checked')) { + button.classList.add(CLASS_NAME_ACTIVE$3); + } else { + button.classList.remove(CLASS_NAME_ACTIVE$3); + } + } // find all button toggles + + + buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE$4)); + + for (var _i = 0, _len = buttons.length; _i < _len; _i++) { + var _button = buttons[_i]; + + if (_button.getAttribute('aria-pressed') === 'true') { + _button.classList.add(CLASS_NAME_ACTIVE$3); + } else { + _button.classList.remove(CLASS_NAME_ACTIVE$3); + } + } + }); + /** + * jQuery + */ + + $__default["default"].fn[NAME$9] = Button._jQueryInterface; + $__default["default"].fn[NAME$9].Constructor = Button; + + $__default["default"].fn[NAME$9].noConflict = function () { + $__default["default"].fn[NAME$9] = JQUERY_NO_CONFLICT$9; + return Button._jQueryInterface; + }; + + /** + * Constants + */ + + var NAME$8 = 'carousel'; + var VERSION$8 = '4.6.1'; + var DATA_KEY$8 = 'bs.carousel'; + var EVENT_KEY$8 = "." + DATA_KEY$8; + var DATA_API_KEY$5 = '.data-api'; + var JQUERY_NO_CONFLICT$8 = $__default["default"].fn[NAME$8]; + var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key + + var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key + + var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch + + var SWIPE_THRESHOLD = 40; + var CLASS_NAME_CAROUSEL = 'carousel'; + var CLASS_NAME_ACTIVE$2 = 'active'; + var CLASS_NAME_SLIDE = 'slide'; + var CLASS_NAME_RIGHT = 'carousel-item-right'; + var CLASS_NAME_LEFT = 'carousel-item-left'; + var CLASS_NAME_NEXT = 'carousel-item-next'; + var CLASS_NAME_PREV = 'carousel-item-prev'; + var CLASS_NAME_POINTER_EVENT = 'pointer-event'; + var DIRECTION_NEXT = 'next'; + var DIRECTION_PREV = 'prev'; + var DIRECTION_LEFT = 'left'; + var DIRECTION_RIGHT = 'right'; + var EVENT_SLIDE = "slide" + EVENT_KEY$8; + var EVENT_SLID = "slid" + EVENT_KEY$8; + var EVENT_KEYDOWN = "keydown" + EVENT_KEY$8; + var EVENT_MOUSEENTER = "mouseenter" + EVENT_KEY$8; + var EVENT_MOUSELEAVE = "mouseleave" + EVENT_KEY$8; + var EVENT_TOUCHSTART = "touchstart" + EVENT_KEY$8; + var EVENT_TOUCHMOVE = "touchmove" + EVENT_KEY$8; + var EVENT_TOUCHEND = "touchend" + EVENT_KEY$8; + var EVENT_POINTERDOWN = "pointerdown" + EVENT_KEY$8; + var EVENT_POINTERUP = "pointerup" + EVENT_KEY$8; + var EVENT_DRAG_START = "dragstart" + EVENT_KEY$8; + var EVENT_LOAD_DATA_API$1 = "load" + EVENT_KEY$8 + DATA_API_KEY$5; + var EVENT_CLICK_DATA_API$4 = "click" + EVENT_KEY$8 + DATA_API_KEY$5; + var SELECTOR_ACTIVE$1 = '.active'; + var SELECTOR_ACTIVE_ITEM = '.active.carousel-item'; + var SELECTOR_ITEM = '.carousel-item'; + var SELECTOR_ITEM_IMG = '.carousel-item img'; + var SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev'; + var SELECTOR_INDICATORS = '.carousel-indicators'; + var SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]'; + var SELECTOR_DATA_RIDE = '[data-ride="carousel"]'; + var Default$7 = { + interval: 5000, + keyboard: true, + slide: false, + pause: 'hover', + wrap: true, + touch: true + }; + var DefaultType$7 = { + interval: '(number|boolean)', + keyboard: 'boolean', + slide: '(boolean|string)', + pause: '(string|boolean)', + wrap: 'boolean', + touch: 'boolean' + }; + var PointerType = { + TOUCH: 'touch', + PEN: 'pen' + }; + /** + * Class definition + */ + + var Carousel = /*#__PURE__*/function () { + function Carousel(element, config) { + this._items = null; + this._interval = null; + this._activeElement = null; + this._isPaused = false; + this._isSliding = false; + this.touchTimeout = null; + this.touchStartX = 0; + this.touchDeltaX = 0; + this._config = this._getConfig(config); + this._element = element; + this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS); + this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0; + this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent); + + this._addEventListeners(); + } // Getters + + + var _proto = Carousel.prototype; + + // Public + _proto.next = function next() { + if (!this._isSliding) { + this._slide(DIRECTION_NEXT); + } + }; + + _proto.nextWhenVisible = function nextWhenVisible() { + var $element = $__default["default"](this._element); // Don't call next when the page isn't visible + // or the carousel or its parent isn't visible + + if (!document.hidden && $element.is(':visible') && $element.css('visibility') !== 'hidden') { + this.next(); + } + }; + + _proto.prev = function prev() { + if (!this._isSliding) { + this._slide(DIRECTION_PREV); + } + }; + + _proto.pause = function pause(event) { + if (!event) { + this._isPaused = true; + } + + if (this._element.querySelector(SELECTOR_NEXT_PREV)) { + Util.triggerTransitionEnd(this._element); + this.cycle(true); + } + + clearInterval(this._interval); + this._interval = null; + }; + + _proto.cycle = function cycle(event) { + if (!event) { + this._isPaused = false; + } + + if (this._interval) { + clearInterval(this._interval); + this._interval = null; + } + + if (this._config.interval && !this._isPaused) { + this._updateInterval(); + + this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval); + } + }; + + _proto.to = function to(index) { + var _this = this; + + this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM); + + var activeIndex = this._getItemIndex(this._activeElement); + + if (index > this._items.length - 1 || index < 0) { + return; + } + + if (this._isSliding) { + $__default["default"](this._element).one(EVENT_SLID, function () { + return _this.to(index); + }); + return; + } + + if (activeIndex === index) { + this.pause(); + this.cycle(); + return; + } + + var direction = index > activeIndex ? DIRECTION_NEXT : DIRECTION_PREV; + + this._slide(direction, this._items[index]); + }; + + _proto.dispose = function dispose() { + $__default["default"](this._element).off(EVENT_KEY$8); + $__default["default"].removeData(this._element, DATA_KEY$8); + this._items = null; + this._config = null; + this._element = null; + this._interval = null; + this._isPaused = null; + this._isSliding = null; + this._activeElement = null; + this._indicatorsElement = null; + } // Private + ; + + _proto._getConfig = function _getConfig(config) { + config = _extends$1({}, Default$7, config); + Util.typeCheckConfig(NAME$8, config, DefaultType$7); + return config; + }; + + _proto._handleSwipe = function _handleSwipe() { + var absDeltax = Math.abs(this.touchDeltaX); + + if (absDeltax <= SWIPE_THRESHOLD) { + return; + } + + var direction = absDeltax / this.touchDeltaX; + this.touchDeltaX = 0; // swipe left + + if (direction > 0) { + this.prev(); + } // swipe right + + + if (direction < 0) { + this.next(); + } + }; + + _proto._addEventListeners = function _addEventListeners() { + var _this2 = this; + + if (this._config.keyboard) { + $__default["default"](this._element).on(EVENT_KEYDOWN, function (event) { + return _this2._keydown(event); + }); + } + + if (this._config.pause === 'hover') { + $__default["default"](this._element).on(EVENT_MOUSEENTER, function (event) { + return _this2.pause(event); + }).on(EVENT_MOUSELEAVE, function (event) { + return _this2.cycle(event); + }); + } + + if (this._config.touch) { + this._addTouchEventListeners(); + } + }; + + _proto._addTouchEventListeners = function _addTouchEventListeners() { + var _this3 = this; + + if (!this._touchSupported) { + return; + } + + var start = function start(event) { + if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) { + _this3.touchStartX = event.originalEvent.clientX; + } else if (!_this3._pointerEvent) { + _this3.touchStartX = event.originalEvent.touches[0].clientX; + } + }; + + var move = function move(event) { + // ensure swiping with one touch and not pinching + _this3.touchDeltaX = event.originalEvent.touches && event.originalEvent.touches.length > 1 ? 0 : event.originalEvent.touches[0].clientX - _this3.touchStartX; + }; + + var end = function end(event) { + if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) { + _this3.touchDeltaX = event.originalEvent.clientX - _this3.touchStartX; + } + + _this3._handleSwipe(); + + if (_this3._config.pause === 'hover') { + // If it's a touch-enabled device, mouseenter/leave are fired as + // part of the mouse compatibility events on first tap - the carousel + // would stop cycling until user tapped out of it; + // here, we listen for touchend, explicitly pause the carousel + // (as if it's the second time we tap on it, mouseenter compat event + // is NOT fired) and after a timeout (to allow for mouse compatibility + // events to fire) we explicitly restart cycling + _this3.pause(); + + if (_this3.touchTimeout) { + clearTimeout(_this3.touchTimeout); + } + + _this3.touchTimeout = setTimeout(function (event) { + return _this3.cycle(event); + }, TOUCHEVENT_COMPAT_WAIT + _this3._config.interval); + } + }; + + $__default["default"](this._element.querySelectorAll(SELECTOR_ITEM_IMG)).on(EVENT_DRAG_START, function (e) { + return e.preventDefault(); + }); + + if (this._pointerEvent) { + $__default["default"](this._element).on(EVENT_POINTERDOWN, function (event) { + return start(event); + }); + $__default["default"](this._element).on(EVENT_POINTERUP, function (event) { + return end(event); + }); + + this._element.classList.add(CLASS_NAME_POINTER_EVENT); + } else { + $__default["default"](this._element).on(EVENT_TOUCHSTART, function (event) { + return start(event); + }); + $__default["default"](this._element).on(EVENT_TOUCHMOVE, function (event) { + return move(event); + }); + $__default["default"](this._element).on(EVENT_TOUCHEND, function (event) { + return end(event); + }); + } + }; + + _proto._keydown = function _keydown(event) { + if (/input|textarea/i.test(event.target.tagName)) { + return; + } + + switch (event.which) { + case ARROW_LEFT_KEYCODE: + event.preventDefault(); + this.prev(); + break; + + case ARROW_RIGHT_KEYCODE: + event.preventDefault(); + this.next(); + break; + } + }; + + _proto._getItemIndex = function _getItemIndex(element) { + this._items = element && element.parentNode ? [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) : []; + return this._items.indexOf(element); + }; + + _proto._getItemByDirection = function _getItemByDirection(direction, activeElement) { + var isNextDirection = direction === DIRECTION_NEXT; + var isPrevDirection = direction === DIRECTION_PREV; + + var activeIndex = this._getItemIndex(activeElement); + + var lastItemIndex = this._items.length - 1; + var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex; + + if (isGoingToWrap && !this._config.wrap) { + return activeElement; + } + + var delta = direction === DIRECTION_PREV ? -1 : 1; + var itemIndex = (activeIndex + delta) % this._items.length; + return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex]; + }; + + _proto._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) { + var targetIndex = this._getItemIndex(relatedTarget); + + var fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM)); + + var slideEvent = $__default["default"].Event(EVENT_SLIDE, { + relatedTarget: relatedTarget, + direction: eventDirectionName, + from: fromIndex, + to: targetIndex + }); + $__default["default"](this._element).trigger(slideEvent); + return slideEvent; + }; + + _proto._setActiveIndicatorElement = function _setActiveIndicatorElement(element) { + if (this._indicatorsElement) { + var indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE$1)); + $__default["default"](indicators).removeClass(CLASS_NAME_ACTIVE$2); + + var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)]; + + if (nextIndicator) { + $__default["default"](nextIndicator).addClass(CLASS_NAME_ACTIVE$2); + } + } + }; + + _proto._updateInterval = function _updateInterval() { + var element = this._activeElement || this._element.querySelector(SELECTOR_ACTIVE_ITEM); + + if (!element) { + return; + } + + var elementInterval = parseInt(element.getAttribute('data-interval'), 10); + + if (elementInterval) { + this._config.defaultInterval = this._config.defaultInterval || this._config.interval; + this._config.interval = elementInterval; + } else { + this._config.interval = this._config.defaultInterval || this._config.interval; + } + }; + + _proto._slide = function _slide(direction, element) { + var _this4 = this; + + var activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM); + + var activeElementIndex = this._getItemIndex(activeElement); + + var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement); + + var nextElementIndex = this._getItemIndex(nextElement); + + var isCycling = Boolean(this._interval); + var directionalClassName; + var orderClassName; + var eventDirectionName; + + if (direction === DIRECTION_NEXT) { + directionalClassName = CLASS_NAME_LEFT; + orderClassName = CLASS_NAME_NEXT; + eventDirectionName = DIRECTION_LEFT; + } else { + directionalClassName = CLASS_NAME_RIGHT; + orderClassName = CLASS_NAME_PREV; + eventDirectionName = DIRECTION_RIGHT; + } + + if (nextElement && $__default["default"](nextElement).hasClass(CLASS_NAME_ACTIVE$2)) { + this._isSliding = false; + return; + } + + var slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName); + + if (slideEvent.isDefaultPrevented()) { + return; + } + + if (!activeElement || !nextElement) { + // Some weirdness is happening, so we bail + return; + } + + this._isSliding = true; + + if (isCycling) { + this.pause(); + } + + this._setActiveIndicatorElement(nextElement); + + this._activeElement = nextElement; + var slidEvent = $__default["default"].Event(EVENT_SLID, { + relatedTarget: nextElement, + direction: eventDirectionName, + from: activeElementIndex, + to: nextElementIndex + }); + + if ($__default["default"](this._element).hasClass(CLASS_NAME_SLIDE)) { + $__default["default"](nextElement).addClass(orderClassName); + Util.reflow(nextElement); + $__default["default"](activeElement).addClass(directionalClassName); + $__default["default"](nextElement).addClass(directionalClassName); + var transitionDuration = Util.getTransitionDurationFromElement(activeElement); + $__default["default"](activeElement).one(Util.TRANSITION_END, function () { + $__default["default"](nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(CLASS_NAME_ACTIVE$2); + $__default["default"](activeElement).removeClass(CLASS_NAME_ACTIVE$2 + " " + orderClassName + " " + directionalClassName); + _this4._isSliding = false; + setTimeout(function () { + return $__default["default"](_this4._element).trigger(slidEvent); + }, 0); + }).emulateTransitionEnd(transitionDuration); + } else { + $__default["default"](activeElement).removeClass(CLASS_NAME_ACTIVE$2); + $__default["default"](nextElement).addClass(CLASS_NAME_ACTIVE$2); + this._isSliding = false; + $__default["default"](this._element).trigger(slidEvent); + } + + if (isCycling) { + this.cycle(); + } + } // Static + ; + + Carousel._jQueryInterface = function _jQueryInterface(config) { + return this.each(function () { + var data = $__default["default"](this).data(DATA_KEY$8); + + var _config = _extends$1({}, Default$7, $__default["default"](this).data()); + + if (typeof config === 'object') { + _config = _extends$1({}, _config, config); + } + + var action = typeof config === 'string' ? config : _config.slide; + + if (!data) { + data = new Carousel(this, _config); + $__default["default"](this).data(DATA_KEY$8, data); + } + + if (typeof config === 'number') { + data.to(config); + } else if (typeof action === 'string') { + if (typeof data[action] === 'undefined') { + throw new TypeError("No method named \"" + action + "\""); + } + + data[action](); + } else if (_config.interval && _config.ride) { + data.pause(); + data.cycle(); + } + }); + }; + + Carousel._dataApiClickHandler = function _dataApiClickHandler(event) { + var selector = Util.getSelectorFromElement(this); + + if (!selector) { + return; + } + + var target = $__default["default"](selector)[0]; + + if (!target || !$__default["default"](target).hasClass(CLASS_NAME_CAROUSEL)) { + return; + } + + var config = _extends$1({}, $__default["default"](target).data(), $__default["default"](this).data()); + + var slideIndex = this.getAttribute('data-slide-to'); + + if (slideIndex) { + config.interval = false; + } + + Carousel._jQueryInterface.call($__default["default"](target), config); + + if (slideIndex) { + $__default["default"](target).data(DATA_KEY$8).to(slideIndex); + } + + event.preventDefault(); + }; + + _createClass(Carousel, null, [{ + key: "VERSION", + get: function get() { + return VERSION$8; + } + }, { + key: "Default", + get: function get() { + return Default$7; + } + }]); + + return Carousel; + }(); + /** + * Data API implementation + */ + + + $__default["default"](document).on(EVENT_CLICK_DATA_API$4, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler); + $__default["default"](window).on(EVENT_LOAD_DATA_API$1, function () { + var carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE)); + + for (var i = 0, len = carousels.length; i < len; i++) { + var $carousel = $__default["default"](carousels[i]); + + Carousel._jQueryInterface.call($carousel, $carousel.data()); + } + }); + /** + * jQuery + */ + + $__default["default"].fn[NAME$8] = Carousel._jQueryInterface; + $__default["default"].fn[NAME$8].Constructor = Carousel; + + $__default["default"].fn[NAME$8].noConflict = function () { + $__default["default"].fn[NAME$8] = JQUERY_NO_CONFLICT$8; + return Carousel._jQueryInterface; + }; + + /** + * Constants + */ + + var NAME$7 = 'collapse'; + var VERSION$7 = '4.6.1'; + var DATA_KEY$7 = 'bs.collapse'; + var EVENT_KEY$7 = "." + DATA_KEY$7; + var DATA_API_KEY$4 = '.data-api'; + var JQUERY_NO_CONFLICT$7 = $__default["default"].fn[NAME$7]; + var CLASS_NAME_SHOW$6 = 'show'; + var CLASS_NAME_COLLAPSE = 'collapse'; + var CLASS_NAME_COLLAPSING = 'collapsing'; + var CLASS_NAME_COLLAPSED = 'collapsed'; + var DIMENSION_WIDTH = 'width'; + var DIMENSION_HEIGHT = 'height'; + var EVENT_SHOW$4 = "show" + EVENT_KEY$7; + var EVENT_SHOWN$4 = "shown" + EVENT_KEY$7; + var EVENT_HIDE$4 = "hide" + EVENT_KEY$7; + var EVENT_HIDDEN$4 = "hidden" + EVENT_KEY$7; + var EVENT_CLICK_DATA_API$3 = "click" + EVENT_KEY$7 + DATA_API_KEY$4; + var SELECTOR_ACTIVES = '.show, .collapsing'; + var SELECTOR_DATA_TOGGLE$3 = '[data-toggle="collapse"]'; + var Default$6 = { + toggle: true, + parent: '' + }; + var DefaultType$6 = { + toggle: 'boolean', + parent: '(string|element)' + }; + /** + * Class definition + */ + + var Collapse = /*#__PURE__*/function () { + function Collapse(element, config) { + this._isTransitioning = false; + this._element = element; + this._config = this._getConfig(config); + this._triggerArray = [].slice.call(document.querySelectorAll("[data-toggle=\"collapse\"][href=\"#" + element.id + "\"]," + ("[data-toggle=\"collapse\"][data-target=\"#" + element.id + "\"]"))); + var toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE$3)); + + for (var i = 0, len = toggleList.length; i < len; i++) { + var elem = toggleList[i]; + var selector = Util.getSelectorFromElement(elem); + var filterElement = [].slice.call(document.querySelectorAll(selector)).filter(function (foundElem) { + return foundElem === element; + }); + + if (selector !== null && filterElement.length > 0) { + this._selector = selector; + + this._triggerArray.push(elem); + } + } + + this._parent = this._config.parent ? this._getParent() : null; + + if (!this._config.parent) { + this._addAriaAndCollapsedClass(this._element, this._triggerArray); + } + + if (this._config.toggle) { + this.toggle(); + } + } // Getters + + + var _proto = Collapse.prototype; + + // Public + _proto.toggle = function toggle() { + if ($__default["default"](this._element).hasClass(CLASS_NAME_SHOW$6)) { + this.hide(); + } else { + this.show(); + } + }; + + _proto.show = function show() { + var _this = this; + + if (this._isTransitioning || $__default["default"](this._element).hasClass(CLASS_NAME_SHOW$6)) { + return; + } + + var actives; + var activesData; + + if (this._parent) { + actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES)).filter(function (elem) { + if (typeof _this._config.parent === 'string') { + return elem.getAttribute('data-parent') === _this._config.parent; + } + + return elem.classList.contains(CLASS_NAME_COLLAPSE); + }); + + if (actives.length === 0) { + actives = null; + } + } + + if (actives) { + activesData = $__default["default"](actives).not(this._selector).data(DATA_KEY$7); + + if (activesData && activesData._isTransitioning) { + return; + } + } + + var startEvent = $__default["default"].Event(EVENT_SHOW$4); + $__default["default"](this._element).trigger(startEvent); + + if (startEvent.isDefaultPrevented()) { + return; + } + + if (actives) { + Collapse._jQueryInterface.call($__default["default"](actives).not(this._selector), 'hide'); + + if (!activesData) { + $__default["default"](actives).data(DATA_KEY$7, null); + } + } + + var dimension = this._getDimension(); + + $__default["default"](this._element).removeClass(CLASS_NAME_COLLAPSE).addClass(CLASS_NAME_COLLAPSING); + this._element.style[dimension] = 0; + + if (this._triggerArray.length) { + $__default["default"](this._triggerArray).removeClass(CLASS_NAME_COLLAPSED).attr('aria-expanded', true); + } + + this.setTransitioning(true); + + var complete = function complete() { + $__default["default"](_this._element).removeClass(CLASS_NAME_COLLAPSING).addClass(CLASS_NAME_COLLAPSE + " " + CLASS_NAME_SHOW$6); + _this._element.style[dimension] = ''; + + _this.setTransitioning(false); + + $__default["default"](_this._element).trigger(EVENT_SHOWN$4); + }; + + var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1); + var scrollSize = "scroll" + capitalizedDimension; + var transitionDuration = Util.getTransitionDurationFromElement(this._element); + $__default["default"](this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); + this._element.style[dimension] = this._element[scrollSize] + "px"; + }; + + _proto.hide = function hide() { + var _this2 = this; + + if (this._isTransitioning || !$__default["default"](this._element).hasClass(CLASS_NAME_SHOW$6)) { + return; + } + + var startEvent = $__default["default"].Event(EVENT_HIDE$4); + $__default["default"](this._element).trigger(startEvent); + + if (startEvent.isDefaultPrevented()) { + return; + } + + var dimension = this._getDimension(); + + this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px"; + Util.reflow(this._element); + $__default["default"](this._element).addClass(CLASS_NAME_COLLAPSING).removeClass(CLASS_NAME_COLLAPSE + " " + CLASS_NAME_SHOW$6); + var triggerArrayLength = this._triggerArray.length; + + if (triggerArrayLength > 0) { + for (var i = 0; i < triggerArrayLength; i++) { + var trigger = this._triggerArray[i]; + var selector = Util.getSelectorFromElement(trigger); + + if (selector !== null) { + var $elem = $__default["default"]([].slice.call(document.querySelectorAll(selector))); + + if (!$elem.hasClass(CLASS_NAME_SHOW$6)) { + $__default["default"](trigger).addClass(CLASS_NAME_COLLAPSED).attr('aria-expanded', false); + } + } + } + } + + this.setTransitioning(true); + + var complete = function complete() { + _this2.setTransitioning(false); + + $__default["default"](_this2._element).removeClass(CLASS_NAME_COLLAPSING).addClass(CLASS_NAME_COLLAPSE).trigger(EVENT_HIDDEN$4); + }; + + this._element.style[dimension] = ''; + var transitionDuration = Util.getTransitionDurationFromElement(this._element); + $__default["default"](this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); + }; + + _proto.setTransitioning = function setTransitioning(isTransitioning) { + this._isTransitioning = isTransitioning; + }; + + _proto.dispose = function dispose() { + $__default["default"].removeData(this._element, DATA_KEY$7); + this._config = null; + this._parent = null; + this._element = null; + this._triggerArray = null; + this._isTransitioning = null; + } // Private + ; + + _proto._getConfig = function _getConfig(config) { + config = _extends$1({}, Default$6, config); + config.toggle = Boolean(config.toggle); // Coerce string values + + Util.typeCheckConfig(NAME$7, config, DefaultType$6); + return config; + }; + + _proto._getDimension = function _getDimension() { + var hasWidth = $__default["default"](this._element).hasClass(DIMENSION_WIDTH); + return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT; + }; + + _proto._getParent = function _getParent() { + var _this3 = this; + + var parent; + + if (Util.isElement(this._config.parent)) { + parent = this._config.parent; // It's a jQuery object + + if (typeof this._config.parent.jquery !== 'undefined') { + parent = this._config.parent[0]; + } + } else { + parent = document.querySelector(this._config.parent); + } + + var selector = "[data-toggle=\"collapse\"][data-parent=\"" + this._config.parent + "\"]"; + var children = [].slice.call(parent.querySelectorAll(selector)); + $__default["default"](children).each(function (i, element) { + _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]); + }); + return parent; + }; + + _proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) { + var isOpen = $__default["default"](element).hasClass(CLASS_NAME_SHOW$6); + + if (triggerArray.length) { + $__default["default"](triggerArray).toggleClass(CLASS_NAME_COLLAPSED, !isOpen).attr('aria-expanded', isOpen); + } + } // Static + ; + + Collapse._getTargetFromElement = function _getTargetFromElement(element) { + var selector = Util.getSelectorFromElement(element); + return selector ? document.querySelector(selector) : null; + }; + + Collapse._jQueryInterface = function _jQueryInterface(config) { + return this.each(function () { + var $element = $__default["default"](this); + var data = $element.data(DATA_KEY$7); + + var _config = _extends$1({}, Default$6, $element.data(), typeof config === 'object' && config ? config : {}); + + if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) { + _config.toggle = false; + } + + if (!data) { + data = new Collapse(this, _config); + $element.data(DATA_KEY$7, data); + } + + if (typeof config === 'string') { + if (typeof data[config] === 'undefined') { + throw new TypeError("No method named \"" + config + "\""); + } + + data[config](); + } + }); + }; + + _createClass(Collapse, null, [{ + key: "VERSION", + get: function get() { + return VERSION$7; + } + }, { + key: "Default", + get: function get() { + return Default$6; + } + }]); + + return Collapse; + }(); + /** + * Data API implementation + */ + + + $__default["default"](document).on(EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$3, function (event) { + // preventDefault only for elements (which change the URL) not inside the collapsible element + if (event.currentTarget.tagName === 'A') { + event.preventDefault(); + } + + var $trigger = $__default["default"](this); + var selector = Util.getSelectorFromElement(this); + var selectors = [].slice.call(document.querySelectorAll(selector)); + $__default["default"](selectors).each(function () { + var $target = $__default["default"](this); + var data = $target.data(DATA_KEY$7); + var config = data ? 'toggle' : $trigger.data(); + + Collapse._jQueryInterface.call($target, config); + }); + }); + /** + * jQuery + */ + + $__default["default"].fn[NAME$7] = Collapse._jQueryInterface; + $__default["default"].fn[NAME$7].Constructor = Collapse; + + $__default["default"].fn[NAME$7].noConflict = function () { + $__default["default"].fn[NAME$7] = JQUERY_NO_CONFLICT$7; + return Collapse._jQueryInterface; + }; + + /**! + * @fileOverview Kickass library to create and place poppers near their reference elements. + * @version 1.16.1 + * @license + * Copyright (c) 2016 Federico Zivolo and contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined'; + + var timeoutDuration = function () { + var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox']; + for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) { + if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) { + return 1; + } + } + return 0; + }(); + + function microtaskDebounce(fn) { + var called = false; + return function () { + if (called) { + return; + } + called = true; + window.Promise.resolve().then(function () { + called = false; + fn(); + }); + }; + } + + function taskDebounce(fn) { + var scheduled = false; + return function () { + if (!scheduled) { + scheduled = true; + setTimeout(function () { + scheduled = false; + fn(); + }, timeoutDuration); + } + }; + } + + var supportsMicroTasks = isBrowser && window.Promise; + + /** + * Create a debounced version of a method, that's asynchronously deferred + * but called in the minimum time possible. + * + * @method + * @memberof Popper.Utils + * @argument {Function} fn + * @returns {Function} + */ + var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce; + + /** + * Check if the given variable is a function + * @method + * @memberof Popper.Utils + * @argument {Any} functionToCheck - variable to check + * @returns {Boolean} answer to: is a function? + */ + function isFunction(functionToCheck) { + var getType = {}; + return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; + } + + /** + * Get CSS computed property of the given element + * @method + * @memberof Popper.Utils + * @argument {Eement} element + * @argument {String} property + */ + function getStyleComputedProperty(element, property) { + if (element.nodeType !== 1) { + return []; + } + // NOTE: 1 DOM access here + var window = element.ownerDocument.defaultView; + var css = window.getComputedStyle(element, null); + return property ? css[property] : css; + } + + /** + * Returns the parentNode or the host of the element + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @returns {Element} parent + */ + function getParentNode(element) { + if (element.nodeName === 'HTML') { + return element; + } + return element.parentNode || element.host; + } + + /** + * Returns the scrolling parent of the given element + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @returns {Element} scroll parent + */ + function getScrollParent(element) { + // Return body, `getScroll` will take care to get the correct `scrollTop` from it + if (!element) { + return document.body; + } + + switch (element.nodeName) { + case 'HTML': + case 'BODY': + return element.ownerDocument.body; + case '#document': + return element.body; + } + + // Firefox want us to check `-x` and `-y` variations as well + + var _getStyleComputedProp = getStyleComputedProperty(element), + overflow = _getStyleComputedProp.overflow, + overflowX = _getStyleComputedProp.overflowX, + overflowY = _getStyleComputedProp.overflowY; + + if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) { + return element; + } + + return getScrollParent(getParentNode(element)); + } + + /** + * Returns the reference node of the reference object, or the reference object itself. + * @method + * @memberof Popper.Utils + * @param {Element|Object} reference - the reference element (the popper will be relative to this) + * @returns {Element} parent + */ + function getReferenceNode(reference) { + return reference && reference.referenceNode ? reference.referenceNode : reference; + } + + var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode); + var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent); + + /** + * Determines if the browser is Internet Explorer + * @method + * @memberof Popper.Utils + * @param {Number} version to check + * @returns {Boolean} isIE + */ + function isIE(version) { + if (version === 11) { + return isIE11; + } + if (version === 10) { + return isIE10; + } + return isIE11 || isIE10; + } + + /** + * Returns the offset parent of the given element + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @returns {Element} offset parent + */ + function getOffsetParent(element) { + if (!element) { + return document.documentElement; + } + + var noOffsetParent = isIE(10) ? document.body : null; + + // NOTE: 1 DOM access here + var offsetParent = element.offsetParent || null; + // Skip hidden elements which don't have an offsetParent + while (offsetParent === noOffsetParent && element.nextElementSibling) { + offsetParent = (element = element.nextElementSibling).offsetParent; + } + + var nodeName = offsetParent && offsetParent.nodeName; + + if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') { + return element ? element.ownerDocument.documentElement : document.documentElement; + } + + // .offsetParent will return the closest TH, TD or TABLE in case + // no offsetParent is present, I hate this job... + if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') { + return getOffsetParent(offsetParent); + } + + return offsetParent; + } + + function isOffsetContainer(element) { + var nodeName = element.nodeName; + + if (nodeName === 'BODY') { + return false; + } + return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element; + } + + /** + * Finds the root node (document, shadowDOM root) of the given element + * @method + * @memberof Popper.Utils + * @argument {Element} node + * @returns {Element} root node + */ + function getRoot(node) { + if (node.parentNode !== null) { + return getRoot(node.parentNode); + } + + return node; + } + + /** + * Finds the offset parent common to the two provided nodes + * @method + * @memberof Popper.Utils + * @argument {Element} element1 + * @argument {Element} element2 + * @returns {Element} common offset parent + */ + function findCommonOffsetParent(element1, element2) { + // This check is needed to avoid errors in case one of the elements isn't defined for any reason + if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) { + return document.documentElement; + } + + // Here we make sure to give as "start" the element that comes first in the DOM + var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING; + var start = order ? element1 : element2; + var end = order ? element2 : element1; + + // Get common ancestor container + var range = document.createRange(); + range.setStart(start, 0); + range.setEnd(end, 0); + var commonAncestorContainer = range.commonAncestorContainer; + + // Both nodes are inside #document + + if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) { + if (isOffsetContainer(commonAncestorContainer)) { + return commonAncestorContainer; + } + + return getOffsetParent(commonAncestorContainer); + } + + // one of the nodes is inside shadowDOM, find which one + var element1root = getRoot(element1); + if (element1root.host) { + return findCommonOffsetParent(element1root.host, element2); + } else { + return findCommonOffsetParent(element1, getRoot(element2).host); + } + } + + /** + * Gets the scroll value of the given element in the given side (top and left) + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @argument {String} side `top` or `left` + * @returns {number} amount of scrolled pixels + */ + function getScroll(element) { + var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top'; + + var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft'; + var nodeName = element.nodeName; + + if (nodeName === 'BODY' || nodeName === 'HTML') { + var html = element.ownerDocument.documentElement; + var scrollingElement = element.ownerDocument.scrollingElement || html; + return scrollingElement[upperSide]; + } + + return element[upperSide]; + } + + /* + * Sum or subtract the element scroll values (left and top) from a given rect object + * @method + * @memberof Popper.Utils + * @param {Object} rect - Rect object you want to change + * @param {HTMLElement} element - The element from the function reads the scroll values + * @param {Boolean} subtract - set to true if you want to subtract the scroll values + * @return {Object} rect - The modifier rect object + */ + function includeScroll(rect, element) { + var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + var scrollTop = getScroll(element, 'top'); + var scrollLeft = getScroll(element, 'left'); + var modifier = subtract ? -1 : 1; + rect.top += scrollTop * modifier; + rect.bottom += scrollTop * modifier; + rect.left += scrollLeft * modifier; + rect.right += scrollLeft * modifier; + return rect; + } + + /* + * Helper to detect borders of a given element + * @method + * @memberof Popper.Utils + * @param {CSSStyleDeclaration} styles + * Result of `getStyleComputedProperty` on the given element + * @param {String} axis - `x` or `y` + * @return {number} borders - The borders size of the given axis + */ + + function getBordersSize(styles, axis) { + var sideA = axis === 'x' ? 'Left' : 'Top'; + var sideB = sideA === 'Left' ? 'Right' : 'Bottom'; + + return parseFloat(styles['border' + sideA + 'Width']) + parseFloat(styles['border' + sideB + 'Width']); + } + + function getSize(axis, body, html, computedStyle) { + return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0); + } + + function getWindowSizes(document) { + var body = document.body; + var html = document.documentElement; + var computedStyle = isIE(10) && getComputedStyle(html); + + return { + height: getSize('Height', body, html, computedStyle), + width: getSize('Width', body, html, computedStyle) + }; + } + + var classCallCheck = function (instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + }; + + var createClass = function () { + function defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + return function (Constructor, protoProps, staticProps) { + if (protoProps) defineProperties(Constructor.prototype, protoProps); + if (staticProps) defineProperties(Constructor, staticProps); + return Constructor; + }; + }(); + + + + + + var defineProperty = function (obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; + }; + + var _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + /** + * Given element offsets, generate an output similar to getBoundingClientRect + * @method + * @memberof Popper.Utils + * @argument {Object} offsets + * @returns {Object} ClientRect like output + */ + function getClientRect(offsets) { + return _extends({}, offsets, { + right: offsets.left + offsets.width, + bottom: offsets.top + offsets.height + }); + } + + /** + * Get bounding client rect of given element + * @method + * @memberof Popper.Utils + * @param {HTMLElement} element + * @return {Object} client rect + */ + function getBoundingClientRect(element) { + var rect = {}; + + // IE10 10 FIX: Please, don't ask, the element isn't + // considered in DOM in some circumstances... + // This isn't reproducible in IE10 compatibility mode of IE11 + try { + if (isIE(10)) { + rect = element.getBoundingClientRect(); + var scrollTop = getScroll(element, 'top'); + var scrollLeft = getScroll(element, 'left'); + rect.top += scrollTop; + rect.left += scrollLeft; + rect.bottom += scrollTop; + rect.right += scrollLeft; + } else { + rect = element.getBoundingClientRect(); + } + } catch (e) {} + + var result = { + left: rect.left, + top: rect.top, + width: rect.right - rect.left, + height: rect.bottom - rect.top + }; + + // subtract scrollbar size from sizes + var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {}; + var width = sizes.width || element.clientWidth || result.width; + var height = sizes.height || element.clientHeight || result.height; + + var horizScrollbar = element.offsetWidth - width; + var vertScrollbar = element.offsetHeight - height; + + // if an hypothetical scrollbar is detected, we must be sure it's not a `border` + // we make this check conditional for performance reasons + if (horizScrollbar || vertScrollbar) { + var styles = getStyleComputedProperty(element); + horizScrollbar -= getBordersSize(styles, 'x'); + vertScrollbar -= getBordersSize(styles, 'y'); + + result.width -= horizScrollbar; + result.height -= vertScrollbar; + } + + return getClientRect(result); + } + + function getOffsetRectRelativeToArbitraryNode(children, parent) { + var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + + var isIE10 = isIE(10); + var isHTML = parent.nodeName === 'HTML'; + var childrenRect = getBoundingClientRect(children); + var parentRect = getBoundingClientRect(parent); + var scrollParent = getScrollParent(children); + + var styles = getStyleComputedProperty(parent); + var borderTopWidth = parseFloat(styles.borderTopWidth); + var borderLeftWidth = parseFloat(styles.borderLeftWidth); + + // In cases where the parent is fixed, we must ignore negative scroll in offset calc + if (fixedPosition && isHTML) { + parentRect.top = Math.max(parentRect.top, 0); + parentRect.left = Math.max(parentRect.left, 0); + } + var offsets = getClientRect({ + top: childrenRect.top - parentRect.top - borderTopWidth, + left: childrenRect.left - parentRect.left - borderLeftWidth, + width: childrenRect.width, + height: childrenRect.height + }); + offsets.marginTop = 0; + offsets.marginLeft = 0; + + // Subtract margins of documentElement in case it's being used as parent + // we do this only on HTML because it's the only element that behaves + // differently when margins are applied to it. The margins are included in + // the box of the documentElement, in the other cases not. + if (!isIE10 && isHTML) { + var marginTop = parseFloat(styles.marginTop); + var marginLeft = parseFloat(styles.marginLeft); + + offsets.top -= borderTopWidth - marginTop; + offsets.bottom -= borderTopWidth - marginTop; + offsets.left -= borderLeftWidth - marginLeft; + offsets.right -= borderLeftWidth - marginLeft; + + // Attach marginTop and marginLeft because in some circumstances we may need them + offsets.marginTop = marginTop; + offsets.marginLeft = marginLeft; + } + + if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') { + offsets = includeScroll(offsets, parent); + } + + return offsets; + } + + function getViewportOffsetRectRelativeToArtbitraryNode(element) { + var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var html = element.ownerDocument.documentElement; + var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html); + var width = Math.max(html.clientWidth, window.innerWidth || 0); + var height = Math.max(html.clientHeight, window.innerHeight || 0); + + var scrollTop = !excludeScroll ? getScroll(html) : 0; + var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0; + + var offset = { + top: scrollTop - relativeOffset.top + relativeOffset.marginTop, + left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft, + width: width, + height: height + }; + + return getClientRect(offset); + } + + /** + * Check if the given element is fixed or is inside a fixed parent + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @argument {Element} customContainer + * @returns {Boolean} answer to "isFixed?" + */ + function isFixed(element) { + var nodeName = element.nodeName; + if (nodeName === 'BODY' || nodeName === 'HTML') { + return false; + } + if (getStyleComputedProperty(element, 'position') === 'fixed') { + return true; + } + var parentNode = getParentNode(element); + if (!parentNode) { + return false; + } + return isFixed(parentNode); + } + + /** + * Finds the first parent of an element that has a transformed property defined + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @returns {Element} first transformed parent or documentElement + */ + + function getFixedPositionOffsetParent(element) { + // This check is needed to avoid errors in case one of the elements isn't defined for any reason + if (!element || !element.parentElement || isIE()) { + return document.documentElement; + } + var el = element.parentElement; + while (el && getStyleComputedProperty(el, 'transform') === 'none') { + el = el.parentElement; + } + return el || document.documentElement; + } + + /** + * Computed the boundaries limits and return them + * @method + * @memberof Popper.Utils + * @param {HTMLElement} popper + * @param {HTMLElement} reference + * @param {number} padding + * @param {HTMLElement} boundariesElement - Element used to define the boundaries + * @param {Boolean} fixedPosition - Is in fixed position mode + * @returns {Object} Coordinates of the boundaries + */ + function getBoundaries(popper, reference, padding, boundariesElement) { + var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + + // NOTE: 1 DOM access here + + var boundaries = { top: 0, left: 0 }; + var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference)); + + // Handle viewport case + if (boundariesElement === 'viewport') { + boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition); + } else { + // Handle other cases based on DOM element used as boundaries + var boundariesNode = void 0; + if (boundariesElement === 'scrollParent') { + boundariesNode = getScrollParent(getParentNode(reference)); + if (boundariesNode.nodeName === 'BODY') { + boundariesNode = popper.ownerDocument.documentElement; + } + } else if (boundariesElement === 'window') { + boundariesNode = popper.ownerDocument.documentElement; + } else { + boundariesNode = boundariesElement; + } + + var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition); + + // In case of HTML, we need a different computation + if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) { + var _getWindowSizes = getWindowSizes(popper.ownerDocument), + height = _getWindowSizes.height, + width = _getWindowSizes.width; + + boundaries.top += offsets.top - offsets.marginTop; + boundaries.bottom = height + offsets.top; + boundaries.left += offsets.left - offsets.marginLeft; + boundaries.right = width + offsets.left; + } else { + // for all the other DOM elements, this one is good + boundaries = offsets; + } + } + + // Add paddings + padding = padding || 0; + var isPaddingNumber = typeof padding === 'number'; + boundaries.left += isPaddingNumber ? padding : padding.left || 0; + boundaries.top += isPaddingNumber ? padding : padding.top || 0; + boundaries.right -= isPaddingNumber ? padding : padding.right || 0; + boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0; + + return boundaries; + } + + function getArea(_ref) { + var width = _ref.width, + height = _ref.height; + + return width * height; + } + + /** + * Utility used to transform the `auto` placement to the placement with more + * available space. + * @method + * @memberof Popper.Utils + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) { + var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0; + + if (placement.indexOf('auto') === -1) { + return placement; + } + + var boundaries = getBoundaries(popper, reference, padding, boundariesElement); + + var rects = { + top: { + width: boundaries.width, + height: refRect.top - boundaries.top + }, + right: { + width: boundaries.right - refRect.right, + height: boundaries.height + }, + bottom: { + width: boundaries.width, + height: boundaries.bottom - refRect.bottom + }, + left: { + width: refRect.left - boundaries.left, + height: boundaries.height + } + }; + + var sortedAreas = Object.keys(rects).map(function (key) { + return _extends({ + key: key + }, rects[key], { + area: getArea(rects[key]) + }); + }).sort(function (a, b) { + return b.area - a.area; + }); + + var filteredAreas = sortedAreas.filter(function (_ref2) { + var width = _ref2.width, + height = _ref2.height; + return width >= popper.clientWidth && height >= popper.clientHeight; + }); + + var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key; + + var variation = placement.split('-')[1]; + + return computedPlacement + (variation ? '-' + variation : ''); + } + + /** + * Get offsets to the reference element + * @method + * @memberof Popper.Utils + * @param {Object} state + * @param {Element} popper - the popper element + * @param {Element} reference - the reference element (the popper will be relative to this) + * @param {Element} fixedPosition - is in fixed position mode + * @returns {Object} An object containing the offsets which will be applied to the popper + */ + function getReferenceOffsets(state, popper, reference) { + var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; + + var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference)); + return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition); + } + + /** + * Get the outer sizes of the given element (offset size + margins) + * @method + * @memberof Popper.Utils + * @argument {Element} element + * @returns {Object} object containing width and height properties + */ + function getOuterSizes(element) { + var window = element.ownerDocument.defaultView; + var styles = window.getComputedStyle(element); + var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0); + var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0); + var result = { + width: element.offsetWidth + y, + height: element.offsetHeight + x + }; + return result; + } + + /** + * Get the opposite placement of the given one + * @method + * @memberof Popper.Utils + * @argument {String} placement + * @returns {String} flipped placement + */ + function getOppositePlacement(placement) { + var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' }; + return placement.replace(/left|right|bottom|top/g, function (matched) { + return hash[matched]; + }); + } + + /** + * Get offsets to the popper + * @method + * @memberof Popper.Utils + * @param {Object} position - CSS position the Popper will get applied + * @param {HTMLElement} popper - the popper element + * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this) + * @param {String} placement - one of the valid placement options + * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper + */ + function getPopperOffsets(popper, referenceOffsets, placement) { + placement = placement.split('-')[0]; + + // Get popper node sizes + var popperRect = getOuterSizes(popper); + + // Add position, width and height to our offsets object + var popperOffsets = { + width: popperRect.width, + height: popperRect.height + }; + + // depending by the popper placement we have to compute its offsets slightly differently + var isHoriz = ['right', 'left'].indexOf(placement) !== -1; + var mainSide = isHoriz ? 'top' : 'left'; + var secondarySide = isHoriz ? 'left' : 'top'; + var measurement = isHoriz ? 'height' : 'width'; + var secondaryMeasurement = !isHoriz ? 'height' : 'width'; + + popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2; + if (placement === secondarySide) { + popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement]; + } else { + popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)]; + } + + return popperOffsets; + } + + /** + * Mimics the `find` method of Array + * @method + * @memberof Popper.Utils + * @argument {Array} arr + * @argument prop + * @argument value + * @returns index or -1 + */ + function find(arr, check) { + // use native find if supported + if (Array.prototype.find) { + return arr.find(check); + } + + // use `filter` to obtain the same behavior of `find` + return arr.filter(check)[0]; + } + + /** + * Return the index of the matching object + * @method + * @memberof Popper.Utils + * @argument {Array} arr + * @argument prop + * @argument value + * @returns index or -1 + */ + function findIndex(arr, prop, value) { + // use native findIndex if supported + if (Array.prototype.findIndex) { + return arr.findIndex(function (cur) { + return cur[prop] === value; + }); + } + + // use `find` + `indexOf` if `findIndex` isn't supported + var match = find(arr, function (obj) { + return obj[prop] === value; + }); + return arr.indexOf(match); + } + + /** + * Loop trough the list of modifiers and run them in order, + * each of them will then edit the data object. + * @method + * @memberof Popper.Utils + * @param {dataObject} data + * @param {Array} modifiers + * @param {String} ends - Optional modifier name used as stopper + * @returns {dataObject} + */ + function runModifiers(modifiers, data, ends) { + var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends)); + + modifiersToRun.forEach(function (modifier) { + if (modifier['function']) { + // eslint-disable-line dot-notation + console.warn('`modifier.function` is deprecated, use `modifier.fn`!'); + } + var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation + if (modifier.enabled && isFunction(fn)) { + // Add properties to offsets to make them a complete clientRect object + // we do this before each modifier to make sure the previous one doesn't + // mess with these values + data.offsets.popper = getClientRect(data.offsets.popper); + data.offsets.reference = getClientRect(data.offsets.reference); + + data = fn(data, modifier); + } + }); + + return data; + } + + /** + * Updates the position of the popper, computing the new offsets and applying + * the new style.
+ * Prefer `scheduleUpdate` over `update` because of performance reasons. + * @method + * @memberof Popper + */ + function update() { + // if popper is destroyed, don't perform any further update + if (this.state.isDestroyed) { + return; + } + + var data = { + instance: this, + styles: {}, + arrowStyles: {}, + attributes: {}, + flipped: false, + offsets: {} + }; + + // compute reference element offsets + data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed); + + // compute auto placement, store placement inside the data object, + // modifiers will be able to edit `placement` if needed + // and refer to originalPlacement to know the original value + data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding); + + // store the computed placement inside `originalPlacement` + data.originalPlacement = data.placement; + + data.positionFixed = this.options.positionFixed; + + // compute the popper offsets + data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement); + + data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute'; + + // run the modifiers + data = runModifiers(this.modifiers, data); + + // the first `update` will call `onCreate` callback + // the other ones will call `onUpdate` callback + if (!this.state.isCreated) { + this.state.isCreated = true; + this.options.onCreate(data); + } else { + this.options.onUpdate(data); + } + } + + /** + * Helper used to know if the given modifier is enabled. + * @method + * @memberof Popper.Utils + * @returns {Boolean} + */ + function isModifierEnabled(modifiers, modifierName) { + return modifiers.some(function (_ref) { + var name = _ref.name, + enabled = _ref.enabled; + return enabled && name === modifierName; + }); + } + + /** + * Get the prefixed supported property name + * @method + * @memberof Popper.Utils + * @argument {String} property (camelCase) + * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix) + */ + function getSupportedPropertyName(property) { + var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O']; + var upperProp = property.charAt(0).toUpperCase() + property.slice(1); + + for (var i = 0; i < prefixes.length; i++) { + var prefix = prefixes[i]; + var toCheck = prefix ? '' + prefix + upperProp : property; + if (typeof document.body.style[toCheck] !== 'undefined') { + return toCheck; + } + } + return null; + } + + /** + * Destroys the popper. + * @method + * @memberof Popper + */ + function destroy() { + this.state.isDestroyed = true; + + // touch DOM only if `applyStyle` modifier is enabled + if (isModifierEnabled(this.modifiers, 'applyStyle')) { + this.popper.removeAttribute('x-placement'); + this.popper.style.position = ''; + this.popper.style.top = ''; + this.popper.style.left = ''; + this.popper.style.right = ''; + this.popper.style.bottom = ''; + this.popper.style.willChange = ''; + this.popper.style[getSupportedPropertyName('transform')] = ''; + } + + this.disableEventListeners(); + + // remove the popper if user explicitly asked for the deletion on destroy + // do not use `remove` because IE11 doesn't support it + if (this.options.removeOnDestroy) { + this.popper.parentNode.removeChild(this.popper); + } + return this; + } + + /** + * Get the window associated with the element + * @argument {Element} element + * @returns {Window} + */ + function getWindow(element) { + var ownerDocument = element.ownerDocument; + return ownerDocument ? ownerDocument.defaultView : window; + } + + function attachToScrollParents(scrollParent, event, callback, scrollParents) { + var isBody = scrollParent.nodeName === 'BODY'; + var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent; + target.addEventListener(event, callback, { passive: true }); + + if (!isBody) { + attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents); + } + scrollParents.push(target); + } + + /** + * Setup needed event listeners used to update the popper position + * @method + * @memberof Popper.Utils + * @private + */ + function setupEventListeners(reference, options, state, updateBound) { + // Resize event listener on window + state.updateBound = updateBound; + getWindow(reference).addEventListener('resize', state.updateBound, { passive: true }); + + // Scroll event listener on scroll parents + var scrollElement = getScrollParent(reference); + attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents); + state.scrollElement = scrollElement; + state.eventsEnabled = true; + + return state; + } + + /** + * It will add resize/scroll events and start recalculating + * position of the popper element when they are triggered. + * @method + * @memberof Popper + */ + function enableEventListeners() { + if (!this.state.eventsEnabled) { + this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate); + } + } + + /** + * Remove event listeners used to update the popper position + * @method + * @memberof Popper.Utils + * @private + */ + function removeEventListeners(reference, state) { + // Remove resize event listener on window + getWindow(reference).removeEventListener('resize', state.updateBound); + + // Remove scroll event listener on scroll parents + state.scrollParents.forEach(function (target) { + target.removeEventListener('scroll', state.updateBound); + }); + + // Reset state + state.updateBound = null; + state.scrollParents = []; + state.scrollElement = null; + state.eventsEnabled = false; + return state; + } + + /** + * It will remove resize/scroll events and won't recalculate popper position + * when they are triggered. It also won't trigger `onUpdate` callback anymore, + * unless you call `update` method manually. + * @method + * @memberof Popper + */ + function disableEventListeners() { + if (this.state.eventsEnabled) { + cancelAnimationFrame(this.scheduleUpdate); + this.state = removeEventListeners(this.reference, this.state); + } + } + + /** + * Tells if a given input is a number + * @method + * @memberof Popper.Utils + * @param {*} input to check + * @return {Boolean} + */ + function isNumeric(n) { + return n !== '' && !isNaN(parseFloat(n)) && isFinite(n); + } + + /** + * Set the style to the given popper + * @method + * @memberof Popper.Utils + * @argument {Element} element - Element to apply the style to + * @argument {Object} styles + * Object with a list of properties and values which will be applied to the element + */ + function setStyles(element, styles) { + Object.keys(styles).forEach(function (prop) { + var unit = ''; + // add unit if the value is numeric and is one of the following + if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) { + unit = 'px'; + } + element.style[prop] = styles[prop] + unit; + }); + } + + /** + * Set the attributes to the given popper + * @method + * @memberof Popper.Utils + * @argument {Element} element - Element to apply the attributes to + * @argument {Object} styles + * Object with a list of properties and values which will be applied to the element + */ + function setAttributes(element, attributes) { + Object.keys(attributes).forEach(function (prop) { + var value = attributes[prop]; + if (value !== false) { + element.setAttribute(prop, attributes[prop]); + } else { + element.removeAttribute(prop); + } + }); + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by `update` method + * @argument {Object} data.styles - List of style properties - values to apply to popper element + * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The same data object + */ + function applyStyle(data) { + // any property present in `data.styles` will be applied to the popper, + // in this way we can make the 3rd party modifiers add custom styles to it + // Be aware, modifiers could override the properties defined in the previous + // lines of this modifier! + setStyles(data.instance.popper, data.styles); + + // any property present in `data.attributes` will be applied to the popper, + // they will be set as HTML attributes of the element + setAttributes(data.instance.popper, data.attributes); + + // if arrowElement is defined and arrowStyles has some properties + if (data.arrowElement && Object.keys(data.arrowStyles).length) { + setStyles(data.arrowElement, data.arrowStyles); + } + + return data; + } + + /** + * Set the x-placement attribute before everything else because it could be used + * to add margins to the popper margins needs to be calculated to get the + * correct popper offsets. + * @method + * @memberof Popper.modifiers + * @param {HTMLElement} reference - The reference element used to position the popper + * @param {HTMLElement} popper - The HTML element used as popper + * @param {Object} options - Popper.js options + */ + function applyStyleOnLoad(reference, popper, options, modifierOptions, state) { + // compute reference element offsets + var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed); + + // compute auto placement, store placement inside the data object, + // modifiers will be able to edit `placement` if needed + // and refer to originalPlacement to know the original value + var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding); + + popper.setAttribute('x-placement', placement); + + // Apply `position` to popper before anything else because + // without the position applied we can't guarantee correct computations + setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' }); + + return options; + } + + /** + * @function + * @memberof Popper.Utils + * @argument {Object} data - The data object generated by `update` method + * @argument {Boolean} shouldRound - If the offsets should be rounded at all + * @returns {Object} The popper's position offsets rounded + * + * The tale of pixel-perfect positioning. It's still not 100% perfect, but as + * good as it can be within reason. + * Discussion here: https://github.com/FezVrasta/popper.js/pull/715 + * + * Low DPI screens cause a popper to be blurry if not using full pixels (Safari + * as well on High DPI screens). + * + * Firefox prefers no rounding for positioning and does not have blurriness on + * high DPI screens. + * + * Only horizontal placement and left/right values need to be considered. + */ + function getRoundedOffsets(data, shouldRound) { + var _data$offsets = data.offsets, + popper = _data$offsets.popper, + reference = _data$offsets.reference; + var round = Math.round, + floor = Math.floor; + + var noRound = function noRound(v) { + return v; + }; + + var referenceWidth = round(reference.width); + var popperWidth = round(popper.width); + + var isVertical = ['left', 'right'].indexOf(data.placement) !== -1; + var isVariation = data.placement.indexOf('-') !== -1; + var sameWidthParity = referenceWidth % 2 === popperWidth % 2; + var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1; + + var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor; + var verticalToInteger = !shouldRound ? noRound : round; + + return { + left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left), + top: verticalToInteger(popper.top), + bottom: verticalToInteger(popper.bottom), + right: horizontalToInteger(popper.right) + }; + } + + var isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent); + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by `update` method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function computeStyle(data, options) { + var x = options.x, + y = options.y; + var popper = data.offsets.popper; + + // Remove this legacy support in Popper.js v2 + + var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) { + return modifier.name === 'applyStyle'; + }).gpuAcceleration; + if (legacyGpuAccelerationOption !== undefined) { + console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!'); + } + var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration; + + var offsetParent = getOffsetParent(data.instance.popper); + var offsetParentRect = getBoundingClientRect(offsetParent); + + // Styles + var styles = { + position: popper.position + }; + + var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox); + + var sideA = x === 'bottom' ? 'top' : 'bottom'; + var sideB = y === 'right' ? 'left' : 'right'; + + // if gpuAcceleration is set to `true` and transform is supported, + // we use `translate3d` to apply the position to the popper we + // automatically use the supported prefixed version if needed + var prefixedProperty = getSupportedPropertyName('transform'); + + // now, let's make a step back and look at this code closely (wtf?) + // If the content of the popper grows once it's been positioned, it + // may happen that the popper gets misplaced because of the new content + // overflowing its reference element + // To avoid this problem, we provide two options (x and y), which allow + // the consumer to define the offset origin. + // If we position a popper on top of a reference element, we can set + // `x` to `top` to make the popper grow towards its top instead of + // its bottom. + var left = void 0, + top = void 0; + if (sideA === 'bottom') { + // when offsetParent is the positioning is relative to the bottom of the screen (excluding the scrollbar) + // and not the bottom of the html element + if (offsetParent.nodeName === 'HTML') { + top = -offsetParent.clientHeight + offsets.bottom; + } else { + top = -offsetParentRect.height + offsets.bottom; + } + } else { + top = offsets.top; + } + if (sideB === 'right') { + if (offsetParent.nodeName === 'HTML') { + left = -offsetParent.clientWidth + offsets.right; + } else { + left = -offsetParentRect.width + offsets.right; + } + } else { + left = offsets.left; + } + if (gpuAcceleration && prefixedProperty) { + styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)'; + styles[sideA] = 0; + styles[sideB] = 0; + styles.willChange = 'transform'; + } else { + // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties + var invertTop = sideA === 'bottom' ? -1 : 1; + var invertLeft = sideB === 'right' ? -1 : 1; + styles[sideA] = top * invertTop; + styles[sideB] = left * invertLeft; + styles.willChange = sideA + ', ' + sideB; + } + + // Attributes + var attributes = { + 'x-placement': data.placement + }; + + // Update `data` attributes, styles and arrowStyles + data.attributes = _extends({}, attributes, data.attributes); + data.styles = _extends({}, styles, data.styles); + data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles); + + return data; + } + + /** + * Helper used to know if the given modifier depends from another one.
+ * It checks if the needed modifier is listed and enabled. + * @method + * @memberof Popper.Utils + * @param {Array} modifiers - list of modifiers + * @param {String} requestingName - name of requesting modifier + * @param {String} requestedName - name of requested modifier + * @returns {Boolean} + */ + function isModifierRequired(modifiers, requestingName, requestedName) { + var requesting = find(modifiers, function (_ref) { + var name = _ref.name; + return name === requestingName; + }); + + var isRequired = !!requesting && modifiers.some(function (modifier) { + return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order; + }); + + if (!isRequired) { + var _requesting = '`' + requestingName + '`'; + var requested = '`' + requestedName + '`'; + console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!'); + } + return isRequired; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function arrow(data, options) { + var _data$offsets$arrow; + + // arrow depends on keepTogether in order to work + if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) { + return data; + } + + var arrowElement = options.element; + + // if arrowElement is a string, suppose it's a CSS selector + if (typeof arrowElement === 'string') { + arrowElement = data.instance.popper.querySelector(arrowElement); + + // if arrowElement is not found, don't run the modifier + if (!arrowElement) { + return data; + } + } else { + // if the arrowElement isn't a query selector we must check that the + // provided DOM node is child of its popper node + if (!data.instance.popper.contains(arrowElement)) { + console.warn('WARNING: `arrow.element` must be child of its popper element!'); + return data; + } + } + + var placement = data.placement.split('-')[0]; + var _data$offsets = data.offsets, + popper = _data$offsets.popper, + reference = _data$offsets.reference; + + var isVertical = ['left', 'right'].indexOf(placement) !== -1; + + var len = isVertical ? 'height' : 'width'; + var sideCapitalized = isVertical ? 'Top' : 'Left'; + var side = sideCapitalized.toLowerCase(); + var altSide = isVertical ? 'left' : 'top'; + var opSide = isVertical ? 'bottom' : 'right'; + var arrowElementSize = getOuterSizes(arrowElement)[len]; + + // + // extends keepTogether behavior making sure the popper and its + // reference have enough pixels in conjunction + // + + // top/left side + if (reference[opSide] - arrowElementSize < popper[side]) { + data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize); + } + // bottom/right side + if (reference[side] + arrowElementSize > popper[opSide]) { + data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide]; + } + data.offsets.popper = getClientRect(data.offsets.popper); + + // compute center of the popper + var center = reference[side] + reference[len] / 2 - arrowElementSize / 2; + + // Compute the sideValue using the updated popper offsets + // take popper margin in account because we don't have this info available + var css = getStyleComputedProperty(data.instance.popper); + var popperMarginSide = parseFloat(css['margin' + sideCapitalized]); + var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width']); + var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide; + + // prevent arrowElement from being placed not contiguously to its popper + sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0); + + data.arrowElement = arrowElement; + data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow); + + return data; + } + + /** + * Get the opposite placement variation of the given one + * @method + * @memberof Popper.Utils + * @argument {String} placement variation + * @returns {String} flipped placement variation + */ + function getOppositeVariation(variation) { + if (variation === 'end') { + return 'start'; + } else if (variation === 'start') { + return 'end'; + } + return variation; + } + + /** + * List of accepted placements to use as values of the `placement` option.
+ * Valid placements are: + * - `auto` + * - `top` + * - `right` + * - `bottom` + * - `left` + * + * Each placement can have a variation from this list: + * - `-start` + * - `-end` + * + * Variations are interpreted easily if you think of them as the left to right + * written languages. Horizontally (`top` and `bottom`), `start` is left and `end` + * is right.
+ * Vertically (`left` and `right`), `start` is top and `end` is bottom. + * + * Some valid examples are: + * - `top-end` (on top of reference, right aligned) + * - `right-start` (on right of reference, top aligned) + * - `bottom` (on bottom, centered) + * - `auto-end` (on the side with more space available, alignment depends by placement) + * + * @static + * @type {Array} + * @enum {String} + * @readonly + * @method placements + * @memberof Popper + */ + var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start']; + + // Get rid of `auto` `auto-start` and `auto-end` + var validPlacements = placements.slice(3); + + /** + * Given an initial placement, returns all the subsequent placements + * clockwise (or counter-clockwise). + * + * @method + * @memberof Popper.Utils + * @argument {String} placement - A valid placement (it accepts variations) + * @argument {Boolean} counter - Set to true to walk the placements counterclockwise + * @returns {Array} placements including their variations + */ + function clockwise(placement) { + var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + + var index = validPlacements.indexOf(placement); + var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index)); + return counter ? arr.reverse() : arr; + } + + var BEHAVIORS = { + FLIP: 'flip', + CLOCKWISE: 'clockwise', + COUNTERCLOCKWISE: 'counterclockwise' + }; + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function flip(data, options) { + // if `inner` modifier is enabled, we can't use the `flip` modifier + if (isModifierEnabled(data.instance.modifiers, 'inner')) { + return data; + } + + if (data.flipped && data.placement === data.originalPlacement) { + // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides + return data; + } + + var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed); + + var placement = data.placement.split('-')[0]; + var placementOpposite = getOppositePlacement(placement); + var variation = data.placement.split('-')[1] || ''; + + var flipOrder = []; + + switch (options.behavior) { + case BEHAVIORS.FLIP: + flipOrder = [placement, placementOpposite]; + break; + case BEHAVIORS.CLOCKWISE: + flipOrder = clockwise(placement); + break; + case BEHAVIORS.COUNTERCLOCKWISE: + flipOrder = clockwise(placement, true); + break; + default: + flipOrder = options.behavior; + } + + flipOrder.forEach(function (step, index) { + if (placement !== step || flipOrder.length === index + 1) { + return data; + } + + placement = data.placement.split('-')[0]; + placementOpposite = getOppositePlacement(placement); + + var popperOffsets = data.offsets.popper; + var refOffsets = data.offsets.reference; + + // using floor because the reference offsets may contain decimals we are not going to consider here + var floor = Math.floor; + var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom); + + var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left); + var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right); + var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top); + var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom); + + var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom; + + // flip the variation if required + var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; + + // flips variation if reference element overflows boundaries + var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom); + + // flips variation if popper content overflows boundaries + var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop); + + var flippedVariation = flippedVariationByRef || flippedVariationByContent; + + if (overlapsRef || overflowsBoundaries || flippedVariation) { + // this boolean to detect any flip loop + data.flipped = true; + + if (overlapsRef || overflowsBoundaries) { + placement = flipOrder[index + 1]; + } + + if (flippedVariation) { + variation = getOppositeVariation(variation); + } + + data.placement = placement + (variation ? '-' + variation : ''); + + // this object contains `position`, we want to preserve it along with + // any additional property we may add in the future + data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement)); + + data = runModifiers(data.instance.modifiers, data, 'flip'); + } + }); + return data; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function keepTogether(data) { + var _data$offsets = data.offsets, + popper = _data$offsets.popper, + reference = _data$offsets.reference; + + var placement = data.placement.split('-')[0]; + var floor = Math.floor; + var isVertical = ['top', 'bottom'].indexOf(placement) !== -1; + var side = isVertical ? 'right' : 'bottom'; + var opSide = isVertical ? 'left' : 'top'; + var measurement = isVertical ? 'width' : 'height'; + + if (popper[side] < floor(reference[opSide])) { + data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement]; + } + if (popper[opSide] > floor(reference[side])) { + data.offsets.popper[opSide] = floor(reference[side]); + } + + return data; + } + + /** + * Converts a string containing value + unit into a px value number + * @function + * @memberof {modifiers~offset} + * @private + * @argument {String} str - Value + unit string + * @argument {String} measurement - `height` or `width` + * @argument {Object} popperOffsets + * @argument {Object} referenceOffsets + * @returns {Number|String} + * Value in pixels, or original string if no values were extracted + */ + function toValue(str, measurement, popperOffsets, referenceOffsets) { + // separate value from unit + var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/); + var value = +split[1]; + var unit = split[2]; + + // If it's not a number it's an operator, I guess + if (!value) { + return str; + } + + if (unit.indexOf('%') === 0) { + var element = void 0; + switch (unit) { + case '%p': + element = popperOffsets; + break; + case '%': + case '%r': + default: + element = referenceOffsets; + } + + var rect = getClientRect(element); + return rect[measurement] / 100 * value; + } else if (unit === 'vh' || unit === 'vw') { + // if is a vh or vw, we calculate the size based on the viewport + var size = void 0; + if (unit === 'vh') { + size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); + } else { + size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); + } + return size / 100 * value; + } else { + // if is an explicit pixel unit, we get rid of the unit and keep the value + // if is an implicit unit, it's px, and we return just the value + return value; + } + } + + /** + * Parse an `offset` string to extrapolate `x` and `y` numeric offsets. + * @function + * @memberof {modifiers~offset} + * @private + * @argument {String} offset + * @argument {Object} popperOffsets + * @argument {Object} referenceOffsets + * @argument {String} basePlacement + * @returns {Array} a two cells array with x and y offsets in numbers + */ + function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) { + var offsets = [0, 0]; + + // Use height if placement is left or right and index is 0 otherwise use width + // in this way the first offset will use an axis and the second one + // will use the other one + var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1; + + // Split the offset string to obtain a list of values and operands + // The regex addresses values with the plus or minus sign in front (+10, -20, etc) + var fragments = offset.split(/(\+|\-)/).map(function (frag) { + return frag.trim(); + }); + + // Detect if the offset string contains a pair of values or a single one + // they could be separated by comma or space + var divider = fragments.indexOf(find(fragments, function (frag) { + return frag.search(/,|\s/) !== -1; + })); + + if (fragments[divider] && fragments[divider].indexOf(',') === -1) { + console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.'); + } + + // If divider is found, we divide the list of values and operands to divide + // them by ofset X and Y. + var splitRegex = /\s*,\s*|\s+/; + var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments]; + + // Convert the values with units to absolute pixels to allow our computations + ops = ops.map(function (op, index) { + // Most of the units rely on the orientation of the popper + var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width'; + var mergeWithPrevious = false; + return op + // This aggregates any `+` or `-` sign that aren't considered operators + // e.g.: 10 + +5 => [10, +, +5] + .reduce(function (a, b) { + if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) { + a[a.length - 1] = b; + mergeWithPrevious = true; + return a; + } else if (mergeWithPrevious) { + a[a.length - 1] += b; + mergeWithPrevious = false; + return a; + } else { + return a.concat(b); + } + }, []) + // Here we convert the string values into number values (in px) + .map(function (str) { + return toValue(str, measurement, popperOffsets, referenceOffsets); + }); + }); + + // Loop trough the offsets arrays and execute the operations + ops.forEach(function (op, index) { + op.forEach(function (frag, index2) { + if (isNumeric(frag)) { + offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1); + } + }); + }); + return offsets; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @argument {Number|String} options.offset=0 + * The offset value as described in the modifier description + * @returns {Object} The data object, properly modified + */ + function offset(data, _ref) { + var offset = _ref.offset; + var placement = data.placement, + _data$offsets = data.offsets, + popper = _data$offsets.popper, + reference = _data$offsets.reference; + + var basePlacement = placement.split('-')[0]; + + var offsets = void 0; + if (isNumeric(+offset)) { + offsets = [+offset, 0]; + } else { + offsets = parseOffset(offset, popper, reference, basePlacement); + } + + if (basePlacement === 'left') { + popper.top += offsets[0]; + popper.left -= offsets[1]; + } else if (basePlacement === 'right') { + popper.top += offsets[0]; + popper.left += offsets[1]; + } else if (basePlacement === 'top') { + popper.left += offsets[0]; + popper.top -= offsets[1]; + } else if (basePlacement === 'bottom') { + popper.left += offsets[0]; + popper.top += offsets[1]; + } + + data.popper = popper; + return data; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by `update` method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function preventOverflow(data, options) { + var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper); + + // If offsetParent is the reference element, we really want to + // go one step up and use the next offsetParent as reference to + // avoid to make this modifier completely useless and look like broken + if (data.instance.reference === boundariesElement) { + boundariesElement = getOffsetParent(boundariesElement); + } + + // NOTE: DOM access here + // resets the popper's position so that the document size can be calculated excluding + // the size of the popper element itself + var transformProp = getSupportedPropertyName('transform'); + var popperStyles = data.instance.popper.style; // assignment to help minification + var top = popperStyles.top, + left = popperStyles.left, + transform = popperStyles[transformProp]; + + popperStyles.top = ''; + popperStyles.left = ''; + popperStyles[transformProp] = ''; + + var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed); + + // NOTE: DOM access here + // restores the original style properties after the offsets have been computed + popperStyles.top = top; + popperStyles.left = left; + popperStyles[transformProp] = transform; + + options.boundaries = boundaries; + + var order = options.priority; + var popper = data.offsets.popper; + + var check = { + primary: function primary(placement) { + var value = popper[placement]; + if (popper[placement] < boundaries[placement] && !options.escapeWithReference) { + value = Math.max(popper[placement], boundaries[placement]); + } + return defineProperty({}, placement, value); + }, + secondary: function secondary(placement) { + var mainSide = placement === 'right' ? 'left' : 'top'; + var value = popper[mainSide]; + if (popper[placement] > boundaries[placement] && !options.escapeWithReference) { + value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height)); + } + return defineProperty({}, mainSide, value); + } + }; + + order.forEach(function (placement) { + var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary'; + popper = _extends({}, popper, check[side](placement)); + }); + + data.offsets.popper = popper; + + return data; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by `update` method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function shift(data) { + var placement = data.placement; + var basePlacement = placement.split('-')[0]; + var shiftvariation = placement.split('-')[1]; + + // if shift shiftvariation is specified, run the modifier + if (shiftvariation) { + var _data$offsets = data.offsets, + reference = _data$offsets.reference, + popper = _data$offsets.popper; + + var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1; + var side = isVertical ? 'left' : 'top'; + var measurement = isVertical ? 'width' : 'height'; + + var shiftOffsets = { + start: defineProperty({}, side, reference[side]), + end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement]) + }; + + data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]); + } + + return data; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by update method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function hide(data) { + if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) { + return data; + } + + var refRect = data.offsets.reference; + var bound = find(data.instance.modifiers, function (modifier) { + return modifier.name === 'preventOverflow'; + }).boundaries; + + if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) { + // Avoid unnecessary DOM access if visibility hasn't changed + if (data.hide === true) { + return data; + } + + data.hide = true; + data.attributes['x-out-of-boundaries'] = ''; + } else { + // Avoid unnecessary DOM access if visibility hasn't changed + if (data.hide === false) { + return data; + } + + data.hide = false; + data.attributes['x-out-of-boundaries'] = false; + } + + return data; + } + + /** + * @function + * @memberof Modifiers + * @argument {Object} data - The data object generated by `update` method + * @argument {Object} options - Modifiers configuration and options + * @returns {Object} The data object, properly modified + */ + function inner(data) { + var placement = data.placement; + var basePlacement = placement.split('-')[0]; + var _data$offsets = data.offsets, + popper = _data$offsets.popper, + reference = _data$offsets.reference; + + var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1; + + var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1; + + popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0); + + data.placement = getOppositePlacement(placement); + data.offsets.popper = getClientRect(popper); + + return data; + } + + /** + * Modifier function, each modifier can have a function of this type assigned + * to its `fn` property.
+ * These functions will be called on each update, this means that you must + * make sure they are performant enough to avoid performance bottlenecks. + * + * @function ModifierFn + * @argument {dataObject} data - The data object generated by `update` method + * @argument {Object} options - Modifiers configuration and options + * @returns {dataObject} The data object, properly modified + */ + + /** + * Modifiers are plugins used to alter the behavior of your poppers.
+ * Popper.js uses a set of 9 modifiers to provide all the basic functionalities + * needed by the library. + * + * Usually you don't want to override the `order`, `fn` and `onLoad` props. + * All the other properties are configurations that could be tweaked. + * @namespace modifiers + */ + var modifiers = { + /** + * Modifier used to shift the popper on the start or end of its reference + * element.
+ * It will read the variation of the `placement` property.
+ * It can be one either `-end` or `-start`. + * @memberof modifiers + * @inner + */ + shift: { + /** @prop {number} order=100 - Index used to define the order of execution */ + order: 100, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: shift + }, + + /** + * The `offset` modifier can shift your popper on both its axis. + * + * It accepts the following units: + * - `px` or unit-less, interpreted as pixels + * - `%` or `%r`, percentage relative to the length of the reference element + * - `%p`, percentage relative to the length of the popper element + * - `vw`, CSS viewport width unit + * - `vh`, CSS viewport height unit + * + * For length is intended the main axis relative to the placement of the popper.
+ * This means that if the placement is `top` or `bottom`, the length will be the + * `width`. In case of `left` or `right`, it will be the `height`. + * + * You can provide a single value (as `Number` or `String`), or a pair of values + * as `String` divided by a comma or one (or more) white spaces.
+ * The latter is a deprecated method because it leads to confusion and will be + * removed in v2.
+ * Additionally, it accepts additions and subtractions between different units. + * Note that multiplications and divisions aren't supported. + * + * Valid examples are: + * ``` + * 10 + * '10%' + * '10, 10' + * '10%, 10' + * '10 + 10%' + * '10 - 5vh + 3%' + * '-10px + 5vh, 5px - 6%' + * ``` + * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap + * > with their reference element, unfortunately, you will have to disable the `flip` modifier. + * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373). + * + * @memberof modifiers + * @inner + */ + offset: { + /** @prop {number} order=200 - Index used to define the order of execution */ + order: 200, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: offset, + /** @prop {Number|String} offset=0 + * The offset value as described in the modifier description + */ + offset: 0 + }, + + /** + * Modifier used to prevent the popper from being positioned outside the boundary. + * + * A scenario exists where the reference itself is not within the boundaries.
+ * We can say it has "escaped the boundaries" — or just "escaped".
+ * In this case we need to decide whether the popper should either: + * + * - detach from the reference and remain "trapped" in the boundaries, or + * - if it should ignore the boundary and "escape with its reference" + * + * When `escapeWithReference` is set to`true` and reference is completely + * outside its boundaries, the popper will overflow (or completely leave) + * the boundaries in order to remain attached to the edge of the reference. + * + * @memberof modifiers + * @inner + */ + preventOverflow: { + /** @prop {number} order=300 - Index used to define the order of execution */ + order: 300, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: preventOverflow, + /** + * @prop {Array} [priority=['left','right','top','bottom']] + * Popper will try to prevent overflow following these priorities by default, + * then, it could overflow on the left and on top of the `boundariesElement` + */ + priority: ['left', 'right', 'top', 'bottom'], + /** + * @prop {number} padding=5 + * Amount of pixel used to define a minimum distance between the boundaries + * and the popper. This makes sure the popper always has a little padding + * between the edges of its container + */ + padding: 5, + /** + * @prop {String|HTMLElement} boundariesElement='scrollParent' + * Boundaries used by the modifier. Can be `scrollParent`, `window`, + * `viewport` or any DOM element. + */ + boundariesElement: 'scrollParent' + }, + + /** + * Modifier used to make sure the reference and its popper stay near each other + * without leaving any gap between the two. Especially useful when the arrow is + * enabled and you want to ensure that it points to its reference element. + * It cares only about the first axis. You can still have poppers with margin + * between the popper and its reference element. + * @memberof modifiers + * @inner + */ + keepTogether: { + /** @prop {number} order=400 - Index used to define the order of execution */ + order: 400, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: keepTogether + }, + + /** + * This modifier is used to move the `arrowElement` of the popper to make + * sure it is positioned between the reference element and its popper element. + * It will read the outer size of the `arrowElement` node to detect how many + * pixels of conjunction are needed. + * + * It has no effect if no `arrowElement` is provided. + * @memberof modifiers + * @inner + */ + arrow: { + /** @prop {number} order=500 - Index used to define the order of execution */ + order: 500, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: arrow, + /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */ + element: '[x-arrow]' + }, + + /** + * Modifier used to flip the popper's placement when it starts to overlap its + * reference element. + * + * Requires the `preventOverflow` modifier before it in order to work. + * + * **NOTE:** this modifier will interrupt the current update cycle and will + * restart it if it detects the need to flip the placement. + * @memberof modifiers + * @inner + */ + flip: { + /** @prop {number} order=600 - Index used to define the order of execution */ + order: 600, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: flip, + /** + * @prop {String|Array} behavior='flip' + * The behavior used to change the popper's placement. It can be one of + * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid + * placements (with optional variations) + */ + behavior: 'flip', + /** + * @prop {number} padding=5 + * The popper will flip if it hits the edges of the `boundariesElement` + */ + padding: 5, + /** + * @prop {String|HTMLElement} boundariesElement='viewport' + * The element which will define the boundaries of the popper position. + * The popper will never be placed outside of the defined boundaries + * (except if `keepTogether` is enabled) + */ + boundariesElement: 'viewport', + /** + * @prop {Boolean} flipVariations=false + * The popper will switch placement variation between `-start` and `-end` when + * the reference element overlaps its boundaries. + * + * The original placement should have a set variation. + */ + flipVariations: false, + /** + * @prop {Boolean} flipVariationsByContent=false + * The popper will switch placement variation between `-start` and `-end` when + * the popper element overlaps its reference boundaries. + * + * The original placement should have a set variation. + */ + flipVariationsByContent: false + }, + + /** + * Modifier used to make the popper flow toward the inner of the reference element. + * By default, when this modifier is disabled, the popper will be placed outside + * the reference element. + * @memberof modifiers + * @inner + */ + inner: { + /** @prop {number} order=700 - Index used to define the order of execution */ + order: 700, + /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */ + enabled: false, + /** @prop {ModifierFn} */ + fn: inner + }, + + /** + * Modifier used to hide the popper when its reference element is outside of the + * popper boundaries. It will set a `x-out-of-boundaries` attribute which can + * be used to hide with a CSS selector the popper when its reference is + * out of boundaries. + * + * Requires the `preventOverflow` modifier before it in order to work. + * @memberof modifiers + * @inner + */ + hide: { + /** @prop {number} order=800 - Index used to define the order of execution */ + order: 800, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: hide + }, + + /** + * Computes the style that will be applied to the popper element to gets + * properly positioned. + * + * Note that this modifier will not touch the DOM, it just prepares the styles + * so that `applyStyle` modifier can apply it. This separation is useful + * in case you need to replace `applyStyle` with a custom implementation. + * + * This modifier has `850` as `order` value to maintain backward compatibility + * with previous versions of Popper.js. Expect the modifiers ordering method + * to change in future major versions of the library. + * + * @memberof modifiers + * @inner + */ + computeStyle: { + /** @prop {number} order=850 - Index used to define the order of execution */ + order: 850, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: computeStyle, + /** + * @prop {Boolean} gpuAcceleration=true + * If true, it uses the CSS 3D transformation to position the popper. + * Otherwise, it will use the `top` and `left` properties + */ + gpuAcceleration: true, + /** + * @prop {string} [x='bottom'] + * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin. + * Change this if your popper should grow in a direction different from `bottom` + */ + x: 'bottom', + /** + * @prop {string} [x='left'] + * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin. + * Change this if your popper should grow in a direction different from `right` + */ + y: 'right' + }, + + /** + * Applies the computed styles to the popper element. + * + * All the DOM manipulations are limited to this modifier. This is useful in case + * you want to integrate Popper.js inside a framework or view library and you + * want to delegate all the DOM manipulations to it. + * + * Note that if you disable this modifier, you must make sure the popper element + * has its position set to `absolute` before Popper.js can do its work! + * + * Just disable this modifier and define your own to achieve the desired effect. + * + * @memberof modifiers + * @inner + */ + applyStyle: { + /** @prop {number} order=900 - Index used to define the order of execution */ + order: 900, + /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */ + enabled: true, + /** @prop {ModifierFn} */ + fn: applyStyle, + /** @prop {Function} */ + onLoad: applyStyleOnLoad, + /** + * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier + * @prop {Boolean} gpuAcceleration=true + * If true, it uses the CSS 3D transformation to position the popper. + * Otherwise, it will use the `top` and `left` properties + */ + gpuAcceleration: undefined + } + }; + + /** + * The `dataObject` is an object containing all the information used by Popper.js. + * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks. + * @name dataObject + * @property {Object} data.instance The Popper.js instance + * @property {String} data.placement Placement applied to popper + * @property {String} data.originalPlacement Placement originally defined on init + * @property {Boolean} data.flipped True if popper has been flipped by flip modifier + * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper + * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier + * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`) + * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`) + * @property {Object} data.boundaries Offsets of the popper boundaries + * @property {Object} data.offsets The measurements of popper, reference and arrow elements + * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values + * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values + * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0 + */ + + /** + * Default options provided to Popper.js constructor.
+ * These can be overridden using the `options` argument of Popper.js.
+ * To override an option, simply pass an object with the same + * structure of the `options` object, as the 3rd argument. For example: + * ``` + * new Popper(ref, pop, { + * modifiers: { + * preventOverflow: { enabled: false } + * } + * }) + * ``` + * @type {Object} + * @static + * @memberof Popper + */ + var Defaults = { + /** + * Popper's placement. + * @prop {Popper.placements} placement='bottom' + */ + placement: 'bottom', + + /** + * Set this to true if you want popper to position it self in 'fixed' mode + * @prop {Boolean} positionFixed=false + */ + positionFixed: false, + + /** + * Whether events (resize, scroll) are initially enabled. + * @prop {Boolean} eventsEnabled=true + */ + eventsEnabled: true, + + /** + * Set to true if you want to automatically remove the popper when + * you call the `destroy` method. + * @prop {Boolean} removeOnDestroy=false + */ + removeOnDestroy: false, + + /** + * Callback called when the popper is created.
+ * By default, it is set to no-op.
+ * Access Popper.js instance with `data.instance`. + * @prop {onCreate} + */ + onCreate: function onCreate() {}, + + /** + * Callback called when the popper is updated. This callback is not called + * on the initialization/creation of the popper, but only on subsequent + * updates.
+ * By default, it is set to no-op.
+ * Access Popper.js instance with `data.instance`. + * @prop {onUpdate} + */ + onUpdate: function onUpdate() {}, + + /** + * List of modifiers used to modify the offsets before they are applied to the popper. + * They provide most of the functionalities of Popper.js. + * @prop {modifiers} + */ + modifiers: modifiers + }; + + /** + * @callback onCreate + * @param {dataObject} data + */ + + /** + * @callback onUpdate + * @param {dataObject} data + */ + + // Utils + // Methods + var Popper = function () { + /** + * Creates a new Popper.js instance. + * @class Popper + * @param {Element|referenceObject} reference - The reference element used to position the popper + * @param {Element} popper - The HTML / XML element used as the popper + * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults) + * @return {Object} instance - The generated Popper.js instance + */ + function Popper(reference, popper) { + var _this = this; + + var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + classCallCheck(this, Popper); + + this.scheduleUpdate = function () { + return requestAnimationFrame(_this.update); + }; + + // make update() debounced, so that it only runs at most once-per-tick + this.update = debounce(this.update.bind(this)); + + // with {} we create a new object with the options inside it + this.options = _extends({}, Popper.Defaults, options); + + // init state + this.state = { + isDestroyed: false, + isCreated: false, + scrollParents: [] + }; + + // get reference and popper elements (allow jQuery wrappers) + this.reference = reference && reference.jquery ? reference[0] : reference; + this.popper = popper && popper.jquery ? popper[0] : popper; + + // Deep merge modifiers options + this.options.modifiers = {}; + Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) { + _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {}); + }); + + // Refactoring modifiers' list (Object => Array) + this.modifiers = Object.keys(this.options.modifiers).map(function (name) { + return _extends({ + name: name + }, _this.options.modifiers[name]); + }) + // sort the modifiers by order + .sort(function (a, b) { + return a.order - b.order; + }); + + // modifiers have the ability to execute arbitrary code when Popper.js get inited + // such code is executed in the same order of its modifier + // they could add new properties to their options configuration + // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`! + this.modifiers.forEach(function (modifierOptions) { + if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) { + modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state); + } + }); + + // fire the first update to position the popper in the right place + this.update(); + + var eventsEnabled = this.options.eventsEnabled; + if (eventsEnabled) { + // setup event listeners, they will take care of update the position in specific situations + this.enableEventListeners(); + } + + this.state.eventsEnabled = eventsEnabled; + } + + // We can't use class properties because they don't get listed in the + // class prototype and break stuff like Sinon stubs + + + createClass(Popper, [{ + key: 'update', + value: function update$$1() { + return update.call(this); + } + }, { + key: 'destroy', + value: function destroy$$1() { + return destroy.call(this); + } + }, { + key: 'enableEventListeners', + value: function enableEventListeners$$1() { + return enableEventListeners.call(this); + } + }, { + key: 'disableEventListeners', + value: function disableEventListeners$$1() { + return disableEventListeners.call(this); + } + + /** + * Schedules an update. It will run on the next UI update available. + * @method scheduleUpdate + * @memberof Popper + */ + + + /** + * Collection of utilities useful when writing custom modifiers. + * Starting from version 1.7, this method is available only if you + * include `popper-utils.js` before `popper.js`. + * + * **DEPRECATION**: This way to access PopperUtils is deprecated + * and will be removed in v2! Use the PopperUtils module directly instead. + * Due to the high instability of the methods contained in Utils, we can't + * guarantee them to follow semver. Use them at your own risk! + * @static + * @private + * @type {Object} + * @deprecated since version 1.8 + * @member Utils + * @memberof Popper + */ + + }]); + return Popper; + }(); + + /** + * The `referenceObject` is an object that provides an interface compatible with Popper.js + * and lets you use it as replacement of a real DOM node.
+ * You can use this method to position a popper relatively to a set of coordinates + * in case you don't have a DOM node to use as reference. + * + * ``` + * new Popper(referenceObject, popperNode); + * ``` + * + * NB: This feature isn't supported in Internet Explorer 10. + * @name referenceObject + * @property {Function} data.getBoundingClientRect + * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method. + * @property {number} data.clientWidth + * An ES6 getter that will return the width of the virtual reference element. + * @property {number} data.clientHeight + * An ES6 getter that will return the height of the virtual reference element. + */ + + + Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils; + Popper.placements = placements; + Popper.Defaults = Defaults; + + var Popper$1 = Popper; + + /** + * Constants + */ + + var NAME$6 = 'dropdown'; + var VERSION$6 = '4.6.1'; + var DATA_KEY$6 = 'bs.dropdown'; + var EVENT_KEY$6 = "." + DATA_KEY$6; + var DATA_API_KEY$3 = '.data-api'; + var JQUERY_NO_CONFLICT$6 = $__default["default"].fn[NAME$6]; + var ESCAPE_KEYCODE$1 = 27; // KeyboardEvent.which value for Escape (Esc) key + + var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key + + var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key + + var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key + + var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key + + var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse) + + var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE$1); + var CLASS_NAME_DISABLED$1 = 'disabled'; + var CLASS_NAME_SHOW$5 = 'show'; + var CLASS_NAME_DROPUP = 'dropup'; + var CLASS_NAME_DROPRIGHT = 'dropright'; + var CLASS_NAME_DROPLEFT = 'dropleft'; + var CLASS_NAME_MENURIGHT = 'dropdown-menu-right'; + var CLASS_NAME_POSITION_STATIC = 'position-static'; + var EVENT_HIDE$3 = "hide" + EVENT_KEY$6; + var EVENT_HIDDEN$3 = "hidden" + EVENT_KEY$6; + var EVENT_SHOW$3 = "show" + EVENT_KEY$6; + var EVENT_SHOWN$3 = "shown" + EVENT_KEY$6; + var EVENT_CLICK = "click" + EVENT_KEY$6; + var EVENT_CLICK_DATA_API$2 = "click" + EVENT_KEY$6 + DATA_API_KEY$3; + var EVENT_KEYDOWN_DATA_API = "keydown" + EVENT_KEY$6 + DATA_API_KEY$3; + var EVENT_KEYUP_DATA_API = "keyup" + EVENT_KEY$6 + DATA_API_KEY$3; + var SELECTOR_DATA_TOGGLE$2 = '[data-toggle="dropdown"]'; + var SELECTOR_FORM_CHILD = '.dropdown form'; + var SELECTOR_MENU = '.dropdown-menu'; + var SELECTOR_NAVBAR_NAV = '.navbar-nav'; + var SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)'; + var PLACEMENT_TOP = 'top-start'; + var PLACEMENT_TOPEND = 'top-end'; + var PLACEMENT_BOTTOM = 'bottom-start'; + var PLACEMENT_BOTTOMEND = 'bottom-end'; + var PLACEMENT_RIGHT = 'right-start'; + var PLACEMENT_LEFT = 'left-start'; + var Default$5 = { + offset: 0, + flip: true, + boundary: 'scrollParent', + reference: 'toggle', + display: 'dynamic', + popperConfig: null + }; + var DefaultType$5 = { + offset: '(number|string|function)', + flip: 'boolean', + boundary: '(string|element)', + reference: '(string|element)', + display: 'string', + popperConfig: '(null|object)' + }; + /** + * Class definition + */ + + var Dropdown = /*#__PURE__*/function () { + function Dropdown(element, config) { + this._element = element; + this._popper = null; + this._config = this._getConfig(config); + this._menu = this._getMenuElement(); + this._inNavbar = this._detectNavbar(); + + this._addEventListeners(); + } // Getters + + + var _proto = Dropdown.prototype; + + // Public + _proto.toggle = function toggle() { + if (this._element.disabled || $__default["default"](this._element).hasClass(CLASS_NAME_DISABLED$1)) { + return; + } + + var isActive = $__default["default"](this._menu).hasClass(CLASS_NAME_SHOW$5); + + Dropdown._clearMenus(); + + if (isActive) { + return; + } + + this.show(true); + }; + + _proto.show = function show(usePopper) { + if (usePopper === void 0) { + usePopper = false; + } + + if (this._element.disabled || $__default["default"](this._element).hasClass(CLASS_NAME_DISABLED$1) || $__default["default"](this._menu).hasClass(CLASS_NAME_SHOW$5)) { + return; + } + + var relatedTarget = { + relatedTarget: this._element + }; + var showEvent = $__default["default"].Event(EVENT_SHOW$3, relatedTarget); + + var parent = Dropdown._getParentFromElement(this._element); + + $__default["default"](parent).trigger(showEvent); + + if (showEvent.isDefaultPrevented()) { + return; + } // Totally disable Popper for Dropdowns in Navbar + + + if (!this._inNavbar && usePopper) { + // Check for Popper dependency + if (typeof Popper$1 === 'undefined') { + throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)'); + } + + var referenceElement = this._element; + + if (this._config.reference === 'parent') { + referenceElement = parent; + } else if (Util.isElement(this._config.reference)) { + referenceElement = this._config.reference; // Check if it's jQuery element + + if (typeof this._config.reference.jquery !== 'undefined') { + referenceElement = this._config.reference[0]; + } + } // If boundary is not `scrollParent`, then set position to `static` + // to allow the menu to "escape" the scroll parent's boundaries + // https://github.com/twbs/bootstrap/issues/24251 + + + if (this._config.boundary !== 'scrollParent') { + $__default["default"](parent).addClass(CLASS_NAME_POSITION_STATIC); + } + + this._popper = new Popper$1(referenceElement, this._menu, this._getPopperConfig()); + } // If this is a touch-enabled device we add extra + // empty mouseover listeners to the body's immediate children; + // only needed because of broken event delegation on iOS + // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html + + + if ('ontouchstart' in document.documentElement && $__default["default"](parent).closest(SELECTOR_NAVBAR_NAV).length === 0) { + $__default["default"](document.body).children().on('mouseover', null, $__default["default"].noop); + } + + this._element.focus(); + + this._element.setAttribute('aria-expanded', true); + + $__default["default"](this._menu).toggleClass(CLASS_NAME_SHOW$5); + $__default["default"](parent).toggleClass(CLASS_NAME_SHOW$5).trigger($__default["default"].Event(EVENT_SHOWN$3, relatedTarget)); + }; + + _proto.hide = function hide() { + if (this._element.disabled || $__default["default"](this._element).hasClass(CLASS_NAME_DISABLED$1) || !$__default["default"](this._menu).hasClass(CLASS_NAME_SHOW$5)) { + return; + } + + var relatedTarget = { + relatedTarget: this._element + }; + var hideEvent = $__default["default"].Event(EVENT_HIDE$3, relatedTarget); + + var parent = Dropdown._getParentFromElement(this._element); + + $__default["default"](parent).trigger(hideEvent); + + if (hideEvent.isDefaultPrevented()) { + return; + } + + if (this._popper) { + this._popper.destroy(); + } + + $__default["default"](this._menu).toggleClass(CLASS_NAME_SHOW$5); + $__default["default"](parent).toggleClass(CLASS_NAME_SHOW$5).trigger($__default["default"].Event(EVENT_HIDDEN$3, relatedTarget)); + }; + + _proto.dispose = function dispose() { + $__default["default"].removeData(this._element, DATA_KEY$6); + $__default["default"](this._element).off(EVENT_KEY$6); + this._element = null; + this._menu = null; + + if (this._popper !== null) { + this._popper.destroy(); + + this._popper = null; + } + }; + + _proto.update = function update() { + this._inNavbar = this._detectNavbar(); + + if (this._popper !== null) { + this._popper.scheduleUpdate(); + } + } // Private + ; + + _proto._addEventListeners = function _addEventListeners() { + var _this = this; + + $__default["default"](this._element).on(EVENT_CLICK, function (event) { + event.preventDefault(); + event.stopPropagation(); + + _this.toggle(); + }); + }; + + _proto._getConfig = function _getConfig(config) { + config = _extends$1({}, this.constructor.Default, $__default["default"](this._element).data(), config); + Util.typeCheckConfig(NAME$6, config, this.constructor.DefaultType); + return config; + }; + + _proto._getMenuElement = function _getMenuElement() { + if (!this._menu) { + var parent = Dropdown._getParentFromElement(this._element); + + if (parent) { + this._menu = parent.querySelector(SELECTOR_MENU); + } + } + + return this._menu; + }; + + _proto._getPlacement = function _getPlacement() { + var $parentDropdown = $__default["default"](this._element.parentNode); + var placement = PLACEMENT_BOTTOM; // Handle dropup + + if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) { + placement = $__default["default"](this._menu).hasClass(CLASS_NAME_MENURIGHT) ? PLACEMENT_TOPEND : PLACEMENT_TOP; + } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) { + placement = PLACEMENT_RIGHT; + } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) { + placement = PLACEMENT_LEFT; + } else if ($__default["default"](this._menu).hasClass(CLASS_NAME_MENURIGHT)) { + placement = PLACEMENT_BOTTOMEND; + } + + return placement; + }; + + _proto._detectNavbar = function _detectNavbar() { + return $__default["default"](this._element).closest('.navbar').length > 0; + }; + + _proto._getOffset = function _getOffset() { + var _this2 = this; + + var offset = {}; + + if (typeof this._config.offset === 'function') { + offset.fn = function (data) { + data.offsets = _extends$1({}, data.offsets, _this2._config.offset(data.offsets, _this2._element)); + return data; + }; + } else { + offset.offset = this._config.offset; + } + + return offset; + }; + + _proto._getPopperConfig = function _getPopperConfig() { + var popperConfig = { + placement: this._getPlacement(), + modifiers: { + offset: this._getOffset(), + flip: { + enabled: this._config.flip + }, + preventOverflow: { + boundariesElement: this._config.boundary + } + } + }; // Disable Popper if we have a static display + + if (this._config.display === 'static') { + popperConfig.modifiers.applyStyle = { + enabled: false + }; + } + + return _extends$1({}, popperConfig, this._config.popperConfig); + } // Static + ; + + Dropdown._jQueryInterface = function _jQueryInterface(config) { + return this.each(function () { + var data = $__default["default"](this).data(DATA_KEY$6); + + var _config = typeof config === 'object' ? config : null; + + if (!data) { + data = new Dropdown(this, _config); + $__default["default"](this).data(DATA_KEY$6, data); + } + + if (typeof config === 'string') { + if (typeof data[config] === 'undefined') { + throw new TypeError("No method named \"" + config + "\""); + } + + data[config](); + } + }); + }; + + Dropdown._clearMenus = function _clearMenus(event) { + if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) { + return; + } + + var toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE$2)); + + for (var i = 0, len = toggles.length; i < len; i++) { + var parent = Dropdown._getParentFromElement(toggles[i]); + + var context = $__default["default"](toggles[i]).data(DATA_KEY$6); + var relatedTarget = { + relatedTarget: toggles[i] + }; + + if (event && event.type === 'click') { + relatedTarget.clickEvent = event; + } + + if (!context) { + continue; + } + + var dropdownMenu = context._menu; + + if (!$__default["default"](parent).hasClass(CLASS_NAME_SHOW$5)) { + continue; + } + + if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $__default["default"].contains(parent, event.target)) { + continue; + } + + var hideEvent = $__default["default"].Event(EVENT_HIDE$3, relatedTarget); + $__default["default"](parent).trigger(hideEvent); + + if (hideEvent.isDefaultPrevented()) { + continue; + } // If this is a touch-enabled device we remove the extra + // empty mouseover listeners we added for iOS support + + + if ('ontouchstart' in document.documentElement) { + $__default["default"](document.body).children().off('mouseover', null, $__default["default"].noop); + } + + toggles[i].setAttribute('aria-expanded', 'false'); + + if (context._popper) { + context._popper.destroy(); + } + + $__default["default"](dropdownMenu).removeClass(CLASS_NAME_SHOW$5); + $__default["default"](parent).removeClass(CLASS_NAME_SHOW$5).trigger($__default["default"].Event(EVENT_HIDDEN$3, relatedTarget)); + } + }; + + Dropdown._getParentFromElement = function _getParentFromElement(element) { + var parent; + var selector = Util.getSelectorFromElement(element); + + if (selector) { + parent = document.querySelector(selector); + } + + return parent || element.parentNode; + } // eslint-disable-next-line complexity + ; + + Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) { + // If not input/textarea: + // - And not a key in REGEXP_KEYDOWN => not a dropdown command + // If input/textarea: + // - If space key => not a dropdown command + // - If key is other than escape + // - If key is not up or down => not a dropdown command + // - If trigger inside the menu => not a dropdown command + if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE$1 && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $__default["default"](event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) { + return; + } + + if (this.disabled || $__default["default"](this).hasClass(CLASS_NAME_DISABLED$1)) { + return; + } + + var parent = Dropdown._getParentFromElement(this); + + var isActive = $__default["default"](parent).hasClass(CLASS_NAME_SHOW$5); + + if (!isActive && event.which === ESCAPE_KEYCODE$1) { + return; + } + + event.preventDefault(); + event.stopPropagation(); + + if (!isActive || event.which === ESCAPE_KEYCODE$1 || event.which === SPACE_KEYCODE) { + if (event.which === ESCAPE_KEYCODE$1) { + $__default["default"](parent.querySelector(SELECTOR_DATA_TOGGLE$2)).trigger('focus'); + } + + $__default["default"](this).trigger('click'); + return; + } + + var items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS)).filter(function (item) { + return $__default["default"](item).is(':visible'); + }); + + if (items.length === 0) { + return; + } + + var index = items.indexOf(event.target); + + if (event.which === ARROW_UP_KEYCODE && index > 0) { + // Up + index--; + } + + if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) { + // Down + index++; + } + + if (index < 0) { + index = 0; + } + + items[index].focus(); + }; + + _createClass(Dropdown, null, [{ + key: "VERSION", + get: function get() { + return VERSION$6; + } + }, { + key: "Default", + get: function get() { + return Default$5; + } + }, { + key: "DefaultType", + get: function get() { + return DefaultType$5; + } + }]); + + return Dropdown; + }(); + /** + * Data API implementation + */ + + + $__default["default"](document).on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$2, Dropdown._dataApiKeydownHandler).on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler).on(EVENT_CLICK_DATA_API$2 + " " + EVENT_KEYUP_DATA_API, Dropdown._clearMenus).on(EVENT_CLICK_DATA_API$2, SELECTOR_DATA_TOGGLE$2, function (event) { + event.preventDefault(); + event.stopPropagation(); + + Dropdown._jQueryInterface.call($__default["default"](this), 'toggle'); + }).on(EVENT_CLICK_DATA_API$2, SELECTOR_FORM_CHILD, function (e) { + e.stopPropagation(); + }); + /** + * jQuery + */ + + $__default["default"].fn[NAME$6] = Dropdown._jQueryInterface; + $__default["default"].fn[NAME$6].Constructor = Dropdown; + + $__default["default"].fn[NAME$6].noConflict = function () { + $__default["default"].fn[NAME$6] = JQUERY_NO_CONFLICT$6; + return Dropdown._jQueryInterface; + }; + + /** + * Constants + */ + + var NAME$5 = 'modal'; + var VERSION$5 = '4.6.1'; + var DATA_KEY$5 = 'bs.modal'; + var EVENT_KEY$5 = "." + DATA_KEY$5; + var DATA_API_KEY$2 = '.data-api'; + var JQUERY_NO_CONFLICT$5 = $__default["default"].fn[NAME$5]; + var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key + + var CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable'; + var CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure'; + var CLASS_NAME_BACKDROP = 'modal-backdrop'; + var CLASS_NAME_OPEN = 'modal-open'; + var CLASS_NAME_FADE$4 = 'fade'; + var CLASS_NAME_SHOW$4 = 'show'; + var CLASS_NAME_STATIC = 'modal-static'; + var EVENT_HIDE$2 = "hide" + EVENT_KEY$5; + var EVENT_HIDE_PREVENTED = "hidePrevented" + EVENT_KEY$5; + var EVENT_HIDDEN$2 = "hidden" + EVENT_KEY$5; + var EVENT_SHOW$2 = "show" + EVENT_KEY$5; + var EVENT_SHOWN$2 = "shown" + EVENT_KEY$5; + var EVENT_FOCUSIN = "focusin" + EVENT_KEY$5; + var EVENT_RESIZE = "resize" + EVENT_KEY$5; + var EVENT_CLICK_DISMISS$1 = "click.dismiss" + EVENT_KEY$5; + var EVENT_KEYDOWN_DISMISS = "keydown.dismiss" + EVENT_KEY$5; + var EVENT_MOUSEUP_DISMISS = "mouseup.dismiss" + EVENT_KEY$5; + var EVENT_MOUSEDOWN_DISMISS = "mousedown.dismiss" + EVENT_KEY$5; + var EVENT_CLICK_DATA_API$1 = "click" + EVENT_KEY$5 + DATA_API_KEY$2; + var SELECTOR_DIALOG = '.modal-dialog'; + var SELECTOR_MODAL_BODY = '.modal-body'; + var SELECTOR_DATA_TOGGLE$1 = '[data-toggle="modal"]'; + var SELECTOR_DATA_DISMISS$1 = '[data-dismiss="modal"]'; + var SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top'; + var SELECTOR_STICKY_CONTENT = '.sticky-top'; + var Default$4 = { + backdrop: true, + keyboard: true, + focus: true, + show: true + }; + var DefaultType$4 = { + backdrop: '(boolean|string)', + keyboard: 'boolean', + focus: 'boolean', + show: 'boolean' + }; + /** + * Class definition + */ + + var Modal = /*#__PURE__*/function () { + function Modal(element, config) { + this._config = this._getConfig(config); + this._element = element; + this._dialog = element.querySelector(SELECTOR_DIALOG); + this._backdrop = null; + this._isShown = false; + this._isBodyOverflowing = false; + this._ignoreBackdropClick = false; + this._isTransitioning = false; + this._scrollbarWidth = 0; + } // Getters + + + var _proto = Modal.prototype; + + // Public + _proto.toggle = function toggle(relatedTarget) { + return this._isShown ? this.hide() : this.show(relatedTarget); + }; + + _proto.show = function show(relatedTarget) { + var _this = this; + + if (this._isShown || this._isTransitioning) { + return; + } + + var showEvent = $__default["default"].Event(EVENT_SHOW$2, { + relatedTarget: relatedTarget + }); + $__default["default"](this._element).trigger(showEvent); + + if (showEvent.isDefaultPrevented()) { + return; + } + + this._isShown = true; + + if ($__default["default"](this._element).hasClass(CLASS_NAME_FADE$4)) { + this._isTransitioning = true; + } + + this._checkScrollbar(); + + this._setScrollbar(); + + this._adjustDialog(); + + this._setEscapeEvent(); + + this._setResizeEvent(); + + $__default["default"](this._element).on(EVENT_CLICK_DISMISS$1, SELECTOR_DATA_DISMISS$1, function (event) { + return _this.hide(event); + }); + $__default["default"](this._dialog).on(EVENT_MOUSEDOWN_DISMISS, function () { + $__default["default"](_this._element).one(EVENT_MOUSEUP_DISMISS, function (event) { + if ($__default["default"](event.target).is(_this._element)) { + _this._ignoreBackdropClick = true; + } + }); + }); + + this._showBackdrop(function () { + return _this._showElement(relatedTarget); + }); + }; + + _proto.hide = function hide(event) { + var _this2 = this; + + if (event) { + event.preventDefault(); + } + + if (!this._isShown || this._isTransitioning) { + return; + } + + var hideEvent = $__default["default"].Event(EVENT_HIDE$2); + $__default["default"](this._element).trigger(hideEvent); + + if (!this._isShown || hideEvent.isDefaultPrevented()) { + return; + } + + this._isShown = false; + var transition = $__default["default"](this._element).hasClass(CLASS_NAME_FADE$4); + + if (transition) { + this._isTransitioning = true; + } + + this._setEscapeEvent(); + + this._setResizeEvent(); + + $__default["default"](document).off(EVENT_FOCUSIN); + $__default["default"](this._element).removeClass(CLASS_NAME_SHOW$4); + $__default["default"](this._element).off(EVENT_CLICK_DISMISS$1); + $__default["default"](this._dialog).off(EVENT_MOUSEDOWN_DISMISS); + + if (transition) { + var transitionDuration = Util.getTransitionDurationFromElement(this._element); + $__default["default"](this._element).one(Util.TRANSITION_END, function (event) { + return _this2._hideModal(event); + }).emulateTransitionEnd(transitionDuration); + } else { + this._hideModal(); + } + }; + + _proto.dispose = function dispose() { + [window, this._element, this._dialog].forEach(function (htmlElement) { + return $__default["default"](htmlElement).off(EVENT_KEY$5); + }); + /** + * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API` + * Do not move `document` in `htmlElements` array + * It will remove `EVENT_CLICK_DATA_API` event that should remain + */ + + $__default["default"](document).off(EVENT_FOCUSIN); + $__default["default"].removeData(this._element, DATA_KEY$5); + this._config = null; + this._element = null; + this._dialog = null; + this._backdrop = null; + this._isShown = null; + this._isBodyOverflowing = null; + this._ignoreBackdropClick = null; + this._isTransitioning = null; + this._scrollbarWidth = null; + }; + + _proto.handleUpdate = function handleUpdate() { + this._adjustDialog(); + } // Private + ; + + _proto._getConfig = function _getConfig(config) { + config = _extends$1({}, Default$4, config); + Util.typeCheckConfig(NAME$5, config, DefaultType$4); + return config; + }; + + _proto._triggerBackdropTransition = function _triggerBackdropTransition() { + var _this3 = this; + + var hideEventPrevented = $__default["default"].Event(EVENT_HIDE_PREVENTED); + $__default["default"](this._element).trigger(hideEventPrevented); + + if (hideEventPrevented.isDefaultPrevented()) { + return; + } + + var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; + + if (!isModalOverflowing) { + this._element.style.overflowY = 'hidden'; + } + + this._element.classList.add(CLASS_NAME_STATIC); + + var modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog); + $__default["default"](this._element).off(Util.TRANSITION_END); + $__default["default"](this._element).one(Util.TRANSITION_END, function () { + _this3._element.classList.remove(CLASS_NAME_STATIC); + + if (!isModalOverflowing) { + $__default["default"](_this3._element).one(Util.TRANSITION_END, function () { + _this3._element.style.overflowY = ''; + }).emulateTransitionEnd(_this3._element, modalTransitionDuration); + } + }).emulateTransitionEnd(modalTransitionDuration); + + this._element.focus(); + }; + + _proto._showElement = function _showElement(relatedTarget) { + var _this4 = this; + + var transition = $__default["default"](this._element).hasClass(CLASS_NAME_FADE$4); + var modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null; + + if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) { + // Don't move modal's DOM position + document.body.appendChild(this._element); + } + + this._element.style.display = 'block'; + + this._element.removeAttribute('aria-hidden'); + + this._element.setAttribute('aria-modal', true); + + this._element.setAttribute('role', 'dialog'); + + if ($__default["default"](this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) { + modalBody.scrollTop = 0; + } else { + this._element.scrollTop = 0; + } + + if (transition) { + Util.reflow(this._element); + } + + $__default["default"](this._element).addClass(CLASS_NAME_SHOW$4); + + if (this._config.focus) { + this._enforceFocus(); + } + + var shownEvent = $__default["default"].Event(EVENT_SHOWN$2, { + relatedTarget: relatedTarget + }); + + var transitionComplete = function transitionComplete() { + if (_this4._config.focus) { + _this4._element.focus(); + } + + _this4._isTransitioning = false; + $__default["default"](_this4._element).trigger(shownEvent); + }; + + if (transition) { + var transitionDuration = Util.getTransitionDurationFromElement(this._dialog); + $__default["default"](this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(transitionDuration); + } else { + transitionComplete(); + } + }; + + _proto._enforceFocus = function _enforceFocus() { + var _this5 = this; + + $__default["default"](document).off(EVENT_FOCUSIN) // Guard against infinite focus loop + .on(EVENT_FOCUSIN, function (event) { + if (document !== event.target && _this5._element !== event.target && $__default["default"](_this5._element).has(event.target).length === 0) { + _this5._element.focus(); + } + }); + }; + + _proto._setEscapeEvent = function _setEscapeEvent() { + var _this6 = this; + + if (this._isShown) { + $__default["default"](this._element).on(EVENT_KEYDOWN_DISMISS, function (event) { + if (_this6._config.keyboard && event.which === ESCAPE_KEYCODE) { + event.preventDefault(); + + _this6.hide(); + } else if (!_this6._config.keyboard && event.which === ESCAPE_KEYCODE) { + _this6._triggerBackdropTransition(); + } + }); + } else if (!this._isShown) { + $__default["default"](this._element).off(EVENT_KEYDOWN_DISMISS); + } + }; + + _proto._setResizeEvent = function _setResizeEvent() { + var _this7 = this; + + if (this._isShown) { + $__default["default"](window).on(EVENT_RESIZE, function (event) { + return _this7.handleUpdate(event); + }); + } else { + $__default["default"](window).off(EVENT_RESIZE); + } + }; + + _proto._hideModal = function _hideModal() { + var _this8 = this; + + this._element.style.display = 'none'; + + this._element.setAttribute('aria-hidden', true); + + this._element.removeAttribute('aria-modal'); + + this._element.removeAttribute('role'); + + this._isTransitioning = false; + + this._showBackdrop(function () { + $__default["default"](document.body).removeClass(CLASS_NAME_OPEN); + + _this8._resetAdjustments(); + + _this8._resetScrollbar(); + + $__default["default"](_this8._element).trigger(EVENT_HIDDEN$2); + }); + }; + + _proto._removeBackdrop = function _removeBackdrop() { + if (this._backdrop) { + $__default["default"](this._backdrop).remove(); + this._backdrop = null; + } + }; + + _proto._showBackdrop = function _showBackdrop(callback) { + var _this9 = this; + + var animate = $__default["default"](this._element).hasClass(CLASS_NAME_FADE$4) ? CLASS_NAME_FADE$4 : ''; + + if (this._isShown && this._config.backdrop) { + this._backdrop = document.createElement('div'); + this._backdrop.className = CLASS_NAME_BACKDROP; + + if (animate) { + this._backdrop.classList.add(animate); + } + + $__default["default"](this._backdrop).appendTo(document.body); + $__default["default"](this._element).on(EVENT_CLICK_DISMISS$1, function (event) { + if (_this9._ignoreBackdropClick) { + _this9._ignoreBackdropClick = false; + return; + } + + if (event.target !== event.currentTarget) { + return; + } + + if (_this9._config.backdrop === 'static') { + _this9._triggerBackdropTransition(); + } else { + _this9.hide(); + } + }); + + if (animate) { + Util.reflow(this._backdrop); + } + + $__default["default"](this._backdrop).addClass(CLASS_NAME_SHOW$4); + + if (!callback) { + return; + } + + if (!animate) { + callback(); + return; + } + + var backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop); + $__default["default"](this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(backdropTransitionDuration); + } else if (!this._isShown && this._backdrop) { + $__default["default"](this._backdrop).removeClass(CLASS_NAME_SHOW$4); + + var callbackRemove = function callbackRemove() { + _this9._removeBackdrop(); + + if (callback) { + callback(); + } + }; + + if ($__default["default"](this._element).hasClass(CLASS_NAME_FADE$4)) { + var _backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop); + + $__default["default"](this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(_backdropTransitionDuration); + } else { + callbackRemove(); + } + } else if (callback) { + callback(); + } + } // ---------------------------------------------------------------------- + // the following methods are used to handle overflowing modals + // todo (fat): these should probably be refactored out of modal.js + // ---------------------------------------------------------------------- + ; + + _proto._adjustDialog = function _adjustDialog() { + var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight; + + if (!this._isBodyOverflowing && isModalOverflowing) { + this._element.style.paddingLeft = this._scrollbarWidth + "px"; + } + + if (this._isBodyOverflowing && !isModalOverflowing) { + this._element.style.paddingRight = this._scrollbarWidth + "px"; + } + }; + + _proto._resetAdjustments = function _resetAdjustments() { + this._element.style.paddingLeft = ''; + this._element.style.paddingRight = ''; + }; + + _proto._checkScrollbar = function _checkScrollbar() { + var rect = document.body.getBoundingClientRect(); + this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth; + this._scrollbarWidth = this._getScrollbarWidth(); + }; + + _proto._setScrollbar = function _setScrollbar() { + var _this10 = this; + + if (this._isBodyOverflowing) { + // Note: DOMNode.style.paddingRight returns the actual value or '' if not set + // while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set + var fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT)); + var stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT)); // Adjust fixed content padding + + $__default["default"](fixedContent).each(function (index, element) { + var actualPadding = element.style.paddingRight; + var calculatedPadding = $__default["default"](element).css('padding-right'); + $__default["default"](element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + _this10._scrollbarWidth + "px"); + }); // Adjust sticky content margin + + $__default["default"](stickyContent).each(function (index, element) { + var actualMargin = element.style.marginRight; + var calculatedMargin = $__default["default"](element).css('margin-right'); + $__default["default"](element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) - _this10._scrollbarWidth + "px"); + }); // Adjust body padding + + var actualPadding = document.body.style.paddingRight; + var calculatedPadding = $__default["default"](document.body).css('padding-right'); + $__default["default"](document.body).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + "px"); + } + + $__default["default"](document.body).addClass(CLASS_NAME_OPEN); + }; + + _proto._resetScrollbar = function _resetScrollbar() { + // Restore fixed content padding + var fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT)); + $__default["default"](fixedContent).each(function (index, element) { + var padding = $__default["default"](element).data('padding-right'); + $__default["default"](element).removeData('padding-right'); + element.style.paddingRight = padding ? padding : ''; + }); // Restore sticky content + + var elements = [].slice.call(document.querySelectorAll("" + SELECTOR_STICKY_CONTENT)); + $__default["default"](elements).each(function (index, element) { + var margin = $__default["default"](element).data('margin-right'); + + if (typeof margin !== 'undefined') { + $__default["default"](element).css('margin-right', margin).removeData('margin-right'); + } + }); // Restore body padding + + var padding = $__default["default"](document.body).data('padding-right'); + $__default["default"](document.body).removeData('padding-right'); + document.body.style.paddingRight = padding ? padding : ''; + }; + + _proto._getScrollbarWidth = function _getScrollbarWidth() { + // thx d.walsh + var scrollDiv = document.createElement('div'); + scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER; + document.body.appendChild(scrollDiv); + var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth; + document.body.removeChild(scrollDiv); + return scrollbarWidth; + } // Static + ; + + Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) { + return this.each(function () { + var data = $__default["default"](this).data(DATA_KEY$5); + + var _config = _extends$1({}, Default$4, $__default["default"](this).data(), typeof config === 'object' && config ? config : {}); + + if (!data) { + data = new Modal(this, _config); + $__default["default"](this).data(DATA_KEY$5, data); + } + + if (typeof config === 'string') { + if (typeof data[config] === 'undefined') { + throw new TypeError("No method named \"" + config + "\""); + } + + data[config](relatedTarget); + } else if (_config.show) { + data.show(relatedTarget); + } + }); + }; + + _createClass(Modal, null, [{ + key: "VERSION", + get: function get() { + return VERSION$5; + } + }, { + key: "Default", + get: function get() { + return Default$4; + } + }]); + + return Modal; + }(); + /** + * Data API implementation + */ + + + $__default["default"](document).on(EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE$1, function (event) { + var _this11 = this; + + var target; + var selector = Util.getSelectorFromElement(this); + + if (selector) { + target = document.querySelector(selector); + } + + var config = $__default["default"](target).data(DATA_KEY$5) ? 'toggle' : _extends$1({}, $__default["default"](target).data(), $__default["default"](this).data()); + + if (this.tagName === 'A' || this.tagName === 'AREA') { + event.preventDefault(); + } + + var $target = $__default["default"](target).one(EVENT_SHOW$2, function (showEvent) { + if (showEvent.isDefaultPrevented()) { + // Only register focus restorer if modal will actually get shown + return; + } + + $target.one(EVENT_HIDDEN$2, function () { + if ($__default["default"](_this11).is(':visible')) { + _this11.focus(); + } + }); + }); + + Modal._jQueryInterface.call($__default["default"](target), config, this); + }); + /** + * jQuery + */ + + $__default["default"].fn[NAME$5] = Modal._jQueryInterface; + $__default["default"].fn[NAME$5].Constructor = Modal; + + $__default["default"].fn[NAME$5].noConflict = function () { + $__default["default"].fn[NAME$5] = JQUERY_NO_CONFLICT$5; + return Modal._jQueryInterface; + }; + + /** + * -------------------------------------------------------------------------- + * Bootstrap (v4.6.1): tools/sanitizer.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + * -------------------------------------------------------------------------- + */ + var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href']; + var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; + var DefaultWhitelist = { + // Global attributes allowed on any supplied element below. + '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN], + a: ['target', 'href', 'title', 'rel'], + area: [], + b: [], + br: [], + col: [], + code: [], + div: [], + em: [], + hr: [], + h1: [], + h2: [], + h3: [], + h4: [], + h5: [], + h6: [], + i: [], + img: ['src', 'srcset', 'alt', 'title', 'width', 'height'], + li: [], + ol: [], + p: [], + pre: [], + s: [], + small: [], + span: [], + sub: [], + sup: [], + strong: [], + u: [], + ul: [] + }; + /** + * A pattern that recognizes a commonly useful subset of URLs that are safe. + * + * Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts + */ + + var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file|sms):|[^#&/:?]*(?:[#/?]|$))/i; + /** + * A pattern that matches safe data URLs. Only matches image, video and audio types. + * + * Shoutout to Angular https://github.com/angular/angular/blob/12.2.x/packages/core/src/sanitization/url_sanitizer.ts + */ + + var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i; + + function allowedAttribute(attr, allowedAttributeList) { + var attrName = attr.nodeName.toLowerCase(); + + if (allowedAttributeList.indexOf(attrName) !== -1) { + if (uriAttrs.indexOf(attrName) !== -1) { + return Boolean(SAFE_URL_PATTERN.test(attr.nodeValue) || DATA_URL_PATTERN.test(attr.nodeValue)); + } + + return true; + } + + var regExp = allowedAttributeList.filter(function (attrRegex) { + return attrRegex instanceof RegExp; + }); // Check if a regular expression validates the attribute. + + for (var i = 0, len = regExp.length; i < len; i++) { + if (regExp[i].test(attrName)) { + return true; + } + } + + return false; + } + + function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) { + if (unsafeHtml.length === 0) { + return unsafeHtml; + } + + if (sanitizeFn && typeof sanitizeFn === 'function') { + return sanitizeFn(unsafeHtml); + } + + var domParser = new window.DOMParser(); + var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html'); + var whitelistKeys = Object.keys(whiteList); + var elements = [].slice.call(createdDocument.body.querySelectorAll('*')); + + var _loop = function _loop(i, len) { + var el = elements[i]; + var elName = el.nodeName.toLowerCase(); + + if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) { + el.parentNode.removeChild(el); + return "continue"; + } + + var attributeList = [].slice.call(el.attributes); // eslint-disable-next-line unicorn/prefer-spread + + var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []); + attributeList.forEach(function (attr) { + if (!allowedAttribute(attr, whitelistedAttributes)) { + el.removeAttribute(attr.nodeName); + } + }); + }; + + for (var i = 0, len = elements.length; i < len; i++) { + var _ret = _loop(i); + + if (_ret === "continue") continue; + } + + return createdDocument.body.innerHTML; + } + + /** + * Constants + */ + + var NAME$4 = 'tooltip'; + var VERSION$4 = '4.6.1'; + var DATA_KEY$4 = 'bs.tooltip'; + var EVENT_KEY$4 = "." + DATA_KEY$4; + var JQUERY_NO_CONFLICT$4 = $__default["default"].fn[NAME$4]; + var CLASS_PREFIX$1 = 'bs-tooltip'; + var BSCLS_PREFIX_REGEX$1 = new RegExp("(^|\\s)" + CLASS_PREFIX$1 + "\\S+", 'g'); + var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']; + var CLASS_NAME_FADE$3 = 'fade'; + var CLASS_NAME_SHOW$3 = 'show'; + var HOVER_STATE_SHOW = 'show'; + var HOVER_STATE_OUT = 'out'; + var SELECTOR_TOOLTIP_INNER = '.tooltip-inner'; + var SELECTOR_ARROW = '.arrow'; + var TRIGGER_HOVER = 'hover'; + var TRIGGER_FOCUS = 'focus'; + var TRIGGER_CLICK = 'click'; + var TRIGGER_MANUAL = 'manual'; + var AttachmentMap = { + AUTO: 'auto', + TOP: 'top', + RIGHT: 'right', + BOTTOM: 'bottom', + LEFT: 'left' + }; + var Default$3 = { + animation: true, + template: '

', + trigger: 'hover focus', + title: '', + delay: 0, + html: false, + selector: false, + placement: 'top', + offset: 0, + container: false, + fallbackPlacement: 'flip', + boundary: 'scrollParent', + customClass: '', + sanitize: true, + sanitizeFn: null, + whiteList: DefaultWhitelist, + popperConfig: null + }; + var DefaultType$3 = { + animation: 'boolean', + template: 'string', + title: '(string|element|function)', + trigger: 'string', + delay: '(number|object)', + html: 'boolean', + selector: '(string|boolean)', + placement: '(string|function)', + offset: '(number|string|function)', + container: '(string|element|boolean)', + fallbackPlacement: '(string|array)', + boundary: '(string|element)', + customClass: '(string|function)', + sanitize: 'boolean', + sanitizeFn: '(null|function)', + whiteList: 'object', + popperConfig: '(null|object)' + }; + var Event$1 = { + HIDE: "hide" + EVENT_KEY$4, + HIDDEN: "hidden" + EVENT_KEY$4, + SHOW: "show" + EVENT_KEY$4, + SHOWN: "shown" + EVENT_KEY$4, + INSERTED: "inserted" + EVENT_KEY$4, + CLICK: "click" + EVENT_KEY$4, + FOCUSIN: "focusin" + EVENT_KEY$4, + FOCUSOUT: "focusout" + EVENT_KEY$4, + MOUSEENTER: "mouseenter" + EVENT_KEY$4, + MOUSELEAVE: "mouseleave" + EVENT_KEY$4 + }; + /** + * Class definition + */ + + var Tooltip = /*#__PURE__*/function () { + function Tooltip(element, config) { + if (typeof Popper$1 === 'undefined') { + throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)'); + } // Private + + + this._isEnabled = true; + this._timeout = 0; + this._hoverState = ''; + this._activeTrigger = {}; + this._popper = null; // Protected + + this.element = element; + this.config = this._getConfig(config); + this.tip = null; + + this._setListeners(); + } // Getters + + + var _proto = Tooltip.prototype; + + // Public + _proto.enable = function enable() { + this._isEnabled = true; + }; + + _proto.disable = function disable() { + this._isEnabled = false; + }; + + _proto.toggleEnabled = function toggleEnabled() { + this._isEnabled = !this._isEnabled; + }; + + _proto.toggle = function toggle(event) { + if (!this._isEnabled) { + return; + } + + if (event) { + var dataKey = this.constructor.DATA_KEY; + var context = $__default["default"](event.currentTarget).data(dataKey); + + if (!context) { + context = new this.constructor(event.currentTarget, this._getDelegateConfig()); + $__default["default"](event.currentTarget).data(dataKey, context); + } + + context._activeTrigger.click = !context._activeTrigger.click; + + if (context._isWithActiveTrigger()) { + context._enter(null, context); + } else { + context._leave(null, context); + } + } else { + if ($__default["default"](this.getTipElement()).hasClass(CLASS_NAME_SHOW$3)) { + this._leave(null, this); + + return; + } + + this._enter(null, this); + } + }; + + _proto.dispose = function dispose() { + clearTimeout(this._timeout); + $__default["default"].removeData(this.element, this.constructor.DATA_KEY); + $__default["default"](this.element).off(this.constructor.EVENT_KEY); + $__default["default"](this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler); + + if (this.tip) { + $__default["default"](this.tip).remove(); + } + + this._isEnabled = null; + this._timeout = null; + this._hoverState = null; + this._activeTrigger = null; + + if (this._popper) { + this._popper.destroy(); + } + + this._popper = null; + this.element = null; + this.config = null; + this.tip = null; + }; + + _proto.show = function show() { + var _this = this; + + if ($__default["default"](this.element).css('display') === 'none') { + throw new Error('Please use show on visible elements'); + } + + var showEvent = $__default["default"].Event(this.constructor.Event.SHOW); + + if (this.isWithContent() && this._isEnabled) { + $__default["default"](this.element).trigger(showEvent); + var shadowRoot = Util.findShadowRoot(this.element); + var isInTheDom = $__default["default"].contains(shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement, this.element); + + if (showEvent.isDefaultPrevented() || !isInTheDom) { + return; + } + + var tip = this.getTipElement(); + var tipId = Util.getUID(this.constructor.NAME); + tip.setAttribute('id', tipId); + this.element.setAttribute('aria-describedby', tipId); + this.setContent(); + + if (this.config.animation) { + $__default["default"](tip).addClass(CLASS_NAME_FADE$3); + } + + var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement; + + var attachment = this._getAttachment(placement); + + this.addAttachmentClass(attachment); + + var container = this._getContainer(); + + $__default["default"](tip).data(this.constructor.DATA_KEY, this); + + if (!$__default["default"].contains(this.element.ownerDocument.documentElement, this.tip)) { + $__default["default"](tip).appendTo(container); + } + + $__default["default"](this.element).trigger(this.constructor.Event.INSERTED); + this._popper = new Popper$1(this.element, tip, this._getPopperConfig(attachment)); + $__default["default"](tip).addClass(CLASS_NAME_SHOW$3); + $__default["default"](tip).addClass(this.config.customClass); // If this is a touch-enabled device we add extra + // empty mouseover listeners to the body's immediate children; + // only needed because of broken event delegation on iOS + // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html + + if ('ontouchstart' in document.documentElement) { + $__default["default"](document.body).children().on('mouseover', null, $__default["default"].noop); + } + + var complete = function complete() { + if (_this.config.animation) { + _this._fixTransition(); + } + + var prevHoverState = _this._hoverState; + _this._hoverState = null; + $__default["default"](_this.element).trigger(_this.constructor.Event.SHOWN); + + if (prevHoverState === HOVER_STATE_OUT) { + _this._leave(null, _this); + } + }; + + if ($__default["default"](this.tip).hasClass(CLASS_NAME_FADE$3)) { + var transitionDuration = Util.getTransitionDurationFromElement(this.tip); + $__default["default"](this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); + } else { + complete(); + } + } + }; + + _proto.hide = function hide(callback) { + var _this2 = this; + + var tip = this.getTipElement(); + var hideEvent = $__default["default"].Event(this.constructor.Event.HIDE); + + var complete = function complete() { + if (_this2._hoverState !== HOVER_STATE_SHOW && tip.parentNode) { + tip.parentNode.removeChild(tip); + } + + _this2._cleanTipClass(); + + _this2.element.removeAttribute('aria-describedby'); + + $__default["default"](_this2.element).trigger(_this2.constructor.Event.HIDDEN); + + if (_this2._popper !== null) { + _this2._popper.destroy(); + } + + if (callback) { + callback(); + } + }; + + $__default["default"](this.element).trigger(hideEvent); + + if (hideEvent.isDefaultPrevented()) { + return; + } + + $__default["default"](tip).removeClass(CLASS_NAME_SHOW$3); // If this is a touch-enabled device we remove the extra + // empty mouseover listeners we added for iOS support + + if ('ontouchstart' in document.documentElement) { + $__default["default"](document.body).children().off('mouseover', null, $__default["default"].noop); + } + + this._activeTrigger[TRIGGER_CLICK] = false; + this._activeTrigger[TRIGGER_FOCUS] = false; + this._activeTrigger[TRIGGER_HOVER] = false; + + if ($__default["default"](this.tip).hasClass(CLASS_NAME_FADE$3)) { + var transitionDuration = Util.getTransitionDurationFromElement(tip); + $__default["default"](tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration); + } else { + complete(); + } + + this._hoverState = ''; + }; + + _proto.update = function update() { + if (this._popper !== null) { + this._popper.scheduleUpdate(); + } + } // Protected + ; + + _proto.isWithContent = function isWithContent() { + return Boolean(this.getTitle()); + }; + + _proto.addAttachmentClass = function addAttachmentClass(attachment) { + $__default["default"](this.getTipElement()).addClass(CLASS_PREFIX$1 + "-" + attachment); + }; + + _proto.getTipElement = function getTipElement() { + this.tip = this.tip || $__default["default"](this.config.template)[0]; + return this.tip; + }; + + _proto.setContent = function setContent() { + var tip = this.getTipElement(); + this.setElementContent($__default["default"](tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle()); + $__default["default"](tip).removeClass(CLASS_NAME_FADE$3 + " " + CLASS_NAME_SHOW$3); + }; + + _proto.setElementContent = function setElementContent($element, content) { + if (typeof content === 'object' && (content.nodeType || content.jquery)) { + // Content is a DOM node or a jQuery + if (this.config.html) { + if (!$__default["default"](content).parent().is($element)) { + $element.empty().append(content); + } + } else { + $element.text($__default["default"](content).text()); + } + + return; + } + + if (this.config.html) { + if (this.config.sanitize) { + content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn); + } + + $element.html(content); + } else { + $element.text(content); + } + }; + + _proto.getTitle = function getTitle() { + var title = this.element.getAttribute('data-original-title'); + + if (!title) { + title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title; + } + + return title; + } // Private + ; + + _proto._getPopperConfig = function _getPopperConfig(attachment) { + var _this3 = this; + + var defaultBsConfig = { + placement: attachment, + modifiers: { + offset: this._getOffset(), + flip: { + behavior: this.config.fallbackPlacement + }, + arrow: { + element: SELECTOR_ARROW + }, + preventOverflow: { + boundariesElement: this.config.boundary + } + }, + onCreate: function onCreate(data) { + if (data.originalPlacement !== data.placement) { + _this3._handlePopperPlacementChange(data); + } + }, + onUpdate: function onUpdate(data) { + return _this3._handlePopperPlacementChange(data); + } + }; + return _extends$1({}, defaultBsConfig, this.config.popperConfig); + }; + + _proto._getOffset = function _getOffset() { + var _this4 = this; + + var offset = {}; + + if (typeof this.config.offset === 'function') { + offset.fn = function (data) { + data.offsets = _extends$1({}, data.offsets, _this4.config.offset(data.offsets, _this4.element)); + return data; + }; + } else { + offset.offset = this.config.offset; + } + + return offset; + }; + + _proto._getContainer = function _getContainer() { + if (this.config.container === false) { + return document.body; + } + + if (Util.isElement(this.config.container)) { + return $__default["default"](this.config.container); + } + + return $__default["default"](document).find(this.config.container); + }; + + _proto._getAttachment = function _getAttachment(placement) { + return AttachmentMap[placement.toUpperCase()]; + }; + + _proto._setListeners = function _setListeners() { + var _this5 = this; + + var triggers = this.config.trigger.split(' '); + triggers.forEach(function (trigger) { + if (trigger === 'click') { + $__default["default"](_this5.element).on(_this5.constructor.Event.CLICK, _this5.config.selector, function (event) { + return _this5.toggle(event); + }); + } else if (trigger !== TRIGGER_MANUAL) { + var eventIn = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSEENTER : _this5.constructor.Event.FOCUSIN; + var eventOut = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSELEAVE : _this5.constructor.Event.FOCUSOUT; + $__default["default"](_this5.element).on(eventIn, _this5.config.selector, function (event) { + return _this5._enter(event); + }).on(eventOut, _this5.config.selector, function (event) { + return _this5._leave(event); + }); + } + }); + + this._hideModalHandler = function () { + if (_this5.element) { + _this5.hide(); + } + }; + + $__default["default"](this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler); + + if (this.config.selector) { + this.config = _extends$1({}, this.config, { + trigger: 'manual', + selector: '' + }); + } else { + this._fixTitle(); + } + }; + + _proto._fixTitle = function _fixTitle() { + var titleType = typeof this.element.getAttribute('data-original-title'); + + if (this.element.getAttribute('title') || titleType !== 'string') { + this.element.setAttribute('data-original-title', this.element.getAttribute('title') || ''); + this.element.setAttribute('title', ''); + } + }; + + _proto._enter = function _enter(event, context) { + var dataKey = this.constructor.DATA_KEY; + context = context || $__default["default"](event.currentTarget).data(dataKey); + + if (!context) { + context = new this.constructor(event.currentTarget, this._getDelegateConfig()); + $__default["default"](event.currentTarget).data(dataKey, context); + } + + if (event) { + context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true; + } + + if ($__default["default"](context.getTipElement()).hasClass(CLASS_NAME_SHOW$3) || context._hoverState === HOVER_STATE_SHOW) { + context._hoverState = HOVER_STATE_SHOW; + return; + } + + clearTimeout(context._timeout); + context._hoverState = HOVER_STATE_SHOW; + + if (!context.config.delay || !context.config.delay.show) { + context.show(); + return; + } + + context._timeout = setTimeout(function () { + if (context._hoverState === HOVER_STATE_SHOW) { + context.show(); + } + }, context.config.delay.show); + }; + + _proto._leave = function _leave(event, context) { + var dataKey = this.constructor.DATA_KEY; + context = context || $__default["default"](event.currentTarget).data(dataKey); + + if (!context) { + context = new this.constructor(event.currentTarget, this._getDelegateConfig()); + $__default["default"](event.currentTarget).data(dataKey, context); + } + + if (event) { + context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = false; + } + + if (context._isWithActiveTrigger()) { + return; + } + + clearTimeout(context._timeout); + context._hoverState = HOVER_STATE_OUT; + + if (!context.config.delay || !context.config.delay.hide) { + context.hide(); + return; + } + + context._timeout = setTimeout(function () { + if (context._hoverState === HOVER_STATE_OUT) { + context.hide(); + } + }, context.config.delay.hide); + }; + + _proto._isWithActiveTrigger = function _isWithActiveTrigger() { + for (var trigger in this._activeTrigger) { + if (this._activeTrigger[trigger]) { + return true; + } + } + + return false; + }; + + _proto._getConfig = function _getConfig(config) { + var dataAttributes = $__default["default"](this.element).data(); + Object.keys(dataAttributes).forEach(function (dataAttr) { + if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) { + delete dataAttributes[dataAttr]; + } + }); + config = _extends$1({}, this.constructor.Default, dataAttributes, typeof config === 'object' && config ? config : {}); + + if (typeof config.delay === 'number') { + config.delay = { + show: config.delay, + hide: config.delay + }; + } + + if (typeof config.title === 'number') { + config.title = config.title.toString(); + } + + if (typeof config.content === 'number') { + config.content = config.content.toString(); + } + + Util.typeCheckConfig(NAME$4, config, this.constructor.DefaultType); + + if (config.sanitize) { + config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn); + } + + return config; + }; + + _proto._getDelegateConfig = function _getDelegateConfig() { + var config = {}; + + if (this.config) { + for (var key in this.config) { + if (this.constructor.Default[key] !== this.config[key]) { + config[key] = this.config[key]; + } + } + } + + return config; + }; + + _proto._cleanTipClass = function _cleanTipClass() { + var $tip = $__default["default"](this.getTipElement()); + var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX$1); + + if (tabClass !== null && tabClass.length) { + $tip.removeClass(tabClass.join('')); + } + }; + + _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) { + this.tip = popperData.instance.popper; + + this._cleanTipClass(); + + this.addAttachmentClass(this._getAttachment(popperData.placement)); + }; + + _proto._fixTransition = function _fixTransition() { + var tip = this.getTipElement(); + var initConfigAnimation = this.config.animation; + + if (tip.getAttribute('x-placement') !== null) { + return; + } + + $__default["default"](tip).removeClass(CLASS_NAME_FADE$3); + this.config.animation = false; + this.hide(); + this.show(); + this.config.animation = initConfigAnimation; + } // Static + ; + + Tooltip._jQueryInterface = function _jQueryInterface(config) { + return this.each(function () { + var $element = $__default["default"](this); + var data = $element.data(DATA_KEY$4); + + var _config = typeof config === 'object' && config; + + if (!data && /dispose|hide/.test(config)) { + return; + } + + if (!data) { + data = new Tooltip(this, _config); + $element.data(DATA_KEY$4, data); + } + + if (typeof config === 'string') { + if (typeof data[config] === 'undefined') { + throw new TypeError("No method named \"" + config + "\""); + } + + data[config](); + } + }); + }; + + _createClass(Tooltip, null, [{ + key: "VERSION", + get: function get() { + return VERSION$4; + } + }, { + key: "Default", + get: function get() { + return Default$3; + } + }, { + key: "NAME", + get: function get() { + return NAME$4; + } + }, { + key: "DATA_KEY", + get: function get() { + return DATA_KEY$4; + } + }, { + key: "Event", + get: function get() { + return Event$1; + } + }, { + key: "EVENT_KEY", + get: function get() { + return EVENT_KEY$4; + } + }, { + key: "DefaultType", + get: function get() { + return DefaultType$3; + } + }]); + + return Tooltip; + }(); + /** + * jQuery + */ + + + $__default["default"].fn[NAME$4] = Tooltip._jQueryInterface; + $__default["default"].fn[NAME$4].Constructor = Tooltip; + + $__default["default"].fn[NAME$4].noConflict = function () { + $__default["default"].fn[NAME$4] = JQUERY_NO_CONFLICT$4; + return Tooltip._jQueryInterface; + }; + + /** + * Constants + */ + + var NAME$3 = 'popover'; + var VERSION$3 = '4.6.1'; + var DATA_KEY$3 = 'bs.popover'; + var EVENT_KEY$3 = "." + DATA_KEY$3; + var JQUERY_NO_CONFLICT$3 = $__default["default"].fn[NAME$3]; + var CLASS_PREFIX = 'bs-popover'; + var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g'); + var CLASS_NAME_FADE$2 = 'fade'; + var CLASS_NAME_SHOW$2 = 'show'; + var SELECTOR_TITLE = '.popover-header'; + var SELECTOR_CONTENT = '.popover-body'; + + var Default$2 = _extends$1({}, Tooltip.Default, { + placement: 'right', + trigger: 'click', + content: '', + template: '' + }); + + var DefaultType$2 = _extends$1({}, Tooltip.DefaultType, { + content: '(string|element|function)' + }); + + var Event = { + HIDE: "hide" + EVENT_KEY$3, + HIDDEN: "hidden" + EVENT_KEY$3, + SHOW: "show" + EVENT_KEY$3, + SHOWN: "shown" + EVENT_KEY$3, + INSERTED: "inserted" + EVENT_KEY$3, + CLICK: "click" + EVENT_KEY$3, + FOCUSIN: "focusin" + EVENT_KEY$3, + FOCUSOUT: "focusout" + EVENT_KEY$3, + MOUSEENTER: "mouseenter" + EVENT_KEY$3, + MOUSELEAVE: "mouseleave" + EVENT_KEY$3 + }; + /** + * Class definition + */ + + var Popover = /*#__PURE__*/function (_Tooltip) { + _inheritsLoose(Popover, _Tooltip); + + function Popover() { + return _Tooltip.apply(this, arguments) || this; + } + + var _proto = Popover.prototype; + + // Overrides + _proto.isWithContent = function isWithContent() { + return this.getTitle() || this._getContent(); + }; + + _proto.addAttachmentClass = function addAttachmentClass(attachment) { + $__default["default"](this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment); + }; + + _proto.getTipElement = function getTipElement() { + this.tip = this.tip || $__default["default"](this.config.template)[0]; + return this.tip; + }; + + _proto.setContent = function setContent() { + var $tip = $__default["default"](this.getTipElement()); // We use append for html objects to maintain js events + + this.setElementContent($tip.find(SELECTOR_TITLE), this.getTitle()); + + var content = this._getContent(); + + if (typeof content === 'function') { + content = content.call(this.element); + } + + this.setElementContent($tip.find(SELECTOR_CONTENT), content); + $tip.removeClass(CLASS_NAME_FADE$2 + " " + CLASS_NAME_SHOW$2); + } // Private + ; + + _proto._getContent = function _getContent() { + return this.element.getAttribute('data-content') || this.config.content; + }; + + _proto._cleanTipClass = function _cleanTipClass() { + var $tip = $__default["default"](this.getTipElement()); + var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX); + + if (tabClass !== null && tabClass.length > 0) { + $tip.removeClass(tabClass.join('')); + } + } // Static + ; + + Popover._jQueryInterface = function _jQueryInterface(config) { + return this.each(function () { + var data = $__default["default"](this).data(DATA_KEY$3); + + var _config = typeof config === 'object' ? config : null; + + if (!data && /dispose|hide/.test(config)) { + return; + } + + if (!data) { + data = new Popover(this, _config); + $__default["default"](this).data(DATA_KEY$3, data); + } + + if (typeof config === 'string') { + if (typeof data[config] === 'undefined') { + throw new TypeError("No method named \"" + config + "\""); + } + + data[config](); + } + }); + }; + + _createClass(Popover, null, [{ + key: "VERSION", + get: // Getters + function get() { + return VERSION$3; + } + }, { + key: "Default", + get: function get() { + return Default$2; + } + }, { + key: "NAME", + get: function get() { + return NAME$3; + } + }, { + key: "DATA_KEY", + get: function get() { + return DATA_KEY$3; + } + }, { + key: "Event", + get: function get() { + return Event; + } + }, { + key: "EVENT_KEY", + get: function get() { + return EVENT_KEY$3; + } + }, { + key: "DefaultType", + get: function get() { + return DefaultType$2; + } + }]); + + return Popover; + }(Tooltip); + /** + * jQuery + */ + + + $__default["default"].fn[NAME$3] = Popover._jQueryInterface; + $__default["default"].fn[NAME$3].Constructor = Popover; + + $__default["default"].fn[NAME$3].noConflict = function () { + $__default["default"].fn[NAME$3] = JQUERY_NO_CONFLICT$3; + return Popover._jQueryInterface; + }; + + /** + * Constants + */ + + var NAME$2 = 'scrollspy'; + var VERSION$2 = '4.6.1'; + var DATA_KEY$2 = 'bs.scrollspy'; + var EVENT_KEY$2 = "." + DATA_KEY$2; + var DATA_API_KEY$1 = '.data-api'; + var JQUERY_NO_CONFLICT$2 = $__default["default"].fn[NAME$2]; + var CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item'; + var CLASS_NAME_ACTIVE$1 = 'active'; + var EVENT_ACTIVATE = "activate" + EVENT_KEY$2; + var EVENT_SCROLL = "scroll" + EVENT_KEY$2; + var EVENT_LOAD_DATA_API = "load" + EVENT_KEY$2 + DATA_API_KEY$1; + var METHOD_OFFSET = 'offset'; + var METHOD_POSITION = 'position'; + var SELECTOR_DATA_SPY = '[data-spy="scroll"]'; + var SELECTOR_NAV_LIST_GROUP$1 = '.nav, .list-group'; + var SELECTOR_NAV_LINKS = '.nav-link'; + var SELECTOR_NAV_ITEMS = '.nav-item'; + var SELECTOR_LIST_ITEMS = '.list-group-item'; + var SELECTOR_DROPDOWN$1 = '.dropdown'; + var SELECTOR_DROPDOWN_ITEMS = '.dropdown-item'; + var SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle'; + var Default$1 = { + offset: 10, + method: 'auto', + target: '' + }; + var DefaultType$1 = { + offset: 'number', + method: 'string', + target: '(string|element)' + }; + /** + * Class definition + */ + + var ScrollSpy = /*#__PURE__*/function () { + function ScrollSpy(element, config) { + var _this = this; + + this._element = element; + this._scrollElement = element.tagName === 'BODY' ? window : element; + this._config = this._getConfig(config); + this._selector = this._config.target + " " + SELECTOR_NAV_LINKS + "," + (this._config.target + " " + SELECTOR_LIST_ITEMS + ",") + (this._config.target + " " + SELECTOR_DROPDOWN_ITEMS); + this._offsets = []; + this._targets = []; + this._activeTarget = null; + this._scrollHeight = 0; + $__default["default"](this._scrollElement).on(EVENT_SCROLL, function (event) { + return _this._process(event); + }); + this.refresh(); + + this._process(); + } // Getters + + + var _proto = ScrollSpy.prototype; + + // Public + _proto.refresh = function refresh() { + var _this2 = this; + + var autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION; + var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method; + var offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0; + this._offsets = []; + this._targets = []; + this._scrollHeight = this._getScrollHeight(); + var targets = [].slice.call(document.querySelectorAll(this._selector)); + targets.map(function (element) { + var target; + var targetSelector = Util.getSelectorFromElement(element); + + if (targetSelector) { + target = document.querySelector(targetSelector); + } + + if (target) { + var targetBCR = target.getBoundingClientRect(); + + if (targetBCR.width || targetBCR.height) { + // TODO (fat): remove sketch reliance on jQuery position/offset + return [$__default["default"](target)[offsetMethod]().top + offsetBase, targetSelector]; + } + } + + return null; + }).filter(function (item) { + return item; + }).sort(function (a, b) { + return a[0] - b[0]; + }).forEach(function (item) { + _this2._offsets.push(item[0]); + + _this2._targets.push(item[1]); + }); + }; + + _proto.dispose = function dispose() { + $__default["default"].removeData(this._element, DATA_KEY$2); + $__default["default"](this._scrollElement).off(EVENT_KEY$2); + this._element = null; + this._scrollElement = null; + this._config = null; + this._selector = null; + this._offsets = null; + this._targets = null; + this._activeTarget = null; + this._scrollHeight = null; + } // Private + ; + + _proto._getConfig = function _getConfig(config) { + config = _extends$1({}, Default$1, typeof config === 'object' && config ? config : {}); + + if (typeof config.target !== 'string' && Util.isElement(config.target)) { + var id = $__default["default"](config.target).attr('id'); + + if (!id) { + id = Util.getUID(NAME$2); + $__default["default"](config.target).attr('id', id); + } + + config.target = "#" + id; + } + + Util.typeCheckConfig(NAME$2, config, DefaultType$1); + return config; + }; + + _proto._getScrollTop = function _getScrollTop() { + return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop; + }; + + _proto._getScrollHeight = function _getScrollHeight() { + return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight); + }; + + _proto._getOffsetHeight = function _getOffsetHeight() { + return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height; + }; + + _proto._process = function _process() { + var scrollTop = this._getScrollTop() + this._config.offset; + + var scrollHeight = this._getScrollHeight(); + + var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight(); + + if (this._scrollHeight !== scrollHeight) { + this.refresh(); + } + + if (scrollTop >= maxScroll) { + var target = this._targets[this._targets.length - 1]; + + if (this._activeTarget !== target) { + this._activate(target); + } + + return; + } + + if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) { + this._activeTarget = null; + + this._clear(); + + return; + } + + for (var i = this._offsets.length; i--;) { + var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]); + + if (isActiveTarget) { + this._activate(this._targets[i]); + } + } + }; + + _proto._activate = function _activate(target) { + this._activeTarget = target; + + this._clear(); + + var queries = this._selector.split(',').map(function (selector) { + return selector + "[data-target=\"" + target + "\"]," + selector + "[href=\"" + target + "\"]"; + }); + + var $link = $__default["default"]([].slice.call(document.querySelectorAll(queries.join(',')))); + + if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) { + $link.closest(SELECTOR_DROPDOWN$1).find(SELECTOR_DROPDOWN_TOGGLE$1).addClass(CLASS_NAME_ACTIVE$1); + $link.addClass(CLASS_NAME_ACTIVE$1); + } else { + // Set triggered link as active + $link.addClass(CLASS_NAME_ACTIVE$1); // Set triggered links parents as active + // With both