diff --git a/.dockerignore b/.dockerignore index 6a71f93a50..0a28a4eef0 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,5 +4,4 @@ **/.gitignore **/.idea docs -private -triplestores \ No newline at end of file +private \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index da3d7a3790..12a8e7dc54 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -5,9 +5,6 @@ on: release: types: [published] -env: - KNORA_GDB_LICENSE: ${{ github.workspace }}/ci/graphdb/UNIBAS_DEV_GRAPHDB_SE_latest-31-12-2020_1cores.license - jobs: compile: name: Build Everything @@ -16,30 +13,10 @@ jobs: - uses: actions/checkout@v1 with: fetch-depth: 1 - - name: Dump GitHub context - env: - GITHUB_CONTEXT: ${{ toJson(github) }} - run: echo "$GITHUB_CONTEXT" - - name: Dump job context - env: - JOB_CONTEXT: ${{ toJson(job) }} - run: echo "$JOB_CONTEXT" - - name: Dump steps context - env: - STEPS_CONTEXT: ${{ toJson(steps) }} - run: echo "$STEPS_CONTEXT" - - name: Dump runner context - env: - RUNNER_CONTEXT: ${{ toJson(runner) }} - run: echo "$RUNNER_CONTEXT" - - name: Dump strategy context - env: - STRATEGY_CONTEXT: ${{ toJson(strategy) }} - run: echo "$STRATEGY_CONTEXT" - - name: Dump matrix context - env: - MATRIX_CONTEXT: ${{ toJson(matrix) }} - run: echo "$MATRIX_CONTEXT" + - uses: joschi/setup-jdk@v2 + with: + java-version: '11' # The OpenJDK version to make available on the path + architecture: 'x64' # defaults to 'x64' - name: cache maven artifacts uses: actions/cache@v1 with: @@ -56,7 +33,7 @@ jobs: docker system prune --all --force --volumes df -h - name: Run build everything - run: sbt clean test:compile it:compile stage + run: make build-all-scala - name: Disk Free After run: | df -h @@ -71,12 +48,10 @@ jobs: uses: actions/checkout@v1 with: fetch-depth: 1 - - name: Checkout private ci-assets - uses: actions/checkout@v2 + - uses: joschi/setup-jdk@v2 with: - repository: dasch-swiss/dsp-ci-assets - token: ${{ secrets.GitHub_PAT }} # `GitHub_PAT` is a secret that contains the PAT. - path: ci + java-version: '11' # The OpenJDK version to make available on the path + architecture: 'x64' # defaults to 'x64' - name: cache maven artifacts uses: actions/cache@v1 with: @@ -112,12 +87,10 @@ jobs: uses: actions/checkout@v1 with: fetch-depth: 1 - - name: Checkout private ci-assets - uses: actions/checkout@v2 + - uses: joschi/setup-jdk@v2 with: - repository: dasch-swiss/dsp-ci-assets - token: ${{ secrets.GitHub_PAT }} # `GitHub_PAT` is a secret that contains the PAT. - path: ci + java-version: '11' # The OpenJDK version to make available on the path + architecture: 'x64' # defaults to 'x64' - name: cache maven artifacts uses: actions/cache@v1 with: @@ -153,12 +126,10 @@ jobs: uses: actions/checkout@v1 with: fetch-depth: 1 - - name: Checkout private ci-assets - uses: actions/checkout@v2 + - uses: joschi/setup-jdk@v2 with: - repository: dasch-swiss/dsp-ci-assets - token: ${{ secrets.GitHub_PAT }} # `GitHub_PAT` is a secret that contains the PAT. - path: ci + java-version: '11' # The OpenJDK version to make available on the path + architecture: 'x64' # defaults to 'x64' - name: cache maven artifacts uses: actions/cache@v1 with: @@ -194,12 +165,10 @@ jobs: uses: actions/checkout@v1 with: fetch-depth: 1 - - name: Checkout private ci-assets - uses: actions/checkout@v2 + - uses: joschi/setup-jdk@v2 with: - repository: dasch-swiss/dsp-ci-assets - token: ${{ secrets.GitHub_PAT }} # `GitHub_PAT` is a secret that contains the PAT. - path: ci + java-version: '11' # The OpenJDK version to make available on the path + architecture: 'x64' # defaults to 'x64' - uses: actions/setup-java@v1 with: java-version: '11.x.x' @@ -221,7 +190,7 @@ jobs: docker system prune --all --force --volumes df -h - name: test repository update - run: cd $GITHUB_WORKSPACE && make test-repository-update + run: make test-repository-update - name: Disk Free After run: | df -h @@ -235,6 +204,10 @@ jobs: - uses: actions/checkout@v1 with: fetch-depth: 1 + - uses: joschi/setup-jdk@v2 + with: + java-version: '11' # The OpenJDK version to make available on the path + architecture: 'x64' # defaults to 'x64' - name: cache maven artifacts uses: actions/cache@v1 with: @@ -276,6 +249,10 @@ jobs: - uses: actions/checkout@v1 with: fetch-depth: 50 + - uses: joschi/setup-jdk@v2 + with: + java-version: '11' # The OpenJDK version to make available on the path + architecture: 'x64' # defaults to 'x64' - name: cache maven artifacts uses: actions/cache@v1 with: @@ -294,7 +271,6 @@ jobs: - name: build and publish all images to Dockerhub run: | echo ${{ secrets.DOCKER_HUB_TOKEN }} | docker login -u ${{ secrets.DOCKER_USER }} --password-stdin - mkdir -p $( dirname "$KNORA_GDB_LICENSE") && touch "$KNORA_GDB_LICENSE" make publish-all-images - name: Disk Free After run: | diff --git a/.gitignore b/.gitignore index 8ef25438ca..27e6c5cfcc 100644 --- a/.gitignore +++ b/.gitignore @@ -45,9 +45,8 @@ sipi/test *.bak .sbtrc +/knora-jena-fuseki /knora-sipi -/knora-graphdb-se -/knora-graphdb-free /knora-assets /knora-upgrade @@ -58,5 +57,5 @@ knora-graphdb-free knora-graphdb-se knora-sipi knora-upgrade -triplestores/fuseki-tomcat/system +triplestores/fuseki/system dump.rdb diff --git a/KnoraBuild.sbt b/KnoraBuild.sbt index 80355d17a0..639515b70f 100644 --- a/KnoraBuild.sbt +++ b/KnoraBuild.sbt @@ -12,12 +12,7 @@ import scala.sys.process.Process // GLOBAL SETTINGS ////////////////////////////////////// -// custom docker-compose plugin settings -lazy val GDB = config("gdb") extend Default - -lazy val GDBSIPI = config("gdbsipi") extend Default - -lazy val aggregatedProjects: Seq[ProjectReference] = Seq(docs, salsah1, webapi, knoraGraphDbSe, knoraGraphdbFree, knoraSipi, knoraAssets) +lazy val aggregatedProjects: Seq[ProjectReference] = Seq(docs, salsah1, webapi, knoraJenaFuseki, knoraSipi) lazy val buildSettings = Dependencies.Versions ++ Seq( organization := "org.knora", @@ -34,6 +29,8 @@ lazy val root: Project = Project(id = "knora", file(".")) // values set for all sub-projects // These are normal sbt settings to configure for release, skip if already defined + Global / onChangedBuildSource := ReloadOnSourceChanges, + ThisBuild / licenses := Seq("AGPL-3.0" -> url("https://opensource.org/licenses/AGPL-3.0")), ThisBuild / homepage := Some(url("https://github.com/dhlab-basel/Knora")), ThisBuild / scmInfo := Some(ScmInfo(url("https://github.com/dhlab-basel/Knora"), "scm:git:git@github.com:dhlab-basel/Knora.git")), @@ -52,38 +49,10 @@ lazy val root: Project = Project(id = "knora", file(".")) Dependencies.sysProps := sys.props.toString(), Dependencies.sysEnvs := sys.env.toString(), - // these can be set by the user as system environment variables - ThisBuild / Dependencies.gdbHomePath := sys.env.getOrElse("KNORA_GDB_HOME", sys.props("user.dir") + "/triplestores/graphdb/home"), - ThisBuild / Dependencies.gdbLicensePath := sys.env.getOrElse("KNORA_GDB_LICENSE", sys.props("user.dir") + "/triplestores/graphdb/graphdb.license"), - - // these are calculated in their respective targets - Dependencies.knoraSipiImage := "dhlabbasel/knora-sipi:" + version.value, - Dependencies.knoraGdbImage := { - if (Dependencies.gdbTypeString.equals("graphdb-free")) { - "dhlabbasel/knora-graphdb-free:" + version.value - } else { - "dhlabbasel/knora-graphdb-se:" + version.value - } - }, - Dependencies.knoraWebapiImage := "dhlabbasel/webapi:" + version.value, - Dependencies.knoraSalsah1Image := "dhlabbasel/salsah1:" + version.value, - - // use these values for variable substitution in the docker-compose.yml - variablesForSubstitution := Map( - "KNORA_GDB_HOME" -> Dependencies.gdbHomePath.value, - "KNORA_GDB_LICENSE" -> Dependencies.gdbLicensePath.value, - "KNORA_GDB_TYPE" -> Dependencies.gdbTypeString, - "KNORA_GDB_IMAGE" -> Dependencies.knoraGdbImage.value, - "KNORA_SIPI_IMAGE" -> Dependencies.knoraSipiImage.value, - "KNORA_WEBAPI_IMAGE" -> Dependencies.knoraWebapiImage.value, - "KNORA_SALSAH1_IMAGE" -> Dependencies.knoraSalsah1Image.value - ), - dockerImageCreationTask := Seq( (salsah1 / Docker / publishLocal).value, (webapi / Docker / publishLocal).value, - (knoraGraphDbSe / Docker / publishLocal).value, - (knoraGraphdbFree / Docker / publishLocal).value, + (knoraJenaFuseki / Docker / publishLocal).value, (knoraSipi / Docker / publishLocal).value ) ) @@ -97,66 +66,66 @@ lazy val root: Project = Project(id = "knora", file(".")) lazy val ParadoxSite = config("paradox") lazy val docs = knoraModule("docs") - .enablePlugins(JekyllPlugin, ParadoxPlugin, ParadoxSitePlugin, ParadoxMaterialThemePlugin, GhpagesPlugin) - .configs( - ParadoxSite - ) - .settings( - // Apply default settings to our two custom configuration instances - ParadoxSitePlugin.paradoxSettings(ParadoxSite), - ParadoxMaterialThemePlugin.paradoxMaterialThemeGlobalSettings, // paradoxTheme and version - ParadoxMaterialThemePlugin.paradoxMaterialThemeSettings(ParadoxSite), - - // Skip packageDoc and packageSrc task on stage - Compile / packageDoc / mappings := Seq(), - Compile / packageSrc / mappings := Seq(), - ) - .settings( - - // Ghpages settings - ghpagesNoJekyll := true, - git.remoteRepo := "git@github.com:dhlab-basel/Knora.git", - ghpagesCleanSite / excludeFilter := - new FileFilter { - def accept(f: File) = (ghpagesRepository.value / "CNAME").getCanonicalPath == f.getCanonicalPath - } || "LICENSE.md" || "README.md", - - // (sbt-site) Customize the source directory - // sourceDirectory in Jekyll := sourceDirectory.value / "overview", - ParadoxSite / sourceDirectory := sourceDirectory.value / "paradox", - - // (sbt-site) Customize the output directory (subdirectory of site) - ParadoxSite / siteSubdirName := "paradox", - - // Set some paradox properties - ParadoxSite / paradoxProperties ++= Map( - "project.name" -> "Knora Documentation", - "github.base_url" -> "https://github.com/dhlab-basel/Knora", - "image.base_url" -> ".../assets/images", - "extref.rfc.base_url" -> "http://tools.ietf.org/html/rfc%s", - "snip.src.base_dir" -> ((baseDirectory in ThisBuild).value / "webapi" / "src" / "main" / "scala").getAbsolutePath, - "snip.test.base_dir" -> ((baseDirectory in ThisBuild).value / "webapi" / "src" / "test" / "scala").getAbsolutePath - ), - - // Paradox Material Theme Settings - ParadoxSite / paradoxMaterialTheme ~= { - _.withColor("blue", "yellow") - .withRepository(uri("https://github.com/dhlab-basel/Knora/docs")) - .withFavicon("cloud") - .withLogoIcon("cloud") - .withSocial( - uri("https://github.com/dhlab-basel"), - uri("https://twitter.com/dhlabbasel") - ) - .withLanguage(java.util.Locale.ENGLISH) - .withCopyright("Copyright 2015-2019 the contributors (see Contributors.md)") - }, - makeSite / mappings ++= Seq( - file("docs/src/api-admin/index.html") -> "api-admin/index.html", - file("docs/src/api-admin/swagger.json") -> "api-admin/swagger.json" - ), - makeSite := makeSite.dependsOn(buildPrequisites).value - ) + .enablePlugins(JekyllPlugin, ParadoxPlugin, ParadoxSitePlugin, ParadoxMaterialThemePlugin, GhpagesPlugin) + .configs( + ParadoxSite + ) + .settings( + // Apply default settings to our two custom configuration instances + ParadoxSitePlugin.paradoxSettings(ParadoxSite), + ParadoxMaterialThemePlugin.paradoxMaterialThemeGlobalSettings, // paradoxTheme and version + ParadoxMaterialThemePlugin.paradoxMaterialThemeSettings(ParadoxSite), + + // Skip packageDoc and packageSrc task on stage + Compile / packageDoc / mappings := Seq(), + Compile / packageSrc / mappings := Seq(), + ) + .settings( + + // Ghpages settings + ghpagesNoJekyll := true, + git.remoteRepo := "git@github.com:dhlab-basel/Knora.git", + ghpagesCleanSite / excludeFilter := + new FileFilter { + def accept(f: File) = (ghpagesRepository.value / "CNAME").getCanonicalPath == f.getCanonicalPath + } || "LICENSE.md" || "README.md", + + // (sbt-site) Customize the source directory + // sourceDirectory in Jekyll := sourceDirectory.value / "overview", + ParadoxSite / sourceDirectory := sourceDirectory.value / "paradox", + + // (sbt-site) Customize the output directory (subdirectory of site) + ParadoxSite / siteSubdirName := "paradox", + + // Set some paradox properties + ParadoxSite / paradoxProperties ++= Map( + "project.name" -> "Knora Documentation", + "github.base_url" -> "https://github.com/dhlab-basel/Knora", + "image.base_url" -> ".../assets/images", + "extref.rfc.base_url" -> "http://tools.ietf.org/html/rfc%s", + "snip.src.base_dir" -> ((baseDirectory in ThisBuild).value / "webapi" / "src" / "main" / "scala").getAbsolutePath, + "snip.test.base_dir" -> ((baseDirectory in ThisBuild).value / "webapi" / "src" / "test" / "scala").getAbsolutePath + ), + + // Paradox Material Theme Settings + ParadoxSite / paradoxMaterialTheme ~= { + _.withColor("blue", "yellow") + .withRepository(uri("https://github.com/dhlab-basel/Knora/docs")) + .withFavicon("cloud") + .withLogoIcon("cloud") + .withSocial( + uri("https://github.com/dhlab-basel"), + uri("https://twitter.com/dhlabbasel") + ) + .withLanguage(java.util.Locale.ENGLISH) + .withCopyright("Copyright 2015-2019 the contributors (see Contributors.md)") + }, + makeSite / mappings ++= Seq( + file("docs/src/api-admin/index.html") -> "api-admin/index.html", + file("docs/src/api-admin/swagger.json") -> "api-admin/swagger.json" + ), + makeSite := makeSite.dependsOn(buildPrequisites).value + ) lazy val buildPrequisites = taskKey[Unit]("Build typescript API documentation and Graphviz diagrams.") @@ -189,81 +158,40 @@ docs / buildPrequisites := { ////////////////////////////////////// -// Knora's custom GraphDB-SE +// Knora's custom Jena Fuseki ////////////////////////////////////// -lazy val graphdbseCommonSettings = Seq( - name := "knora-graphdb-se" +lazy val jenaFusekiCommonSettings = Seq( + name := "knora-jena-fuseki" ) -lazy val knoraGraphDbSe: Project = knoraModule("knora-graphdb-se") +lazy val knoraJenaFuseki: Project = knoraModule("knora-jena-fuseki") .enablePlugins(DockerPlugin) .settings( - graphdbseCommonSettings + jenaFusekiCommonSettings ) .settings( // enable deployment staging with `sbt stage` // Skip packageDoc and packageSrc task on stage Compile / packageDoc / mappings := Seq(), Compile / packageSrc / mappings := Seq(), Universal / mappings ++= { - // copy the webapi/scripts folder - directory("webapi/scripts") + // copy the jena-fuseki folder + directory("jena-fuseki") }, // add dockerCommands used to create the image // docker:stage, docker:publishLocal, docker:publish, docker:clean - dockerRepository := Some("dhlabbasel"), + dockerRepository := Some("daschswiss"), maintainer := "400790+subotic@users.noreply.github.com", - Docker / dockerExposedPorts ++= Seq(7200), + Docker / dockerExposedPorts ++= Seq(3030), Docker / dockerCommands := Seq( // FIXME: Someday find out how to reference here Dependencies.Versions.gdbSEImage - Cmd("FROM", "ontotext/graphdb:8.10.1-se"), - Cmd("LABEL", s"""MAINTAINER="${maintainer.value}""""), - Cmd("COPY", "opt/docker/scripts", "/scripts"), - Cmd("RUN", "mkdir -p /graphdb && cp /scripts/KnoraRules.pie /graphdb/KnoraRules.pie && rm -rf /scripts"), - ) - ) - - -////////////////////////////////////// -// Knora's custom GraphDB-Free -////////////////////////////////////// - -lazy val graphdbfreeCommonSettings = Seq( - name := "knora-graphdb-free" -) - -lazy val knoraGraphdbFree: Project = knoraModule("knora-graphdb-free") - .enablePlugins(DockerPlugin) - .settings( - graphdbfreeCommonSettings - ) - .settings( - // Skip packageDoc and packageSrc task on stage - Compile / packageDoc / mappings := Seq(), - Compile / packageSrc / mappings := Seq(), - Universal / mappings ++= { - // copy the webapi/scripts folder - directory("webapi/scripts") - }, - - // add dockerCommands used to create the image - // docker:stage, docker:publishLocal, docker:publish, docker:clean - - dockerRepository := Some("dhlabbasel"), - - maintainer := "400790+subotic@users.noreply.github.com", - - Docker / dockerExposedPorts ++= Seq(7200), - Docker / dockerCommands := Seq( - // FIXME: Someday find out how to reference here Dependencies.Versions.gdbFreeImage - Cmd("FROM", "dhlabbasel/graphdb:8.10.0-free"), + Cmd("FROM", "stain/jena-fuseki:3.14.0"), Cmd("LABEL", s"""MAINTAINER="${maintainer.value}""""), - Cmd("COPY", "opt/docker/scripts", "/scripts"), - Cmd("RUN", "mkdir -p /graphdb && cp /scripts/KnoraRules.pie /graphdb/KnoraRules.pie && rm -rf /scripts"), + Cmd("COPY", "config.ttl", "/fuseki/config.ttl"), ) ) @@ -307,46 +235,6 @@ lazy val knoraSipi: Project = knoraModule("knora-sipi") ) -////////////////////////////////////// -// Knora's assets -////////////////////////////////////// - -lazy val knoraAssetsCommonSettings = Seq( - name := "knora-assets" -) - -lazy val knoraAssets: Project = knoraModule("knora-assets") - .enablePlugins(DockerPlugin) - .settings( - knoraAssetsCommonSettings - ) - .settings( - // Skip packageDoc and packageSrc task on stage - Compile / packageDoc / mappings := Seq(), - Compile / packageSrc / mappings := Seq(), - Universal / mappings ++= { - // copy the different folders - directory("webapi/scripts") ++ - directory("webapi/_test_data") ++ - directory("webapi/_assets") ++ - directory("knora-ontologies") - }, - - // add dockerCommands used to create the image - // docker:stage, docker:publishLocal, docker:publish, docker:clean - - dockerRepository := Some("dhlabbasel"), - - maintainer := "400790+subotic@users.noreply.github.com", - Docker / dockerExposedPorts ++= Seq(9999), // not used. added just so that there is no warning - Docker / dockerCommands := Seq( - Cmd("FROM", "scratch"), - Cmd("LABEL", s"""MAINTAINER="${maintainer.value}""""), - Cmd("COPY", "opt/docker", "/assets") - ) - ) - - ////////////////////////////////////// // SALSAH1 (./salsah1) ////////////////////////////////////// @@ -384,9 +272,9 @@ lazy val salsah1: Project = knoraModule("salsah1") Test / testOptions += Tests.Argument("-oDF") ) .settings( // enable deployment staging with `sbt stage` - // Skip packageDoc and packageSrc task on stage - Compile / packageDoc / mappings := Seq(), - Compile / packageSrc / mappings := Seq(), + // Skip packageDoc and packageSrc task on stage + Compile / packageDoc / mappings := Seq(), + Compile / packageSrc / mappings := Seq(), Universal / mappings ++= { // copy the public folder directory("salsah1/src/public") ++ @@ -482,163 +370,177 @@ lazy val EmbeddedJenaTDBTest = config("tdb") extend Test // BuildInfoPlugin - allows generation of scala code with version information lazy val webapi = knoraModule("webapi") - .enablePlugins(SbtTwirl, JavaAppPackaging, DockerPlugin, GatlingPlugin, JavaAgent, RevolverPlugin, BuildInfoPlugin) - .configs( - IntegrationTest, - Gatling, - GatlingIt, - GDBSE, - GDBSEIt, - GDBFree, - GDBFreeIt, - FusekiTest, - FusekiIt, - EmbeddedJenaTDBTest - ) - .settings( - webApiCommonSettings, - resolvers ++= Seq( - Resolver.bintrayRepo("hseeberger", "maven") - ), - Dependencies.webapiLibraryDependencies - ) - .settings( - inConfig(Test)(Defaults.testTasks ++ baseAssemblySettings), - inConfig(IntegrationTest)(Defaults.testSettings), - inConfig(Gatling)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)), - inConfig(GatlingIt)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)), - inConfig(GDBSE)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)), - inConfig(GDBSEIt)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)), - inConfig(GDBFree)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)), - inConfig(GDBFreeIt)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)), - inConfig(FusekiTest)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)), - inConfig(FusekiIt)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)), - inConfig(EmbeddedJenaTDBTest)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)) - ) - - .settings( - exportJars := true, - unmanagedResourceDirectories in Compile += (rootBaseDir.value / "knora-ontologies"), - - // add content of knora-ontologies to jar - mappings in (Compile, packageBin) ++= Seq ( - (rootBaseDir.value / "knora-ontologies" / "knora-admin.ttl") -> "knora-ontologies/knora-admin.ttl", - (rootBaseDir.value / "knora-ontologies" / "knora-base.ttl") -> "knora-ontologies/knora-base.ttl", - (rootBaseDir.value / "knora-ontologies" / "salsah-gui.ttl") -> "knora-ontologies/salsah-gui.ttl", - (rootBaseDir.value / "knora-ontologies" / "standoff-data.ttl") -> "knora-ontologies/standoff-data.ttl", - (rootBaseDir.value / "knora-ontologies" / "standoff-onto.ttl") -> "knora-ontologies/standoff-onto.ttl", - ), - // contentOf("salsah1/src/main/resources").toMap.mapValues("config/" + _) - // (rootBaseDir.value / "knora-ontologies") -> "knora-ontologies", - ) - - .settings( - scalacOptions ++= Seq("-feature", "-unchecked", "-deprecation", "-Yresolve-term-conflict:package"), - - logLevel := Level.Info, - - fork := true, // always fork - - run / javaOptions := webapiJavaRunOptions, - - reStart / javaOptions ++= resolvedJavaAgents.value map { resolved => - "-javaagent:" + resolved.artifact.absolutePath + resolved.agent.arguments - }, // allows sbt-javaagent to work with sbt-revolver - reStart / javaOptions ++= webapiJavaRunOptions, - - javaAgents += Dependencies.Compile.aspectJWeaver, - - Test / parallelExecution := false, - Test / javaOptions ++= Seq("-Dconfig.resource=graphdb-se.conf") ++ webapiJavaTestOptions, - // Test / javaOptions ++= Seq("-Dakka.log-config-on-start=on"), // prints out akka config - // Test / javaOptions ++= Seq("-Dconfig.trace=loads"), // prints out config locations - Test / testOptions += Tests.Argument("-oDF"), // show full stack traces and test case durations - - IntegrationTest / javaOptions := Seq("-Dconfig.resource=graphdb-se.conf") ++ webapiJavaTestOptions, - IntegrationTest / testOptions += Tests.Argument("-oDF"), // show full stack traces and test case durations - - Gatling / javaOptions := Seq("-Dconfig.resource=graphdb-se.conf") ++ webapiJavaTestOptions, - Gatling / testOptions := Seq(), - GatlingIt / javaOptions := Seq("-Dconfig.resource=graphdb-se.conf") ++ webapiJavaTestOptions, - GatlingIt / testOptions := Seq(), - - GDBSE / javaOptions := Seq("-Dconfig.resource=graphdb-se.conf") ++ webapiJavaTestOptions, - GDBSEIt / javaOptions := Seq("-Dconfig.resource=graphdb-se.conf") ++ webapiJavaTestOptions, - - GDBFree / javaOptions := Seq("-Dconfig.resource=graphdb-free.conf") ++ webapiJavaTestOptions, - GDBFreeIt / javaOptions := Seq("-Dconfig.resource=graphdb-free.conf") ++ webapiJavaTestOptions, - - FusekiTest / javaOptions := Seq("-Dconfig.resource=fuseki.conf") ++ webapiJavaTestOptions, - FusekiIt / javaOptions := Seq("-Dconfig.resource=fuseki.conf") ++ webapiJavaTestOptions, - - EmbeddedJenaTDBTest / javaOptions := Seq("-Dconfig.resource=jenatdb.conf") ++ webapiJavaTestOptions - - // enable publishing the jars for test and it - // Test / packageBin / publishArtifact := true, - // IntegrationTest / packageBin / publishArtifact := true, - // addArtifact(artifact in (IntegrationTest, packageBin), packageBin in IntegrationTest) - ) - .settings( - // prepare for publishing - - // Skip packageDoc and packageSrc task on stage - Compile / packageDoc / mappings := Seq(), - Compile / packageSrc / mappings := Seq(), - - Universal / mappings ++= { - // copy the scripts folder - directory("webapi/scripts") ++ - // add knora-ontologies - directory("knora-ontologies") ++ - // add test-data directory - directory("webapi/_test_data") ++ - // copy the configuration files to config directory - contentOf("webapi/configs").toMap.mapValues("config/" + _) ++ - // copy configuration files to config directory - contentOf("webapi/src/main/resources").toMap.mapValues("config/" + _) - }, - - // add 'config' directory to the classpath of the start script, - Universal / scriptClasspath := Seq("../config/") ++ scriptClasspath.value, - - // need this here, so that the Manifest inside the jars has the correct main class set. - Compile / mainClass := Some("org.knora.webapi.Main"), - Compile / run / mainClass := Some("org.knora.webapi.Main"), - - // add dockerCommands used to create the image - // docker:stage, docker:publishLocal, docker:publish, docker:clean - - dockerRepository := Some("dhlabbasel"), - - maintainer := "400790+subotic@users.noreply.github.com", + .enablePlugins(SbtTwirl, JavaAppPackaging, DockerPlugin, GatlingPlugin, JavaAgent, RevolverPlugin, BuildInfoPlugin) + .configs( + IntegrationTest, + Gatling, + GatlingIt, + GDBSE, + GDBSEIt, + GDBFree, + GDBFreeIt, + FusekiTest, + FusekiIt, + EmbeddedJenaTDBTest + ) + .settings( + webApiCommonSettings, + resolvers ++= Seq( + Resolver.bintrayRepo("hseeberger", "maven") + ), + Dependencies.webapiLibraryDependencies + ) + .settings( + inConfig(Test)(Defaults.testTasks ++ baseAssemblySettings), + inConfig(IntegrationTest)(Defaults.testSettings), + inConfig(Gatling)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)), + inConfig(GatlingIt)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)), + inConfig(GDBSE)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)), + inConfig(GDBSEIt)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)), + inConfig(GDBFree)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)), + inConfig(GDBFreeIt)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)), + inConfig(FusekiTest)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)), + inConfig(FusekiIt)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)), + inConfig(EmbeddedJenaTDBTest)(Defaults.testTasks ++ Seq(forkOptions := Defaults.forkOptionsTask.value)) + ) + + .settings( + exportJars := true, + unmanagedResourceDirectories in Compile += (rootBaseDir.value / "knora-ontologies"), + + // add needed files to jar + mappings in(Compile, packageBin) ++= Seq( + (rootBaseDir.value / "knora-ontologies" / "knora-admin.ttl") -> "knora-ontologies/knora-admin.ttl", + (rootBaseDir.value / "knora-ontologies" / "knora-base.ttl") -> "knora-ontologies/knora-base.ttl", + (rootBaseDir.value / "knora-ontologies" / "salsah-gui.ttl") -> "knora-ontologies/salsah-gui.ttl", + (rootBaseDir.value / "knora-ontologies" / "standoff-data.ttl") -> "knora-ontologies/standoff-data.ttl", + (rootBaseDir.value / "knora-ontologies" / "standoff-onto.ttl") -> "knora-ontologies/standoff-onto.ttl", + (rootBaseDir.value / "webapi" / "scripts" / "fuseki-knora-test-repository-config.ttl") -> "webapi/scripts/fuseki-knora-test-repository-config.ttl", + (rootBaseDir.value / "webapi" / "scripts" / "fuseki-knora-test-unit-repository-config.ttl") -> "webapi/scripts/fuseki-knora-test-unit-repository-config.ttl", + ), + // contentOf("salsah1/src/main/resources").toMap.mapValues("config/" + _) + // (rootBaseDir.value / "knora-ontologies") -> "knora-ontologies", + + // put additional files into the jar when running tests which are needed by testcontainers + mappings in(Test, packageBin) ++= Seq( + (rootBaseDir.value / "sipi" / "config" / "sipi.init-knora.lua") -> "sipi/config/sipi.init-knora.lua", + (rootBaseDir.value / "sipi" / "config" / "sipi.knora-docker-config.lua") -> "sipi/config/sipi.knora-docker-config.lua", + (rootBaseDir.value / "sipi" / "config" / "sipi.knora-docker-config.lua") -> "sipi/config/sipi.knora-docker-config.lua", + ), + mappings in(IntegrationTest, packageBin) ++= Seq( + (rootBaseDir.value / "sipi" / "config" / "sipi.init-knora.lua") -> "sipi/config/sipi.init-knora.lua", + (rootBaseDir.value / "sipi" / "config" / "sipi.knora-docker-config.lua") -> "sipi/config/sipi.knora-docker-config.lua", + ), + ) + + .settings( + scalacOptions ++= Seq("-feature", "-unchecked", "-deprecation", "-Yresolve-term-conflict:package"), - Docker / dockerExposedPorts ++= Seq(3333, 10001), - Docker / dockerCommands := Seq( - Cmd("FROM", "adoptopenjdk/openjdk11:alpine-jre"), - Cmd("LABEL", s"""MAINTAINER="${maintainer.value}""""), + logLevel := Level.Info, - Cmd("RUN apk update && apk upgrade && apk add bash"), + run / javaOptions := webapiJavaRunOptions, - Cmd("COPY", "opt/docker", "/webapi"), - Cmd("WORKDIR", "/webapi"), + reStart / javaOptions ++= resolvedJavaAgents.value map { resolved => + "-javaagent:" + resolved.artifact.absolutePath + resolved.agent.arguments + }, // allows sbt-javaagent to work with sbt-revolver + reStart / javaOptions ++= webapiJavaRunOptions, - Cmd("EXPOSE", "3333"), + javaAgents += Dependencies.Compile.aspectJWeaver, - ExecCmd("ENTRYPOINT", "bin/webapi"), - ) + fork := true, // run tests in a forked JVM + Test / testForkedParallel := false, // run forked tests in parallel + Test / parallelExecution := false, // run non-forked tests in parallel + // Global / concurrentRestrictions += Tags.limit(Tags.Test, 1), // restrict the number of concurrently executing tests in all projects + Test / javaOptions ++= Seq("-Dconfig.resource=fuseki.conf") ++ webapiJavaTestOptions, + // Test / javaOptions ++= Seq("-Dakka.log-config-on-start=on"), // prints out akka config + // Test / javaOptions ++= Seq("-Dconfig.trace=loads"), // prints out config locations + Test / testOptions += Tests.Argument("-oDF"), // show full stack traces and test case durations + + IntegrationTest / javaOptions := Seq("-Dconfig.resource=fuseki.conf") ++ webapiJavaTestOptions, + IntegrationTest / testOptions += Tests.Argument("-oDF"), // show full stack traces and test case durations - ) - .settings( - buildInfoKeys ++= Seq[BuildInfoKey]( - name, - version, - "akkaHttp" -> Dependencies.akkaHttpVersion.value, - "sipi" -> Dependencies.sipiImage.value, - "gdbSE" -> Dependencies.gdbSEImage.value, - "gdbFree" -> Dependencies.gdbFreeImage.value - ), - buildInfoPackage := "org.knora.webapi" - ) + Gatling / javaOptions := Seq("-Dconfig.resource=fuseki.conf") ++ webapiJavaTestOptions, + Gatling / testOptions := Seq(), + GatlingIt / javaOptions := Seq("-Dconfig.resource=fuseki.conf") ++ webapiJavaTestOptions, + GatlingIt / testOptions := Seq(), + + GDBSE / javaOptions := Seq("-Dconfig.resource=graphdb-se.conf") ++ webapiJavaTestOptions, + GDBSEIt / javaOptions := Seq("-Dconfig.resource=graphdb-se.conf") ++ webapiJavaTestOptions, + + GDBFree / javaOptions := Seq("-Dconfig.resource=graphdb-free.conf") ++ webapiJavaTestOptions, + GDBFreeIt / javaOptions := Seq("-Dconfig.resource=graphdb-free.conf") ++ webapiJavaTestOptions, + + FusekiTest / javaOptions := Seq("-Dconfig.resource=fuseki.conf") ++ webapiJavaTestOptions, + FusekiIt / javaOptions := Seq("-Dconfig.resource=fuseki.conf") ++ webapiJavaTestOptions, + + EmbeddedJenaTDBTest / javaOptions := Seq("-Dconfig.resource=jenatdb.conf") ++ webapiJavaTestOptions + + // enable publishing the jars for test and it + // Test / packageBin / publishArtifact := true, + // IntegrationTest / packageBin / publishArtifact := true, + // addArtifact(artifact in (IntegrationTest, packageBin), packageBin in IntegrationTest) + ) + .settings( + // prepare for publishing + + // Skip packageDoc and packageSrc task on stage + Compile / packageDoc / mappings := Seq(), + Compile / packageSrc / mappings := Seq(), + + Universal / mappings ++= { + // copy the scripts folder + directory("webapi/scripts") ++ + // add knora-ontologies + directory("knora-ontologies") ++ + // add test-data directory + directory("webapi/_test_data") ++ + // copy the configuration files to config directory + contentOf("webapi/configs").toMap.mapValues("config/" + _) ++ + // copy configuration files to config directory + contentOf("webapi/src/main/resources").toMap.mapValues("config/" + _) + }, + + // add 'config' directory to the classpath of the start script, + Universal / scriptClasspath := Seq("../config/") ++ scriptClasspath.value, + + // need this here, so that the Manifest inside the jars has the correct main class set. + Compile / mainClass := Some("org.knora.webapi.Main"), + Compile / run / mainClass := Some("org.knora.webapi.Main"), + + // add dockerCommands used to create the image + // docker:stage, docker:publishLocal, docker:publish, docker:clean + + dockerRepository := Some("dhlabbasel"), + + maintainer := "400790+subotic@users.noreply.github.com", + + Docker / dockerExposedPorts ++= Seq(3333, 10001), + Docker / dockerCommands := Seq( + Cmd("FROM", "adoptopenjdk/openjdk11:alpine-jre"), + Cmd("LABEL", s"""MAINTAINER="${maintainer.value}""""), + + Cmd("RUN apk update && apk upgrade && apk add bash"), + + Cmd("COPY", "opt/docker", "/webapi"), + Cmd("WORKDIR", "/webapi"), + + Cmd("EXPOSE", "3333"), + + ExecCmd("ENTRYPOINT", "bin/webapi"), + ) + + ) + .settings( + buildInfoKeys ++= Seq[BuildInfoKey]( + name, + version, + "akkaHttp" -> Dependencies.akkaHttpVersion.value, + "sipi" -> Dependencies.sipiImage.value, + "gdbSE" -> Dependencies.gdbSEImage.value, + "gdbFree" -> Dependencies.gdbFreeImage.value + ), + buildInfoPackage := "org.knora.webapi" + ) lazy val webapiJavaRunOptions = Seq( // "-showversion", @@ -664,69 +566,6 @@ lazy val webapiJavaTestOptions = Seq( //"-XX:MaxMetaspaceSize=4096m" ) -// packaging for running normal tests (usage: webapi_test/stage) -lazy val webapi_test = project - // we put the results in a build folder - .in(file("webapi/build/test")) - .enablePlugins(JavaAppPackaging) - .settings( - Dependencies.webapiTestAndITLibraryDependencies, - // Skip packageDoc and packageSrc task on stage - Compile / packageDoc / mappings := Seq(), - Compile / packageSrc / mappings := Seq(), - publishArtifact in (Test, packageBin) := true, - Compile / mainClass := Some("org.scalatest.tools.Runner"), - // adds the test jar to mappings - mappings in Universal ++= { - // generates the test package - val testjar = (packageBin in Test).value - // maps this file to your lib folder in your output package - testjar -> s"lib/${testjar.getName}" - // copy the scripts folder - directory("webapi/scripts") ++ - // add knora-ontologies - directory("knora-ontologies") ++ - // add test-data directory - directory("webapi/_test_data") ++ - // copy the configuration files to config directory - contentOf("webapi/configs").toMap.mapValues("config/" + _) ++ - // copy configuration files to config directory - contentOf("webapi/src/main/resources").toMap.mapValues("config/" + _) - }, - scriptClasspath += (packageBin in Test).value.getName - ) - .dependsOn(webapi) - -// packaging for running IT tests (usage: webapi_it/stage) -lazy val webapi_it = project - // we put the results in a build folder - .in(file("webapi/build/it")) - .enablePlugins(JavaAppPackaging) - .configs( - IntegrationTest - ) - .settings( - inConfig(IntegrationTest)(Defaults.testSettings), - ) - .settings( - Dependencies.webapiTestAndITLibraryDependencies, - // Skip packageDoc and packageSrc task on stage - Compile / packageDoc / mappings := Seq(), - Compile / packageSrc / mappings := Seq(), - IntegrationTest / packageBin / publishArtifact := true, - addArtifact(artifact in (IntegrationTest, packageBin), packageBin in IntegrationTest), - Compile / mainClass := Some("org.scalatest.run"), - // adds the test jar to mappings - mappings in Universal += { - // generates the test package - val testjar = (packageBin in IntegrationTest).value - // maps this file to your lib folder in your output package - testjar -> s"lib/${testjar.getName}" - }, - scriptClasspath += (packageBin in Test).value.getName - ) - .dependsOn(webapi) - def knoraModule(name: String): Project = Project(id = name, base = file(name)) .settings(buildSettings) diff --git a/Makefile b/Makefile index f376fd3319..f298f0f62c 100644 --- a/Makefile +++ b/Makefile @@ -24,51 +24,32 @@ docs-build: ## build the docs .PHONY: build-all-scala build-all-scala: ## build all scala projects - @sbt webapi/universal:stage knora-graphdb-se/universal:stage knora-graphdb-free/universal:stage knora-sipi/universal:stage salsah1/universal:stage knora-assets/universal:stage webapi_test/universal:stage webapi_it/universal:stage + @sbt clean test:compile it:compile stage webapi/universal:stage knora-jena-fuseki/universal:stage knora-sipi/universal:stage salsah1/universal:stage ## knora-api .PHONY: build-knora-api-image build-knora-api-image: build-all-scala ## build and publish knora-api docker image locally - docker build -t $(KNORA_API_IMAGE) -f docker/knora-api.dockerfile webapi/target/universal + docker build -t $(KNORA_API_IMAGE) -t $(REPO_PREFIX)/$(KNORA_API_REPO):latest -f docker/knora-api.dockerfile webapi/target/universal .PHONY: publish-knora-api publish-knora-api-image: build-knora-api-image ## publish knora-api image to Dockerhub docker push $(KNORA_API_IMAGE) -## knora-graphdb-se -.PHONY: build-knora-graphdb-se-image -build-knora-graphdb-se-image: build-all-scala ## build and publish knora-graphdb-se docker image locally - @mkdir -p .docker - @sed -e "s/@GRAPHDB_IMAGE@/daschswiss\/graphdb\:$(GRAPHDB_SE_VERSION)-se/" docker/knora-graphdb.template.dockerfile > .docker/knora-graphdb-se.dockerfile -ifeq ($(KNORA_GDB_LICENSE), unknown) - touch $(CURRENT_DIR)/knora-graphdb-se/target/universal/stage/scripts/graphdb.license -else - cp $(KNORA_GDB_LICENSE) $(CURRENT_DIR)/knora-graphdb-se/target/universal/stage/scripts/graphdb.license -endif - docker build -t $(KNORA_GRAPHDB_SE_IMAGE) -t $(REPO_PREFIX)/$(KNORA_GRAPHDB_SE_REPO):latest -f .docker/knora-graphdb-se.dockerfile knora-graphdb-se/target/universal +## knora-fuseki +.PHONY: build-knora-jena-fuseki-image +build-knora-jena-fuseki-image: build-all-scala ## build and publish knora-jena-fuseki docker image locally + docker build -t $(KNORA_FUSEKI_IMAGE) -t $(REPO_PREFIX)/$(KNORA_FUSEKI_REPO):latest -f docker/knora-jena-fuseki.dockerfile knora-jena-fuseki/target/universal -.PHONY: publish-knora-graphdb-se-image -publish-knora-graphdb-se-image: build-knora-graphdb-se-image ## publish knora-graphdb-se image to Dockerhub - docker push $(KNORA_GRAPHDB_SE_IMAGE) - -## knora-graphdb-free -.PHONY: build-knora-graphdb-free-image -build-knora-graphdb-free-image: build-all-scala ## build and publish knora-graphdb-free docker image locally - @mkdir -p .docker - @sed -e "s/@GRAPHDB_IMAGE@/daschswiss\/graphdb\:$(GRAPHDB_FREE_VERSION)-free/" docker/knora-graphdb.template.dockerfile > .docker/knora-graphdb-free.dockerfile - touch $(CURRENT_DIR)/knora-graphdb-free/target/universal/stage/scripts/graphdb.license - docker build -t $(KNORA_GRAPHDB_FREE_IMAGE) -f .docker/knora-graphdb-free.dockerfile knora-graphdb-free/target/universal - -.PHONY: publish-knora-graphdb-free-image -publish-knora-graphdb-free-image: build-knora-graphdb-free-image ## publish knora-graphdb-se image to Dockerhub - docker push $(KNORA_GRAPHDB_FREE_IMAGE) +.PHONY: publish-knora-jena-fuseki-image +publish-knora-jena-fuseki-image: build-knora-jena-fuseki-image ## publish knora-jena-fuseki image to Dockerhub + docker push $(KNORA_FUSEKI_IMAGE) ## knora-sipi .PHONY: build-knora-sipi-image build-knora-sipi-image: build-all-scala ## build and publish knora-sipi docker image locally @mkdir -p .docker @sed -e "s/@SIPI_VERSION@/$(SIPI_VERSION)/" docker/knora-sipi.template.dockerfile > .docker/knora-sipi.dockerfile - docker build -t $(KNORA_SIPI_IMAGE) -f .docker/knora-sipi.dockerfile knora-sipi/target/universal + docker build -t $(KNORA_SIPI_IMAGE) -t $(REPO_PREFIX)/$(KNORA_SIPI_REPO):latest -f .docker/knora-sipi.dockerfile knora-sipi/target/universal .PHONY: publish-knora-sipi-image publish-knora-sipi-image: build-knora-sipi-image ## publish knora-sipi image to Dockerhub @@ -83,21 +64,12 @@ build-knora-salsah1-image: build-all-scala ## build and publish knora-salsah1 do publish-knora-salsah1-image: build-knora-salsah1-image ## publish knora-salsah1 image to Dockerhub docker push $(KNORA_SALSAH1_IMAGE) -## knora-assets -.PHONY: build-knora-assets-image -build-knora-assets-image: build-all-scala ## build and publish knora-assets docker image locally - docker build -t $(KNORA_ASSETS_IMAGE) -f docker/knora-assets.dockerfile knora-assets/target/universal - -.PHONY: publish-knora-assets-image -publish-knora-assets-image: build-knora-assets-image ## publish knora-assets image to Dockerhub - docker push $(KNORA_ASSETS_IMAGE) - ## all images .PHONY: build-all-images -build-all-images: build-knora-api-image build-knora-graphdb-se-image build-knora-graphdb-free-image build-knora-sipi-image build-knora-salsah1-image build-knora-assets-image ## build all Docker images +build-all-images: build-knora-api-image build-knora-jena-fuseki-image build-knora-sipi-image build-knora-salsah1-image ## build all Docker images .PHONY: publish-all-images -publish-all-images: publish-knora-api-image publish-knora-graphdb-se-image publish-knora-graphdb-free-image publish-knora-sipi-image publish-knora-salsah1-image publish-knora-assets-image ## publish all Docker images +publish-all-images: publish-knora-api-image publish-knora-jena-fuseki-image publish-knora-sipi-image publish-knora-salsah1-image ## publish all Docker images ################################# ## Docker-Compose targets @@ -109,33 +81,26 @@ print-env-file: ## prints the env file used by knora-stack .PHONY: env-file env-file: ## write the env file used by knora-stack. -ifeq ($(KNORA_GDB_LICENSE), unknown) - $(warning No GraphDB-SE license set. Using GraphDB-Free.) - @echo KNORA_GRAPHDB_IMAGE=$(KNORA_GRAPHDB_FREE_IMAGE) > .env - @echo KNORA_GDB_TYPE=graphdb-free >> .env -else - @echo KNORA_GRAPHDB_IMAGE=$(KNORA_GRAPHDB_SE_IMAGE) > .env - @echo KNORA_GDB_TYPE=graphdb-se >> .env -endif -ifeq ($(KNORA_GDB_IMPORT), unknown) - $(warning The path to the GraphDB import directory is not set. Using docker volume: db-import.) - @echo KNORA_GDB_IMPORT_DIR=db-import >> .env +ifeq ($(KNORA_DB_HOME), unknown) + @echo KNORA_DB_HOME_DIR=db-home > .env else - @echo KNORA_GDB_IMPORT_DIR=$(KNORA_GDB_IMPORT) >> .env + $(info Using $(KNORA_DB_HOME) for the DB home directory.) + @echo KNORA_DB_HOME_DIR=$(KNORA_DB_HOME) > .env endif -ifeq ($(KNORA_GDB_HOME), unknown) - $(warning The path to the GraphDB home directory is not set. Using docker volume: db-home.) - @echo KNORA_GDB_HOME_DIR=db-home >> .env +ifeq ($(KNORA_DB_IMPORT), unknown) + @echo KNORA_DB_IMPORT_DIR=db-import >> .env else - @echo KNORA_GDB_HOME_DIR=$(KNORA_GDB_HOME) >> .env + $(info Using $(KNORA_DB_IMPORT) for the DB import directory.) + @echo KNORA_DB_IMPORT_DIR=$(KNORA_DB_IMPORT) >> .env endif - @echo KNORA_GDB_HEAP_SIZE=$(KNORA_GDB_HEAP_SIZE) >> .env @echo KNORA_SIPI_IMAGE=$(KNORA_SIPI_IMAGE) >> .env + @echo KNORA_FUSEKI_IMAGE=$(KNORA_FUSEKI_IMAGE) >> .env + @echo FUSEKI_HEAP_SIZE=$(FUSEKI_HEAP_SIZE) >> .env @echo KNORA_API_IMAGE=$(KNORA_API_IMAGE) >> .env @echo KNORA_SALSAH1_IMAGE=$(KNORA_SALSAH1_IMAGE) >> .env @echo DOCKERHOST=$(DOCKERHOST) >> .env @echo KNORA_WEBAPI_DB_CONNECTIONS=$(KNORA_WEBAPI_DB_CONNECTIONS) >> .env - @echo KNORA_GRAPHDB_REPOSITORY_NAME=$(KNORA_GRAPHDB_REPOSITORY_NAME) >> .env + @echo KNORA_DB_REPOSITORY_NAME=$(KNORA_DB_REPOSITORY_NAME) >> .env @echo LOCAL_HOME=$(CURRENT_DIR) >> .env ## knora stack @@ -146,7 +111,7 @@ stack-up: build-all-images env-file ## starts the knora-stack: graphdb, sipi, re docker-compose -f docker/knora.docker-compose.yml up -d .PHONY: stack-up-ci -stack-up-ci: KNORA_GRAPHDB_REPOSITORY_NAME := knora-test-unit +stack-up-ci: KNORA_DB_REPOSITORY_NAME := knora-test-unit stack-up-ci: build-all-images env-file print-env-file ## starts the knora-stack using 'knora-test-unit' repository: graphdb, sipi, redis, api, salsah1. docker-compose -f docker/knora.docker-compose.yml up -d @@ -207,8 +172,12 @@ stack-status: stack-down: ## stops the knora-stack. docker-compose -f docker/knora.docker-compose.yml down +.PHONY: stack-down-delete-volumes +stack-down-delete-volumes: ## stops the knora-stack and delete any created volumes (deletes the database!). + docker-compose -f docker/knora.docker-compose.yml down --volumes + .PHONY: stack-config -stack-config: +stack-config: env-file docker-compose -f docker/knora.docker-compose.yml config ## stack without api @@ -223,180 +192,76 @@ stack-without-api-and-sipi: stack-up ## starts the knora-stack without knora-api docker-compose -f docker/knora.docker-compose.yml stop sipi .PHONY: test-only -test-only: stack-without-api init-db-test-unit ## runs only the supplied tests, e.g., make test-only TARGET="*.CORSSupportE2ESpec". +test-only: build-all-images ## runs only the supplied tests, e.g., make test-only TARGET="*.CORSSupportE2ESpec". @echo $@ # print target name - docker run --rm \ - -v /tmp:/tmp:delegated \ - -v $(CURRENT_DIR):/src:delegated \ - -v $(HOME)/.ivy2:/root/.ivy2:delegated \ - --name=api \ - -e KNORA_WEBAPI_TRIPLESTORE_HOST=db \ - -e KNORA_WEBAPI_SIPI_EXTERNAL_HOST=sipi \ - -e KNORA_WEBAPI_SIPI_INTERNAL_HOST=sipi \ - -e KNORA_WEBAPI_CACHE_SERVICE_REDIS_HOST=redis \ - -e SBT_OPTS="-Xms2048M -Xmx2048M -Xss6M" \ - --network=docker_knora-net \ - daschswiss/scala-sbt sbt "webapi/testOnly $(TARGET)" + sbt "webapi/testOnly $(TARGET)" .PHONY: test-unit -test-unit: stack-without-api init-db-test-unit ## runs the unit tests (equivalent to 'sbt webapi/testOnly -- -l org.knora.webapi.testing.tags.E2ETest'). +test-unit: build-all-images ## runs the unit tests (equivalent to 'sbt webapi/testOnly -- -l org.knora.webapi.testing.tags.E2ETest'). @echo $@ # print target name - docker run --rm \ - -v /tmp:/tmp \ - -v $(CURRENT_DIR):/src \ - -v $(HOME)/.ivy2:/root/.ivy2 \ - --name=api \ - -e KNORA_WEBAPI_TRIPLESTORE_HOST=db \ - -e KNORA_WEBAPI_SIPI_EXTERNAL_HOST=sipi \ - -e KNORA_WEBAPI_SIPI_INTERNAL_HOST=sipi \ - -e KNORA_WEBAPI_CACHE_SERVICE_REDIS_HOST=redis \ - -e SBT_OPTS="-Xms2048M -Xmx2048M -Xss6M" \ - --network=docker_knora-net \ - daschswiss/scala-sbt sbt 'webapi/testOnly -- -l org.knora.webapi.testing.tags.E2ETest' + sbt 'webapi/testOnly -- -l org.knora.webapi.testing.tags.E2ETest' .PHONY: test-unit-ci -test-unit-ci: stack-without-api init-db-test-unit ## runs the unit tests (equivalent to 'sbt webapi/testOnly -- -l org.knora.webapi.testing.tags.E2ETest') with code-coverage reporting. +test-unit-ci: build-all-images ## runs the unit tests (equivalent to 'sbt webapi/testOnly -- -l org.knora.webapi.testing.tags.E2ETest') with code-coverage reporting. @echo $@ # print target name - docker run --rm \ - -v /tmp:/tmp \ - -v $(CURRENT_DIR):/src \ - -v $(HOME)/.ivy2:/root/.ivy2 \ - --name=api \ - -e KNORA_WEBAPI_TRIPLESTORE_HOST=db \ - -e KNORA_WEBAPI_SIPI_EXTERNAL_HOST=sipi \ - -e KNORA_WEBAPI_SIPI_INTERNAL_HOST=sipi \ - -e KNORA_WEBAPI_CACHE_SERVICE_REDIS_HOST=redis \ - -e SBT_OPTS="-Xms2048M -Xmx2048M -Xss6M" \ - --network=docker_knora-net \ - daschswiss/scala-sbt sbt coverage 'webapi/testOnly -- -l org.knora.webapi.testing.tags.E2ETest' webapi/coverageReport + sbt coverage 'webapi/testOnly -- -l org.knora.webapi.testing.tags.E2ETest' webapi/coverageReport .PHONY: test-e2e -test-e2e: stack-without-api init-db-test-unit ## runs the e2e tests (equivalent to 'sbt webapi/testOnly -- -n org.knora.webapi.testing.tags.E2ETest'). +test-e2e: build-all-images ## runs the e2e tests (equivalent to 'sbt webapi/testOnly -- -n org.knora.webapi.testing.tags.E2ETest'). @echo $@ # print target name - docker run --rm \ - -v /tmp:/tmp \ - -v $(CURRENT_DIR):/src \ - -v $(HOME)/.ivy2:/root/.ivy2 \ - --name=api \ - -e KNORA_WEBAPI_TRIPLESTORE_HOST=db \ - -e KNORA_WEBAPI_SIPI_EXTERNAL_HOST=sipi \ - -e KNORA_WEBAPI_SIPI_INTERNAL_HOST=sipi \ - -e KNORA_WEBAPI_CACHE_SERVICE_REDIS_HOST=redis \ - -e SBT_OPTS="-Xms2048M -Xmx2048M -Xss6M" \ - --network=docker_knora-net \ - daschswiss/scala-sbt sbt 'webapi/testOnly -- -n org.knora.webapi.testing.tags.E2ETest' + sbt 'webapi/testOnly -- -n org.knora.webapi.testing.tags.E2ETest' .PHONY: test-e2e-ci -test-e2e-ci: stack-without-api init-db-test-unit ## runs the e2e tests (equivalent to 'sbt webapi/testOnly -- -n org.knora.webapi.testing.tags.E2ETest') with code-coverage reporting. +test-e2e-ci: build-all-images ## runs the e2e tests (equivalent to 'sbt webapi/testOnly -- -n org.knora.webapi.testing.tags.E2ETest') with code-coverage reporting. @echo $@ # print target name - docker run --rm \ - -v /tmp:/tmp \ - -v $(CURRENT_DIR):/src \ - -v $(HOME)/.ivy2:/root/.ivy2 \ - --name=api \ - -e KNORA_WEBAPI_TRIPLESTORE_HOST=db \ - -e KNORA_WEBAPI_SIPI_EXTERNAL_HOST=sipi \ - -e KNORA_WEBAPI_SIPI_INTERNAL_HOST=sipi \ - -e KNORA_WEBAPI_CACHE_SERVICE_REDIS_HOST=redis \ - -e SBT_OPTS="-Xms2048M -Xmx2048M -Xss6M" \ - --network=docker_knora-net \ - daschswiss/scala-sbt sbt coverage 'webapi/testOnly -- -n org.knora.webapi.testing.tags.E2ETest' webapi/coverageReport + sbt coverage 'webapi/testOnly -- -n org.knora.webapi.testing.tags.E2ETest' webapi/coverageReport .PHONY: test-it -test-it: stack-without-api init-db-test-unit ## runs the integration tests (equivalent to 'sbt webapi/it'). +test-it: build-all-images ## runs the integration tests (equivalent to 'sbt webapi/it'). @echo $@ - docker run --rm \ - -v /tmp:/tmp \ - -v $(CURRENT_DIR):/src \ - -v $(HOME)/.ivy2:/root/.ivy2 \ - --name=api \ - -e KNORA_WEBAPI_TRIPLESTORE_HOST=db \ - -e KNORA_WEBAPI_SIPI_EXTERNAL_HOST=sipi \ - -e KNORA_WEBAPI_SIPI_INTERNAL_HOST=sipi \ - -e KNORA_WEBAPI_CACHE_SERVICE_REDIS_HOST=redis \ - -e SBT_OPTS="-Xms2048M -Xmx2048M -Xss6M" \ - --network=docker_knora-net \ - daschswiss/scala-sbt sbt 'webapi/it:test' + sbt 'webapi/it:test' .PHONY: test-it-ci -test-it-ci: stack-without-api init-db-test-unit ## runs the integration tests (equivalent to 'sbt webapi/it:test') with code-coverage reporting. +test-it-ci: build-all-images ## runs the integration tests (equivalent to 'sbt webapi/it:test') with code-coverage reporting. @echo $@ # print target name - docker run --rm \ - -v /tmp:/tmp \ - -v $(CURRENT_DIR):/src \ - -v $(HOME)/.ivy2:/root/.ivy2 \ - --name=api \ - -e KNORA_WEBAPI_TRIPLESTORE_HOST=db \ - -e KNORA_WEBAPI_SIPI_EXTERNAL_HOST=sipi \ - -e KNORA_WEBAPI_SIPI_INTERNAL_HOST=sipi \ - -e KNORA_WEBAPI_CACHE_SERVICE_REDIS_HOST=redis \ - -e SBT_OPTS="-Xms2048M -Xmx2048M -Xss6M" \ - --network=docker_knora-net \ - daschswiss/scala-sbt sbt coverage webapi/it:test webapi/coverageReport - -.PHONY: test-all -test-all: stack-without-api init-db-test-unit ## runs the all tests (equivalent to 'sbt webapi/test'). + sbt coverage webapi/it:test webapi/coverageReport + +.PHONY: test +test: build-all-images ## runs all tests. @echo $@ - # docker build -t webapi-test -f docker/knora-api-test.dockerfile webapi/build/test/target/universal - docker run --rm \ - -v /tmp:/tmp \ - -v $(CURRENT_DIR):/src \ - -v $(HOME)/.ivy2:/root/.ivy2 \ - --name=api \ - -e KNORA_WEBAPI_TRIPLESTORE_HOST=db \ - -e KNORA_WEBAPI_SIPI_EXTERNAL_HOST=sipi \ - -e KNORA_WEBAPI_SIPI_INTERNAL_HOST=sipi \ - -e KNORA_WEBAPI_CACHE_SERVICE_REDIS_HOST=redis \ - -e SBT_OPTS="-Xms2048M -Xmx2048M -Xss6M" \ - --network=docker_knora-net \ - daschswiss/scala-sbt sbt webapi/test + sbt webapi/test webapi/it:test .PHONY: test-repository-update -test-repository-update: stack-without-api +test-repository-update: stack-down-delete-volumes stack-without-api @sleep 15 @$(MAKE) -f $(THIS_FILE) init-db-test-minimal @rm -rf /tmp/knora-test-data/v7.0.0/ @mkdir -p /tmp/knora-test-data/v7.0.0/ @unzip $(CURRENT_DIR)/test-data/v7.0.0/v7.0.0-knora-test.trig.zip -d /tmp/knora-test-data/v7.0.0/ - $(CURRENT_DIR)/webapi/scripts/graphdb-empty-repository.sh -r knora-test -u gaga -p gaga -h localhost:7200 - $(CURRENT_DIR)/webapi/scripts/graphdb-upload-repository.sh -r knora-test -u gaga -p gaga -h localhost:7200 /tmp/knora-test-data/v7.0.0/v7.0.0-knora-test.trig + $(CURRENT_DIR)/webapi/scripts/fuseki-empty-repository.sh -r knora-test -u gaga -p gaga -h localhost:3030 + $(CURRENT_DIR)/webapi/scripts/fuseki-upload-repository.sh -r knora-test -u gaga -p gaga -h localhost:3030 /tmp/knora-test-data/v7.0.0/v7.0.0-knora-test.trig @$(MAKE) -f $(THIS_FILE) stack-restart-api @$(MAKE) -f $(THIS_FILE) stack-logs-api-no-follow .PHONY: init-db-test -init-db-test: ## initializes the knora-test repository +init-db-test: stack-down-delete-volumes stack-without-api ## initializes the knora-test repository @echo $@ - @$(MAKE) -C webapi/scripts graphdb-se-docker-init-knora-test + @$(MAKE) -C webapi/scripts fuseki-init-knora-test .PHONY: init-db-test-minimal -init-db-test-minimal: ## initializes the knora-test repository with minimal data +init-db-test-minimal: stack-down-delete-volumes stack-without-api ## initializes the knora-test repository with minimal data @echo $@ - @$(MAKE) -C webapi/scripts graphdb-se-docker-init-knora-test-minimal + @$(MAKE) -C webapi/scripts fuseki-init-knora-test-minimal .PHONY: init-db-test-unit -init-db-test-unit: ## initializes the knora-test-unit repository +init-db-test-unit: stack-down-delete-volumes stack-without-api ## initializes the knora-test-unit repository @echo $@ - @$(MAKE) -C webapi/scripts graphdb-se-docker-init-knora-test-unit + @$(MAKE) -C webapi/scripts fuseki-init-knora-test-unit .PHONY: init-db-test-unit-minimal -init-db-test-unit-minimal: ## initializes the knora-test-unit repository with minimal data - @echo $@ - @$(MAKE) -C webapi/scripts graphdb-se-docker-init-knora-test-unit-minimal - -.PHONY: init-db-test-free -init-db-test-free: ## initializes the knora-test repository (for GraphDB-Free) - @echo $@ - @$(MAKE) -C webapi/scripts graphdb-free-docker-init-knora-test-free - -.PHONY: init-db-test-minimal-free -init-db-test-minimal-free: ## initializes the knora-test repository with minimal data (for GraphDB-Free) - @echo $@ - @$(MAKE) -C webapi/scripts graphdb-free-docker-init-knora-test-minimal - -.PHONY: init-db-test-unit-free -init-db-test-unit-free: ## initializes the knora-test-unit repository (for GraphDB-Free) +init-db-test-unit-minimal: stack-down-delete-volumes stack-without-api ## initializes the knora-test-unit repository with minimal data @echo $@ - @$(MAKE) -C webapi/scripts graphdb-free-docker-init-knora-test-unit + @$(MAKE) -C webapi/scripts fuseki-init-knora-test-unit-minimal ################################# # Other @@ -418,19 +283,16 @@ clean-docker: ## cleans the docker installation .PHONY: info info: ## print out all variables - @echo "BUILD_TAG: \t\t\t $(BUILD_TAG)" - @echo "GIT_EMAIL: \t\t\t $(GIT_EMAIL)" - @echo "SIPI_VERSION: \t\t\t $(SIPI_VERSION)" - @echo "GRAPHDB_SE_VERSION: \t\t $(GRAPHDB_SE_VERSION)" - @echo "KNORA_API_IMAGE: \t\t $(KNORA_API_IMAGE)" - @echo "KNORA_GRAPHDB_SE_IMAGE: \t $(KNORA_GRAPHDB_SE_IMAGE)" - @echo "KNORA_GRAPHDB_FREE_IMAGE: \t $(KNORA_GRAPHDB_FREE_IMAGE)" - @echo "KNORA_SIPI_IMAGE: \t\t $(KNORA_SIPI_IMAGE)" - @echo "KNORA_ASSETS_IMAGE: \t\t $(KNORA_ASSETS_IMAGE)" - @echo "KNORA_SALSAH1_IMAGE: \t\t $(KNORA_SALSAH1_IMAGE)" - @echo "KNORA_GDB_LICENSE: \t\t $(KNORA_GDB_LICENSE)" - @echo "KNORA_GDB_IMPORT: \t\t $(KNORA_GDB_IMPORT)" - @echo "KNORA_GDB_HOME: \t\t $(KNORA_GDB_HOME)" + @echo "BUILD_TAG: \t\t $(BUILD_TAG)" + @echo "GIT_EMAIL: \t\t $(GIT_EMAIL)" + @echo "SIPI_VERSION: \t\t $(SIPI_VERSION)" + @echo "KNORA_API_IMAGE: \t $(KNORA_API_IMAGE)" + @echo "KNORA_FUSEKI_IMAGE: \t $(KNORA_FUSEKI_IMAGE)" + @echo "KNORA_SIPI_IMAGE: \t $(KNORA_SIPI_IMAGE)" + @echo "KNORA_ASSETS_IMAGE: \t $(KNORA_ASSETS_IMAGE)" + @echo "KNORA_SALSAH1_IMAGE: \t $(KNORA_SALSAH1_IMAGE)" + @echo "KNORA_DB_IMPORT: \t $(KNORA_DB_IMPORT)" + @echo "KNORA_DB_HOME: \t\t $(KNORA_DB_HOME)" .PHONY: help help: ## this help diff --git a/README.md b/README.md index 9cb7af25e9..44528ac02e 100644 --- a/README.md +++ b/README.md @@ -2,23 +2,28 @@ [![Codacy Badge](https://api.codacy.com/project/badge/Grade/7e7c734a37ef403a964345e29106b267)](https://app.codacy.com/app/dhlab-basel/Knora?utm_source=github.com&utm_medium=referral&utm_content=dhlab-basel/Knora&utm_campaign=Badge_Grade_Dashboard) # Knora -[Knora](http://www.knora.org/) (Knowledge Organization, Representation, and Annotation) is a server -application for storing, sharing, and working with primary sources and data in the humanities. +[Knora](https://www.knora.org/) (Knowledge Organization, Representation, and +Annotation) is a server application for storing, sharing, and working with +primary sources and data in the humanities. -It is developed by the [Digital Humanities Lab](http://www.dhlab.unibas.ch/) at the [University of Basel](https://www.unibas.ch/en.html), and is supported by the [Swiss Academy of Humanities and Social Sciences](http://www.sagw.ch/en/sagw.html). +It is developed by the [Data and Service Center for the Humanities](https://dasch.swiss) +at the [University of Basel](https://www.unibas.ch), and is supported by the +[Swiss Academy of Humanities and Social Sciences](https://www.sagw.ch) and +the [Swiss National Science Foundation](https://snf.ch). -Knora is [free software](http://www.gnu.org/philosophy/free-sw.en.html), released under the [GNU Affero General Public License](http://www.gnu.org/licenses/agpl-3.0.en.html). +Knora is [free software](http://www.gnu.org/philosophy/free-sw.en.html), +released under the [GNU Affero General Public License](http://www.gnu.org/licenses/agpl-3.0.en.html). ## Features * Stores humanities data as industry-standard [RDF](http://www.w3.org/TR/2014/NOTE-rdf11-primer-20140624/) graphs, plus files for binary data such as digitized primary sources. - * Designed to work with any standards-compliant RDF triplestore. Tested with [Ontotext GraphDB](http://ontotext.com/products/graphdb/). + * Designed to work with any standards-compliant RDF triplestore. Tested with [Jena Fuseki](https://jena.apache.org/). * Based on [OWL](http://www.w3.org/TR/2012/REC-owl2-primer-20121211/) ontologies that express abstract, cross-disciplinary commonalities in the structure and semantics of research data. -* Offers a generic HTTP-based API, implemented in [Scala](http://www.scala-lang.org/), for querying, annotating, and linking together heterogeneous data in a unified way. +* Offers a generic HTTP-based API, implemented in [Scala](https://www.scala-lang.org/), for querying, annotating, and linking together heterogeneous data in a unified way. * Handles authentication and authorization. * Provides automatic versioning of data. -* Uses [Sipi](http://www.sipi.io/), a high-performance media server implemented in C++. -* Designed to be be used with [SALSAH](https://dhlab-basel.github.io/Salsah/), a general-purpose, browser-based virtual research environment, +* Uses [Sipi](https://www.sipi.io), a high-performance media server implemented in C++. +* Designed to be be used with [DSP-APP](https://docs.dasch.swiss/user-guide/), a general-purpose, browser-based virtual research environment, as well as with custom user interfaces. ## Status @@ -36,18 +41,18 @@ Knora is [free software](http://www.gnu.org/philosophy/free-sw.en.html), release ### New features under development -* See the [Roadmap](https://github.com/dhlab-basel/Knora/wiki/Roadmap) +* See the [Roadmap](https://github.com/dasch-swiss/knora-api/wiki/Roadmap) ## Requirements ### For developing and testing the API server * Linux or macOS (with some caveats) -* [Java Development Kit 10](http://www.oracle.com/technetwork/java/javase/downloads/jdk10-downloads-4416644.html) -* [SBT](http://www.scala-sbt.org/) +* [OpenJDK](https://adoptopenjdk.net) +* [SBT](https://www.scala-sbt.org) -[Ontotext GraphDB](http://ontotext.com/products/graphdb/) is recommended. Support for -other RDF triplestores is planned. +[Jena Fuseki](https://jena.apache.org) is recommended. Support for other RDF +triplestores is planned. ### For building the documentation @@ -55,12 +60,9 @@ See [docs/Readme.md](docs/Readme.md). ## Try it out -### Quick Installation Guide for Knora, Salsah, Sipi and GraphDB -A manual to get all mentioned components locally up and running can be found [here](https://github.com/dhlab-basel/Knora/wiki/Quick-Installation-Guide-for-Knora,-Salsah,-Sipi-and-GraphDB). - ### Run the Knora API server -With [Docker](https://www.docker.com/) installed, run the following: +With [Docker](https://www.docker.com) installed, run the following: ``` $ make stack-up @@ -69,7 +71,7 @@ $ make stack-up Then to create a test repository and load some test data into the triplestore: ``` -$ make init-db-test-free +$ make init-db-test ``` Then we need to restart knora-api after loading the data: @@ -91,56 +93,65 @@ $ make stack-down Run : ``` -$ make init-db-test-unit-free -$ make normal-tests +$ make test ``` -### Running with a GraphDB License and Custom Folders +### Running with Custom Folders -The `$ make stack-up` target can be additonally configured thorugh the following environment variables: +The `$ make stack-up` target can be additionally configured thorough the +following environment variables: -``` -KNORA_GDB_LICENSE - sets the path to the GraphDB-SE license -KNORA_GDB_IMPORT - sets the path to the import directory accessible from inside the GraphDB Workbench -KNORA_GDB_HOME - sets the path to the folder where GraphDB will store the database files -``` +- `KNORA_DB_HOME`: sets the path to the folder where the triplestore will store +the database files +- `KNORA_DB_IMPORT`: sets the path to the import directory accessible from +inside the docker image -Some or all environment variables can be set, as required. If the license file is not set, then GraphDB-Free will be -started. If the import and/or data directories are not set, then Docker volumes will be used instead. +If the import and/or data directory are not set, then Docker volumes will be +used instead. Be aware on macOS, that setting the `KNORA_DB_HOME` has a +significant negative impact on performance, because of how synchronization with +the VM, in which docker is running, is implemented. ## How to Contribute -You can help by testing Knora with your data, making bug reports, improving the documentation, and adding features that you need. +You can help by testing Knora with your data, making bug reports, improving the +documentation, and adding features that you need. -First, open an [issue](https://github.com/dhlab-basel/Knora/issues) to describe your problem or idea. We may ask you to submit a [pull request](https://help.github.com/articles/about-pull-requests/) implementing the desired functionality. +First, open an [issue](https://github.com/dasch-swiss/knora-api/issues) to +describe your problem or idea. We may ask you to submit a +[pull request](https://help.github.com/articles/about-pull-requests/) +implementing the desired functionality. ### Coding conventions Use `camelCase` for names of classes, variables, and functions. Make names descriptive, and don't worry if they're long. -Format your code consistently. We [IntelliJ IDEA](https://www.jetbrains.com/idea/) to format code, with 4 spaces indentation. Use whitespace to make your code easier to read. Add lots of implementation comments describing what your code is doing, how it works, and why it works that way. +Format your code consistently. We [IntelliJ IDEA](https://www.jetbrains.com/idea) to format code, with 4 spaces indentation. Use whitespace to make your code easier to read. Add lots of implementation comments describing what your code is doing, how it works, and why it works that way. ### Tests -We write automated tests using [ScalaTest](http://www.scalatest.org/). You can run them from the [SBT](http://www.scala-sbt.org/) console. +We write automated tests using [ScalaTest](https://www.scalatest.org). You can run them from the [SBT](https://www.scala-sbt.org) console. There are three sets of automated tests: * Unit tests, route-to-route tests, and end-to-end tests are under `webapi/src/test`. To run these, type `graphdb:test` or `graphdb-free:test` (depending on which triplestore you're using) at the SBT console in the `webapi` project. To run a single test, use `graphdb:test-only *NameOfTestSpec`. -* Integration tests, which can involve [Sipi](https://github.com/dhlab-basel/Sipi), are under `src/it`. To run these, first start Sipi, then type `it:test` at the SBT console in the `webapi` project. -* Browser interaction tests are under `salsah/src/test`, and are written using [Selenium](http://www.seleniumhq.org/). To run these, you will need to unpack the correct [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/) for your platform found under `salsah/lib/chromedriver` and put it in the same folder. Then start Sipi and the Knora API server, and type `test` at the SBT console in the `salsah` project. +* Integration tests, which can involve [Sipi](https://github.com/daschswiss/sipi), are under `src/it`. To run these, first start Sipi, then type `it:test` at the SBT console in the `webapi` project. +* Browser interaction tests are under `salsah/src/test`, and are written using [Selenium](https://www.seleniumhq.org). To run these, you will need to unpack the correct [ChromeDriver](https://sites.google.com/a/chromium.org/chromedriver/) for your platform found under `salsah/lib/chromedriver` and put it in the same folder. Then start Sipi and the Knora API server, and type `test` at the SBT console in the `salsah` project. -Whenever you add a new feature or fix a bug, you should add one or more tests for the change you made. +Whenever you add a new feature or fix a bug, you should add one or more tests +for the change you made. ### Documentation -A pull request should include tests and documentation for the changes that were made. See the [documentation README](https://github.com/dhlab-basel/Knora/blob/develop/docs/Readme.md) for information on writing Knora documentation. +A pull request should include tests and documentation for the changes that were +made. See the [documentation README](https://github.com/dasch-swiss/knora-api/blob/develop/docs/Readme.md) +for information on writing Knora documentation. ## Contact information ### Technical -Please use the [discuss.dasch.swiss](https://discuss.dasch.swiss) forum for technical questions. +Please use the [discuss.dasch.swiss](https://discuss.dasch.swiss) forum for +technical questions. ### Administrative diff --git a/docker/knora-api-it.dockerfile b/docker/knora-api-it.dockerfile deleted file mode 100644 index e6b3e6a262..0000000000 --- a/docker/knora-api-it.dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM adoptopenjdk/openjdk11:alpine-jre - -RUN \ - apk update && \ - apk upgrade && \ - apk add bash - -COPY stage /webapi-it - -WORKDIR /webapi-it - -EXPOSE 3333 - -ENTRYPOINT ["bin/webapi-it"] - -LABEL MAINTAINER="400790+subotic@users.noreply.github.com" diff --git a/docker/knora-api-test.dockerfile b/docker/knora-api-test.dockerfile deleted file mode 100644 index ae1efd536c..0000000000 --- a/docker/knora-api-test.dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM adoptopenjdk/openjdk11:alpine-jre - -RUN \ - apk update && \ - apk upgrade && \ - apk add bash - -COPY stage /webapi-test - -WORKDIR /webapi-test - -EXPOSE 3333 - -ENTRYPOINT ["bin/webapi-test"] - -LABEL MAINTAINER="400790+subotic@users.noreply.github.com" diff --git a/docker/knora-graphdb.template.dockerfile b/docker/knora-graphdb.template.dockerfile deleted file mode 100644 index 09f8db0b9f..0000000000 --- a/docker/knora-graphdb.template.dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM @GRAPHDB_IMAGE@ - -COPY stage/scripts/KnoraRules.pie /graphdb/KnoraRules.pie -COPY stage/scripts/graphdb.license /graphdb/graphdb.license - -LABEL MAINTAINER="400790+subotic@users.noreply.github.com" diff --git a/docker/knora-jena-fuseki.dockerfile b/docker/knora-jena-fuseki.dockerfile new file mode 100644 index 0000000000..65005c5cd9 --- /dev/null +++ b/docker/knora-jena-fuseki.dockerfile @@ -0,0 +1,4 @@ +FROM stain/jena-fuseki:3.14.0 + +# add our fuseki config +COPY stage/jena-fuseki/config.ttl $FUSEKI_BASE/config.ttl diff --git a/docker/knora.docker-compose.yml b/docker/knora.docker-compose.yml index a436bb1e27..e707cf6cf7 100644 --- a/docker/knora.docker-compose.yml +++ b/docker/knora.docker-compose.yml @@ -3,18 +3,17 @@ version: '3.7' services: db: - image: ${KNORA_GRAPHDB_IMAGE} + image: ${KNORA_FUSEKI_IMAGE} ports: - - "7200:7200" + - "3030:3030" volumes: - - ${KNORA_GDB_IMPORT_DIR}:/root/graphdb-import:delegated - - ${KNORA_GDB_HOME_DIR}:/opt/graphdb/home:delegated + - ${KNORA_DB_HOME_DIR}:/fuseki:delegated + - ${KNORA_DB_IMPORT_DIR}:/staging:delegated networks: - knora-net environment: - - GDB_HEAP_SIZE=$KNORA_GDB_HEAP_SIZE - - GDB_JAVA_OPTS=-Dgraphdb.license.file=/graphdb/graphdb.license -Dgraphdb.home=/opt/graphdb/home - command: ["/graphdb/bin/graphdb"] + - ADMIN_PASSWORD=test + - JVM_ARGS=-Xmx${FUSEKI_HEAP_SIZE} sipi: image: ${KNORA_SIPI_IMAGE} @@ -57,9 +56,11 @@ services: - KNORA_AKKA_STDOUT_LOGLEVEL=DEBUG - KNORA_WEBAPI_DB_CONNECTIONS=${KNORA_WEBAPI_DB_CONNECTIONS} - KNORA_WEBAPI_TRIPLESTORE_HOST=db - - KNORA_WEBAPI_TRIPLESTORE_DBTYPE=${KNORA_GDB_TYPE} + - KNORA_WEBAPI_TRIPLESTORE_DBTYPE=fuseki - KNORA_WEBAPI_SIPI_INTERNAL_HOST=sipi - - KNORA_WEBAPI_TRIPLESTORE_GRAPHDB_REPOSITORY_NAME=${KNORA_GRAPHDB_REPOSITORY_NAME} + - KNORA_WEBAPI_TRIPLESTORE_FUSEKI_REPOSITORY_NAME=${KNORA_DB_REPOSITORY_NAME} + - KNORA_WEBAPI_TRIPLESTORE_FUSEKI_USERNAME=admin + - KNORA_WEBAPI_TRIPLESTORE_FUSEKI_PASSWORD=test - KNORA_WEBAPI_CACHE_SERVICE_ENABLED=true - KNORA_WEBAPI_CACHE_SERVICE_REDIS_HOST=redis - KNORA_WEBAPI_CACHE_SERVICE_REDIS_PORT=6379 @@ -82,5 +83,4 @@ networks: volumes: db-home: - db-import: - no-license: \ No newline at end of file + db-import: \ No newline at end of file diff --git a/docs/src/paradox/04-publishing-deployment/configuration.md b/docs/src/paradox/04-publishing-deployment/configuration.md index 1144f633af..93b1ea9bd9 100644 --- a/docs/src/paradox/04-publishing-deployment/configuration.md +++ b/docs/src/paradox/04-publishing-deployment/configuration.md @@ -62,17 +62,20 @@ A number of core settings is additionally configurable through system environmen | app.sipi.external-host | KNORA_WEBAPI_SIPI_EXTERNAL_HOST | localhost | | app.sipi.external-port | KNORA_WEBAPI_SIPI_EXTERNAL_PORT | 443 | | app.ark.resolver | KNORA_WEBAPI_ARK_RESOLVER_URL | http://0.0.0.0:3336 | -| app.ark.assigned-number | KNORA_WEBAPI_ARK_NAAN | 72163 +| app.ark.assigned-number | KNORA_WEBAPI_ARK_NAAN | 72163 | | app.salsah1.base-url | KNORA_WEBAPI_SALSAH1_BASE_URL | http://localhost:3335| -| app.triplestore.dbtype | KNORA_WEBAPI_TRIPLESTORE_DBTYPE | graphdb-se | +| app.triplestore.dbtype | KNORA_WEBAPI_TRIPLESTORE_DBTYPE | fuseki | | app.triplestore.use-https | KNORA_WEBAPI_TRIPLESTORE_USE_HTTPS | false | | app.triplestore.host | KNORA_WEBAPI_TRIPLESTORE_HOST | localhost | +| app.triplestore.auto-init | KNORA_WEBAPI_TRIPLESTORE_AUTOINIT | false | | app.triplestore.graphdb.port | KNORA_WEBAPI_TRIPLESTORE_GRAPHDB_PORT | 7200 | | app.triplestore.graphdb.repository-name | KNORA_WEBAPI_TRIPLESTORE_GRAPHDB_REPOSITORY_NAME | knora-test | | app.triplestore.graphdb.username | KNORA_WEBAPI_TRIPLESTORE_GRAPHDB_USERNAME | admin | | app.triplestore.graphdb.password | KNORA_WEBAPI_TRIPLESTORE_GRAPHDB_PASSWORD | root | | app.triplestore.fuseki.port | KNORA_WEBAPI_TRIPLESTORE_FUSEKI_PORT | 3030 | | app.triplestore.fuseki.repository-name | KNORA_WEBAPI_TRIPLESTORE_FUSEKI_REPOSITORY_NAME | knora-test | +| app.triplestore.fuseki.username | KNORA_WEBAPI_TRIPLESTORE_FUSEKI_USERNAME | admin | +| app.triplestore.fuseki.password | KNORA_WEBAPI_TRIPLESTORE_FUSEKI_PASSWORD | test | | app.cache-service.enabled | KNORA_WEBAPI_CACHE_SERVICE_ENABLED | true | | app.cache-service.redis.host | KNORA_WEBAPI_CACHE_SERVICE_REDIS_HOST | localhost | | app.cache-service.redis.port | KNORA_WEBAPI_CACHE_SERVICE_REDIS_PORT | 6379 | diff --git a/docs/src/paradox/04-publishing-deployment/getting-started.md b/docs/src/paradox/04-publishing-deployment/getting-started.md index 8d80de71dd..8ab0480a59 100644 --- a/docs/src/paradox/04-publishing-deployment/getting-started.md +++ b/docs/src/paradox/04-publishing-deployment/getting-started.md @@ -61,47 +61,31 @@ software](http://www.gnu.org/philosophy/free-sw.en.html) as well as proprietary options. Knora is designed to work with any standards-compliant -triplestore. It is primarily tested with [Ontotext -GraphDB](http://ontotext.com/products/graphdb/), a high-performance, -proprietary triplestore. We recommend GraphDB Standard Edition, but -GraphDB Free (which is proprietary but available free of charge) also -works, where both need to be licensed separately from -Ontotext (http://ontotext.com). GraphDB-Free can be simply licensed by filling out -their registration from. +triplestore. It is primarily tested with +[Apache Jena Fuseki](https://jena.apache.org), an open source triplestore. -Built-in support and configuration for other triplestores is planned. +Built-in support and configuration for a high-performance, proprietary +triplestore [Ontotext GraphDB](http://ontotext.com/products/graphdb/) is +provided but unmaintained (GraphDB must be licensed separately by the user). +Other triplestores are planned. ## Running the Knora-Stack -Use `git` to clone the Knora repository from [Github](https://github.com/dhlab-basel/Knora). - -After having GraphDB licensed, you need to set some environment variables: - -**GraphDB-Free**: +Use `git` to clone the Knora repository from [Github](https://github.com/dasch-swiss/knora-api). The following environment variables are **optional**: -```bash -$ export KNORA_GDB_IMPORT=/path/to/some/folder - sets the path to the import directory accessible from inside the GraphDB Workbench -$ export KNORA_GDB_HOME=/path/to/some/other_folder // sets the path to the folder where GraphDB will store the database files -``` - -**GraphDB-SE**: - -The following environment variable is **required**: +- `KNORA_DB_HOME`: sets the path to the folder where the triplestore will store +the database files +- `KNORA_DB_IMPORT`: sets the path to the import directory accessible from +inside the docker image ```bash -export KNORA_GDB_LICENSE=/path/to/license/file - sets the path to the GraphDB-SE license file +$ export KNORA_DB_IMPORT=/path/to/some/folder +$ export KNORA_DB_HOME=/path/to/some/other_folder ``` -The following environment variables are **optional**: - -```bash -$ export KNORA_GDB_IMPORT=/path/to/some/folder - sets the path to the import directory accessible from inside the GraphDB Workbench -$ export KNORA_GDB_HOME=/path/to/some/other_folder // sets the path to the folder where GraphDB will store the database files -``` - -Then from inside the cloned `Knora` repository folder, run: +Then from inside the cloned `Knora-API` repository folder, run: ```bash $ make stack-up @@ -111,30 +95,22 @@ $ make stack-up To create a test repository called `knora-test` and load test data, run: - - For GraphDB-SE: `$ make init-db-test`. - - - For GraphDB-Free: `$ make init-db-test-free`. +``` +$ make init-db-test +``` The scripts called by `make` can be found under `webapi/scripts`. You can create your own scripts based on these scripts, to create new repositories and optionally to load existing Knora-compliant RDF data into them. -If you are using GraphDB, you must create your repository using a -repository configuration file that specifies the file `KnoraRules.pie` -as its `owlim:ruleset`. This enables RDFS inference and Knora-specific -consistency rules. When using GraphDB, Knora uses RDFS inference to improve -query performance. The Knora-specific consistency rules help ensure that your -data is internally consistent and conforms to the Knora ontologies. - -This file is already packaged inside Knora's Docker images for GraphDB-SE and -GraphDB-Free. +If you need to reload the test data, you need to stop and **delete** the +running Apache Fuseki instance. **Make sure you don't delete important data.** +To stop the instance and delete the repository, run the following command: -When testing with GraphDB, you may sometimes get an error when loading -the test data that says that there are multiple IDs for the same -repository `knora-test`. In that case, something went wrong when -dropping and recreating the repository. You can solve this by deleting -the repository manually and starting over. **Make sure you don't delete -important data.** To delete the repository, stop GraphDB, delete the -`data` directory in your GraphDB installation, and restart GraphDB. +``` +$ make stack-down-delete-volumes +``` +after which you can start the stack again with `make stack-up`, recreate +the repository and load the data with `make init-db-test`. diff --git a/docs/src/paradox/04-publishing-deployment/publishing.md b/docs/src/paradox/04-publishing-deployment/publishing.md index 24fa5f4468..ff54539a93 100644 --- a/docs/src/paradox/04-publishing-deployment/publishing.md +++ b/docs/src/paradox/04-publishing-deployment/publishing.md @@ -26,26 +26,20 @@ The following Docker images are published: - Knora-API: - https://hub.docker.com/r/daschswiss/knora-api -- GraphDB-SE (includes `KnoraRules.pie`): - - https://hub.docker.com/r/daschswiss/knora-graphdb-se -- GraphDB-Free (includes `KnoraRules.pie`): - - https://hub.docker.com/r/daschswiss/knora-graphdb-free +- Jena Fuseki: + - https://hub.docker.com/r/daschswiss/knora-jena-fuseki - Sipi (includes Knora's Sipi scripts): - https://hub.docker.com/r/daschswiss/knora-sipi -- Knora-Assets (Knora-Base ontologies, test data, and scripts): - - https://hub.docker.com/r/daschswiss/knora-assets -- Knora-Upgrade (Knora upgrade tool): - - https://hub.docker.com/r/daschswiss/knora-upgrade - Salsah 1: - https://hub.docker.com/r/daschswiss/knora-salsah1 - Salsah 2: - https://hub.docker.com/r/daschswiss/knora-app-web -Knora's Docker images are published automatically through Github CI each time a pull-request -is merged into the `develop` branch. +Knora's Docker images are published automatically through Github CI each time a +pull-request is merged into the `develop` branch. -Each image is tagged with a version number, where the version is derived by using the result -of `git describe`. The describe version is built from the +Each image is tagged with a version number, where the version is derived by +using the result of `git describe`. The describe version is built from the `last tag + number of commits since tag + short hash`, e.g., `8.0.0-7-ga7827e9`. The images can be published locally by running: @@ -59,13 +53,3 @@ or to Dockerhub: ```bash $ make publish-all-images ``` - -## GraphDB Licensing - -**GraphDB-Free** is the Free Edition of the triplestore from Ontotext (http://ontotext.com). -GraphDB-Free must be licensed separately by the user, by registering with Ontotext, i.e. -filling out the form for downloading the free edition. - -**GraphDB-SE** is the Standard Edition of the triplestore from Ontotext (http://ontotext.com). - -GraphDB-SE must be licensed separately by the user. \ No newline at end of file diff --git a/docs/src/paradox/04-publishing-deployment/updates.md b/docs/src/paradox/04-publishing-deployment/updates.md index 38b3700337..d481f888f5 100644 --- a/docs/src/paradox/04-publishing-deployment/updates.md +++ b/docs/src/paradox/04-publishing-deployment/updates.md @@ -34,8 +34,9 @@ Before starting a new version of Knora, back up your repository, so you can rest in case the automatic repository update fails. You can use one of these scripts in `webapi/scripts`: -- `graphdb-dump-repository.sh` for GraphDB - `fuseki-dump-repository.sh` for Fuseki +- `graphdb-dump-repository.sh` for GraphDB + For information on command-line options, run the script with no arguments. diff --git a/docs/src/paradox/05-internals/design/principles/store-module.md b/docs/src/paradox/05-internals/design/principles/store-module.md index 59f820af95..dbb568fa70 100644 --- a/docs/src/paradox/05-internals/design/principles/store-module.md +++ b/docs/src/paradox/05-internals/design/principles/store-module.md @@ -45,7 +45,7 @@ An HTTP-based triplestore is one that is accessed remotely over the HTTP protocol. `HttpTriplestoreConnector` supports the following triplestores: - Ontotext GraphDB - - Fuseki 2 (not currently supported) + - Fuseki 2 ### GraphDB diff --git a/docs/src/paradox/05-internals/development/building-and-running.md b/docs/src/paradox/05-internals/development/building-and-running.md index b1155b049c..b64e511f8b 100644 --- a/docs/src/paradox/05-internals/development/building-and-running.md +++ b/docs/src/paradox/05-internals/development/building-and-running.md @@ -23,63 +23,40 @@ License along with Knora. If not, see . @@toc -## Starting a Triplestore +## Running the stack -Start a triplestore (GraphDB-Free or GraphDB-SE). Download distribution from [Ontotext](http://ontotext.com). -Unzip distribution to a place of your choosing and run the following: +With [Docker](https://www.docker.com/) installed, run the following: ``` -$ cd /to/unziped/location -$ ./bin/graphdb -Dgraphdb.license.file=/path/to/GRAPHDB_SE.license +$ make stack-up ``` -Here we use GraphDB-SE which needs to be licensed separately. +Then to create a test repository and load some test data into the triplestore: -Then in another terminal, initialize the data repository and load some test data: - -``` -$ cd KNORA_PROJECT_DIRECTORY/webapi/scripts -$ ./graphdb-se-local-init-knora-test.sh ``` - -Then in another terminal, start the [Redis Server](https://redis.io): - -```bash -$ redis-server +$ make init-db-test ``` -Then go back to the webapi root directory and use SBT to start the API -server: +Then we need to restart knora-api after loading the data: ``` -$ cd KNORA_PROJECT_DIRECTORY -$ sbt -> webapi / compile -> webapi / reStart +$ make stack-restart-api ``` -To shut down Knora: +Then try opening [http://localhost:3333/v1/resources/http%3A%2F%2Frdfh.ch%2F0803%2Fc5058f3a](http://localhost:3333/v1/resources/http%3A%2F%2Frdfh.ch%2F0803%2Fc5058f3a) in a web browser. You should see a response in JSON describing a book. + +To shut down the Knora-Stack: ``` -> webapi / reStop +$ make stack-down ``` ## Running the automated tests -Make sure you've started the triplestore as shown above. - -Then in another terminal, initialise the repository used for automated -testing: - -``` -$ cd KNORA_PROJECT_DIRECTORY/webapi/scripts -$ ./graphdb-se-local-init-knora-test-unit.sh -``` - Run the automated tests from sbt: ``` -> webapi / graphdb:test +> webapi / test ``` ## Load Testing on Mac OS X diff --git a/docs/src/paradox/05-internals/development/fuseki.md b/docs/src/paradox/05-internals/development/fuseki.md index 24a7d9a9d3..096cc24a9d 100644 --- a/docs/src/paradox/05-internals/development/fuseki.md +++ b/docs/src/paradox/05-internals/development/fuseki.md @@ -17,7 +17,7 @@ You should have received a copy of the GNU Affero General Public License along with Knora. If not, see . --> -# Starting Fuseki 3 +# Starting Jena-Fuseki 2 ## Locally diff --git a/docs/src/paradox/05-internals/development/index.md b/docs/src/paradox/05-internals/development/index.md index e3a6add1f5..5d88e443e5 100644 --- a/docs/src/paradox/05-internals/development/index.md +++ b/docs/src/paradox/05-internals/development/index.md @@ -24,7 +24,7 @@ License along with Knora. If not, see . @@@ index - [Overview](overview.md) -- [Starting Fuseki 3](fuseki.md) +- [Starting Fuseki 2](fuseki.md) - [Starting GraphDB](graphdb.md) - [Build and Running](building-and-running.md) - [Build Process](build-process.md) diff --git a/triplestores/fuseki-tomcat/config.ttl b/jena-fuseki/config.ttl similarity index 94% rename from triplestores/fuseki-tomcat/config.ttl rename to jena-fuseki/config.ttl index f835274c17..f39e14807d 100644 --- a/triplestores/fuseki-tomcat/config.ttl +++ b/jena-fuseki/config.ttl @@ -27,7 +27,6 @@ # Add any custom classes you want to load. # Must have a "public static void init()" method. # ja:loadClass "your.code.Class" ; - ja:loadClass "org.apache.jena.query.text.TextQuery"; # End triples. . diff --git a/project/Dependencies.scala b/project/Dependencies.scala index a6261a9356..e90ce3ea72 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -38,7 +38,7 @@ object Dependencies { lazy val jenaVersion = settingKey[String]("the Jena library version") lazy val metricsVersion = settingKey[String]("the metrics library version") - lazy val knoraGdbImage = SettingKey[String]("the Knora specific GraphDB Image") + lazy val knoraJenaFusekiImage = SettingKey[String]("the Knora specific Jena Fuseki Image") lazy val knoraSipiImage = SettingKey[String]("the Knora specific Sipi Image") lazy val knoraWebapiImage = SettingKey[String]("the Knora webapi Image") lazy val knoraSalsah1Image = SettingKey[String]("the Knora Salsah1 Image") @@ -47,7 +47,7 @@ object Dependencies { scalaVersion := "2.12.11", akkaVersion := "2.6.5", akkaHttpVersion := "10.1.12", - jenaVersion := "3.4.0", + jenaVersion := "3.14.0", metricsVersion := "4.0.1", sipiImage := "dhlabbasel/sipi:v2.0.1", gdbSEImage := "daschswiss/graphdb:9.0.0-se", @@ -72,8 +72,6 @@ object Dependencies { val typesafeConfig = "com.typesafe" % "config" % "1.3.3" - // testing - //CORS support val akkaHttpCors = "ch.megard" %% "akka-http-cors" % "1.0.0" @@ -163,7 +161,7 @@ object Dependencies { val scalaTest = "org.scalatest" %% "scalatest" % "3.1.2" % "test, it, gdbse, gdbse-it, gdbfree, gdbfree-it, tdb, fuseki, fuseki-it" val gatlingHighcharts = "io.gatling.highcharts" % "gatling-charts-highcharts"% "2.3.1" % "test, it, gdbse, gdbse-it, gdbfree, gdbfree-it, tdb, fuseki, fuseki-it" val gatlingTestFramework = "io.gatling" % "gatling-test-framework" % "2.3.1" % "test, it, gdbse, gdbse-it, gdbfree, gdbfree-it, tdb, fuseki, fuseki-it" - + val testcontainers = "org.testcontainers" % "testcontainers" % "1.14.3" % "test, it, gdbse, gdbse-it, gdbfree, gdbfree-it, tdb, fuseki, fuseki-it" } object TestBinaries { @@ -244,6 +242,7 @@ object Dependencies { scallop, springSecurityCore, swaggerAkkaHttp, + WebapiTest.testcontainers, typesafeConfig, xmlunitCore ) diff --git a/project/build.properties b/project/build.properties index 797e7ccfdb..654fe70c42 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.3.10 +sbt.version=1.3.12 diff --git a/project/plugins.sbt b/project/plugins.sbt index 94869ea157..7393197aa1 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -6,23 +6,23 @@ resolvers ++= Seq( // Knora addSbtPlugin("com.typesafe.sbt" % "sbt-git" % "1.0.0") -addSbtPlugin("com.tapad" % "sbt-docker-compose" % "1.0.34") -addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.3.22") +addSbtPlugin("com.tapad" % "sbt-docker-compose" % "1.0.35") +addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "1.7.2") addSbtPlugin("io.kamon" % "sbt-aspectj-runner" % "1.1.1") // docs -addSbtPlugin("com.lightbend.paradox" % "sbt-paradox" % "0.3.2") -addSbtPlugin("io.github.jonas" % "sbt-paradox-material-theme" % "0.4.0") +addSbtPlugin("com.lightbend.paradox" % "sbt-paradox" % "0.4.4") +addSbtPlugin("io.github.jonas" % "sbt-paradox-material-theme" % "0.6.0") addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "1.3.2") -addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.6.2") +addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.6.3") // webapi addSbtPlugin("io.spray" % "sbt-revolver" % "0.9.1") -addSbtPlugin("com.typesafe.sbt" % "sbt-twirl" % "1.3.13") -addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5") +addSbtPlugin("com.typesafe.sbt" % "sbt-twirl" % "1.5.0") +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.10") -addSbtPlugin("com.lightbend.sbt" % "sbt-javaagent" % "0.1.4") +addSbtPlugin("com.lightbend.sbt" % "sbt-javaagent" % "0.1.5") addSbtPlugin("io.gatling" % "gatling-sbt" % "2.2.2") -addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.5.1") +addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.1") addSbtPlugin("com.codacy" % "sbt-codacy-coverage" % "1.3.15") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.9.0") diff --git a/sipi/scripts/convert_from_file.lua b/sipi/scripts/convert_from_file.lua index 07e2192f63..ca83434d5b 100644 --- a/sipi/scripts/convert_from_file.lua +++ b/sipi/scripts/convert_from_file.lua @@ -54,7 +54,7 @@ end if not exists then local error_msg - success, error_msg = server.fs.mkdir(storage_dir, 511) + success, error_msg = server.fs.mkdir(projectDir, 511) if not success then send_error(500, "server.fs.mkdir() failed: " .. error_msg) diff --git a/sipi/scripts/upload.lua b/sipi/scripts/upload.lua index d192b1e97e..cde54b95f7 100644 --- a/sipi/scripts/upload.lua +++ b/sipi/scripts/upload.lua @@ -42,6 +42,27 @@ if token == nil then return end +-- Check that the temp folder is created +local tmpFolder = config.imgroot .. '/tmp/' + +local exists +success, exists = server.fs.exists(tmpFolder) + +if not success then + send_error(500, "server.fs.exists() failed: " .. exists) + return +end + +if not exists then + local error_msg + success, error_msg = server.fs.mkdir(tmpFolder, 511) + + if not success then + send_error(500, "server.fs.mkdir() failed: " .. error_msg) + return + end +end + -- A table of data about each file that was uploaded. local file_upload_data = {} diff --git a/triplestores/.gitignore b/triplestores/.gitignore deleted file mode 100644 index f1110a1f7f..0000000000 --- a/triplestores/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -fuseki/run/databases -fuseki/run/system -fuseki/run/templates -fuseki/run/lucene \ No newline at end of file diff --git a/triplestores/fuseki-tomcat/databases/.gitignore b/triplestores/fuseki-tomcat/databases/.gitignore deleted file mode 100644 index 5e7d2734cf..0000000000 --- a/triplestores/fuseki-tomcat/databases/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory -* -# Except this file -!.gitignore diff --git a/triplestores/fuseki-tomcat/lucene/.gitignore b/triplestores/fuseki-tomcat/lucene/.gitignore deleted file mode 100644 index 5e7d2734cf..0000000000 --- a/triplestores/fuseki-tomcat/lucene/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# Ignore everything in this directory -* -# Except this file -!.gitignore diff --git a/triplestores/fuseki-tomcat/shiro.ini b/triplestores/fuseki-tomcat/shiro.ini deleted file mode 100644 index 5d129d0062..0000000000 --- a/triplestores/fuseki-tomcat/shiro.ini +++ /dev/null @@ -1,38 +0,0 @@ -# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0 - -[main] -# Development -ssl.enabled = false - -plainMatcher=org.apache.shiro.authc.credential.SimpleCredentialsMatcher -#iniRealm=org.apache.shiro.realm.text.IniRealm -iniRealm.credentialsMatcher = $plainMatcher - -localhostFilter=org.apache.jena.fuseki.authz.LocalhostFilter - -[users] -# Implicitly adds "iniRealm = org.apache.shiro.realm.text.IniRealm" -admin=pw - -[roles] - -[urls] -## Control functions open to anyone -/$/status = anon -/$/ping = anon -/$/metrics = anon - -## and the rest are restricted to localhost. -/$/** = localhostFilter - -## If you want simple, basic authentication user/password -## on the operations, -## 1 - set a better password in [users] above. -## 2 - comment out the "/$/** = localhost" line and use: -## "/$/** = authcBasic,user[admin]" - -## or to allow any access. -##/$/** = anon - -# Everything else -/**=anon diff --git a/triplestores/fuseki-tomcat/templates/config-mem b/triplestores/fuseki-tomcat/templates/config-mem deleted file mode 100644 index a8b4cd65f7..0000000000 --- a/triplestores/fuseki-tomcat/templates/config-mem +++ /dev/null @@ -1,27 +0,0 @@ -# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0 - -@prefix : <#> . -@prefix fuseki: . -@prefix rdf: . - -@prefix rdfs: . -@prefix tdb: . -@prefix ja: . - -## --------------------------------------------------------------- -## Updatable in-memory dataset. - -<#service1> rdf:type fuseki:Service ; - # URI of the dataset -- http://host:port/{NAME} - fuseki:name "{NAME}" ; - fuseki:serviceQuery "sparql" ; - fuseki:serviceQuery "query" ; - fuseki:serviceUpdate "update" ; - fuseki:serviceUpload "upload" ; - fuseki:serviceReadWriteGraphStore "data" ; - fuseki:serviceReadGraphStore "get" ; - fuseki:dataset <#dataset> ; - . - -# Transactional, in-memory dataset. Initially empty. -<#dataset> rdf:type ja:DatasetTxnMem . diff --git a/triplestores/fuseki-tomcat/templates/config-service b/triplestores/fuseki-tomcat/templates/config-service deleted file mode 100644 index a019496a59..0000000000 --- a/triplestores/fuseki-tomcat/templates/config-service +++ /dev/null @@ -1,23 +0,0 @@ -# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0 - -@prefix : <#> . -@prefix fuseki: . -@prefix rdf: . - -@prefix rdfs: . -@prefix tdb: . -@prefix ja: . - -## --------------------------------------------------------------- -## Read-only in-memory dataset - used as a default, dummy datasets - -<#service1> rdf:type fuseki:Service ; - fuseki:name "" ; - fuseki:serviceQuery "sparql" ; - fuseki:serviceQuery "query" ; - fuseki:serviceReadGraphStore "get" ; - fuseki:dataset <#dataset> ; - . - -## In-memory, empty. -<#dataset> rdf:type ja:RDFDataset . diff --git a/triplestores/fuseki-tomcat/templates/config-tdb b/triplestores/fuseki-tomcat/templates/config-tdb deleted file mode 100644 index a16575bb8e..0000000000 --- a/triplestores/fuseki-tomcat/templates/config-tdb +++ /dev/null @@ -1,31 +0,0 @@ -# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0 - -@prefix : <#> . -@prefix fuseki: . -@prefix rdf: . -@prefix rdfs: . -@prefix tdb: . -@prefix ja: . - -## --------------------------------------------------------------- -## Updatable TDB dataset with all services enabled. - -<#service_tdb_all> rdf:type fuseki:Service ; - rdfs:label "TDB {NAME}" ; - fuseki:name "{NAME}" ; - fuseki:serviceQuery "query" ; - fuseki:serviceQuery "sparql" ; - fuseki:serviceUpdate "update" ; - fuseki:serviceUpload "upload" ; - fuseki:serviceReadWriteGraphStore "data" ; - # A separate read-only graph store endpoint: - fuseki:serviceReadGraphStore "get" ; - fuseki:dataset <#tdb_dataset_readwrite> ; - - . - -<#tdb_dataset_readwrite> rdf:type tdb:DatasetTDB ; - tdb:location "{FUSEKI_BASE}/databases/{NAME}" ; - ##ja:context [ ja:cxtName "arq:queryTimeout" ; ja:cxtValue "3000" ] ; - ##tdb:unionDefaultGraph true ; - . diff --git a/triplestores/fuseki-tomcat/templates/config-tdb-dir b/triplestores/fuseki-tomcat/templates/config-tdb-dir deleted file mode 100644 index 4362f87691..0000000000 --- a/triplestores/fuseki-tomcat/templates/config-tdb-dir +++ /dev/null @@ -1,30 +0,0 @@ -# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0 - -@prefix : <#> . -@prefix fuseki: . -@prefix rdf: . -@prefix rdfs: . -@prefix tdb: . -@prefix ja: . - -## --------------------------------------------------------------- -## Updatable TDB dataset with all services enabled. - -<#service_tdb_all> rdf:type fuseki:Service ; - rdfs:label "TDB {NAME}" ; - fuseki:name "{NAME}" ; - fuseki:serviceQuery "query" ; - fuseki:serviceQuery "sparql" ; - fuseki:serviceUpdate "update" ; - fuseki:serviceUpload "upload" ; - fuseki:serviceReadWriteGraphStore "data" ; - # A separate read-only graph store endpoint: - fuseki:serviceReadGraphStore "get" ; - fuseki:dataset <#tdb_dataset_readwrite> ; - - . - -<#tdb_dataset_readwrite> rdf:type tdb:DatasetTDB ; - tdb:location "{DIR}" ; - ##tdb:unionDefaultGraph true ; - . diff --git a/triplestores/fuseki-tomcat/templates/config-tdb-mem b/triplestores/fuseki-tomcat/templates/config-tdb-mem deleted file mode 100644 index 449de5e447..0000000000 --- a/triplestores/fuseki-tomcat/templates/config-tdb-mem +++ /dev/null @@ -1,30 +0,0 @@ -# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0 - -@prefix : <#> . -@prefix fuseki: . -@prefix rdf: . -@prefix rdfs: . -@prefix tdb: . -@prefix ja: . - -## --------------------------------------------------------------- -## Updatable TDB dataset im-memory with all services enabled. - -<#service_tdb_all> rdf:type fuseki:Service ; - rdfs:label "TDB {NAME}" ; - fuseki:name "{NAME}" ; - fuseki:serviceQuery "query" ; - fuseki:serviceQuery "sparql" ; - fuseki:serviceUpdate "update" ; - fuseki:serviceUpload "upload" ; - fuseki:serviceReadWriteGraphStore "data" ; - # A separate read-only graph store endpoint: - fuseki:serviceReadGraphStore "get" ; - fuseki:dataset <#tdb_dataset_readwrite> ; - - . - -<#tdb_dataset_readwrite> rdf:type tdb:DatasetTDB ; - tdb:location "--mem--" ; - ## tdb:unionDefaultGraph true ; - . diff --git a/triplestores/fuseki-tomcat/templates/config-tdb2 b/triplestores/fuseki-tomcat/templates/config-tdb2 deleted file mode 100644 index 835d3f82b9..0000000000 --- a/triplestores/fuseki-tomcat/templates/config-tdb2 +++ /dev/null @@ -1,31 +0,0 @@ -# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0 - -PREFIX : <#> -PREFIX fuseki: -PREFIX rdf: -PREFIX rdfs: -PREFIX tdb2: -PREFIX ja: - -## --------------------------------------------------------------- -## Updatable TDB dataset with all services enabled. - -<#service_tdb_all> rdf:type fuseki:Service ; - rdfs:label "TDB2 {NAME}" ; - fuseki:name "{NAME}" ; - fuseki:serviceQuery "query" ; - fuseki:serviceQuery "sparql" ; - fuseki:serviceUpdate "update" ; - fuseki:serviceUpload "upload" ; - fuseki:serviceReadWriteGraphStore "data" ; - # A separate read-only graph store endpoint: - fuseki:serviceReadGraphStore "get" ; - fuseki:dataset <#tdb_dataset_readwrite> ; - - . - -<#tdb_dataset_readwrite> rdf:type tdb2:DatasetTDB2 ; - tdb2:location "{FUSEKI_BASE}/databases/{NAME}" ; - ##ja:context [ ja:cxtName "arq:queryTimeout" ; ja:cxtValue "3000" ] ; - ##tdb2:unionDefaultGraph true ; - . diff --git a/triplestores/fuseki-tomcat/templates/config-tdb2-dir b/triplestores/fuseki-tomcat/templates/config-tdb2-dir deleted file mode 100644 index 4a89278599..0000000000 --- a/triplestores/fuseki-tomcat/templates/config-tdb2-dir +++ /dev/null @@ -1,30 +0,0 @@ -# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0 - -PREFIX : <#> -PREFIX fuseki: -PREFIX rdf: -PREFIX rdfs: -PREFIX tdb2: -PREFIX ja: - -## --------------------------------------------------------------- -## Updatable TDB2 dataset with all services enabled. - -<#service_tdb_all> rdf:type fuseki:Service ; - rdfs:label "TDB2 {NAME}" ; - fuseki:name "{NAME}" ; - fuseki:serviceQuery "query" ; - fuseki:serviceQuery "sparql" ; - fuseki:serviceUpdate "update" ; - fuseki:serviceUpload "upload" ; - fuseki:serviceReadWriteGraphStore "data" ; - # A separate read-only graph store endpoint: - fuseki:serviceReadGraphStore "get" ; - fuseki:dataset <#tdb_dataset_readwrite> ; - - . - -<#tdb_dataset_readwrite> rdf:type tdb2:DatasetTDB2 ; - tdb2:location "{DIR}" ; - ##tdb2:unionDefaultGraph true ; - . diff --git a/triplestores/fuseki-tomcat/templates/config-tdb2-mem b/triplestores/fuseki-tomcat/templates/config-tdb2-mem deleted file mode 100644 index f53be7f781..0000000000 --- a/triplestores/fuseki-tomcat/templates/config-tdb2-mem +++ /dev/null @@ -1,30 +0,0 @@ -# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0 - -PREFIX : <#> -PREFIX fuseki: -PREFIX rdf: -PREFIX rdfs: -PREFIX tdb2: -PREFIX ja: - -## --------------------------------------------------------------- -## Updatable TDB2 dataset im-memory with all services enabled. - -<#service_tdb_all> rdf:type fuseki:Service ; - rdfs:label "TDB2 {NAME}" ; - fuseki:name "{NAME}" ; - fuseki:serviceQuery "query" ; - fuseki:serviceQuery "sparql" ; - fuseki:serviceUpdate "update" ; - fuseki:serviceUpload "upload" ; - fuseki:serviceReadWriteGraphStore "data" ; - # A separate read-only graph store endpoint: - fuseki:serviceReadGraphStore "get" ; - fuseki:dataset <#tdb_dataset_readwrite> ; - - . - -<#tdb_dataset_readwrite> rdf:type tdb2:DatasetTDB2 ; - tdb2:location "--mem--" ; - ## tdb2:unionDefaultGraph true ; - . diff --git a/triplestores/fuseki/LICENSE b/triplestores/fuseki/LICENSE deleted file mode 100644 index 10474abd30..0000000000 --- a/triplestores/fuseki/LICENSE +++ /dev/null @@ -1,617 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - -- - - - - - - - - - - - - - - - - - - - - - - - - (c) Copyright 2003, Plugged In Software - - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - 3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -- - - - - - - - - - - - - - - - - - - - - - - - -http://www.slf4j.org/license.html - - Copyright (c) 2004-2011 QOS.ch - All rights reserved. - - 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. - -- - - - - - - - - - - - - - - - - - - - - - - - -============================================================== - Jetty Web Container - Copyright 1995-2012 Mort Bay Consulting Pty Ltd. -============================================================== - -The Jetty Web Container is Copyright Mort Bay Consulting Pty Ltd -unless otherwise noted. - -Jetty is dual licensed under both - - * The Apache 2.0 License - http://www.apache.org/licenses/LICENSE-2.0.html - - and - - * The Eclipse Public 1.0 License - http://www.eclipse.org/legal/epl-v10.html - -Jetty may be distributed under either license. - -The javax.servlet package used was sourced from the Apache -Software Foundation and is distributed under the apache 2.0 -license. - -The UnixCrypt.java code implements the one way cryptography used by -Unix systems for simple password protection. Copyright 1996 Aki Yoshida, -modified April 2001 by Iris Van den Broeke, Daniel Deville. -Permission to use, copy, modify and distribute UnixCrypt -for non-commercial or commercial purposes and without fee is -granted provided that the copyright notice appears in all copies. - -- - - - - - - - - - - - - - - - - - - - - - - - -This product bundles "Bootstrap", which is available under an -MIT license. See: https://github.com/twbs/bootstrap/blob/master/LICENSE - -This product bundles "codemirror", which is available under an -MIT license. See http://codemirror.net/LICENSE - -This product bundles "jquery", which is available under an -MIT license. See https://jquery.org/license/ - -This product bundles "jquery.form", which is available under an -MIT license. See http://malsup.github.io/mit-license.txt - -This product bundles "jquery.xdomainrequest", which is available under an -MIT license. See https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest/blob/master/LICENSE.txt - -This product bundles "backbone.js", which is available under an -MIT license. See https://github.com/jashkenas/backbone/blob/master/LICENSE - -This product bundles "backbone.marionette", which is available under an -MIT license. See http://mutedsolutions.mit-license.org/ - "backbone.marionette" includes "Backbone.BabySitter" and - "Backbone.Wreqr" also available under the same MIT license. - -This product bundles "html5shiv", which is available under an -MIT license. See https://code.google.com/p/html5shiv/ - -This product bundles "RequireJS", which is available under an -MIT license. -https://github.com/jrburke/requirejs/blob/master/LICENSE - "RequireJS" is also available with a "30clause BSD license" - -This product bundles "Respond", which is available under an -MIT license. See https://github.com/scottjehl/Respond/blob/master/LICENSE-MIT - -This product bundles "sprintf.js", which is available under a -"3 clause BSD" license. - https://github.com/alexei/sprintf.js/blob/master/LICENSE - -This product bundles "underscore", which is available under an -MIT license. See https://github.com/jashkenas/underscore/blob/master/LICENSE - -This product bundles "FontAwesome" - "Font Awesome by Dave Gandy - http://fontawesome.io" -The font is available under an SIL Open Font License 1.1 -and the CSS files under an MIT License. -See http://fontawesome.io/license/ - -This product bundles "jQuery File Upload Plugin" -which is available under an MIT License. -See https://github.com/blueimp/jQuery-File-Upload - -This product bundles "Bootstrap-select" -which is available under an MIT License. -See https://github.com/silviomoreto/bootstrap-select/blob/master/LICENSE - -This product bundles "pivot.js" -which is available under a BSD 3-clause style license. -https://github.com/rwjblue/pivot.js/blob/master/LICENSE - -This product bundles "YASEQE - Yet Another Sparql Query Editor" -which is available under an MIT License. -See http://yasqe.yasgui.org/license.txt - -This product bundles "YASR - Yet Another Sparql Resultset GUI" -which is available under an MIT License. -See http://yasr.yasgui.org/license.txt - -- - - - - - - - - - - - - - - - - - - - - - - - -From Apache HttpComponents Client - -This project contains annotations derived from JCIP-ANNOTATIONS -Copyright (c) 2005 Brian Goetz and Tim Peierls. -See http://www.jcip.net and the Creative Commons Attribution License -(http://creativecommons.org/licenses/by/2.5) - -- - - - - - - - - - - - - - - - - - - - - - - - -From Apache Lucene - -Some code in core/src/java/org/apache/lucene/util/UnicodeUtil.java was -derived from unicode conversion examples available at -http://www.unicode.org/Public/PROGRAMS/CVTUTF. Here is the copyright -from those sources: - -/* - * Copyright 2001-2004 Unicode, Inc. - * - * Disclaimer - * - * This source code is provided as is by Unicode, Inc. No claims are - * made as to fitness for any particular purpose. No warranties of any - * kind are expressed or implied. The recipient agrees to determine - * applicability of information provided. If this file has been - * purchased on magnetic or optical media from Unicode, Inc., the - * sole remedy for any claim will be exchange of defective media - * within 90 days of receipt. - * - * Limitations on Rights to Redistribute This Code - * - * Unicode, Inc. hereby grants the right to freely use the information - * supplied in this file in the creation of products supporting the - * Unicode Standard, and to make copies of this file in any form - * for internal or external distribution as long as this notice - * remains attached. - */ - - -Some code in core/src/java/org/apache/lucene/util/ArrayUtil.java was -derived from Python 2.4.2 sources available at -http://www.python.org. Full license is here: - - http://www.python.org/download/releases/2.4.2/license/ - -Some code in core/src/java/org/apache/lucene/util/UnicodeUtil.java was -derived from Python 3.1.2 sources available at -http://www.python.org. Full license is here: - - http://www.python.org/download/releases/3.1.2/license/ - -Some code in core/src/java/org/apache/lucene/util/automaton was -derived from Brics automaton sources available at -www.brics.dk/automaton/. Here is the copyright from those sources: - -/* - * Copyright (c) 2001-2009 Anders Moeller - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -The levenshtein automata tables in core/src/java/org/apache/lucene/util/automaton -were automatically generated with the moman/finenight FSA package. -Here is the copyright for those sources: - -# Copyright (c) 2010, Jean-Philippe Barrette-LaPierre, -# -# 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. - -Some code in core/src/java/org/apache/lucene/util/UnicodeUtil.java was -derived from ICU (http://www.icu-project.org) -The full license is available here: - http://source.icu-project.org/repos/icu/icu/trunk/license.html - -/* - * Copyright (C) 1999-2010, International Business Machines - * Corporation and others. All Rights Reserved. - * - * 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, and/or sell copies of the - * Software, and to permit persons to whom the Software is furnished to do so, - * provided that the above copyright notice(s) and this permission notice appear - * in all copies of the Software and that both the above copyright notice(s) and - * this permission notice appear in supporting documentation. - * - * 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 OF THIRD PARTY RIGHTS. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE - * LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR - * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER - * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Except as contained in this notice, the name of a copyright holder shall not - * be used in advertising or otherwise to promote the sale, use or other - * dealings in this Software without prior written authorization of the - * copyright holder. - */ - -The following license applies to the Snowball stemmers: - -Copyright (c) 2001, Dr Martin Porter -Copyright (c) 2002, Richard Boulton -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * Neither the name of the copyright holders nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -The following license applies to the KStemmer: - -Copyright © 2003, -Center for Intelligent Information Retrieval, -University of Massachusetts, Amherst. -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, -this list of conditions and the following disclaimer in the documentation -and/or other materials provided with the distribution. - -3. The names "Center for Intelligent Information Retrieval" and -"University of Massachusetts" must not be used to endorse or promote products -derived from this software without prior written permission. To obtain -permission, contact info@ciir.cs.umass.edu. - -THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF MASSACHUSETTS AND OTHER CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - -The following license applies to the Morfologik project: - -Copyright (c) 2006 Dawid Weiss -Copyright (c) 2007-2011 Dawid Weiss, Marcin Miłkowski -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name of Morfologik nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - ---- - -The dictionary comes from Morfologik project. Morfologik uses data from -Polish ispell/myspell dictionary hosted at http://www.sjp.pl/slownik/en/ and -is licenced on the terms of (inter alia) LGPL and Creative Commons -ShareAlike. The part-of-speech tags were added in Morfologik project and -are not found in the data from sjp.pl. The tagset is similar to IPI PAN -tagset. - ---- - -The following license applies to the Morfeusz project, -used by org.apache.lucene.analysis.morfologik. - -BSD-licensed dictionary of Polish (SGJP) -http://sgjp.pl/morfeusz/ - -Copyright © 2011 Zygmunt Saloni, Włodzimierz Gruszczyński, - Marcin Woliński, Robert Wołosz - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the - distribution. - -THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS “AS IS” AND ANY EXPRESS -OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - diff --git a/triplestores/fuseki/NOTICE b/triplestores/fuseki/NOTICE deleted file mode 100644 index 0bf830c18b..0000000000 --- a/triplestores/fuseki/NOTICE +++ /dev/null @@ -1,216 +0,0 @@ -Apache Jena - module Fuseki -Copyright 2011, 2012, 2013, 2014, 2015, 2016 The Apache Software Foundation - -This product includes software developed at -The Apache Software Foundation (http://www.apache.org/). - -Portions of this software were originally based on the following: - - Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Hewlett-Packard Development Company, LP - - Copyright 2010, 2011 Epimorphics Ltd. - - Copyright 2010, 2011 Talis Systems Ltd. -These have been licensed to the Apache Software Foundation under a software grant. - -- - - - - - - - - - - - - - - - - - - - - - - - -slf4j: - Copyright (c) 2004-2011 QOS.ch - All rights reserved. - -- - - - - - - - - - - - - - - - - - - - - - - - -(c) Copyright 2003, Plugged In Software -This product includes software developed by -PluggedIn Software under a BSD license. - -- - - - - - - - - - - - - - - - - - - - - - - - - Jetty Web Container - Copyright 1995-2012 Mort Bay Consulting Pty Ltd. - -under the Apache 2.0 License. - -The Jetty Web Container includes: - -UnixCrypt.java -Copyright 1996 Aki Yoshida, -modified April 2001 by Iris Van den Broeke, Daniel Deville. - -- - - - - - - - - - - - - - - - - - - - - - - - -From Apache HttpComponents Client: - -This project contains annotations derived from JCIP-ANNOTATIONS -Copyright (c) 2005 Brian Goetz and Tim Peierls. See http://www.jcip.net - -- - - - - - - - - - - - - - - - - - - - - - - - - Apache Xerces Java - Copyright 1999-2013 The Apache Software Foundation - - This product includes software developed at - The Apache Software Foundation (http://www.apache.org/). - - Portions of this software were originally based on the following: - - software copyright (c) 1999, IBM Corporation., http://www.ibm.com. - - software copyright (c) 1999, Sun Microsystems., http://www.sun.com. - - voluntary contributions made by Paul Eng on behalf of the - Apache Software Foundation that were originally developed at iClick, Inc., - software copyright (c) 1999. - -- - - - - - - - - - - - - - - - - - - - - - - - -From Apache Lucene: - -ICU4J, (under analysis/icu) is licensed under an MIT styles license -and Copyright (c) 1995-2008 International Business Machines Corporation and others - -Some data files (under analysis/icu/src/data) are derived from Unicode data such -as the Unicode Character Database. See http://unicode.org/copyright.html for more -details. - -Brics Automaton (under core/src/java/org/apache/lucene/util/automaton) is -BSD-licensed, created by Anders Møller. See http://www.brics.dk/automaton/ - -The levenshtein automata tables (under core/src/java/org/apache/lucene/util/automaton) were -automatically generated with the moman/finenight FSA library, created by -Jean-Philippe Barrette-LaPierre. This library is available under an MIT license, -see http://sites.google.com/site/rrettesite/moman and -http://bitbucket.org/jpbarrette/moman/overview/ - -This product includes code (JaspellTernarySearchTrie) from Java Spelling -Checking Package (jaspell): http://jaspell.sourceforge.net/ -License: The BSD License (http://www.opensource.org/licenses/bsd-license.php) - -The snowball stemmers in - analysis/common/src/java/net/sf/snowball -were developed by Martin Porter and Richard Boulton. -The snowball stopword lists in - analysis/common/src/resources/org/apache/lucene/analysis/snowball -were developed by Martin Porter and Richard Boulton. -The full snowball package is available from - http://snowball.tartarus.org/ - -The KStem stemmer in - analysis/common/src/org/apache/lucene/analysis/en -was developed by Bob Krovetz and Sergio Guzman-Lara (CIIR-UMass Amherst) -under the BSD-license. - -The Arabic,Persian,Romanian,Bulgarian, and Hindi analyzers (common) come with a default -stopword list that is BSD-licensed created by Jacques Savoy. -See http://members.unine.ch/jacques.savoy/clef/index.html. - -The German,Spanish,Finnish,French,Hungarian,Italian,Portuguese,Russian and Swedish light stemmers -(common) are based on BSD-licensed reference implementations created by Jacques Savoy and -Ljiljana Dolamic. - -The Stempel analyzer (stempel) includes BSD-licensed software developed -by the Egothor project http://egothor.sf.net/, created by Leo Galambos, Martin Kvapil, -and Edmond Nolan. - -The Polish analyzer (stempel) comes with a default -stopword list that is BSD-licensed created by the Carrot2 project. The file resides -in stempel/src/resources/org/apache/lucene/analysis/pl/stopwords.txt. -See http://project.carrot2.org/license.html. - -The SmartChineseAnalyzer source code (smartcn) was -provided by Xiaoping Gao and copyright 2009 by www.imdict.net. - -WordBreakTestUnicode_*.java (under modules/analysis/common/src/test/) -is derived from Unicode data such as the Unicode Character Database. -See http://unicode.org/copyright.html for more details. - -The Morfologik analyzer (morfologik) includes BSD-licensed software -developed by Dawid Weiss and Marcin Miłkowski (http://morfologik.blogspot.com/). - -Morfologik uses data from Polish ispell/myspell dictionary -(http://www.sjp.pl/slownik/en/) licenced on the terms of (inter alia) -LGPL and Creative Commons ShareAlike. - -Morfologic includes data from BSD-licensed dictionary of Polish (SGJP) -(http://sgjp.pl/morfeusz/) - -Servlet-api.jar and javax.servlet-*.jar are under the CDDL license, the original -source code for this can be found at http://www.eclipse.org/jetty/downloads.php - -=========================================================================== -Kuromoji Japanese Morphological Analyzer - Apache Lucene Integration -=========================================================================== - -This software includes a binary and/or source version of data from - - mecab-ipadic-2.7.0-20070801 - -which can be obtained from - - http://atilika.com/releases/mecab-ipadic/mecab-ipadic-2.7.0-20070801.tar.gz - -or - - http://jaist.dl.sourceforge.net/project/mecab/mecab-ipadic/2.7.0-20070801/mecab-ipadic-2.7.0-20070801.tar.gz - -=========================================================================== -mecab-ipadic-2.7.0-20070801 Notice -=========================================================================== - -Nara Institute of Science and Technology (NAIST), -the copyright holders, disclaims all warranties with regard to this -software, including all implied warranties of merchantability and -fitness, in no event shall NAIST be liable for -any special, indirect or consequential damages or any damages -whatsoever resulting from loss of use, data or profits, whether in an -action of contract, negligence or other tortuous action, arising out -of or in connection with the use or performance of this software. - -A large portion of the dictionary entries -originate from ICOT Free Software. The following conditions for ICOT -Free Software applies to the current dictionary as well. - -Each User may also freely distribute the Program, whether in its -original form or modified, to any third party or parties, PROVIDED -that the provisions of Section 3 ("NO WARRANTY") will ALWAYS appear -on, or be attached to, the Program, which is distributed substantially -in the same form as set out herein and that such intended -distribution, if actually made, will neither violate or otherwise -contravene any of the laws and regulations of the countries having -jurisdiction over the User or the intended distribution itself. - -NO WARRANTY - -The program was produced on an experimental basis in the course of the -research and development conducted during the project and is provided -to users as so produced on an experimental basis. Accordingly, the -program is provided without any warranty whatsoever, whether express, -implied, statutory or otherwise. The term "warranty" used herein -includes, but is not limited to, any warranty of the quality, -performance, merchantability and fitness for a particular purpose of -the program and the nonexistence of any infringement or violation of -any right of any third party. - -Each user of the program will agree and understand, and be deemed to -have agreed and understood, that there is no warranty whatsoever for -the program and, accordingly, the entire risk arising from or -otherwise connected with the program is assumed by the user. - -Therefore, neither ICOT, the copyright holder, or any other -organization that participated in or was otherwise related to the -development of the program and their respective officials, directors, -officers and other employees shall be held liable for any and all -damages, including, without limitation, general, special, incidental -and consequential damages, arising out of or otherwise in connection -with the use or inability to use the program or any product, material -or result produced or otherwise obtained by using the program, -regardless of whether they have been advised of, or otherwise had -knowledge of, the possibility of such damages at any time during the -project or thereafter. Each user will be deemed to have agreed to the -foregoing by his or her commencement of use of the program. The term -"use" as used herein includes, but is not limited to, the use, -modification, copying and distribution of the program and the -production of secondary products from the program. - -In the case where the program, whether in its original form or -modified, was distributed or delivered to or received by a user from -any person, organization or entity other than ICOT, unless it makes or -grants independently of ICOT any specific warranty to the user in -writing, such person, organization or entity, will also be exempted -from and not be held liable to the user for any such damages as noted -above as far as the program is concerned. diff --git a/triplestores/fuseki/README.md b/triplestores/fuseki/README.md deleted file mode 100644 index 1964d9b125..0000000000 --- a/triplestores/fuseki/README.md +++ /dev/null @@ -1,12 +0,0 @@ -### Apache Jena Fuseki 3 ### - -This folder contains a distribution for the latest version of **Apache Jena Fuseki 3** supported by Knora. - -Fuseki is the triplestore from the Apache Jena project (http://https://jena.apache.org). Apache Jena license applies. - - -#### Usage #### - -``` -$ ./fuseki-server -``` \ No newline at end of file diff --git a/triplestores/fuseki/bin/s-delete b/triplestores/fuseki/bin/s-delete deleted file mode 100755 index 16cb44ccb9..0000000000 --- a/triplestores/fuseki/bin/s-delete +++ /dev/null @@ -1,716 +0,0 @@ -#!/usr/bin/env ruby -# -*- coding: utf-8 -*- - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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 -# -# http://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. - -# SPARQL HTTP Update, client. - -require 'optparse' -require 'net/http' -require 'uri' -require 'cgi' -require 'pp' -require 'ostruct' - -# ToDo -# Allow a choice of media type for GET -# --accept "content-type" (and abbreviations) -# --header "Add:this" -# --user, --password -# Basic authentication: request.basic_auth("username", "password") -# Follow redirects => 301: puts response["location"] # All headers are lowercase? - -SOH_NAME="SOH" -SOH_VERSION="1.0.0" - -$proxy = ENV['http_proxy'] ? URI.parse(ENV['http_proxy']) : OpenStruct.new - -# What about direct naming? - -# Names -$mtTurtle = 'text/turtle;charset=utf-8' -$mtRDF = 'application/rdf+xml' -$mtText = 'text/plain' -$mtNTriples = 'application/n-triples' -$mtNQuads = 'application/n-quads' -$mtJSONLD = 'application/ld+json' -$mtTriG = 'application/trig' -$mtSparqlResultsX = 'application/sparql-results+xml' -$mtSparqlResultsJ = 'application/sparql-results+json' -$mtAppJSON = 'application/json' -$mtAppXML = 'application/xml' -$mtSparqlResultsTSV = 'application/sparql-results+tsv' -$mtSparqlResultsCSV = 'application/sparql-results+csv' -$mtSparqlUpdate = 'application/sparql-update' -$mtWWWForm = 'application/x-www-form-urlencoded' -$mtSparqlQuery = "application/sparql-query" ; - -# Global media type table. -$fileMediaTypes = {} -$fileMediaTypes['ttl'] = $mtTurtle -$fileMediaTypes['n3'] = 'text/n3; charset=utf-8' -$fileMediaTypes['nt'] = $mtText -$fileMediaTypes['rdf'] = $mtRDF -$fileMediaTypes['owl'] = $mtRDF -$fileMediaTypes['nq'] = $mtNQuads -$fileMediaTypes['trig'] = $mtTriG -$fileMediaTypes['json-ld'] = $mtJSONLD -$fileMediaTypes['jsonld'] = $mtJSONLD - -# Global charset : no entry means "don't set" -$charsetUTF8 = 'utf-8' -$charset = {} -$charset[$mtTurtle] = 'utf-8' -$charset[$mtText] = 'ascii' -$charset[$mtTriG] = 'utf-8' -$charset[$mtNQuads] = 'utf-8' - -# Headers - -$hContentType = 'Content-Type' -# $hContentEncoding = 'Content-Encoding' -$hContentLength = 'Content-Length' -# $hContentLocation = 'Content-Location' -# $hContentRange = 'Content-Range' - -$hAccept = 'Accept' -$hAcceptCharset = 'Accept-Charset' -$hAcceptEncoding = 'Accept-Encoding' -$hAcceptRanges = 'Accept-Ranges' - -$headers = { "User-Agent" => "#{SOH_NAME}/Fuseki #{SOH_VERSION}"} -$print_http = false - -# Default for GET -# At least allow anything (and hope!) -$accept_rdf="#{$mtTurtle} , #{$mtNTriples};q=0.9 , #{$mtRDF};q=0.8 , #{$mtJSONLD};q=0.5" -# Datasets -$accept_ds="#{$mtTrig} , #{$mtNQuads};q=0.9 , #{$mtJSONLD};q=0.5" -# For SPARQL query -$accept_results="#{$mtSparqlResultsJ} , #{$mtSparqlResultsX};q=0.9 , #{$accept_rdf}" - -# Accept any in case of trouble. -$accept_rdf="#{$accept_rdf} , */*;q=0.1" -$accept_results="#{$accept_results} , */*;q=0.1" - -# The media type usually forces the charset. -$accept_charset=nil - -## Who we are. -## Two styles: -## s-query ..... -## soh query ..... - -$cmd = File.basename($0) -if $cmd == 'soh' -then - $cmd = (ARGV.size == 0) ? 'soh' : ARGV.shift -end - -if ! $cmd.start_with?('s-') && $cmd != 'soh' - $cmd = 's-'+$cmd -end - -## -------- - -def GET(dataset, graph) - print "GET #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - get_worker(requestURI, headers) -end - -def get_worker(requestURI, headers) - uri = URI.parse(requestURI) - request = Net::HTTP::Get.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_print_body(uri, request) -end - -def HEAD(dataset, graph) - print "HEAD #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - uri = URI.parse(requestURI) - request = Net::HTTP::Head.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def PUT(dataset, graph, file) - print "PUT #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Put) -end - -def POST(dataset, graph, file) - print "POST #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Post) -end - -def DELETE(dataset, graph) - print "DELETE #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - request = Net::HTTP::Delete.new(uri.request_uri) - headers = {} - headers.merge!($headers) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def uri_escape(string) - CGI.escape(string) -end - -def target(dataset, graph) - return dataset+"?default" if graph == "default" - return dataset+"?graph="+uri_escape(graph) -end - -def send_body(dataset, graph, file, method) - mt = content_type(file) - if mt.nil? - warn_exit "Can't identify the content type of '#{file}'", 9 - end - headers = {} - headers.merge!($headers) - headers[$hContentType] = mt - headers[$hContentLength] = File.size(file).to_s - ## p headers - - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - - request = method.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - request.body_stream = File.open(file) - response_no_body(uri, request) -end - -def response_no_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue Exception => e - # puts e.message - #puts e.backtrace.inspect - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - response = http.request(request) - print_http_response(response) - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code} #{response.message} #{uri}", 9 - # Unreachable - response.error! - end - # NO BODY IN RESPONSE -end - -def response_print_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue => e - #puts e.backtrace.inspect - #print e.class - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - - # Add a blank line if headers were output. - print "\n" if $http_print ; - - begin - response = http.request(request) { |res| - print_http_response(res) - #puts res.code - res.read_body do |segment| - print segment - end - } - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code}: #{uri}", 9 - # Unreachable - response.error! - end - rescue EOFError => e - warn_exit "IO Error: "+e.message, 3 - end -end - -def print_http_request(uri, request) - return unless $print_http - #print "Request\n" - print request.method," ",uri, "\n" - print_headers(" ",request) -end - -def print_http_response(response) - return unless $print_http - #print "Response\n" - print response.code, " ", response.message, "\n" - print_headers(" ",response) -end - -def print_headers(marker, headers) - headers.each do |k,v| - k = k.split('-').map{|w| w.capitalize}.join('-')+':' - printf "%s%-20s %s\n",marker,k,v - end -end - -def content_type(file) - file =~ /\.([^.]*)$/ - ext = $1 - mt = $fileMediaTypes[ext] - cs = $charset[mt] - mt = mt+';charset='+cs if ! cs.nil? - return mt -end - -def charset(content_type) - return $charset[content_type] -end - -def warn_exit(msg, rc) - warn msg - exit rc ; -end - -def parseURI(uri_string) - begin - return URI.parse(uri_string).to_s - rescue URI::InvalidURIError => err - warn_exit "Bad URI: <#{uri_string}>", 2 - end -end - -## ---- Command - -def cmd_soh(command=nil) - ## Command line - options = {} - optparse = OptionParser.new do |opts| - # Set a banner, displayed at the top - # of the help screen. - case $cmd - when "s-http", "sparql-http", "soh" - banner="$cmd [get|post|put|delete] datasetURI graph [file]" - when "s-get", "s-head", "s-delete" - banner="$cmd datasetURI graph" - end - - opts.banner = $banner - # Define the options, and what they do - - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - - options[:version] = false - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - - # This displays the help screen, all programs are - # assumed to have this option. - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - if command.nil? - if ARGV.size == 0 - warn "No command given: expected one of 'get', 'put', 'post', 'delete', 'query' or 'update'" - exit 1 - end - cmdPrint=ARGV.shift - command=cmdPrint.upcase - else - cmdPrint=command - end - - case command - when "HEAD", "GET", "DELETE" - requiredFile=false - when "PUT", "POST" - requiredFile=true - when "QUERY" - cmd_sparql_query - when "UPDATE" - cmd_sparql_update - else - warn_exit "Unknown command: #{command}", 2 - end - - if requiredFile - then - if ARGV.size != 3 - warn_exit "Required: dataset URI, graph URI (or 'default') and file", 1 - end - else - if ARGV.size != 2 - warn_exit "Required: dataset URI and graph URI (or 'default')", 1 - end - end - - dataset=parseURI(ARGV.shift) - # Relative URI? - graph=parseURI(ARGV.shift) - file="" - if requiredFile - then - file = ARGV.shift if requiredFile - if ! File.exist?(file) - warn_exit "No such file: "+file, 3 - end - if File.directory?(file) - warn_exit "File is a directory: "+file, 3 - end - end - - case command - when "GET" - GET(dataset, graph) - when "HEAD" - HEAD(dataset, graph) - when "PUT" - PUT(dataset, graph, file) - when "DELETE" - DELETE(dataset, graph) - when "POST" - POST(dataset, graph, file) - else - warn_exit "Internal error: Unknown command: #{cmd}", 2 - end - exit 0 -end - -## -------- -def string_or_file(arg) - return arg if ! arg.match(/^@/) - a=(arg[1..-1]) - open(a, 'rb'){|f| f.read} -end - -## -------- SPARQL Query - -## Choose method -def SPARQL_query(service, query, query_file, forcePOST=false, args2={}) - if ! query_file.nil? - query = open(query_file, 'rb'){|f| f.read} - end - if forcePOST || query.length >= 2*1024 - SPARQL_query_POST(service, query, args2) - else - SPARQL_query_GET(service, query, args2) - end -end - -## By GET - -def SPARQL_query_GET(service, query, args2) - args = { "query" => query } - args.merge!(args2) - qs=args.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - action="#{service}?#{qs}" - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - get_worker(action, headers) -end - -## By POST - -def SPARQL_query_POST(service, query, args2) - # DRY - body/no body for each of request and response. - post_params={ "query" => query } - post_params.merge!(args2) - uri = URI.parse(service) - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - execute_post_form_body(uri, headers, post_params) -end - -def execute_post_form_body(uri, headers, post_params) - request = Net::HTTP::Post.new(uri.request_uri) - qs=post_params.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = qs.length.to_s - request.initialize_http_header(headers) - request.body = qs - print_http_request(uri, request) - response_print_body(uri, request) -end - -# Usage: -v --help --file= --query= -def cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--query QUERY] [--service URI] [--post] 'query' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--query=FILE','--file=FILE', 'Take query from a file') do |file| - options[:file]=file - end - opts.on('--output=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the output argument') do |type| - options[:output]=type - end - opts.on('--accept=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the accept header type') do |type| - options[:accept]=type - end - options[:verbose] = false - opts.on( '--post', 'Force use of POST' ) do - options[:post] = true - end - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e - warn e - exit 1 - end - - $verbose = options[:verbose] - $print_http = $verbose - usePOST = options[:post] - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - # Query - query=nil - query_file=options[:file] - if query_file.nil? && ARGV.size == 0 - then - warn_exit 'No query specified.',1 - end - if query_file.nil? - query = ARGV.shift - if query.match(/^@/) - query_file = query[1..-1] - query = nil - end - end - - # --output ==> output= (non-standard) - args={} - case options[:output] - when nil - when "json","xml","text","csv","tsv" - args['output'] = options[:output] - when :json,:xml,:text,:csv,:tsv - args['output'] = options[:output].to_s - else - warn_exit "Unrecognized output type: "+options[:output],2 - end - - # --accept - # options[:accept] - - print "SPARQL #{service}\n" if $verbose - #args={"output"=>"text"} - SPARQL_query(service, query, query_file, usePOST, args) - exit(0) -end - -## -------- SPARQL Update - -# Update sent as a WWW form. -def SPARQL_update_by_form(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - # args? encode? - body="update="+uri_escape(update) - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = body.length.to_s - uri = URI.parse(service) - execute_post_form(uri, headers, body) -end - -# DRY - query form. -def execute_post_form(uri, headers, body) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = body - print_http_request(uri, request) - response_no_body(uri, request) -end - -def SPARQL_update(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - headers[$hContentType] = $mtSparqlUpdate - uri = URI.parse(service) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = update - print_http_request(uri, request) - response_no_body(uri, request) -end - -def cmd_sparql_update(by_raw_post=true) - # Share with cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--file REQUEST] [--service URI] 'request' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--update=FILE', '--file=FILE', 'Take update from a file') do |file| - options[:file]=file - end - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - update=nil - update_file=options[:file] - - if update_file.nil? && ARGV.size == 0 - then - warn_exit 'No update specified.',1 - end - if update_file.nil? - update = ARGV.shift - if update.match(/^@/) - update_file = update[1..-1] - update = nil - end - end - - print "SPARQL-Update #{service}\n" if $verbose - args={} - - # Reads in the file :-( - if update.nil? - then - update = open(update_file, 'rb'){|f| f.read} - else - update = string_or_file(update) - end - - if by_raw_post - SPARQL_update(service, update, args) - else - SPARQL_update_by_form(service, update, args) - end - exit(0) -end - -## ------- - -case $cmd -when "s-http", "sparql-http", "soh" - $banner="#{$cmd} [get|post|put|delete] datasetURI graph [file]" - cmd_soh -when "s-get", "s-head", "s-put", "s-delete", "s-post" - - case $cmd - when "s-get", "s-head", "s-delete" - $banner="#{$cmd} datasetURI graph" - when "s-put", "s-post" - $banner="#{$cmd} datasetURI graph file" - end - cmd2 = $cmd.sub(/^s-/, '').upcase - cmd_soh cmd2 - -when "s-query", "sparql-query" - cmd_sparql_query -when "s-update", "sparql-update" - cmd_sparql_update true -when "s-update-form", "sparql-update-form" - cmd_sparql_update false -else - warn_exit "Unknown: "+$cmd, 1 -end diff --git a/triplestores/fuseki/bin/s-get b/triplestores/fuseki/bin/s-get deleted file mode 100755 index 16cb44ccb9..0000000000 --- a/triplestores/fuseki/bin/s-get +++ /dev/null @@ -1,716 +0,0 @@ -#!/usr/bin/env ruby -# -*- coding: utf-8 -*- - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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 -# -# http://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. - -# SPARQL HTTP Update, client. - -require 'optparse' -require 'net/http' -require 'uri' -require 'cgi' -require 'pp' -require 'ostruct' - -# ToDo -# Allow a choice of media type for GET -# --accept "content-type" (and abbreviations) -# --header "Add:this" -# --user, --password -# Basic authentication: request.basic_auth("username", "password") -# Follow redirects => 301: puts response["location"] # All headers are lowercase? - -SOH_NAME="SOH" -SOH_VERSION="1.0.0" - -$proxy = ENV['http_proxy'] ? URI.parse(ENV['http_proxy']) : OpenStruct.new - -# What about direct naming? - -# Names -$mtTurtle = 'text/turtle;charset=utf-8' -$mtRDF = 'application/rdf+xml' -$mtText = 'text/plain' -$mtNTriples = 'application/n-triples' -$mtNQuads = 'application/n-quads' -$mtJSONLD = 'application/ld+json' -$mtTriG = 'application/trig' -$mtSparqlResultsX = 'application/sparql-results+xml' -$mtSparqlResultsJ = 'application/sparql-results+json' -$mtAppJSON = 'application/json' -$mtAppXML = 'application/xml' -$mtSparqlResultsTSV = 'application/sparql-results+tsv' -$mtSparqlResultsCSV = 'application/sparql-results+csv' -$mtSparqlUpdate = 'application/sparql-update' -$mtWWWForm = 'application/x-www-form-urlencoded' -$mtSparqlQuery = "application/sparql-query" ; - -# Global media type table. -$fileMediaTypes = {} -$fileMediaTypes['ttl'] = $mtTurtle -$fileMediaTypes['n3'] = 'text/n3; charset=utf-8' -$fileMediaTypes['nt'] = $mtText -$fileMediaTypes['rdf'] = $mtRDF -$fileMediaTypes['owl'] = $mtRDF -$fileMediaTypes['nq'] = $mtNQuads -$fileMediaTypes['trig'] = $mtTriG -$fileMediaTypes['json-ld'] = $mtJSONLD -$fileMediaTypes['jsonld'] = $mtJSONLD - -# Global charset : no entry means "don't set" -$charsetUTF8 = 'utf-8' -$charset = {} -$charset[$mtTurtle] = 'utf-8' -$charset[$mtText] = 'ascii' -$charset[$mtTriG] = 'utf-8' -$charset[$mtNQuads] = 'utf-8' - -# Headers - -$hContentType = 'Content-Type' -# $hContentEncoding = 'Content-Encoding' -$hContentLength = 'Content-Length' -# $hContentLocation = 'Content-Location' -# $hContentRange = 'Content-Range' - -$hAccept = 'Accept' -$hAcceptCharset = 'Accept-Charset' -$hAcceptEncoding = 'Accept-Encoding' -$hAcceptRanges = 'Accept-Ranges' - -$headers = { "User-Agent" => "#{SOH_NAME}/Fuseki #{SOH_VERSION}"} -$print_http = false - -# Default for GET -# At least allow anything (and hope!) -$accept_rdf="#{$mtTurtle} , #{$mtNTriples};q=0.9 , #{$mtRDF};q=0.8 , #{$mtJSONLD};q=0.5" -# Datasets -$accept_ds="#{$mtTrig} , #{$mtNQuads};q=0.9 , #{$mtJSONLD};q=0.5" -# For SPARQL query -$accept_results="#{$mtSparqlResultsJ} , #{$mtSparqlResultsX};q=0.9 , #{$accept_rdf}" - -# Accept any in case of trouble. -$accept_rdf="#{$accept_rdf} , */*;q=0.1" -$accept_results="#{$accept_results} , */*;q=0.1" - -# The media type usually forces the charset. -$accept_charset=nil - -## Who we are. -## Two styles: -## s-query ..... -## soh query ..... - -$cmd = File.basename($0) -if $cmd == 'soh' -then - $cmd = (ARGV.size == 0) ? 'soh' : ARGV.shift -end - -if ! $cmd.start_with?('s-') && $cmd != 'soh' - $cmd = 's-'+$cmd -end - -## -------- - -def GET(dataset, graph) - print "GET #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - get_worker(requestURI, headers) -end - -def get_worker(requestURI, headers) - uri = URI.parse(requestURI) - request = Net::HTTP::Get.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_print_body(uri, request) -end - -def HEAD(dataset, graph) - print "HEAD #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - uri = URI.parse(requestURI) - request = Net::HTTP::Head.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def PUT(dataset, graph, file) - print "PUT #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Put) -end - -def POST(dataset, graph, file) - print "POST #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Post) -end - -def DELETE(dataset, graph) - print "DELETE #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - request = Net::HTTP::Delete.new(uri.request_uri) - headers = {} - headers.merge!($headers) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def uri_escape(string) - CGI.escape(string) -end - -def target(dataset, graph) - return dataset+"?default" if graph == "default" - return dataset+"?graph="+uri_escape(graph) -end - -def send_body(dataset, graph, file, method) - mt = content_type(file) - if mt.nil? - warn_exit "Can't identify the content type of '#{file}'", 9 - end - headers = {} - headers.merge!($headers) - headers[$hContentType] = mt - headers[$hContentLength] = File.size(file).to_s - ## p headers - - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - - request = method.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - request.body_stream = File.open(file) - response_no_body(uri, request) -end - -def response_no_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue Exception => e - # puts e.message - #puts e.backtrace.inspect - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - response = http.request(request) - print_http_response(response) - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code} #{response.message} #{uri}", 9 - # Unreachable - response.error! - end - # NO BODY IN RESPONSE -end - -def response_print_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue => e - #puts e.backtrace.inspect - #print e.class - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - - # Add a blank line if headers were output. - print "\n" if $http_print ; - - begin - response = http.request(request) { |res| - print_http_response(res) - #puts res.code - res.read_body do |segment| - print segment - end - } - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code}: #{uri}", 9 - # Unreachable - response.error! - end - rescue EOFError => e - warn_exit "IO Error: "+e.message, 3 - end -end - -def print_http_request(uri, request) - return unless $print_http - #print "Request\n" - print request.method," ",uri, "\n" - print_headers(" ",request) -end - -def print_http_response(response) - return unless $print_http - #print "Response\n" - print response.code, " ", response.message, "\n" - print_headers(" ",response) -end - -def print_headers(marker, headers) - headers.each do |k,v| - k = k.split('-').map{|w| w.capitalize}.join('-')+':' - printf "%s%-20s %s\n",marker,k,v - end -end - -def content_type(file) - file =~ /\.([^.]*)$/ - ext = $1 - mt = $fileMediaTypes[ext] - cs = $charset[mt] - mt = mt+';charset='+cs if ! cs.nil? - return mt -end - -def charset(content_type) - return $charset[content_type] -end - -def warn_exit(msg, rc) - warn msg - exit rc ; -end - -def parseURI(uri_string) - begin - return URI.parse(uri_string).to_s - rescue URI::InvalidURIError => err - warn_exit "Bad URI: <#{uri_string}>", 2 - end -end - -## ---- Command - -def cmd_soh(command=nil) - ## Command line - options = {} - optparse = OptionParser.new do |opts| - # Set a banner, displayed at the top - # of the help screen. - case $cmd - when "s-http", "sparql-http", "soh" - banner="$cmd [get|post|put|delete] datasetURI graph [file]" - when "s-get", "s-head", "s-delete" - banner="$cmd datasetURI graph" - end - - opts.banner = $banner - # Define the options, and what they do - - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - - options[:version] = false - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - - # This displays the help screen, all programs are - # assumed to have this option. - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - if command.nil? - if ARGV.size == 0 - warn "No command given: expected one of 'get', 'put', 'post', 'delete', 'query' or 'update'" - exit 1 - end - cmdPrint=ARGV.shift - command=cmdPrint.upcase - else - cmdPrint=command - end - - case command - when "HEAD", "GET", "DELETE" - requiredFile=false - when "PUT", "POST" - requiredFile=true - when "QUERY" - cmd_sparql_query - when "UPDATE" - cmd_sparql_update - else - warn_exit "Unknown command: #{command}", 2 - end - - if requiredFile - then - if ARGV.size != 3 - warn_exit "Required: dataset URI, graph URI (or 'default') and file", 1 - end - else - if ARGV.size != 2 - warn_exit "Required: dataset URI and graph URI (or 'default')", 1 - end - end - - dataset=parseURI(ARGV.shift) - # Relative URI? - graph=parseURI(ARGV.shift) - file="" - if requiredFile - then - file = ARGV.shift if requiredFile - if ! File.exist?(file) - warn_exit "No such file: "+file, 3 - end - if File.directory?(file) - warn_exit "File is a directory: "+file, 3 - end - end - - case command - when "GET" - GET(dataset, graph) - when "HEAD" - HEAD(dataset, graph) - when "PUT" - PUT(dataset, graph, file) - when "DELETE" - DELETE(dataset, graph) - when "POST" - POST(dataset, graph, file) - else - warn_exit "Internal error: Unknown command: #{cmd}", 2 - end - exit 0 -end - -## -------- -def string_or_file(arg) - return arg if ! arg.match(/^@/) - a=(arg[1..-1]) - open(a, 'rb'){|f| f.read} -end - -## -------- SPARQL Query - -## Choose method -def SPARQL_query(service, query, query_file, forcePOST=false, args2={}) - if ! query_file.nil? - query = open(query_file, 'rb'){|f| f.read} - end - if forcePOST || query.length >= 2*1024 - SPARQL_query_POST(service, query, args2) - else - SPARQL_query_GET(service, query, args2) - end -end - -## By GET - -def SPARQL_query_GET(service, query, args2) - args = { "query" => query } - args.merge!(args2) - qs=args.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - action="#{service}?#{qs}" - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - get_worker(action, headers) -end - -## By POST - -def SPARQL_query_POST(service, query, args2) - # DRY - body/no body for each of request and response. - post_params={ "query" => query } - post_params.merge!(args2) - uri = URI.parse(service) - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - execute_post_form_body(uri, headers, post_params) -end - -def execute_post_form_body(uri, headers, post_params) - request = Net::HTTP::Post.new(uri.request_uri) - qs=post_params.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = qs.length.to_s - request.initialize_http_header(headers) - request.body = qs - print_http_request(uri, request) - response_print_body(uri, request) -end - -# Usage: -v --help --file= --query= -def cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--query QUERY] [--service URI] [--post] 'query' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--query=FILE','--file=FILE', 'Take query from a file') do |file| - options[:file]=file - end - opts.on('--output=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the output argument') do |type| - options[:output]=type - end - opts.on('--accept=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the accept header type') do |type| - options[:accept]=type - end - options[:verbose] = false - opts.on( '--post', 'Force use of POST' ) do - options[:post] = true - end - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e - warn e - exit 1 - end - - $verbose = options[:verbose] - $print_http = $verbose - usePOST = options[:post] - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - # Query - query=nil - query_file=options[:file] - if query_file.nil? && ARGV.size == 0 - then - warn_exit 'No query specified.',1 - end - if query_file.nil? - query = ARGV.shift - if query.match(/^@/) - query_file = query[1..-1] - query = nil - end - end - - # --output ==> output= (non-standard) - args={} - case options[:output] - when nil - when "json","xml","text","csv","tsv" - args['output'] = options[:output] - when :json,:xml,:text,:csv,:tsv - args['output'] = options[:output].to_s - else - warn_exit "Unrecognized output type: "+options[:output],2 - end - - # --accept - # options[:accept] - - print "SPARQL #{service}\n" if $verbose - #args={"output"=>"text"} - SPARQL_query(service, query, query_file, usePOST, args) - exit(0) -end - -## -------- SPARQL Update - -# Update sent as a WWW form. -def SPARQL_update_by_form(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - # args? encode? - body="update="+uri_escape(update) - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = body.length.to_s - uri = URI.parse(service) - execute_post_form(uri, headers, body) -end - -# DRY - query form. -def execute_post_form(uri, headers, body) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = body - print_http_request(uri, request) - response_no_body(uri, request) -end - -def SPARQL_update(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - headers[$hContentType] = $mtSparqlUpdate - uri = URI.parse(service) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = update - print_http_request(uri, request) - response_no_body(uri, request) -end - -def cmd_sparql_update(by_raw_post=true) - # Share with cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--file REQUEST] [--service URI] 'request' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--update=FILE', '--file=FILE', 'Take update from a file') do |file| - options[:file]=file - end - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - update=nil - update_file=options[:file] - - if update_file.nil? && ARGV.size == 0 - then - warn_exit 'No update specified.',1 - end - if update_file.nil? - update = ARGV.shift - if update.match(/^@/) - update_file = update[1..-1] - update = nil - end - end - - print "SPARQL-Update #{service}\n" if $verbose - args={} - - # Reads in the file :-( - if update.nil? - then - update = open(update_file, 'rb'){|f| f.read} - else - update = string_or_file(update) - end - - if by_raw_post - SPARQL_update(service, update, args) - else - SPARQL_update_by_form(service, update, args) - end - exit(0) -end - -## ------- - -case $cmd -when "s-http", "sparql-http", "soh" - $banner="#{$cmd} [get|post|put|delete] datasetURI graph [file]" - cmd_soh -when "s-get", "s-head", "s-put", "s-delete", "s-post" - - case $cmd - when "s-get", "s-head", "s-delete" - $banner="#{$cmd} datasetURI graph" - when "s-put", "s-post" - $banner="#{$cmd} datasetURI graph file" - end - cmd2 = $cmd.sub(/^s-/, '').upcase - cmd_soh cmd2 - -when "s-query", "sparql-query" - cmd_sparql_query -when "s-update", "sparql-update" - cmd_sparql_update true -when "s-update-form", "sparql-update-form" - cmd_sparql_update false -else - warn_exit "Unknown: "+$cmd, 1 -end diff --git a/triplestores/fuseki/bin/s-head b/triplestores/fuseki/bin/s-head deleted file mode 100755 index 16cb44ccb9..0000000000 --- a/triplestores/fuseki/bin/s-head +++ /dev/null @@ -1,716 +0,0 @@ -#!/usr/bin/env ruby -# -*- coding: utf-8 -*- - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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 -# -# http://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. - -# SPARQL HTTP Update, client. - -require 'optparse' -require 'net/http' -require 'uri' -require 'cgi' -require 'pp' -require 'ostruct' - -# ToDo -# Allow a choice of media type for GET -# --accept "content-type" (and abbreviations) -# --header "Add:this" -# --user, --password -# Basic authentication: request.basic_auth("username", "password") -# Follow redirects => 301: puts response["location"] # All headers are lowercase? - -SOH_NAME="SOH" -SOH_VERSION="1.0.0" - -$proxy = ENV['http_proxy'] ? URI.parse(ENV['http_proxy']) : OpenStruct.new - -# What about direct naming? - -# Names -$mtTurtle = 'text/turtle;charset=utf-8' -$mtRDF = 'application/rdf+xml' -$mtText = 'text/plain' -$mtNTriples = 'application/n-triples' -$mtNQuads = 'application/n-quads' -$mtJSONLD = 'application/ld+json' -$mtTriG = 'application/trig' -$mtSparqlResultsX = 'application/sparql-results+xml' -$mtSparqlResultsJ = 'application/sparql-results+json' -$mtAppJSON = 'application/json' -$mtAppXML = 'application/xml' -$mtSparqlResultsTSV = 'application/sparql-results+tsv' -$mtSparqlResultsCSV = 'application/sparql-results+csv' -$mtSparqlUpdate = 'application/sparql-update' -$mtWWWForm = 'application/x-www-form-urlencoded' -$mtSparqlQuery = "application/sparql-query" ; - -# Global media type table. -$fileMediaTypes = {} -$fileMediaTypes['ttl'] = $mtTurtle -$fileMediaTypes['n3'] = 'text/n3; charset=utf-8' -$fileMediaTypes['nt'] = $mtText -$fileMediaTypes['rdf'] = $mtRDF -$fileMediaTypes['owl'] = $mtRDF -$fileMediaTypes['nq'] = $mtNQuads -$fileMediaTypes['trig'] = $mtTriG -$fileMediaTypes['json-ld'] = $mtJSONLD -$fileMediaTypes['jsonld'] = $mtJSONLD - -# Global charset : no entry means "don't set" -$charsetUTF8 = 'utf-8' -$charset = {} -$charset[$mtTurtle] = 'utf-8' -$charset[$mtText] = 'ascii' -$charset[$mtTriG] = 'utf-8' -$charset[$mtNQuads] = 'utf-8' - -# Headers - -$hContentType = 'Content-Type' -# $hContentEncoding = 'Content-Encoding' -$hContentLength = 'Content-Length' -# $hContentLocation = 'Content-Location' -# $hContentRange = 'Content-Range' - -$hAccept = 'Accept' -$hAcceptCharset = 'Accept-Charset' -$hAcceptEncoding = 'Accept-Encoding' -$hAcceptRanges = 'Accept-Ranges' - -$headers = { "User-Agent" => "#{SOH_NAME}/Fuseki #{SOH_VERSION}"} -$print_http = false - -# Default for GET -# At least allow anything (and hope!) -$accept_rdf="#{$mtTurtle} , #{$mtNTriples};q=0.9 , #{$mtRDF};q=0.8 , #{$mtJSONLD};q=0.5" -# Datasets -$accept_ds="#{$mtTrig} , #{$mtNQuads};q=0.9 , #{$mtJSONLD};q=0.5" -# For SPARQL query -$accept_results="#{$mtSparqlResultsJ} , #{$mtSparqlResultsX};q=0.9 , #{$accept_rdf}" - -# Accept any in case of trouble. -$accept_rdf="#{$accept_rdf} , */*;q=0.1" -$accept_results="#{$accept_results} , */*;q=0.1" - -# The media type usually forces the charset. -$accept_charset=nil - -## Who we are. -## Two styles: -## s-query ..... -## soh query ..... - -$cmd = File.basename($0) -if $cmd == 'soh' -then - $cmd = (ARGV.size == 0) ? 'soh' : ARGV.shift -end - -if ! $cmd.start_with?('s-') && $cmd != 'soh' - $cmd = 's-'+$cmd -end - -## -------- - -def GET(dataset, graph) - print "GET #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - get_worker(requestURI, headers) -end - -def get_worker(requestURI, headers) - uri = URI.parse(requestURI) - request = Net::HTTP::Get.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_print_body(uri, request) -end - -def HEAD(dataset, graph) - print "HEAD #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - uri = URI.parse(requestURI) - request = Net::HTTP::Head.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def PUT(dataset, graph, file) - print "PUT #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Put) -end - -def POST(dataset, graph, file) - print "POST #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Post) -end - -def DELETE(dataset, graph) - print "DELETE #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - request = Net::HTTP::Delete.new(uri.request_uri) - headers = {} - headers.merge!($headers) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def uri_escape(string) - CGI.escape(string) -end - -def target(dataset, graph) - return dataset+"?default" if graph == "default" - return dataset+"?graph="+uri_escape(graph) -end - -def send_body(dataset, graph, file, method) - mt = content_type(file) - if mt.nil? - warn_exit "Can't identify the content type of '#{file}'", 9 - end - headers = {} - headers.merge!($headers) - headers[$hContentType] = mt - headers[$hContentLength] = File.size(file).to_s - ## p headers - - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - - request = method.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - request.body_stream = File.open(file) - response_no_body(uri, request) -end - -def response_no_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue Exception => e - # puts e.message - #puts e.backtrace.inspect - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - response = http.request(request) - print_http_response(response) - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code} #{response.message} #{uri}", 9 - # Unreachable - response.error! - end - # NO BODY IN RESPONSE -end - -def response_print_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue => e - #puts e.backtrace.inspect - #print e.class - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - - # Add a blank line if headers were output. - print "\n" if $http_print ; - - begin - response = http.request(request) { |res| - print_http_response(res) - #puts res.code - res.read_body do |segment| - print segment - end - } - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code}: #{uri}", 9 - # Unreachable - response.error! - end - rescue EOFError => e - warn_exit "IO Error: "+e.message, 3 - end -end - -def print_http_request(uri, request) - return unless $print_http - #print "Request\n" - print request.method," ",uri, "\n" - print_headers(" ",request) -end - -def print_http_response(response) - return unless $print_http - #print "Response\n" - print response.code, " ", response.message, "\n" - print_headers(" ",response) -end - -def print_headers(marker, headers) - headers.each do |k,v| - k = k.split('-').map{|w| w.capitalize}.join('-')+':' - printf "%s%-20s %s\n",marker,k,v - end -end - -def content_type(file) - file =~ /\.([^.]*)$/ - ext = $1 - mt = $fileMediaTypes[ext] - cs = $charset[mt] - mt = mt+';charset='+cs if ! cs.nil? - return mt -end - -def charset(content_type) - return $charset[content_type] -end - -def warn_exit(msg, rc) - warn msg - exit rc ; -end - -def parseURI(uri_string) - begin - return URI.parse(uri_string).to_s - rescue URI::InvalidURIError => err - warn_exit "Bad URI: <#{uri_string}>", 2 - end -end - -## ---- Command - -def cmd_soh(command=nil) - ## Command line - options = {} - optparse = OptionParser.new do |opts| - # Set a banner, displayed at the top - # of the help screen. - case $cmd - when "s-http", "sparql-http", "soh" - banner="$cmd [get|post|put|delete] datasetURI graph [file]" - when "s-get", "s-head", "s-delete" - banner="$cmd datasetURI graph" - end - - opts.banner = $banner - # Define the options, and what they do - - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - - options[:version] = false - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - - # This displays the help screen, all programs are - # assumed to have this option. - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - if command.nil? - if ARGV.size == 0 - warn "No command given: expected one of 'get', 'put', 'post', 'delete', 'query' or 'update'" - exit 1 - end - cmdPrint=ARGV.shift - command=cmdPrint.upcase - else - cmdPrint=command - end - - case command - when "HEAD", "GET", "DELETE" - requiredFile=false - when "PUT", "POST" - requiredFile=true - when "QUERY" - cmd_sparql_query - when "UPDATE" - cmd_sparql_update - else - warn_exit "Unknown command: #{command}", 2 - end - - if requiredFile - then - if ARGV.size != 3 - warn_exit "Required: dataset URI, graph URI (or 'default') and file", 1 - end - else - if ARGV.size != 2 - warn_exit "Required: dataset URI and graph URI (or 'default')", 1 - end - end - - dataset=parseURI(ARGV.shift) - # Relative URI? - graph=parseURI(ARGV.shift) - file="" - if requiredFile - then - file = ARGV.shift if requiredFile - if ! File.exist?(file) - warn_exit "No such file: "+file, 3 - end - if File.directory?(file) - warn_exit "File is a directory: "+file, 3 - end - end - - case command - when "GET" - GET(dataset, graph) - when "HEAD" - HEAD(dataset, graph) - when "PUT" - PUT(dataset, graph, file) - when "DELETE" - DELETE(dataset, graph) - when "POST" - POST(dataset, graph, file) - else - warn_exit "Internal error: Unknown command: #{cmd}", 2 - end - exit 0 -end - -## -------- -def string_or_file(arg) - return arg if ! arg.match(/^@/) - a=(arg[1..-1]) - open(a, 'rb'){|f| f.read} -end - -## -------- SPARQL Query - -## Choose method -def SPARQL_query(service, query, query_file, forcePOST=false, args2={}) - if ! query_file.nil? - query = open(query_file, 'rb'){|f| f.read} - end - if forcePOST || query.length >= 2*1024 - SPARQL_query_POST(service, query, args2) - else - SPARQL_query_GET(service, query, args2) - end -end - -## By GET - -def SPARQL_query_GET(service, query, args2) - args = { "query" => query } - args.merge!(args2) - qs=args.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - action="#{service}?#{qs}" - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - get_worker(action, headers) -end - -## By POST - -def SPARQL_query_POST(service, query, args2) - # DRY - body/no body for each of request and response. - post_params={ "query" => query } - post_params.merge!(args2) - uri = URI.parse(service) - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - execute_post_form_body(uri, headers, post_params) -end - -def execute_post_form_body(uri, headers, post_params) - request = Net::HTTP::Post.new(uri.request_uri) - qs=post_params.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = qs.length.to_s - request.initialize_http_header(headers) - request.body = qs - print_http_request(uri, request) - response_print_body(uri, request) -end - -# Usage: -v --help --file= --query= -def cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--query QUERY] [--service URI] [--post] 'query' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--query=FILE','--file=FILE', 'Take query from a file') do |file| - options[:file]=file - end - opts.on('--output=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the output argument') do |type| - options[:output]=type - end - opts.on('--accept=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the accept header type') do |type| - options[:accept]=type - end - options[:verbose] = false - opts.on( '--post', 'Force use of POST' ) do - options[:post] = true - end - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e - warn e - exit 1 - end - - $verbose = options[:verbose] - $print_http = $verbose - usePOST = options[:post] - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - # Query - query=nil - query_file=options[:file] - if query_file.nil? && ARGV.size == 0 - then - warn_exit 'No query specified.',1 - end - if query_file.nil? - query = ARGV.shift - if query.match(/^@/) - query_file = query[1..-1] - query = nil - end - end - - # --output ==> output= (non-standard) - args={} - case options[:output] - when nil - when "json","xml","text","csv","tsv" - args['output'] = options[:output] - when :json,:xml,:text,:csv,:tsv - args['output'] = options[:output].to_s - else - warn_exit "Unrecognized output type: "+options[:output],2 - end - - # --accept - # options[:accept] - - print "SPARQL #{service}\n" if $verbose - #args={"output"=>"text"} - SPARQL_query(service, query, query_file, usePOST, args) - exit(0) -end - -## -------- SPARQL Update - -# Update sent as a WWW form. -def SPARQL_update_by_form(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - # args? encode? - body="update="+uri_escape(update) - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = body.length.to_s - uri = URI.parse(service) - execute_post_form(uri, headers, body) -end - -# DRY - query form. -def execute_post_form(uri, headers, body) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = body - print_http_request(uri, request) - response_no_body(uri, request) -end - -def SPARQL_update(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - headers[$hContentType] = $mtSparqlUpdate - uri = URI.parse(service) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = update - print_http_request(uri, request) - response_no_body(uri, request) -end - -def cmd_sparql_update(by_raw_post=true) - # Share with cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--file REQUEST] [--service URI] 'request' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--update=FILE', '--file=FILE', 'Take update from a file') do |file| - options[:file]=file - end - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - update=nil - update_file=options[:file] - - if update_file.nil? && ARGV.size == 0 - then - warn_exit 'No update specified.',1 - end - if update_file.nil? - update = ARGV.shift - if update.match(/^@/) - update_file = update[1..-1] - update = nil - end - end - - print "SPARQL-Update #{service}\n" if $verbose - args={} - - # Reads in the file :-( - if update.nil? - then - update = open(update_file, 'rb'){|f| f.read} - else - update = string_or_file(update) - end - - if by_raw_post - SPARQL_update(service, update, args) - else - SPARQL_update_by_form(service, update, args) - end - exit(0) -end - -## ------- - -case $cmd -when "s-http", "sparql-http", "soh" - $banner="#{$cmd} [get|post|put|delete] datasetURI graph [file]" - cmd_soh -when "s-get", "s-head", "s-put", "s-delete", "s-post" - - case $cmd - when "s-get", "s-head", "s-delete" - $banner="#{$cmd} datasetURI graph" - when "s-put", "s-post" - $banner="#{$cmd} datasetURI graph file" - end - cmd2 = $cmd.sub(/^s-/, '').upcase - cmd_soh cmd2 - -when "s-query", "sparql-query" - cmd_sparql_query -when "s-update", "sparql-update" - cmd_sparql_update true -when "s-update-form", "sparql-update-form" - cmd_sparql_update false -else - warn_exit "Unknown: "+$cmd, 1 -end diff --git a/triplestores/fuseki/bin/s-post b/triplestores/fuseki/bin/s-post deleted file mode 100755 index 16cb44ccb9..0000000000 --- a/triplestores/fuseki/bin/s-post +++ /dev/null @@ -1,716 +0,0 @@ -#!/usr/bin/env ruby -# -*- coding: utf-8 -*- - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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 -# -# http://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. - -# SPARQL HTTP Update, client. - -require 'optparse' -require 'net/http' -require 'uri' -require 'cgi' -require 'pp' -require 'ostruct' - -# ToDo -# Allow a choice of media type for GET -# --accept "content-type" (and abbreviations) -# --header "Add:this" -# --user, --password -# Basic authentication: request.basic_auth("username", "password") -# Follow redirects => 301: puts response["location"] # All headers are lowercase? - -SOH_NAME="SOH" -SOH_VERSION="1.0.0" - -$proxy = ENV['http_proxy'] ? URI.parse(ENV['http_proxy']) : OpenStruct.new - -# What about direct naming? - -# Names -$mtTurtle = 'text/turtle;charset=utf-8' -$mtRDF = 'application/rdf+xml' -$mtText = 'text/plain' -$mtNTriples = 'application/n-triples' -$mtNQuads = 'application/n-quads' -$mtJSONLD = 'application/ld+json' -$mtTriG = 'application/trig' -$mtSparqlResultsX = 'application/sparql-results+xml' -$mtSparqlResultsJ = 'application/sparql-results+json' -$mtAppJSON = 'application/json' -$mtAppXML = 'application/xml' -$mtSparqlResultsTSV = 'application/sparql-results+tsv' -$mtSparqlResultsCSV = 'application/sparql-results+csv' -$mtSparqlUpdate = 'application/sparql-update' -$mtWWWForm = 'application/x-www-form-urlencoded' -$mtSparqlQuery = "application/sparql-query" ; - -# Global media type table. -$fileMediaTypes = {} -$fileMediaTypes['ttl'] = $mtTurtle -$fileMediaTypes['n3'] = 'text/n3; charset=utf-8' -$fileMediaTypes['nt'] = $mtText -$fileMediaTypes['rdf'] = $mtRDF -$fileMediaTypes['owl'] = $mtRDF -$fileMediaTypes['nq'] = $mtNQuads -$fileMediaTypes['trig'] = $mtTriG -$fileMediaTypes['json-ld'] = $mtJSONLD -$fileMediaTypes['jsonld'] = $mtJSONLD - -# Global charset : no entry means "don't set" -$charsetUTF8 = 'utf-8' -$charset = {} -$charset[$mtTurtle] = 'utf-8' -$charset[$mtText] = 'ascii' -$charset[$mtTriG] = 'utf-8' -$charset[$mtNQuads] = 'utf-8' - -# Headers - -$hContentType = 'Content-Type' -# $hContentEncoding = 'Content-Encoding' -$hContentLength = 'Content-Length' -# $hContentLocation = 'Content-Location' -# $hContentRange = 'Content-Range' - -$hAccept = 'Accept' -$hAcceptCharset = 'Accept-Charset' -$hAcceptEncoding = 'Accept-Encoding' -$hAcceptRanges = 'Accept-Ranges' - -$headers = { "User-Agent" => "#{SOH_NAME}/Fuseki #{SOH_VERSION}"} -$print_http = false - -# Default for GET -# At least allow anything (and hope!) -$accept_rdf="#{$mtTurtle} , #{$mtNTriples};q=0.9 , #{$mtRDF};q=0.8 , #{$mtJSONLD};q=0.5" -# Datasets -$accept_ds="#{$mtTrig} , #{$mtNQuads};q=0.9 , #{$mtJSONLD};q=0.5" -# For SPARQL query -$accept_results="#{$mtSparqlResultsJ} , #{$mtSparqlResultsX};q=0.9 , #{$accept_rdf}" - -# Accept any in case of trouble. -$accept_rdf="#{$accept_rdf} , */*;q=0.1" -$accept_results="#{$accept_results} , */*;q=0.1" - -# The media type usually forces the charset. -$accept_charset=nil - -## Who we are. -## Two styles: -## s-query ..... -## soh query ..... - -$cmd = File.basename($0) -if $cmd == 'soh' -then - $cmd = (ARGV.size == 0) ? 'soh' : ARGV.shift -end - -if ! $cmd.start_with?('s-') && $cmd != 'soh' - $cmd = 's-'+$cmd -end - -## -------- - -def GET(dataset, graph) - print "GET #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - get_worker(requestURI, headers) -end - -def get_worker(requestURI, headers) - uri = URI.parse(requestURI) - request = Net::HTTP::Get.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_print_body(uri, request) -end - -def HEAD(dataset, graph) - print "HEAD #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - uri = URI.parse(requestURI) - request = Net::HTTP::Head.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def PUT(dataset, graph, file) - print "PUT #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Put) -end - -def POST(dataset, graph, file) - print "POST #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Post) -end - -def DELETE(dataset, graph) - print "DELETE #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - request = Net::HTTP::Delete.new(uri.request_uri) - headers = {} - headers.merge!($headers) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def uri_escape(string) - CGI.escape(string) -end - -def target(dataset, graph) - return dataset+"?default" if graph == "default" - return dataset+"?graph="+uri_escape(graph) -end - -def send_body(dataset, graph, file, method) - mt = content_type(file) - if mt.nil? - warn_exit "Can't identify the content type of '#{file}'", 9 - end - headers = {} - headers.merge!($headers) - headers[$hContentType] = mt - headers[$hContentLength] = File.size(file).to_s - ## p headers - - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - - request = method.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - request.body_stream = File.open(file) - response_no_body(uri, request) -end - -def response_no_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue Exception => e - # puts e.message - #puts e.backtrace.inspect - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - response = http.request(request) - print_http_response(response) - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code} #{response.message} #{uri}", 9 - # Unreachable - response.error! - end - # NO BODY IN RESPONSE -end - -def response_print_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue => e - #puts e.backtrace.inspect - #print e.class - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - - # Add a blank line if headers were output. - print "\n" if $http_print ; - - begin - response = http.request(request) { |res| - print_http_response(res) - #puts res.code - res.read_body do |segment| - print segment - end - } - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code}: #{uri}", 9 - # Unreachable - response.error! - end - rescue EOFError => e - warn_exit "IO Error: "+e.message, 3 - end -end - -def print_http_request(uri, request) - return unless $print_http - #print "Request\n" - print request.method," ",uri, "\n" - print_headers(" ",request) -end - -def print_http_response(response) - return unless $print_http - #print "Response\n" - print response.code, " ", response.message, "\n" - print_headers(" ",response) -end - -def print_headers(marker, headers) - headers.each do |k,v| - k = k.split('-').map{|w| w.capitalize}.join('-')+':' - printf "%s%-20s %s\n",marker,k,v - end -end - -def content_type(file) - file =~ /\.([^.]*)$/ - ext = $1 - mt = $fileMediaTypes[ext] - cs = $charset[mt] - mt = mt+';charset='+cs if ! cs.nil? - return mt -end - -def charset(content_type) - return $charset[content_type] -end - -def warn_exit(msg, rc) - warn msg - exit rc ; -end - -def parseURI(uri_string) - begin - return URI.parse(uri_string).to_s - rescue URI::InvalidURIError => err - warn_exit "Bad URI: <#{uri_string}>", 2 - end -end - -## ---- Command - -def cmd_soh(command=nil) - ## Command line - options = {} - optparse = OptionParser.new do |opts| - # Set a banner, displayed at the top - # of the help screen. - case $cmd - when "s-http", "sparql-http", "soh" - banner="$cmd [get|post|put|delete] datasetURI graph [file]" - when "s-get", "s-head", "s-delete" - banner="$cmd datasetURI graph" - end - - opts.banner = $banner - # Define the options, and what they do - - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - - options[:version] = false - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - - # This displays the help screen, all programs are - # assumed to have this option. - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - if command.nil? - if ARGV.size == 0 - warn "No command given: expected one of 'get', 'put', 'post', 'delete', 'query' or 'update'" - exit 1 - end - cmdPrint=ARGV.shift - command=cmdPrint.upcase - else - cmdPrint=command - end - - case command - when "HEAD", "GET", "DELETE" - requiredFile=false - when "PUT", "POST" - requiredFile=true - when "QUERY" - cmd_sparql_query - when "UPDATE" - cmd_sparql_update - else - warn_exit "Unknown command: #{command}", 2 - end - - if requiredFile - then - if ARGV.size != 3 - warn_exit "Required: dataset URI, graph URI (or 'default') and file", 1 - end - else - if ARGV.size != 2 - warn_exit "Required: dataset URI and graph URI (or 'default')", 1 - end - end - - dataset=parseURI(ARGV.shift) - # Relative URI? - graph=parseURI(ARGV.shift) - file="" - if requiredFile - then - file = ARGV.shift if requiredFile - if ! File.exist?(file) - warn_exit "No such file: "+file, 3 - end - if File.directory?(file) - warn_exit "File is a directory: "+file, 3 - end - end - - case command - when "GET" - GET(dataset, graph) - when "HEAD" - HEAD(dataset, graph) - when "PUT" - PUT(dataset, graph, file) - when "DELETE" - DELETE(dataset, graph) - when "POST" - POST(dataset, graph, file) - else - warn_exit "Internal error: Unknown command: #{cmd}", 2 - end - exit 0 -end - -## -------- -def string_or_file(arg) - return arg if ! arg.match(/^@/) - a=(arg[1..-1]) - open(a, 'rb'){|f| f.read} -end - -## -------- SPARQL Query - -## Choose method -def SPARQL_query(service, query, query_file, forcePOST=false, args2={}) - if ! query_file.nil? - query = open(query_file, 'rb'){|f| f.read} - end - if forcePOST || query.length >= 2*1024 - SPARQL_query_POST(service, query, args2) - else - SPARQL_query_GET(service, query, args2) - end -end - -## By GET - -def SPARQL_query_GET(service, query, args2) - args = { "query" => query } - args.merge!(args2) - qs=args.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - action="#{service}?#{qs}" - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - get_worker(action, headers) -end - -## By POST - -def SPARQL_query_POST(service, query, args2) - # DRY - body/no body for each of request and response. - post_params={ "query" => query } - post_params.merge!(args2) - uri = URI.parse(service) - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - execute_post_form_body(uri, headers, post_params) -end - -def execute_post_form_body(uri, headers, post_params) - request = Net::HTTP::Post.new(uri.request_uri) - qs=post_params.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = qs.length.to_s - request.initialize_http_header(headers) - request.body = qs - print_http_request(uri, request) - response_print_body(uri, request) -end - -# Usage: -v --help --file= --query= -def cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--query QUERY] [--service URI] [--post] 'query' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--query=FILE','--file=FILE', 'Take query from a file') do |file| - options[:file]=file - end - opts.on('--output=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the output argument') do |type| - options[:output]=type - end - opts.on('--accept=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the accept header type') do |type| - options[:accept]=type - end - options[:verbose] = false - opts.on( '--post', 'Force use of POST' ) do - options[:post] = true - end - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e - warn e - exit 1 - end - - $verbose = options[:verbose] - $print_http = $verbose - usePOST = options[:post] - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - # Query - query=nil - query_file=options[:file] - if query_file.nil? && ARGV.size == 0 - then - warn_exit 'No query specified.',1 - end - if query_file.nil? - query = ARGV.shift - if query.match(/^@/) - query_file = query[1..-1] - query = nil - end - end - - # --output ==> output= (non-standard) - args={} - case options[:output] - when nil - when "json","xml","text","csv","tsv" - args['output'] = options[:output] - when :json,:xml,:text,:csv,:tsv - args['output'] = options[:output].to_s - else - warn_exit "Unrecognized output type: "+options[:output],2 - end - - # --accept - # options[:accept] - - print "SPARQL #{service}\n" if $verbose - #args={"output"=>"text"} - SPARQL_query(service, query, query_file, usePOST, args) - exit(0) -end - -## -------- SPARQL Update - -# Update sent as a WWW form. -def SPARQL_update_by_form(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - # args? encode? - body="update="+uri_escape(update) - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = body.length.to_s - uri = URI.parse(service) - execute_post_form(uri, headers, body) -end - -# DRY - query form. -def execute_post_form(uri, headers, body) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = body - print_http_request(uri, request) - response_no_body(uri, request) -end - -def SPARQL_update(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - headers[$hContentType] = $mtSparqlUpdate - uri = URI.parse(service) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = update - print_http_request(uri, request) - response_no_body(uri, request) -end - -def cmd_sparql_update(by_raw_post=true) - # Share with cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--file REQUEST] [--service URI] 'request' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--update=FILE', '--file=FILE', 'Take update from a file') do |file| - options[:file]=file - end - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - update=nil - update_file=options[:file] - - if update_file.nil? && ARGV.size == 0 - then - warn_exit 'No update specified.',1 - end - if update_file.nil? - update = ARGV.shift - if update.match(/^@/) - update_file = update[1..-1] - update = nil - end - end - - print "SPARQL-Update #{service}\n" if $verbose - args={} - - # Reads in the file :-( - if update.nil? - then - update = open(update_file, 'rb'){|f| f.read} - else - update = string_or_file(update) - end - - if by_raw_post - SPARQL_update(service, update, args) - else - SPARQL_update_by_form(service, update, args) - end - exit(0) -end - -## ------- - -case $cmd -when "s-http", "sparql-http", "soh" - $banner="#{$cmd} [get|post|put|delete] datasetURI graph [file]" - cmd_soh -when "s-get", "s-head", "s-put", "s-delete", "s-post" - - case $cmd - when "s-get", "s-head", "s-delete" - $banner="#{$cmd} datasetURI graph" - when "s-put", "s-post" - $banner="#{$cmd} datasetURI graph file" - end - cmd2 = $cmd.sub(/^s-/, '').upcase - cmd_soh cmd2 - -when "s-query", "sparql-query" - cmd_sparql_query -when "s-update", "sparql-update" - cmd_sparql_update true -when "s-update-form", "sparql-update-form" - cmd_sparql_update false -else - warn_exit "Unknown: "+$cmd, 1 -end diff --git a/triplestores/fuseki/bin/s-put b/triplestores/fuseki/bin/s-put deleted file mode 100755 index 16cb44ccb9..0000000000 --- a/triplestores/fuseki/bin/s-put +++ /dev/null @@ -1,716 +0,0 @@ -#!/usr/bin/env ruby -# -*- coding: utf-8 -*- - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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 -# -# http://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. - -# SPARQL HTTP Update, client. - -require 'optparse' -require 'net/http' -require 'uri' -require 'cgi' -require 'pp' -require 'ostruct' - -# ToDo -# Allow a choice of media type for GET -# --accept "content-type" (and abbreviations) -# --header "Add:this" -# --user, --password -# Basic authentication: request.basic_auth("username", "password") -# Follow redirects => 301: puts response["location"] # All headers are lowercase? - -SOH_NAME="SOH" -SOH_VERSION="1.0.0" - -$proxy = ENV['http_proxy'] ? URI.parse(ENV['http_proxy']) : OpenStruct.new - -# What about direct naming? - -# Names -$mtTurtle = 'text/turtle;charset=utf-8' -$mtRDF = 'application/rdf+xml' -$mtText = 'text/plain' -$mtNTriples = 'application/n-triples' -$mtNQuads = 'application/n-quads' -$mtJSONLD = 'application/ld+json' -$mtTriG = 'application/trig' -$mtSparqlResultsX = 'application/sparql-results+xml' -$mtSparqlResultsJ = 'application/sparql-results+json' -$mtAppJSON = 'application/json' -$mtAppXML = 'application/xml' -$mtSparqlResultsTSV = 'application/sparql-results+tsv' -$mtSparqlResultsCSV = 'application/sparql-results+csv' -$mtSparqlUpdate = 'application/sparql-update' -$mtWWWForm = 'application/x-www-form-urlencoded' -$mtSparqlQuery = "application/sparql-query" ; - -# Global media type table. -$fileMediaTypes = {} -$fileMediaTypes['ttl'] = $mtTurtle -$fileMediaTypes['n3'] = 'text/n3; charset=utf-8' -$fileMediaTypes['nt'] = $mtText -$fileMediaTypes['rdf'] = $mtRDF -$fileMediaTypes['owl'] = $mtRDF -$fileMediaTypes['nq'] = $mtNQuads -$fileMediaTypes['trig'] = $mtTriG -$fileMediaTypes['json-ld'] = $mtJSONLD -$fileMediaTypes['jsonld'] = $mtJSONLD - -# Global charset : no entry means "don't set" -$charsetUTF8 = 'utf-8' -$charset = {} -$charset[$mtTurtle] = 'utf-8' -$charset[$mtText] = 'ascii' -$charset[$mtTriG] = 'utf-8' -$charset[$mtNQuads] = 'utf-8' - -# Headers - -$hContentType = 'Content-Type' -# $hContentEncoding = 'Content-Encoding' -$hContentLength = 'Content-Length' -# $hContentLocation = 'Content-Location' -# $hContentRange = 'Content-Range' - -$hAccept = 'Accept' -$hAcceptCharset = 'Accept-Charset' -$hAcceptEncoding = 'Accept-Encoding' -$hAcceptRanges = 'Accept-Ranges' - -$headers = { "User-Agent" => "#{SOH_NAME}/Fuseki #{SOH_VERSION}"} -$print_http = false - -# Default for GET -# At least allow anything (and hope!) -$accept_rdf="#{$mtTurtle} , #{$mtNTriples};q=0.9 , #{$mtRDF};q=0.8 , #{$mtJSONLD};q=0.5" -# Datasets -$accept_ds="#{$mtTrig} , #{$mtNQuads};q=0.9 , #{$mtJSONLD};q=0.5" -# For SPARQL query -$accept_results="#{$mtSparqlResultsJ} , #{$mtSparqlResultsX};q=0.9 , #{$accept_rdf}" - -# Accept any in case of trouble. -$accept_rdf="#{$accept_rdf} , */*;q=0.1" -$accept_results="#{$accept_results} , */*;q=0.1" - -# The media type usually forces the charset. -$accept_charset=nil - -## Who we are. -## Two styles: -## s-query ..... -## soh query ..... - -$cmd = File.basename($0) -if $cmd == 'soh' -then - $cmd = (ARGV.size == 0) ? 'soh' : ARGV.shift -end - -if ! $cmd.start_with?('s-') && $cmd != 'soh' - $cmd = 's-'+$cmd -end - -## -------- - -def GET(dataset, graph) - print "GET #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - get_worker(requestURI, headers) -end - -def get_worker(requestURI, headers) - uri = URI.parse(requestURI) - request = Net::HTTP::Get.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_print_body(uri, request) -end - -def HEAD(dataset, graph) - print "HEAD #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - uri = URI.parse(requestURI) - request = Net::HTTP::Head.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def PUT(dataset, graph, file) - print "PUT #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Put) -end - -def POST(dataset, graph, file) - print "POST #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Post) -end - -def DELETE(dataset, graph) - print "DELETE #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - request = Net::HTTP::Delete.new(uri.request_uri) - headers = {} - headers.merge!($headers) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def uri_escape(string) - CGI.escape(string) -end - -def target(dataset, graph) - return dataset+"?default" if graph == "default" - return dataset+"?graph="+uri_escape(graph) -end - -def send_body(dataset, graph, file, method) - mt = content_type(file) - if mt.nil? - warn_exit "Can't identify the content type of '#{file}'", 9 - end - headers = {} - headers.merge!($headers) - headers[$hContentType] = mt - headers[$hContentLength] = File.size(file).to_s - ## p headers - - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - - request = method.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - request.body_stream = File.open(file) - response_no_body(uri, request) -end - -def response_no_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue Exception => e - # puts e.message - #puts e.backtrace.inspect - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - response = http.request(request) - print_http_response(response) - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code} #{response.message} #{uri}", 9 - # Unreachable - response.error! - end - # NO BODY IN RESPONSE -end - -def response_print_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue => e - #puts e.backtrace.inspect - #print e.class - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - - # Add a blank line if headers were output. - print "\n" if $http_print ; - - begin - response = http.request(request) { |res| - print_http_response(res) - #puts res.code - res.read_body do |segment| - print segment - end - } - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code}: #{uri}", 9 - # Unreachable - response.error! - end - rescue EOFError => e - warn_exit "IO Error: "+e.message, 3 - end -end - -def print_http_request(uri, request) - return unless $print_http - #print "Request\n" - print request.method," ",uri, "\n" - print_headers(" ",request) -end - -def print_http_response(response) - return unless $print_http - #print "Response\n" - print response.code, " ", response.message, "\n" - print_headers(" ",response) -end - -def print_headers(marker, headers) - headers.each do |k,v| - k = k.split('-').map{|w| w.capitalize}.join('-')+':' - printf "%s%-20s %s\n",marker,k,v - end -end - -def content_type(file) - file =~ /\.([^.]*)$/ - ext = $1 - mt = $fileMediaTypes[ext] - cs = $charset[mt] - mt = mt+';charset='+cs if ! cs.nil? - return mt -end - -def charset(content_type) - return $charset[content_type] -end - -def warn_exit(msg, rc) - warn msg - exit rc ; -end - -def parseURI(uri_string) - begin - return URI.parse(uri_string).to_s - rescue URI::InvalidURIError => err - warn_exit "Bad URI: <#{uri_string}>", 2 - end -end - -## ---- Command - -def cmd_soh(command=nil) - ## Command line - options = {} - optparse = OptionParser.new do |opts| - # Set a banner, displayed at the top - # of the help screen. - case $cmd - when "s-http", "sparql-http", "soh" - banner="$cmd [get|post|put|delete] datasetURI graph [file]" - when "s-get", "s-head", "s-delete" - banner="$cmd datasetURI graph" - end - - opts.banner = $banner - # Define the options, and what they do - - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - - options[:version] = false - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - - # This displays the help screen, all programs are - # assumed to have this option. - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - if command.nil? - if ARGV.size == 0 - warn "No command given: expected one of 'get', 'put', 'post', 'delete', 'query' or 'update'" - exit 1 - end - cmdPrint=ARGV.shift - command=cmdPrint.upcase - else - cmdPrint=command - end - - case command - when "HEAD", "GET", "DELETE" - requiredFile=false - when "PUT", "POST" - requiredFile=true - when "QUERY" - cmd_sparql_query - when "UPDATE" - cmd_sparql_update - else - warn_exit "Unknown command: #{command}", 2 - end - - if requiredFile - then - if ARGV.size != 3 - warn_exit "Required: dataset URI, graph URI (or 'default') and file", 1 - end - else - if ARGV.size != 2 - warn_exit "Required: dataset URI and graph URI (or 'default')", 1 - end - end - - dataset=parseURI(ARGV.shift) - # Relative URI? - graph=parseURI(ARGV.shift) - file="" - if requiredFile - then - file = ARGV.shift if requiredFile - if ! File.exist?(file) - warn_exit "No such file: "+file, 3 - end - if File.directory?(file) - warn_exit "File is a directory: "+file, 3 - end - end - - case command - when "GET" - GET(dataset, graph) - when "HEAD" - HEAD(dataset, graph) - when "PUT" - PUT(dataset, graph, file) - when "DELETE" - DELETE(dataset, graph) - when "POST" - POST(dataset, graph, file) - else - warn_exit "Internal error: Unknown command: #{cmd}", 2 - end - exit 0 -end - -## -------- -def string_or_file(arg) - return arg if ! arg.match(/^@/) - a=(arg[1..-1]) - open(a, 'rb'){|f| f.read} -end - -## -------- SPARQL Query - -## Choose method -def SPARQL_query(service, query, query_file, forcePOST=false, args2={}) - if ! query_file.nil? - query = open(query_file, 'rb'){|f| f.read} - end - if forcePOST || query.length >= 2*1024 - SPARQL_query_POST(service, query, args2) - else - SPARQL_query_GET(service, query, args2) - end -end - -## By GET - -def SPARQL_query_GET(service, query, args2) - args = { "query" => query } - args.merge!(args2) - qs=args.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - action="#{service}?#{qs}" - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - get_worker(action, headers) -end - -## By POST - -def SPARQL_query_POST(service, query, args2) - # DRY - body/no body for each of request and response. - post_params={ "query" => query } - post_params.merge!(args2) - uri = URI.parse(service) - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - execute_post_form_body(uri, headers, post_params) -end - -def execute_post_form_body(uri, headers, post_params) - request = Net::HTTP::Post.new(uri.request_uri) - qs=post_params.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = qs.length.to_s - request.initialize_http_header(headers) - request.body = qs - print_http_request(uri, request) - response_print_body(uri, request) -end - -# Usage: -v --help --file= --query= -def cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--query QUERY] [--service URI] [--post] 'query' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--query=FILE','--file=FILE', 'Take query from a file') do |file| - options[:file]=file - end - opts.on('--output=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the output argument') do |type| - options[:output]=type - end - opts.on('--accept=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the accept header type') do |type| - options[:accept]=type - end - options[:verbose] = false - opts.on( '--post', 'Force use of POST' ) do - options[:post] = true - end - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e - warn e - exit 1 - end - - $verbose = options[:verbose] - $print_http = $verbose - usePOST = options[:post] - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - # Query - query=nil - query_file=options[:file] - if query_file.nil? && ARGV.size == 0 - then - warn_exit 'No query specified.',1 - end - if query_file.nil? - query = ARGV.shift - if query.match(/^@/) - query_file = query[1..-1] - query = nil - end - end - - # --output ==> output= (non-standard) - args={} - case options[:output] - when nil - when "json","xml","text","csv","tsv" - args['output'] = options[:output] - when :json,:xml,:text,:csv,:tsv - args['output'] = options[:output].to_s - else - warn_exit "Unrecognized output type: "+options[:output],2 - end - - # --accept - # options[:accept] - - print "SPARQL #{service}\n" if $verbose - #args={"output"=>"text"} - SPARQL_query(service, query, query_file, usePOST, args) - exit(0) -end - -## -------- SPARQL Update - -# Update sent as a WWW form. -def SPARQL_update_by_form(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - # args? encode? - body="update="+uri_escape(update) - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = body.length.to_s - uri = URI.parse(service) - execute_post_form(uri, headers, body) -end - -# DRY - query form. -def execute_post_form(uri, headers, body) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = body - print_http_request(uri, request) - response_no_body(uri, request) -end - -def SPARQL_update(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - headers[$hContentType] = $mtSparqlUpdate - uri = URI.parse(service) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = update - print_http_request(uri, request) - response_no_body(uri, request) -end - -def cmd_sparql_update(by_raw_post=true) - # Share with cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--file REQUEST] [--service URI] 'request' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--update=FILE', '--file=FILE', 'Take update from a file') do |file| - options[:file]=file - end - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - update=nil - update_file=options[:file] - - if update_file.nil? && ARGV.size == 0 - then - warn_exit 'No update specified.',1 - end - if update_file.nil? - update = ARGV.shift - if update.match(/^@/) - update_file = update[1..-1] - update = nil - end - end - - print "SPARQL-Update #{service}\n" if $verbose - args={} - - # Reads in the file :-( - if update.nil? - then - update = open(update_file, 'rb'){|f| f.read} - else - update = string_or_file(update) - end - - if by_raw_post - SPARQL_update(service, update, args) - else - SPARQL_update_by_form(service, update, args) - end - exit(0) -end - -## ------- - -case $cmd -when "s-http", "sparql-http", "soh" - $banner="#{$cmd} [get|post|put|delete] datasetURI graph [file]" - cmd_soh -when "s-get", "s-head", "s-put", "s-delete", "s-post" - - case $cmd - when "s-get", "s-head", "s-delete" - $banner="#{$cmd} datasetURI graph" - when "s-put", "s-post" - $banner="#{$cmd} datasetURI graph file" - end - cmd2 = $cmd.sub(/^s-/, '').upcase - cmd_soh cmd2 - -when "s-query", "sparql-query" - cmd_sparql_query -when "s-update", "sparql-update" - cmd_sparql_update true -when "s-update-form", "sparql-update-form" - cmd_sparql_update false -else - warn_exit "Unknown: "+$cmd, 1 -end diff --git a/triplestores/fuseki/bin/s-query b/triplestores/fuseki/bin/s-query deleted file mode 100755 index 16cb44ccb9..0000000000 --- a/triplestores/fuseki/bin/s-query +++ /dev/null @@ -1,716 +0,0 @@ -#!/usr/bin/env ruby -# -*- coding: utf-8 -*- - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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 -# -# http://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. - -# SPARQL HTTP Update, client. - -require 'optparse' -require 'net/http' -require 'uri' -require 'cgi' -require 'pp' -require 'ostruct' - -# ToDo -# Allow a choice of media type for GET -# --accept "content-type" (and abbreviations) -# --header "Add:this" -# --user, --password -# Basic authentication: request.basic_auth("username", "password") -# Follow redirects => 301: puts response["location"] # All headers are lowercase? - -SOH_NAME="SOH" -SOH_VERSION="1.0.0" - -$proxy = ENV['http_proxy'] ? URI.parse(ENV['http_proxy']) : OpenStruct.new - -# What about direct naming? - -# Names -$mtTurtle = 'text/turtle;charset=utf-8' -$mtRDF = 'application/rdf+xml' -$mtText = 'text/plain' -$mtNTriples = 'application/n-triples' -$mtNQuads = 'application/n-quads' -$mtJSONLD = 'application/ld+json' -$mtTriG = 'application/trig' -$mtSparqlResultsX = 'application/sparql-results+xml' -$mtSparqlResultsJ = 'application/sparql-results+json' -$mtAppJSON = 'application/json' -$mtAppXML = 'application/xml' -$mtSparqlResultsTSV = 'application/sparql-results+tsv' -$mtSparqlResultsCSV = 'application/sparql-results+csv' -$mtSparqlUpdate = 'application/sparql-update' -$mtWWWForm = 'application/x-www-form-urlencoded' -$mtSparqlQuery = "application/sparql-query" ; - -# Global media type table. -$fileMediaTypes = {} -$fileMediaTypes['ttl'] = $mtTurtle -$fileMediaTypes['n3'] = 'text/n3; charset=utf-8' -$fileMediaTypes['nt'] = $mtText -$fileMediaTypes['rdf'] = $mtRDF -$fileMediaTypes['owl'] = $mtRDF -$fileMediaTypes['nq'] = $mtNQuads -$fileMediaTypes['trig'] = $mtTriG -$fileMediaTypes['json-ld'] = $mtJSONLD -$fileMediaTypes['jsonld'] = $mtJSONLD - -# Global charset : no entry means "don't set" -$charsetUTF8 = 'utf-8' -$charset = {} -$charset[$mtTurtle] = 'utf-8' -$charset[$mtText] = 'ascii' -$charset[$mtTriG] = 'utf-8' -$charset[$mtNQuads] = 'utf-8' - -# Headers - -$hContentType = 'Content-Type' -# $hContentEncoding = 'Content-Encoding' -$hContentLength = 'Content-Length' -# $hContentLocation = 'Content-Location' -# $hContentRange = 'Content-Range' - -$hAccept = 'Accept' -$hAcceptCharset = 'Accept-Charset' -$hAcceptEncoding = 'Accept-Encoding' -$hAcceptRanges = 'Accept-Ranges' - -$headers = { "User-Agent" => "#{SOH_NAME}/Fuseki #{SOH_VERSION}"} -$print_http = false - -# Default for GET -# At least allow anything (and hope!) -$accept_rdf="#{$mtTurtle} , #{$mtNTriples};q=0.9 , #{$mtRDF};q=0.8 , #{$mtJSONLD};q=0.5" -# Datasets -$accept_ds="#{$mtTrig} , #{$mtNQuads};q=0.9 , #{$mtJSONLD};q=0.5" -# For SPARQL query -$accept_results="#{$mtSparqlResultsJ} , #{$mtSparqlResultsX};q=0.9 , #{$accept_rdf}" - -# Accept any in case of trouble. -$accept_rdf="#{$accept_rdf} , */*;q=0.1" -$accept_results="#{$accept_results} , */*;q=0.1" - -# The media type usually forces the charset. -$accept_charset=nil - -## Who we are. -## Two styles: -## s-query ..... -## soh query ..... - -$cmd = File.basename($0) -if $cmd == 'soh' -then - $cmd = (ARGV.size == 0) ? 'soh' : ARGV.shift -end - -if ! $cmd.start_with?('s-') && $cmd != 'soh' - $cmd = 's-'+$cmd -end - -## -------- - -def GET(dataset, graph) - print "GET #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - get_worker(requestURI, headers) -end - -def get_worker(requestURI, headers) - uri = URI.parse(requestURI) - request = Net::HTTP::Get.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_print_body(uri, request) -end - -def HEAD(dataset, graph) - print "HEAD #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - uri = URI.parse(requestURI) - request = Net::HTTP::Head.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def PUT(dataset, graph, file) - print "PUT #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Put) -end - -def POST(dataset, graph, file) - print "POST #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Post) -end - -def DELETE(dataset, graph) - print "DELETE #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - request = Net::HTTP::Delete.new(uri.request_uri) - headers = {} - headers.merge!($headers) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def uri_escape(string) - CGI.escape(string) -end - -def target(dataset, graph) - return dataset+"?default" if graph == "default" - return dataset+"?graph="+uri_escape(graph) -end - -def send_body(dataset, graph, file, method) - mt = content_type(file) - if mt.nil? - warn_exit "Can't identify the content type of '#{file}'", 9 - end - headers = {} - headers.merge!($headers) - headers[$hContentType] = mt - headers[$hContentLength] = File.size(file).to_s - ## p headers - - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - - request = method.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - request.body_stream = File.open(file) - response_no_body(uri, request) -end - -def response_no_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue Exception => e - # puts e.message - #puts e.backtrace.inspect - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - response = http.request(request) - print_http_response(response) - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code} #{response.message} #{uri}", 9 - # Unreachable - response.error! - end - # NO BODY IN RESPONSE -end - -def response_print_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue => e - #puts e.backtrace.inspect - #print e.class - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - - # Add a blank line if headers were output. - print "\n" if $http_print ; - - begin - response = http.request(request) { |res| - print_http_response(res) - #puts res.code - res.read_body do |segment| - print segment - end - } - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code}: #{uri}", 9 - # Unreachable - response.error! - end - rescue EOFError => e - warn_exit "IO Error: "+e.message, 3 - end -end - -def print_http_request(uri, request) - return unless $print_http - #print "Request\n" - print request.method," ",uri, "\n" - print_headers(" ",request) -end - -def print_http_response(response) - return unless $print_http - #print "Response\n" - print response.code, " ", response.message, "\n" - print_headers(" ",response) -end - -def print_headers(marker, headers) - headers.each do |k,v| - k = k.split('-').map{|w| w.capitalize}.join('-')+':' - printf "%s%-20s %s\n",marker,k,v - end -end - -def content_type(file) - file =~ /\.([^.]*)$/ - ext = $1 - mt = $fileMediaTypes[ext] - cs = $charset[mt] - mt = mt+';charset='+cs if ! cs.nil? - return mt -end - -def charset(content_type) - return $charset[content_type] -end - -def warn_exit(msg, rc) - warn msg - exit rc ; -end - -def parseURI(uri_string) - begin - return URI.parse(uri_string).to_s - rescue URI::InvalidURIError => err - warn_exit "Bad URI: <#{uri_string}>", 2 - end -end - -## ---- Command - -def cmd_soh(command=nil) - ## Command line - options = {} - optparse = OptionParser.new do |opts| - # Set a banner, displayed at the top - # of the help screen. - case $cmd - when "s-http", "sparql-http", "soh" - banner="$cmd [get|post|put|delete] datasetURI graph [file]" - when "s-get", "s-head", "s-delete" - banner="$cmd datasetURI graph" - end - - opts.banner = $banner - # Define the options, and what they do - - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - - options[:version] = false - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - - # This displays the help screen, all programs are - # assumed to have this option. - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - if command.nil? - if ARGV.size == 0 - warn "No command given: expected one of 'get', 'put', 'post', 'delete', 'query' or 'update'" - exit 1 - end - cmdPrint=ARGV.shift - command=cmdPrint.upcase - else - cmdPrint=command - end - - case command - when "HEAD", "GET", "DELETE" - requiredFile=false - when "PUT", "POST" - requiredFile=true - when "QUERY" - cmd_sparql_query - when "UPDATE" - cmd_sparql_update - else - warn_exit "Unknown command: #{command}", 2 - end - - if requiredFile - then - if ARGV.size != 3 - warn_exit "Required: dataset URI, graph URI (or 'default') and file", 1 - end - else - if ARGV.size != 2 - warn_exit "Required: dataset URI and graph URI (or 'default')", 1 - end - end - - dataset=parseURI(ARGV.shift) - # Relative URI? - graph=parseURI(ARGV.shift) - file="" - if requiredFile - then - file = ARGV.shift if requiredFile - if ! File.exist?(file) - warn_exit "No such file: "+file, 3 - end - if File.directory?(file) - warn_exit "File is a directory: "+file, 3 - end - end - - case command - when "GET" - GET(dataset, graph) - when "HEAD" - HEAD(dataset, graph) - when "PUT" - PUT(dataset, graph, file) - when "DELETE" - DELETE(dataset, graph) - when "POST" - POST(dataset, graph, file) - else - warn_exit "Internal error: Unknown command: #{cmd}", 2 - end - exit 0 -end - -## -------- -def string_or_file(arg) - return arg if ! arg.match(/^@/) - a=(arg[1..-1]) - open(a, 'rb'){|f| f.read} -end - -## -------- SPARQL Query - -## Choose method -def SPARQL_query(service, query, query_file, forcePOST=false, args2={}) - if ! query_file.nil? - query = open(query_file, 'rb'){|f| f.read} - end - if forcePOST || query.length >= 2*1024 - SPARQL_query_POST(service, query, args2) - else - SPARQL_query_GET(service, query, args2) - end -end - -## By GET - -def SPARQL_query_GET(service, query, args2) - args = { "query" => query } - args.merge!(args2) - qs=args.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - action="#{service}?#{qs}" - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - get_worker(action, headers) -end - -## By POST - -def SPARQL_query_POST(service, query, args2) - # DRY - body/no body for each of request and response. - post_params={ "query" => query } - post_params.merge!(args2) - uri = URI.parse(service) - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - execute_post_form_body(uri, headers, post_params) -end - -def execute_post_form_body(uri, headers, post_params) - request = Net::HTTP::Post.new(uri.request_uri) - qs=post_params.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = qs.length.to_s - request.initialize_http_header(headers) - request.body = qs - print_http_request(uri, request) - response_print_body(uri, request) -end - -# Usage: -v --help --file= --query= -def cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--query QUERY] [--service URI] [--post] 'query' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--query=FILE','--file=FILE', 'Take query from a file') do |file| - options[:file]=file - end - opts.on('--output=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the output argument') do |type| - options[:output]=type - end - opts.on('--accept=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the accept header type') do |type| - options[:accept]=type - end - options[:verbose] = false - opts.on( '--post', 'Force use of POST' ) do - options[:post] = true - end - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e - warn e - exit 1 - end - - $verbose = options[:verbose] - $print_http = $verbose - usePOST = options[:post] - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - # Query - query=nil - query_file=options[:file] - if query_file.nil? && ARGV.size == 0 - then - warn_exit 'No query specified.',1 - end - if query_file.nil? - query = ARGV.shift - if query.match(/^@/) - query_file = query[1..-1] - query = nil - end - end - - # --output ==> output= (non-standard) - args={} - case options[:output] - when nil - when "json","xml","text","csv","tsv" - args['output'] = options[:output] - when :json,:xml,:text,:csv,:tsv - args['output'] = options[:output].to_s - else - warn_exit "Unrecognized output type: "+options[:output],2 - end - - # --accept - # options[:accept] - - print "SPARQL #{service}\n" if $verbose - #args={"output"=>"text"} - SPARQL_query(service, query, query_file, usePOST, args) - exit(0) -end - -## -------- SPARQL Update - -# Update sent as a WWW form. -def SPARQL_update_by_form(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - # args? encode? - body="update="+uri_escape(update) - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = body.length.to_s - uri = URI.parse(service) - execute_post_form(uri, headers, body) -end - -# DRY - query form. -def execute_post_form(uri, headers, body) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = body - print_http_request(uri, request) - response_no_body(uri, request) -end - -def SPARQL_update(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - headers[$hContentType] = $mtSparqlUpdate - uri = URI.parse(service) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = update - print_http_request(uri, request) - response_no_body(uri, request) -end - -def cmd_sparql_update(by_raw_post=true) - # Share with cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--file REQUEST] [--service URI] 'request' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--update=FILE', '--file=FILE', 'Take update from a file') do |file| - options[:file]=file - end - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - update=nil - update_file=options[:file] - - if update_file.nil? && ARGV.size == 0 - then - warn_exit 'No update specified.',1 - end - if update_file.nil? - update = ARGV.shift - if update.match(/^@/) - update_file = update[1..-1] - update = nil - end - end - - print "SPARQL-Update #{service}\n" if $verbose - args={} - - # Reads in the file :-( - if update.nil? - then - update = open(update_file, 'rb'){|f| f.read} - else - update = string_or_file(update) - end - - if by_raw_post - SPARQL_update(service, update, args) - else - SPARQL_update_by_form(service, update, args) - end - exit(0) -end - -## ------- - -case $cmd -when "s-http", "sparql-http", "soh" - $banner="#{$cmd} [get|post|put|delete] datasetURI graph [file]" - cmd_soh -when "s-get", "s-head", "s-put", "s-delete", "s-post" - - case $cmd - when "s-get", "s-head", "s-delete" - $banner="#{$cmd} datasetURI graph" - when "s-put", "s-post" - $banner="#{$cmd} datasetURI graph file" - end - cmd2 = $cmd.sub(/^s-/, '').upcase - cmd_soh cmd2 - -when "s-query", "sparql-query" - cmd_sparql_query -when "s-update", "sparql-update" - cmd_sparql_update true -when "s-update-form", "sparql-update-form" - cmd_sparql_update false -else - warn_exit "Unknown: "+$cmd, 1 -end diff --git a/triplestores/fuseki/bin/s-update b/triplestores/fuseki/bin/s-update deleted file mode 100755 index 16cb44ccb9..0000000000 --- a/triplestores/fuseki/bin/s-update +++ /dev/null @@ -1,716 +0,0 @@ -#!/usr/bin/env ruby -# -*- coding: utf-8 -*- - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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 -# -# http://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. - -# SPARQL HTTP Update, client. - -require 'optparse' -require 'net/http' -require 'uri' -require 'cgi' -require 'pp' -require 'ostruct' - -# ToDo -# Allow a choice of media type for GET -# --accept "content-type" (and abbreviations) -# --header "Add:this" -# --user, --password -# Basic authentication: request.basic_auth("username", "password") -# Follow redirects => 301: puts response["location"] # All headers are lowercase? - -SOH_NAME="SOH" -SOH_VERSION="1.0.0" - -$proxy = ENV['http_proxy'] ? URI.parse(ENV['http_proxy']) : OpenStruct.new - -# What about direct naming? - -# Names -$mtTurtle = 'text/turtle;charset=utf-8' -$mtRDF = 'application/rdf+xml' -$mtText = 'text/plain' -$mtNTriples = 'application/n-triples' -$mtNQuads = 'application/n-quads' -$mtJSONLD = 'application/ld+json' -$mtTriG = 'application/trig' -$mtSparqlResultsX = 'application/sparql-results+xml' -$mtSparqlResultsJ = 'application/sparql-results+json' -$mtAppJSON = 'application/json' -$mtAppXML = 'application/xml' -$mtSparqlResultsTSV = 'application/sparql-results+tsv' -$mtSparqlResultsCSV = 'application/sparql-results+csv' -$mtSparqlUpdate = 'application/sparql-update' -$mtWWWForm = 'application/x-www-form-urlencoded' -$mtSparqlQuery = "application/sparql-query" ; - -# Global media type table. -$fileMediaTypes = {} -$fileMediaTypes['ttl'] = $mtTurtle -$fileMediaTypes['n3'] = 'text/n3; charset=utf-8' -$fileMediaTypes['nt'] = $mtText -$fileMediaTypes['rdf'] = $mtRDF -$fileMediaTypes['owl'] = $mtRDF -$fileMediaTypes['nq'] = $mtNQuads -$fileMediaTypes['trig'] = $mtTriG -$fileMediaTypes['json-ld'] = $mtJSONLD -$fileMediaTypes['jsonld'] = $mtJSONLD - -# Global charset : no entry means "don't set" -$charsetUTF8 = 'utf-8' -$charset = {} -$charset[$mtTurtle] = 'utf-8' -$charset[$mtText] = 'ascii' -$charset[$mtTriG] = 'utf-8' -$charset[$mtNQuads] = 'utf-8' - -# Headers - -$hContentType = 'Content-Type' -# $hContentEncoding = 'Content-Encoding' -$hContentLength = 'Content-Length' -# $hContentLocation = 'Content-Location' -# $hContentRange = 'Content-Range' - -$hAccept = 'Accept' -$hAcceptCharset = 'Accept-Charset' -$hAcceptEncoding = 'Accept-Encoding' -$hAcceptRanges = 'Accept-Ranges' - -$headers = { "User-Agent" => "#{SOH_NAME}/Fuseki #{SOH_VERSION}"} -$print_http = false - -# Default for GET -# At least allow anything (and hope!) -$accept_rdf="#{$mtTurtle} , #{$mtNTriples};q=0.9 , #{$mtRDF};q=0.8 , #{$mtJSONLD};q=0.5" -# Datasets -$accept_ds="#{$mtTrig} , #{$mtNQuads};q=0.9 , #{$mtJSONLD};q=0.5" -# For SPARQL query -$accept_results="#{$mtSparqlResultsJ} , #{$mtSparqlResultsX};q=0.9 , #{$accept_rdf}" - -# Accept any in case of trouble. -$accept_rdf="#{$accept_rdf} , */*;q=0.1" -$accept_results="#{$accept_results} , */*;q=0.1" - -# The media type usually forces the charset. -$accept_charset=nil - -## Who we are. -## Two styles: -## s-query ..... -## soh query ..... - -$cmd = File.basename($0) -if $cmd == 'soh' -then - $cmd = (ARGV.size == 0) ? 'soh' : ARGV.shift -end - -if ! $cmd.start_with?('s-') && $cmd != 'soh' - $cmd = 's-'+$cmd -end - -## -------- - -def GET(dataset, graph) - print "GET #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - get_worker(requestURI, headers) -end - -def get_worker(requestURI, headers) - uri = URI.parse(requestURI) - request = Net::HTTP::Get.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_print_body(uri, request) -end - -def HEAD(dataset, graph) - print "HEAD #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - uri = URI.parse(requestURI) - request = Net::HTTP::Head.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def PUT(dataset, graph, file) - print "PUT #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Put) -end - -def POST(dataset, graph, file) - print "POST #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Post) -end - -def DELETE(dataset, graph) - print "DELETE #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - request = Net::HTTP::Delete.new(uri.request_uri) - headers = {} - headers.merge!($headers) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def uri_escape(string) - CGI.escape(string) -end - -def target(dataset, graph) - return dataset+"?default" if graph == "default" - return dataset+"?graph="+uri_escape(graph) -end - -def send_body(dataset, graph, file, method) - mt = content_type(file) - if mt.nil? - warn_exit "Can't identify the content type of '#{file}'", 9 - end - headers = {} - headers.merge!($headers) - headers[$hContentType] = mt - headers[$hContentLength] = File.size(file).to_s - ## p headers - - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - - request = method.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - request.body_stream = File.open(file) - response_no_body(uri, request) -end - -def response_no_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue Exception => e - # puts e.message - #puts e.backtrace.inspect - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - response = http.request(request) - print_http_response(response) - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code} #{response.message} #{uri}", 9 - # Unreachable - response.error! - end - # NO BODY IN RESPONSE -end - -def response_print_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue => e - #puts e.backtrace.inspect - #print e.class - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - - # Add a blank line if headers were output. - print "\n" if $http_print ; - - begin - response = http.request(request) { |res| - print_http_response(res) - #puts res.code - res.read_body do |segment| - print segment - end - } - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code}: #{uri}", 9 - # Unreachable - response.error! - end - rescue EOFError => e - warn_exit "IO Error: "+e.message, 3 - end -end - -def print_http_request(uri, request) - return unless $print_http - #print "Request\n" - print request.method," ",uri, "\n" - print_headers(" ",request) -end - -def print_http_response(response) - return unless $print_http - #print "Response\n" - print response.code, " ", response.message, "\n" - print_headers(" ",response) -end - -def print_headers(marker, headers) - headers.each do |k,v| - k = k.split('-').map{|w| w.capitalize}.join('-')+':' - printf "%s%-20s %s\n",marker,k,v - end -end - -def content_type(file) - file =~ /\.([^.]*)$/ - ext = $1 - mt = $fileMediaTypes[ext] - cs = $charset[mt] - mt = mt+';charset='+cs if ! cs.nil? - return mt -end - -def charset(content_type) - return $charset[content_type] -end - -def warn_exit(msg, rc) - warn msg - exit rc ; -end - -def parseURI(uri_string) - begin - return URI.parse(uri_string).to_s - rescue URI::InvalidURIError => err - warn_exit "Bad URI: <#{uri_string}>", 2 - end -end - -## ---- Command - -def cmd_soh(command=nil) - ## Command line - options = {} - optparse = OptionParser.new do |opts| - # Set a banner, displayed at the top - # of the help screen. - case $cmd - when "s-http", "sparql-http", "soh" - banner="$cmd [get|post|put|delete] datasetURI graph [file]" - when "s-get", "s-head", "s-delete" - banner="$cmd datasetURI graph" - end - - opts.banner = $banner - # Define the options, and what they do - - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - - options[:version] = false - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - - # This displays the help screen, all programs are - # assumed to have this option. - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - if command.nil? - if ARGV.size == 0 - warn "No command given: expected one of 'get', 'put', 'post', 'delete', 'query' or 'update'" - exit 1 - end - cmdPrint=ARGV.shift - command=cmdPrint.upcase - else - cmdPrint=command - end - - case command - when "HEAD", "GET", "DELETE" - requiredFile=false - when "PUT", "POST" - requiredFile=true - when "QUERY" - cmd_sparql_query - when "UPDATE" - cmd_sparql_update - else - warn_exit "Unknown command: #{command}", 2 - end - - if requiredFile - then - if ARGV.size != 3 - warn_exit "Required: dataset URI, graph URI (or 'default') and file", 1 - end - else - if ARGV.size != 2 - warn_exit "Required: dataset URI and graph URI (or 'default')", 1 - end - end - - dataset=parseURI(ARGV.shift) - # Relative URI? - graph=parseURI(ARGV.shift) - file="" - if requiredFile - then - file = ARGV.shift if requiredFile - if ! File.exist?(file) - warn_exit "No such file: "+file, 3 - end - if File.directory?(file) - warn_exit "File is a directory: "+file, 3 - end - end - - case command - when "GET" - GET(dataset, graph) - when "HEAD" - HEAD(dataset, graph) - when "PUT" - PUT(dataset, graph, file) - when "DELETE" - DELETE(dataset, graph) - when "POST" - POST(dataset, graph, file) - else - warn_exit "Internal error: Unknown command: #{cmd}", 2 - end - exit 0 -end - -## -------- -def string_or_file(arg) - return arg if ! arg.match(/^@/) - a=(arg[1..-1]) - open(a, 'rb'){|f| f.read} -end - -## -------- SPARQL Query - -## Choose method -def SPARQL_query(service, query, query_file, forcePOST=false, args2={}) - if ! query_file.nil? - query = open(query_file, 'rb'){|f| f.read} - end - if forcePOST || query.length >= 2*1024 - SPARQL_query_POST(service, query, args2) - else - SPARQL_query_GET(service, query, args2) - end -end - -## By GET - -def SPARQL_query_GET(service, query, args2) - args = { "query" => query } - args.merge!(args2) - qs=args.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - action="#{service}?#{qs}" - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - get_worker(action, headers) -end - -## By POST - -def SPARQL_query_POST(service, query, args2) - # DRY - body/no body for each of request and response. - post_params={ "query" => query } - post_params.merge!(args2) - uri = URI.parse(service) - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - execute_post_form_body(uri, headers, post_params) -end - -def execute_post_form_body(uri, headers, post_params) - request = Net::HTTP::Post.new(uri.request_uri) - qs=post_params.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = qs.length.to_s - request.initialize_http_header(headers) - request.body = qs - print_http_request(uri, request) - response_print_body(uri, request) -end - -# Usage: -v --help --file= --query= -def cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--query QUERY] [--service URI] [--post] 'query' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--query=FILE','--file=FILE', 'Take query from a file') do |file| - options[:file]=file - end - opts.on('--output=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the output argument') do |type| - options[:output]=type - end - opts.on('--accept=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the accept header type') do |type| - options[:accept]=type - end - options[:verbose] = false - opts.on( '--post', 'Force use of POST' ) do - options[:post] = true - end - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e - warn e - exit 1 - end - - $verbose = options[:verbose] - $print_http = $verbose - usePOST = options[:post] - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - # Query - query=nil - query_file=options[:file] - if query_file.nil? && ARGV.size == 0 - then - warn_exit 'No query specified.',1 - end - if query_file.nil? - query = ARGV.shift - if query.match(/^@/) - query_file = query[1..-1] - query = nil - end - end - - # --output ==> output= (non-standard) - args={} - case options[:output] - when nil - when "json","xml","text","csv","tsv" - args['output'] = options[:output] - when :json,:xml,:text,:csv,:tsv - args['output'] = options[:output].to_s - else - warn_exit "Unrecognized output type: "+options[:output],2 - end - - # --accept - # options[:accept] - - print "SPARQL #{service}\n" if $verbose - #args={"output"=>"text"} - SPARQL_query(service, query, query_file, usePOST, args) - exit(0) -end - -## -------- SPARQL Update - -# Update sent as a WWW form. -def SPARQL_update_by_form(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - # args? encode? - body="update="+uri_escape(update) - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = body.length.to_s - uri = URI.parse(service) - execute_post_form(uri, headers, body) -end - -# DRY - query form. -def execute_post_form(uri, headers, body) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = body - print_http_request(uri, request) - response_no_body(uri, request) -end - -def SPARQL_update(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - headers[$hContentType] = $mtSparqlUpdate - uri = URI.parse(service) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = update - print_http_request(uri, request) - response_no_body(uri, request) -end - -def cmd_sparql_update(by_raw_post=true) - # Share with cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--file REQUEST] [--service URI] 'request' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--update=FILE', '--file=FILE', 'Take update from a file') do |file| - options[:file]=file - end - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - update=nil - update_file=options[:file] - - if update_file.nil? && ARGV.size == 0 - then - warn_exit 'No update specified.',1 - end - if update_file.nil? - update = ARGV.shift - if update.match(/^@/) - update_file = update[1..-1] - update = nil - end - end - - print "SPARQL-Update #{service}\n" if $verbose - args={} - - # Reads in the file :-( - if update.nil? - then - update = open(update_file, 'rb'){|f| f.read} - else - update = string_or_file(update) - end - - if by_raw_post - SPARQL_update(service, update, args) - else - SPARQL_update_by_form(service, update, args) - end - exit(0) -end - -## ------- - -case $cmd -when "s-http", "sparql-http", "soh" - $banner="#{$cmd} [get|post|put|delete] datasetURI graph [file]" - cmd_soh -when "s-get", "s-head", "s-put", "s-delete", "s-post" - - case $cmd - when "s-get", "s-head", "s-delete" - $banner="#{$cmd} datasetURI graph" - when "s-put", "s-post" - $banner="#{$cmd} datasetURI graph file" - end - cmd2 = $cmd.sub(/^s-/, '').upcase - cmd_soh cmd2 - -when "s-query", "sparql-query" - cmd_sparql_query -when "s-update", "sparql-update" - cmd_sparql_update true -when "s-update-form", "sparql-update-form" - cmd_sparql_update false -else - warn_exit "Unknown: "+$cmd, 1 -end diff --git a/triplestores/fuseki/bin/s-update-form b/triplestores/fuseki/bin/s-update-form deleted file mode 100755 index 16cb44ccb9..0000000000 --- a/triplestores/fuseki/bin/s-update-form +++ /dev/null @@ -1,716 +0,0 @@ -#!/usr/bin/env ruby -# -*- coding: utf-8 -*- - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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 -# -# http://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. - -# SPARQL HTTP Update, client. - -require 'optparse' -require 'net/http' -require 'uri' -require 'cgi' -require 'pp' -require 'ostruct' - -# ToDo -# Allow a choice of media type for GET -# --accept "content-type" (and abbreviations) -# --header "Add:this" -# --user, --password -# Basic authentication: request.basic_auth("username", "password") -# Follow redirects => 301: puts response["location"] # All headers are lowercase? - -SOH_NAME="SOH" -SOH_VERSION="1.0.0" - -$proxy = ENV['http_proxy'] ? URI.parse(ENV['http_proxy']) : OpenStruct.new - -# What about direct naming? - -# Names -$mtTurtle = 'text/turtle;charset=utf-8' -$mtRDF = 'application/rdf+xml' -$mtText = 'text/plain' -$mtNTriples = 'application/n-triples' -$mtNQuads = 'application/n-quads' -$mtJSONLD = 'application/ld+json' -$mtTriG = 'application/trig' -$mtSparqlResultsX = 'application/sparql-results+xml' -$mtSparqlResultsJ = 'application/sparql-results+json' -$mtAppJSON = 'application/json' -$mtAppXML = 'application/xml' -$mtSparqlResultsTSV = 'application/sparql-results+tsv' -$mtSparqlResultsCSV = 'application/sparql-results+csv' -$mtSparqlUpdate = 'application/sparql-update' -$mtWWWForm = 'application/x-www-form-urlencoded' -$mtSparqlQuery = "application/sparql-query" ; - -# Global media type table. -$fileMediaTypes = {} -$fileMediaTypes['ttl'] = $mtTurtle -$fileMediaTypes['n3'] = 'text/n3; charset=utf-8' -$fileMediaTypes['nt'] = $mtText -$fileMediaTypes['rdf'] = $mtRDF -$fileMediaTypes['owl'] = $mtRDF -$fileMediaTypes['nq'] = $mtNQuads -$fileMediaTypes['trig'] = $mtTriG -$fileMediaTypes['json-ld'] = $mtJSONLD -$fileMediaTypes['jsonld'] = $mtJSONLD - -# Global charset : no entry means "don't set" -$charsetUTF8 = 'utf-8' -$charset = {} -$charset[$mtTurtle] = 'utf-8' -$charset[$mtText] = 'ascii' -$charset[$mtTriG] = 'utf-8' -$charset[$mtNQuads] = 'utf-8' - -# Headers - -$hContentType = 'Content-Type' -# $hContentEncoding = 'Content-Encoding' -$hContentLength = 'Content-Length' -# $hContentLocation = 'Content-Location' -# $hContentRange = 'Content-Range' - -$hAccept = 'Accept' -$hAcceptCharset = 'Accept-Charset' -$hAcceptEncoding = 'Accept-Encoding' -$hAcceptRanges = 'Accept-Ranges' - -$headers = { "User-Agent" => "#{SOH_NAME}/Fuseki #{SOH_VERSION}"} -$print_http = false - -# Default for GET -# At least allow anything (and hope!) -$accept_rdf="#{$mtTurtle} , #{$mtNTriples};q=0.9 , #{$mtRDF};q=0.8 , #{$mtJSONLD};q=0.5" -# Datasets -$accept_ds="#{$mtTrig} , #{$mtNQuads};q=0.9 , #{$mtJSONLD};q=0.5" -# For SPARQL query -$accept_results="#{$mtSparqlResultsJ} , #{$mtSparqlResultsX};q=0.9 , #{$accept_rdf}" - -# Accept any in case of trouble. -$accept_rdf="#{$accept_rdf} , */*;q=0.1" -$accept_results="#{$accept_results} , */*;q=0.1" - -# The media type usually forces the charset. -$accept_charset=nil - -## Who we are. -## Two styles: -## s-query ..... -## soh query ..... - -$cmd = File.basename($0) -if $cmd == 'soh' -then - $cmd = (ARGV.size == 0) ? 'soh' : ARGV.shift -end - -if ! $cmd.start_with?('s-') && $cmd != 'soh' - $cmd = 's-'+$cmd -end - -## -------- - -def GET(dataset, graph) - print "GET #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - get_worker(requestURI, headers) -end - -def get_worker(requestURI, headers) - uri = URI.parse(requestURI) - request = Net::HTTP::Get.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_print_body(uri, request) -end - -def HEAD(dataset, graph) - print "HEAD #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - uri = URI.parse(requestURI) - request = Net::HTTP::Head.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def PUT(dataset, graph, file) - print "PUT #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Put) -end - -def POST(dataset, graph, file) - print "POST #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Post) -end - -def DELETE(dataset, graph) - print "DELETE #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - request = Net::HTTP::Delete.new(uri.request_uri) - headers = {} - headers.merge!($headers) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def uri_escape(string) - CGI.escape(string) -end - -def target(dataset, graph) - return dataset+"?default" if graph == "default" - return dataset+"?graph="+uri_escape(graph) -end - -def send_body(dataset, graph, file, method) - mt = content_type(file) - if mt.nil? - warn_exit "Can't identify the content type of '#{file}'", 9 - end - headers = {} - headers.merge!($headers) - headers[$hContentType] = mt - headers[$hContentLength] = File.size(file).to_s - ## p headers - - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - - request = method.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - request.body_stream = File.open(file) - response_no_body(uri, request) -end - -def response_no_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue Exception => e - # puts e.message - #puts e.backtrace.inspect - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - response = http.request(request) - print_http_response(response) - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code} #{response.message} #{uri}", 9 - # Unreachable - response.error! - end - # NO BODY IN RESPONSE -end - -def response_print_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue => e - #puts e.backtrace.inspect - #print e.class - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - - # Add a blank line if headers were output. - print "\n" if $http_print ; - - begin - response = http.request(request) { |res| - print_http_response(res) - #puts res.code - res.read_body do |segment| - print segment - end - } - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code}: #{uri}", 9 - # Unreachable - response.error! - end - rescue EOFError => e - warn_exit "IO Error: "+e.message, 3 - end -end - -def print_http_request(uri, request) - return unless $print_http - #print "Request\n" - print request.method," ",uri, "\n" - print_headers(" ",request) -end - -def print_http_response(response) - return unless $print_http - #print "Response\n" - print response.code, " ", response.message, "\n" - print_headers(" ",response) -end - -def print_headers(marker, headers) - headers.each do |k,v| - k = k.split('-').map{|w| w.capitalize}.join('-')+':' - printf "%s%-20s %s\n",marker,k,v - end -end - -def content_type(file) - file =~ /\.([^.]*)$/ - ext = $1 - mt = $fileMediaTypes[ext] - cs = $charset[mt] - mt = mt+';charset='+cs if ! cs.nil? - return mt -end - -def charset(content_type) - return $charset[content_type] -end - -def warn_exit(msg, rc) - warn msg - exit rc ; -end - -def parseURI(uri_string) - begin - return URI.parse(uri_string).to_s - rescue URI::InvalidURIError => err - warn_exit "Bad URI: <#{uri_string}>", 2 - end -end - -## ---- Command - -def cmd_soh(command=nil) - ## Command line - options = {} - optparse = OptionParser.new do |opts| - # Set a banner, displayed at the top - # of the help screen. - case $cmd - when "s-http", "sparql-http", "soh" - banner="$cmd [get|post|put|delete] datasetURI graph [file]" - when "s-get", "s-head", "s-delete" - banner="$cmd datasetURI graph" - end - - opts.banner = $banner - # Define the options, and what they do - - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - - options[:version] = false - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - - # This displays the help screen, all programs are - # assumed to have this option. - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - if command.nil? - if ARGV.size == 0 - warn "No command given: expected one of 'get', 'put', 'post', 'delete', 'query' or 'update'" - exit 1 - end - cmdPrint=ARGV.shift - command=cmdPrint.upcase - else - cmdPrint=command - end - - case command - when "HEAD", "GET", "DELETE" - requiredFile=false - when "PUT", "POST" - requiredFile=true - when "QUERY" - cmd_sparql_query - when "UPDATE" - cmd_sparql_update - else - warn_exit "Unknown command: #{command}", 2 - end - - if requiredFile - then - if ARGV.size != 3 - warn_exit "Required: dataset URI, graph URI (or 'default') and file", 1 - end - else - if ARGV.size != 2 - warn_exit "Required: dataset URI and graph URI (or 'default')", 1 - end - end - - dataset=parseURI(ARGV.shift) - # Relative URI? - graph=parseURI(ARGV.shift) - file="" - if requiredFile - then - file = ARGV.shift if requiredFile - if ! File.exist?(file) - warn_exit "No such file: "+file, 3 - end - if File.directory?(file) - warn_exit "File is a directory: "+file, 3 - end - end - - case command - when "GET" - GET(dataset, graph) - when "HEAD" - HEAD(dataset, graph) - when "PUT" - PUT(dataset, graph, file) - when "DELETE" - DELETE(dataset, graph) - when "POST" - POST(dataset, graph, file) - else - warn_exit "Internal error: Unknown command: #{cmd}", 2 - end - exit 0 -end - -## -------- -def string_or_file(arg) - return arg if ! arg.match(/^@/) - a=(arg[1..-1]) - open(a, 'rb'){|f| f.read} -end - -## -------- SPARQL Query - -## Choose method -def SPARQL_query(service, query, query_file, forcePOST=false, args2={}) - if ! query_file.nil? - query = open(query_file, 'rb'){|f| f.read} - end - if forcePOST || query.length >= 2*1024 - SPARQL_query_POST(service, query, args2) - else - SPARQL_query_GET(service, query, args2) - end -end - -## By GET - -def SPARQL_query_GET(service, query, args2) - args = { "query" => query } - args.merge!(args2) - qs=args.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - action="#{service}?#{qs}" - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - get_worker(action, headers) -end - -## By POST - -def SPARQL_query_POST(service, query, args2) - # DRY - body/no body for each of request and response. - post_params={ "query" => query } - post_params.merge!(args2) - uri = URI.parse(service) - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - execute_post_form_body(uri, headers, post_params) -end - -def execute_post_form_body(uri, headers, post_params) - request = Net::HTTP::Post.new(uri.request_uri) - qs=post_params.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = qs.length.to_s - request.initialize_http_header(headers) - request.body = qs - print_http_request(uri, request) - response_print_body(uri, request) -end - -# Usage: -v --help --file= --query= -def cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--query QUERY] [--service URI] [--post] 'query' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--query=FILE','--file=FILE', 'Take query from a file') do |file| - options[:file]=file - end - opts.on('--output=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the output argument') do |type| - options[:output]=type - end - opts.on('--accept=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the accept header type') do |type| - options[:accept]=type - end - options[:verbose] = false - opts.on( '--post', 'Force use of POST' ) do - options[:post] = true - end - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e - warn e - exit 1 - end - - $verbose = options[:verbose] - $print_http = $verbose - usePOST = options[:post] - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - # Query - query=nil - query_file=options[:file] - if query_file.nil? && ARGV.size == 0 - then - warn_exit 'No query specified.',1 - end - if query_file.nil? - query = ARGV.shift - if query.match(/^@/) - query_file = query[1..-1] - query = nil - end - end - - # --output ==> output= (non-standard) - args={} - case options[:output] - when nil - when "json","xml","text","csv","tsv" - args['output'] = options[:output] - when :json,:xml,:text,:csv,:tsv - args['output'] = options[:output].to_s - else - warn_exit "Unrecognized output type: "+options[:output],2 - end - - # --accept - # options[:accept] - - print "SPARQL #{service}\n" if $verbose - #args={"output"=>"text"} - SPARQL_query(service, query, query_file, usePOST, args) - exit(0) -end - -## -------- SPARQL Update - -# Update sent as a WWW form. -def SPARQL_update_by_form(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - # args? encode? - body="update="+uri_escape(update) - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = body.length.to_s - uri = URI.parse(service) - execute_post_form(uri, headers, body) -end - -# DRY - query form. -def execute_post_form(uri, headers, body) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = body - print_http_request(uri, request) - response_no_body(uri, request) -end - -def SPARQL_update(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - headers[$hContentType] = $mtSparqlUpdate - uri = URI.parse(service) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = update - print_http_request(uri, request) - response_no_body(uri, request) -end - -def cmd_sparql_update(by_raw_post=true) - # Share with cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--file REQUEST] [--service URI] 'request' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--update=FILE', '--file=FILE', 'Take update from a file') do |file| - options[:file]=file - end - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - update=nil - update_file=options[:file] - - if update_file.nil? && ARGV.size == 0 - then - warn_exit 'No update specified.',1 - end - if update_file.nil? - update = ARGV.shift - if update.match(/^@/) - update_file = update[1..-1] - update = nil - end - end - - print "SPARQL-Update #{service}\n" if $verbose - args={} - - # Reads in the file :-( - if update.nil? - then - update = open(update_file, 'rb'){|f| f.read} - else - update = string_or_file(update) - end - - if by_raw_post - SPARQL_update(service, update, args) - else - SPARQL_update_by_form(service, update, args) - end - exit(0) -end - -## ------- - -case $cmd -when "s-http", "sparql-http", "soh" - $banner="#{$cmd} [get|post|put|delete] datasetURI graph [file]" - cmd_soh -when "s-get", "s-head", "s-put", "s-delete", "s-post" - - case $cmd - when "s-get", "s-head", "s-delete" - $banner="#{$cmd} datasetURI graph" - when "s-put", "s-post" - $banner="#{$cmd} datasetURI graph file" - end - cmd2 = $cmd.sub(/^s-/, '').upcase - cmd_soh cmd2 - -when "s-query", "sparql-query" - cmd_sparql_query -when "s-update", "sparql-update" - cmd_sparql_update true -when "s-update-form", "sparql-update-form" - cmd_sparql_update false -else - warn_exit "Unknown: "+$cmd, 1 -end diff --git a/triplestores/fuseki/bin/soh b/triplestores/fuseki/bin/soh deleted file mode 100755 index 16cb44ccb9..0000000000 --- a/triplestores/fuseki/bin/soh +++ /dev/null @@ -1,716 +0,0 @@ -#!/usr/bin/env ruby -# -*- coding: utf-8 -*- - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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 -# -# http://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. - -# SPARQL HTTP Update, client. - -require 'optparse' -require 'net/http' -require 'uri' -require 'cgi' -require 'pp' -require 'ostruct' - -# ToDo -# Allow a choice of media type for GET -# --accept "content-type" (and abbreviations) -# --header "Add:this" -# --user, --password -# Basic authentication: request.basic_auth("username", "password") -# Follow redirects => 301: puts response["location"] # All headers are lowercase? - -SOH_NAME="SOH" -SOH_VERSION="1.0.0" - -$proxy = ENV['http_proxy'] ? URI.parse(ENV['http_proxy']) : OpenStruct.new - -# What about direct naming? - -# Names -$mtTurtle = 'text/turtle;charset=utf-8' -$mtRDF = 'application/rdf+xml' -$mtText = 'text/plain' -$mtNTriples = 'application/n-triples' -$mtNQuads = 'application/n-quads' -$mtJSONLD = 'application/ld+json' -$mtTriG = 'application/trig' -$mtSparqlResultsX = 'application/sparql-results+xml' -$mtSparqlResultsJ = 'application/sparql-results+json' -$mtAppJSON = 'application/json' -$mtAppXML = 'application/xml' -$mtSparqlResultsTSV = 'application/sparql-results+tsv' -$mtSparqlResultsCSV = 'application/sparql-results+csv' -$mtSparqlUpdate = 'application/sparql-update' -$mtWWWForm = 'application/x-www-form-urlencoded' -$mtSparqlQuery = "application/sparql-query" ; - -# Global media type table. -$fileMediaTypes = {} -$fileMediaTypes['ttl'] = $mtTurtle -$fileMediaTypes['n3'] = 'text/n3; charset=utf-8' -$fileMediaTypes['nt'] = $mtText -$fileMediaTypes['rdf'] = $mtRDF -$fileMediaTypes['owl'] = $mtRDF -$fileMediaTypes['nq'] = $mtNQuads -$fileMediaTypes['trig'] = $mtTriG -$fileMediaTypes['json-ld'] = $mtJSONLD -$fileMediaTypes['jsonld'] = $mtJSONLD - -# Global charset : no entry means "don't set" -$charsetUTF8 = 'utf-8' -$charset = {} -$charset[$mtTurtle] = 'utf-8' -$charset[$mtText] = 'ascii' -$charset[$mtTriG] = 'utf-8' -$charset[$mtNQuads] = 'utf-8' - -# Headers - -$hContentType = 'Content-Type' -# $hContentEncoding = 'Content-Encoding' -$hContentLength = 'Content-Length' -# $hContentLocation = 'Content-Location' -# $hContentRange = 'Content-Range' - -$hAccept = 'Accept' -$hAcceptCharset = 'Accept-Charset' -$hAcceptEncoding = 'Accept-Encoding' -$hAcceptRanges = 'Accept-Ranges' - -$headers = { "User-Agent" => "#{SOH_NAME}/Fuseki #{SOH_VERSION}"} -$print_http = false - -# Default for GET -# At least allow anything (and hope!) -$accept_rdf="#{$mtTurtle} , #{$mtNTriples};q=0.9 , #{$mtRDF};q=0.8 , #{$mtJSONLD};q=0.5" -# Datasets -$accept_ds="#{$mtTrig} , #{$mtNQuads};q=0.9 , #{$mtJSONLD};q=0.5" -# For SPARQL query -$accept_results="#{$mtSparqlResultsJ} , #{$mtSparqlResultsX};q=0.9 , #{$accept_rdf}" - -# Accept any in case of trouble. -$accept_rdf="#{$accept_rdf} , */*;q=0.1" -$accept_results="#{$accept_results} , */*;q=0.1" - -# The media type usually forces the charset. -$accept_charset=nil - -## Who we are. -## Two styles: -## s-query ..... -## soh query ..... - -$cmd = File.basename($0) -if $cmd == 'soh' -then - $cmd = (ARGV.size == 0) ? 'soh' : ARGV.shift -end - -if ! $cmd.start_with?('s-') && $cmd != 'soh' - $cmd = 's-'+$cmd -end - -## -------- - -def GET(dataset, graph) - print "GET #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - get_worker(requestURI, headers) -end - -def get_worker(requestURI, headers) - uri = URI.parse(requestURI) - request = Net::HTTP::Get.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_print_body(uri, request) -end - -def HEAD(dataset, graph) - print "HEAD #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - headers = {} - headers.merge!($headers) - headers[$hAccept] = $accept_rdf - headers[$hAcceptCharset] = $accept_charset unless $accept_charset.nil? - uri = URI.parse(requestURI) - request = Net::HTTP::Head.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def PUT(dataset, graph, file) - print "PUT #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Put) -end - -def POST(dataset, graph, file) - print "POST #{dataset} #{graph} #{file}\n" if $verbose - send_body(dataset, graph, file, Net::HTTP::Post) -end - -def DELETE(dataset, graph) - print "DELETE #{dataset} #{graph}\n" if $verbose - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - request = Net::HTTP::Delete.new(uri.request_uri) - headers = {} - headers.merge!($headers) - request.initialize_http_header(headers) - print_http_request(uri, request) - response_no_body(uri, request) -end - -def uri_escape(string) - CGI.escape(string) -end - -def target(dataset, graph) - return dataset+"?default" if graph == "default" - return dataset+"?graph="+uri_escape(graph) -end - -def send_body(dataset, graph, file, method) - mt = content_type(file) - if mt.nil? - warn_exit "Can't identify the content type of '#{file}'", 9 - end - headers = {} - headers.merge!($headers) - headers[$hContentType] = mt - headers[$hContentLength] = File.size(file).to_s - ## p headers - - requestURI = target(dataset, graph) - uri = URI.parse(requestURI) - - request = method.new(uri.request_uri) - request.initialize_http_header(headers) - print_http_request(uri, request) - request.body_stream = File.open(file) - response_no_body(uri, request) -end - -def response_no_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue Exception => e - # puts e.message - #puts e.backtrace.inspect - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - response = http.request(request) - print_http_response(response) - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code} #{response.message} #{uri}", 9 - # Unreachable - response.error! - end - # NO BODY IN RESPONSE -end - -def response_print_body(uri, request) - http = Net::HTTP::Proxy($proxy.host,$proxy.port).new(uri.host, uri.port) - http.read_timeout = nil - # check we can connect. - begin http.start - rescue => e - #puts e.backtrace.inspect - #print e.class - warn_exit "Failed to connect: #{uri.host}:#{uri.port}: #{e.message}", 3 - end - - # Add a blank line if headers were output. - print "\n" if $http_print ; - - begin - response = http.request(request) { |res| - print_http_response(res) - #puts res.code - res.read_body do |segment| - print segment - end - } - case response - when Net::HTTPSuccess, Net::HTTPRedirection - # OK - when Net::HTTPNotFound - warn_exit "404 Not found: #{uri}", 9 - #print response.body - else - warn_exit "#{response.code}: #{uri}", 9 - # Unreachable - response.error! - end - rescue EOFError => e - warn_exit "IO Error: "+e.message, 3 - end -end - -def print_http_request(uri, request) - return unless $print_http - #print "Request\n" - print request.method," ",uri, "\n" - print_headers(" ",request) -end - -def print_http_response(response) - return unless $print_http - #print "Response\n" - print response.code, " ", response.message, "\n" - print_headers(" ",response) -end - -def print_headers(marker, headers) - headers.each do |k,v| - k = k.split('-').map{|w| w.capitalize}.join('-')+':' - printf "%s%-20s %s\n",marker,k,v - end -end - -def content_type(file) - file =~ /\.([^.]*)$/ - ext = $1 - mt = $fileMediaTypes[ext] - cs = $charset[mt] - mt = mt+';charset='+cs if ! cs.nil? - return mt -end - -def charset(content_type) - return $charset[content_type] -end - -def warn_exit(msg, rc) - warn msg - exit rc ; -end - -def parseURI(uri_string) - begin - return URI.parse(uri_string).to_s - rescue URI::InvalidURIError => err - warn_exit "Bad URI: <#{uri_string}>", 2 - end -end - -## ---- Command - -def cmd_soh(command=nil) - ## Command line - options = {} - optparse = OptionParser.new do |opts| - # Set a banner, displayed at the top - # of the help screen. - case $cmd - when "s-http", "sparql-http", "soh" - banner="$cmd [get|post|put|delete] datasetURI graph [file]" - when "s-get", "s-head", "s-delete" - banner="$cmd datasetURI graph" - end - - opts.banner = $banner - # Define the options, and what they do - - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - - options[:version] = false - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - - # This displays the help screen, all programs are - # assumed to have this option. - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - if command.nil? - if ARGV.size == 0 - warn "No command given: expected one of 'get', 'put', 'post', 'delete', 'query' or 'update'" - exit 1 - end - cmdPrint=ARGV.shift - command=cmdPrint.upcase - else - cmdPrint=command - end - - case command - when "HEAD", "GET", "DELETE" - requiredFile=false - when "PUT", "POST" - requiredFile=true - when "QUERY" - cmd_sparql_query - when "UPDATE" - cmd_sparql_update - else - warn_exit "Unknown command: #{command}", 2 - end - - if requiredFile - then - if ARGV.size != 3 - warn_exit "Required: dataset URI, graph URI (or 'default') and file", 1 - end - else - if ARGV.size != 2 - warn_exit "Required: dataset URI and graph URI (or 'default')", 1 - end - end - - dataset=parseURI(ARGV.shift) - # Relative URI? - graph=parseURI(ARGV.shift) - file="" - if requiredFile - then - file = ARGV.shift if requiredFile - if ! File.exist?(file) - warn_exit "No such file: "+file, 3 - end - if File.directory?(file) - warn_exit "File is a directory: "+file, 3 - end - end - - case command - when "GET" - GET(dataset, graph) - when "HEAD" - HEAD(dataset, graph) - when "PUT" - PUT(dataset, graph, file) - when "DELETE" - DELETE(dataset, graph) - when "POST" - POST(dataset, graph, file) - else - warn_exit "Internal error: Unknown command: #{cmd}", 2 - end - exit 0 -end - -## -------- -def string_or_file(arg) - return arg if ! arg.match(/^@/) - a=(arg[1..-1]) - open(a, 'rb'){|f| f.read} -end - -## -------- SPARQL Query - -## Choose method -def SPARQL_query(service, query, query_file, forcePOST=false, args2={}) - if ! query_file.nil? - query = open(query_file, 'rb'){|f| f.read} - end - if forcePOST || query.length >= 2*1024 - SPARQL_query_POST(service, query, args2) - else - SPARQL_query_GET(service, query, args2) - end -end - -## By GET - -def SPARQL_query_GET(service, query, args2) - args = { "query" => query } - args.merge!(args2) - qs=args.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - action="#{service}?#{qs}" - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - get_worker(action, headers) -end - -## By POST - -def SPARQL_query_POST(service, query, args2) - # DRY - body/no body for each of request and response. - post_params={ "query" => query } - post_params.merge!(args2) - uri = URI.parse(service) - headers={} - headers.merge!($headers) - headers[$hAccept]=$accept_results - execute_post_form_body(uri, headers, post_params) -end - -def execute_post_form_body(uri, headers, post_params) - request = Net::HTTP::Post.new(uri.request_uri) - qs=post_params.collect { |k,v| "#{k}=#{uri_escape(v)}" }.join('&') - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = qs.length.to_s - request.initialize_http_header(headers) - request.body = qs - print_http_request(uri, request) - response_print_body(uri, request) -end - -# Usage: -v --help --file= --query= -def cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--query QUERY] [--service URI] [--post] 'query' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--query=FILE','--file=FILE', 'Take query from a file') do |file| - options[:file]=file - end - opts.on('--output=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the output argument') do |type| - options[:output]=type - end - opts.on('--accept=TYPE', [:json,:xml,:text,:csv,:tsv], - 'Set the accept header type') do |type| - options[:accept]=type - end - options[:verbose] = false - opts.on( '--post', 'Force use of POST' ) do - options[:post] = true - end - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument, OptionParser::InvalidOption => e - warn e - exit 1 - end - - $verbose = options[:verbose] - $print_http = $verbose - usePOST = options[:post] - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - # Query - query=nil - query_file=options[:file] - if query_file.nil? && ARGV.size == 0 - then - warn_exit 'No query specified.',1 - end - if query_file.nil? - query = ARGV.shift - if query.match(/^@/) - query_file = query[1..-1] - query = nil - end - end - - # --output ==> output= (non-standard) - args={} - case options[:output] - when nil - when "json","xml","text","csv","tsv" - args['output'] = options[:output] - when :json,:xml,:text,:csv,:tsv - args['output'] = options[:output].to_s - else - warn_exit "Unrecognized output type: "+options[:output],2 - end - - # --accept - # options[:accept] - - print "SPARQL #{service}\n" if $verbose - #args={"output"=>"text"} - SPARQL_query(service, query, query_file, usePOST, args) - exit(0) -end - -## -------- SPARQL Update - -# Update sent as a WWW form. -def SPARQL_update_by_form(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - # args? encode? - body="update="+uri_escape(update) - headers[$hContentType] = $mtWWWForm - headers[$hContentLength] = body.length.to_s - uri = URI.parse(service) - execute_post_form(uri, headers, body) -end - -# DRY - query form. -def execute_post_form(uri, headers, body) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = body - print_http_request(uri, request) - response_no_body(uri, request) -end - -def SPARQL_update(service, update, args2={}) - args = {} - args.merge!(args2) - headers={} - headers.merge!($headers) - headers[$hContentType] = $mtSparqlUpdate - uri = URI.parse(service) - request = Net::HTTP::Post.new(uri.request_uri) - request.initialize_http_header(headers) - request.body = update - print_http_request(uri, request) - response_no_body(uri, request) -end - -def cmd_sparql_update(by_raw_post=true) - # Share with cmd_sparql_query - options={} - optparse = OptionParser.new do |opts| - opts.banner = "Usage: #{$cmd} [--file REQUEST] [--service URI] 'request' | @file" - opts.on('--service=URI', '--server=URI', 'SPARQL endpoint') do |uri| - options[:service]=uri - end - opts.on('--update=FILE', '--file=FILE', 'Take update from a file') do |file| - options[:file]=file - end - options[:verbose] = false - opts.on( '-v', '--verbose', 'Verbose' ) do - options[:verbose] = true - end - opts.on( '--version', 'Print version and exit' ) do - print "#{SOH_NAME} #{SOH_VERSION}\n" - exit - end - opts.on( '-h', '--help', 'Display this screen and exit' ) do - puts opts - exit - end - end - - begin optparse.parse! - rescue OptionParser::InvalidArgument => e - warn e - exit - end - - $verbose = options[:verbose] - $print_http = $verbose - - service = options[:service] - warn_exit 'No service specified. Required --service=URI',1 if service.nil? - - update=nil - update_file=options[:file] - - if update_file.nil? && ARGV.size == 0 - then - warn_exit 'No update specified.',1 - end - if update_file.nil? - update = ARGV.shift - if update.match(/^@/) - update_file = update[1..-1] - update = nil - end - end - - print "SPARQL-Update #{service}\n" if $verbose - args={} - - # Reads in the file :-( - if update.nil? - then - update = open(update_file, 'rb'){|f| f.read} - else - update = string_or_file(update) - end - - if by_raw_post - SPARQL_update(service, update, args) - else - SPARQL_update_by_form(service, update, args) - end - exit(0) -end - -## ------- - -case $cmd -when "s-http", "sparql-http", "soh" - $banner="#{$cmd} [get|post|put|delete] datasetURI graph [file]" - cmd_soh -when "s-get", "s-head", "s-put", "s-delete", "s-post" - - case $cmd - when "s-get", "s-head", "s-delete" - $banner="#{$cmd} datasetURI graph" - when "s-put", "s-post" - $banner="#{$cmd} datasetURI graph file" - end - cmd2 = $cmd.sub(/^s-/, '').upcase - cmd_soh cmd2 - -when "s-query", "sparql-query" - cmd_sparql_query -when "s-update", "sparql-update" - cmd_sparql_update true -when "s-update-form", "sparql-update-form" - cmd_sparql_update false -else - warn_exit "Unknown: "+$cmd, 1 -end diff --git a/triplestores/fuseki/fuseki-server b/triplestores/fuseki/fuseki-server deleted file mode 100755 index 78f50e37e2..0000000000 --- a/triplestores/fuseki/fuseki-server +++ /dev/null @@ -1,95 +0,0 @@ -#!/bin/sh -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you 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 -# -# http://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. - -# Run fuseki as a standalone server - -export FUSEKI_HOME="${FUSEKI_HOME:-$PWD}" - -if [ ! -e "$FUSEKI_HOME" ] -then - echo "$FUSEKI_HOME does not exist" 1>&2 - exit 1 - fi - -JAR1="$FUSEKI_HOME/fuseki-server.jar" -JAR2="$FUSEKI_HOME/jena-fuseki-server-*.jar" -JAR="" - -for J in "$JAR1" "$JAR2" -do - # Expand - J="$(echo $J)" - if [ -e "$J" ] - then - JAR="$J" - break - fi -done - -if [ "$JAR" = "" ] -then - echo "Can't find jarfile to run" - exit 1 -fi - -# Deal with Cygwin path issues -cygwin=false -case "`uname`" in - CYGWIN*) cygwin=true;; -esac -if [ "$cygwin" = "true" ] -then - JAR=`cygpath -w "$JAR"` - FUSEKI_HOME=`cygpath -w "$FUSEKI_HOME"` -fi - -export FUSEKI_BASE="${FUSEKI_BASE:-$PWD/run}" - -if [ -z "$JAVA" ] -then - if [ -z "$JAVA_HOME" ] - then - JAVA=$(which java) - else - JAVA=$JAVA_HOME/bin/java - fi -fi - -if [ -z "$JAVA" ] -then - ( - echo "Cannot find a Java JDK." - echo "Please set either set JAVA or JAVA_HOME and put java (>=1.8) in your PATH." - ) 1>&2 - exit 1 -fi - -JVM_ARGS=${JVM_ARGS:--Xmx1200M} - -exec $JAVA $JVM_ARGS -jar "$JAR" "$@" - -## Adding custom code to the Fuseki server: -## -## It is also possible to launch Fuseki using -## java $JVM_ARGS -cp "$JAR" org.apache.jena.fuseki.cmd.FusekiCmd "$@" -## -## "exec" is optional - it simply frees up an OS process. -## In this way, you can add custom java to the classpath: -## -## APPJAR=MyCode.jar -## java $JVM_ARGS -cp "$JAR:$APPJAR" org.apache.jena.fuseki.cmd.FusekiCmd "$@" - diff --git a/triplestores/fuseki/fuseki-server.jar b/triplestores/fuseki/fuseki-server.jar deleted file mode 100644 index 951df47047..0000000000 Binary files a/triplestores/fuseki/fuseki-server.jar and /dev/null differ diff --git a/triplestores/fuseki/log4j.properties b/triplestores/fuseki/log4j.properties deleted file mode 100644 index 174492d564..0000000000 --- a/triplestores/fuseki/log4j.properties +++ /dev/null @@ -1,40 +0,0 @@ -# Plain output to stdout -log4j.appender.jena.plainstdout=org.apache.log4j.ConsoleAppender -log4j.appender.jena.plainstdout.target=System.out -log4j.appender.jena.plainstdout.layout=org.apache.log4j.PatternLayout -log4j.appender.jena.plainstdout.layout.ConversionPattern=[%d{yyyy-MM-dd HH:mm:ss}] %-10c{1} %-5p %m%n -## %d{ISO8601} -- includes "ss,sss" -## log4j.appender.jena.plainstdout.layout.ConversionPattern=[%d{ISO8601}] %-10c{1} %-5p %m%n - -# Unadorned, for the NCSA requests log. -log4j.appender.fuseki.plain=org.apache.log4j.ConsoleAppender -log4j.appender.fuseki.plain.target=System.out -log4j.appender.fuseki.plain.layout=org.apache.log4j.PatternLayout -log4j.appender.fuseki.plain.layout.ConversionPattern=%m%n - -log4j.rootLogger=INFO, jena.plainstdout -log4j.logger.org.apache.jena=WARN -log4j.logger.org.apache.jena=WARN -log4j.logger.org.apache.jena.fuseki=INFO - -# Others -log4j.logger.org.eclipse.jetty=WARN -log4j.logger.org.apache.shiro=WARN - -# Fuseki System logs. -log4j.logger.org.apache.jena.fuseki.Server=INFO -log4j.logger.org.apache.jena.fuseki.Fuseki=WARN -log4j.logger.org.apache.jena.fuseki.Admin=WARN -log4j.logger.org.apache.jena.fuseki.Validate=WARN -log4j.logger.org.apache.jena.fuseki.Config=WARN -log4j.logger.org.apache.jena.fuseki.Servlet=WARN - -# NCSA Request log. -log4j.additivity.org.apache.jena.fuseki.Request=false -log4j.logger.org.apache.jena.fuseki.Request=OFF, fuseki.plain - -# TDB -log4j.logger.org.apache.jena.tdb.loader=INFO -## Parser output -log4j.additivity.org.apache.jena.riot=false -log4j.logger.org.apache.jena.riot=INFO, jena.plainstdout \ No newline at end of file diff --git a/triplestores/fuseki/run/config.ttl b/triplestores/fuseki/run/config.ttl deleted file mode 100644 index f835274c17..0000000000 --- a/triplestores/fuseki/run/config.ttl +++ /dev/null @@ -1,33 +0,0 @@ -# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0 - -## Fuseki Server configuration file. - -@prefix : <#> . -@prefix fuseki: . -@prefix rdf: . -@prefix rdfs: . -@prefix ja: . - -[] rdf:type fuseki:Server ; - # Example:: - # Server-wide query timeout. - # - # Timeout - server-wide default: milliseconds. - # Format 1: "1000" -- 1 second timeout - # Format 2: "10000,60000" -- 10s timeout to first result, - # then 60s timeout for the rest of query. - # - # See javadoc for ARQ.queryTimeout for details. - # This can also be set on a per dataset basis in the dataset assembler. - # - # ja:context [ ja:cxtName "arq:queryTimeout" ; ja:cxtValue "30000" ] ; - - - - # Add any custom classes you want to load. - # Must have a "public static void init()" method. - # ja:loadClass "your.code.Class" ; - ja:loadClass "org.apache.jena.query.text.TextQuery"; - - # End triples. - . diff --git a/triplestores/fuseki/run/configuration/knora-test-unit.ttl b/triplestores/fuseki/run/configuration/knora-test-unit.ttl deleted file mode 100644 index 618cffb21d..0000000000 --- a/triplestores/fuseki/run/configuration/knora-test-unit.ttl +++ /dev/null @@ -1,52 +0,0 @@ -@prefix : . -@prefix tdb: . -@prefix rdf: . -@prefix ja: . -@prefix rdfs: . -@prefix fuseki: . -@prefix text: . -@prefix knora-base: . - -:service_tdb_all a fuseki:Service ; - rdfs:label "TDB knora-test-unit" ; - fuseki:dataset :text_dataset ; - fuseki:name "knora-test-unit" ; - fuseki:serviceQuery "query" , "sparql" ; - fuseki:serviceReadGraphStore "get" ; - fuseki:serviceReadWriteGraphStore "data" ; - fuseki:serviceUpdate "update" ; - fuseki:serviceUpload "upload" . - -## --------------------------------------------------------------- -## This URI must be fixed - it's used to assemble the text dataset. - -:text_dataset rdf:type text:TextDataset ; - text:dataset :tdb_dataset_readwrite ; - text:index :indexLucene . - -# A TDB datset used for RDF storage -:tdb_dataset_readwrite a tdb:DatasetTDB ; - tdb:unionDefaultGraph true ; - tdb:location "./run/databases/knora-test-unit" ; - # Fuseki 2.4.0 only - remove for later versions. - ja:context [ ja:cxtName "arq:optFilterPlacementBGP" ; - ja:cxtValue "true" ] . - -# Text index description -:indexLucene a text:TextIndexLucene ; - text:directory "./run/lucene/knora-test-unit" ; - ##text:directory "mem" ; - text:entityMap :entMap . - -# Mapping in the index -# URI stored in field "uri" -# knora-base:valueHasString is mapped to field "text" -:entMap a text:EntityMap ; - text:entityField "uri" ; - text:defaultField "text" ; - text:uidField "uid" ; - text:map ( - [ text:field "text" ; text:predicate rdfs:label ] - [ text:field "text" ; text:predicate knora-base:valueHasString ] - [ text:field "text" ; text:predicate knora-base:valueHasComment ] - ) . diff --git a/triplestores/fuseki/run/configuration/knora-test.ttl b/triplestores/fuseki/run/configuration/knora-test.ttl deleted file mode 100644 index d59a0034c3..0000000000 --- a/triplestores/fuseki/run/configuration/knora-test.ttl +++ /dev/null @@ -1,53 +0,0 @@ -@prefix : . -@prefix tdb: . -@prefix rdf: . -@prefix ja: . -@prefix rdfs: . -@prefix fuseki: . -@prefix text: . -@prefix knora-base: . - -:service_tdb_all a fuseki:Service ; - rdfs:label "TDB knora-test" ; - fuseki:dataset :text_dataset ; - fuseki:name "knora-test" ; - fuseki:serviceQuery "query" , "sparql" ; - fuseki:serviceReadGraphStore "get" ; - fuseki:serviceReadWriteGraphStore "data" ; - fuseki:serviceUpdate "update" ; - fuseki:serviceUpload "upload" . - -## --------------------------------------------------------------- -## This URI must be fixed - it's used to assemble the text dataset. - -:text_dataset rdf:type text:TextDataset ; - text:dataset :tdb_dataset_readwrite ; - text:index :indexLucene . - -# A TDB datset used for RDF storage -:tdb_dataset_readwrite a tdb:DatasetTDB ; - tdb:unionDefaultGraph true ; - tdb:location "./run/databases/knora-test" ; - # Fuseki 2.4.0 only - remove for later versions. - ja:context [ ja:cxtName "arq:optFilterPlacementBGP" ; - ja:cxtValue "true" ] . - -# Text index description -:indexLucene a text:TextIndexLucene ; - text:directory "./run/lucene/knora-test" ; - ##text:directory "mem" ; - text:entityMap :entMap . - -# Mapping in the index -# URI stored in field "uri" -# knora-base:valueHasString is mapped to field "text" -:entMap a text:EntityMap ; - text:entityField "uri" ; - text:defaultField "text" ; - text:uidField "uid" ; - text:map ( - [ text:field "text" ; text:predicate rdfs:label ] - [ text:field "text" ; text:predicate knora-base:valueHasString ] - [ text:field "text" ; text:predicate knora-base:valueHasComment ] - - ) . \ No newline at end of file diff --git a/triplestores/fuseki/run/shiro.ini b/triplestores/fuseki/run/shiro.ini deleted file mode 100644 index 595fc839d6..0000000000 --- a/triplestores/fuseki/run/shiro.ini +++ /dev/null @@ -1,37 +0,0 @@ -# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0 - -[main] -# Development -ssl.enabled = false - -plainMatcher=org.apache.shiro.authc.credential.SimpleCredentialsMatcher -#iniRealm=org.apache.shiro.realm.text.IniRealm -iniRealm.credentialsMatcher = $plainMatcher - -localhostFilter=org.apache.jena.fuseki.authz.LocalhostFilter - -[users] -# Implicitly adds "iniRealm = org.apache.shiro.realm.text.IniRealm" -admin=pw - -[roles] - -[urls] -## Control functions open to anyone -/$/status = anon -/$/ping = anon - -## and the rest are restricted to localhost. -/$/** = localhostFilter - -## If you want simple, basic authentication user/password -## on the operations, -## 1 - set a better password in [users] above. -## 2 - comment out the "/$/** = localhost" line and use: -## "/$/** = authcBasic,user[admin]" - -## or to allow any access. -##/$/** = anon - -# Everything else -/**=anon diff --git a/triplestores/fuseki/webapp/WEB-INF/web.xml b/triplestores/fuseki/webapp/WEB-INF/web.xml deleted file mode 100644 index 0b646de2c0..0000000000 --- a/triplestores/fuseki/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,289 +0,0 @@ - - - - - - Apache Jena Fuseki Server - - - - org.apache.jena.fuseki.server.FusekiServerEnvironmentInit - - - - - - org.apache.jena.fuseki.server.ShiroEnvironmentLoader - - - - - cross-origin - - org.apache.jena.fuseki.servlets.CrossOriginFilter - - - allowedOrigins - * - - - allowedMethods - GET,POST,DELETE,PUT,HEAD,OPTIONS,PATCH - - - allowedHeaders - Accept, Origin, X-Requested-With, Content-Type, Last-Modified, Authorization - - - exposedHeaders - Access-Control-Allow-Origin,Access-Control-Allow-Credentials - - - - - cross-origin - /* - - - - - ShiroFilter - org.apache.shiro.web.servlet.ShiroFilter - - - - ShiroFilter - /* - REQUEST - FORWARD - INCLUDE - ERROR - - - - shiroConfigLocations - - shiro.ini - - - - - - org.apache.jena.fuseki.server.FusekiServerListener - - - - - Fuseki - org.apache.jena.fuseki.servlets.FusekiFilter - - - - Fuseki - /* - REQUEST - FORWARD - INCLUDE - ERROR - - - - - QueryValidator - org.apache.jena.fuseki.validation.QueryValidator - - - - UpdateValidator - org.apache.jena.fuseki.validation.UpdateValidator - - - - DataValidator - org.apache.jena.fuseki.validation.DataValidator - - - - IRIValidator - org.apache.jena.fuseki.validation.IRIValidator - - - - QueryValidator - /validate/query - - - - UpdateValidator - /validate/update - - - - IRIValidator - /validate/iri - - - - DataValidator - /validate/data - - - - - - DumpServlet - org.apache.jena.fuseki.mgt.DumpServlet - - - - ServerStatusServlet - org.apache.jena.fuseki.mgt.ActionServerStatus - - - - PingServlet - org.apache.jena.fuseki.mgt.ActionPing - - - - BackupListServlet - org.apache.jena.fuseki.mgt.ActionBackupList - - - - BackupListServlet - /$/backups-list - - - - DumpServlet - /$/dump - - - - ServerStatusServlet - /$/server - - - - PingServlet - /$/ping - - - - ActionDatasets - org.apache.jena.fuseki.mgt.ActionDatasets - - - - ActionStats - org.apache.jena.fuseki.mgt.ActionStats - - - - ActionLogs - org.apache.jena.fuseki.mgt.ActionLogs - - - - ActionBackup - org.apache.jena.fuseki.mgt.ActionBackup - - - - ActionTasks - org.apache.jena.fuseki.mgt.ActionTasks - - - - - ActionSleep - org.apache.jena.fuseki.mgt.ActionSleep - - - - ActionDatasets - /$/datasets/* - - - - ActionStats - /$/stats/* - - - - ActionLogs - /$/logs - - - - ActionBackup - /$/backup/* - - - - ActionBackup - /$/backups/* - - - - ActionTasks - /$/tasks/* - - - - ActionSleep - /$/sleep/* - - - - index.html - - - - rdf - application/rdf+xml;charset=utf-8 - - - ttl - text/turtle;charset=utf-8 - - - nt - text/plain;charset=utf-8 - - - nq - text/nquads;charset=utf-8 - - - trig - application/trig;charset=utf-8 - - - diff --git a/triplestores/fuseki/webapp/admin-logs.html b/triplestores/fuseki/webapp/admin-logs.html deleted file mode 100644 index 10660e42b0..0000000000 --- a/triplestores/fuseki/webapp/admin-logs.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - Apache Jena Fuseki - - - - - - - - - - - - - - -
-
-

Server logs

-

Forthcoming feature. Show some or all of the recent log file, assuming it is in the usual place.

-
-
- - - - - \ No newline at end of file diff --git a/triplestores/fuseki/webapp/css/bootstrap-select.min.css b/triplestores/fuseki/webapp/css/bootstrap-select.min.css deleted file mode 100644 index edb090cad5..0000000000 --- a/triplestores/fuseki/webapp/css/bootstrap-select.min.css +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * bootstrap-select v1.5.4 - * http://silviomoreto.github.io/bootstrap-select/ - * - * Copyright 2013 bootstrap-select - * Licensed under the MIT license - */.bootstrap-select.btn-group:not(.input-group-btn),.bootstrap-select.btn-group[class*="span"]{float:none;display:inline-block;margin-bottom:10px;margin-left:0}.form-search .bootstrap-select.btn-group,.form-inline .bootstrap-select.btn-group,.form-horizontal .bootstrap-select.btn-group{margin-bottom:0}.bootstrap-select.form-control{margin-bottom:0;padding:0;border:0}.bootstrap-select.btn-group.pull-right,.bootstrap-select.btn-group[class*="span"].pull-right,.row-fluid .bootstrap-select.btn-group[class*="span"].pull-right{float:right}.input-append .bootstrap-select.btn-group{margin-left:-1px}.input-prepend .bootstrap-select.btn-group{margin-right:-1px}.bootstrap-select:not([class*="span"]):not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn){width:220px}.bootstrap-select{width:220px\0}.bootstrap-select.form-control:not([class*="span"]){width:100%}.bootstrap-select>.btn{width:100%;padding-right:25px}.error .bootstrap-select .btn{border:1px solid #b94a48}.bootstrap-select.show-menu-arrow.open>.btn{z-index:2051}.bootstrap-select .btn:focus{outline:thin dotted #333 !important;outline:5px auto -webkit-focus-ring-color !important;outline-offset:-2px}.bootstrap-select.btn-group .btn .filter-option{display:inline-block;overflow:hidden;width:100%;float:left;text-align:left}.bootstrap-select.btn-group .btn .caret{position:absolute;top:50%;right:12px;margin-top:-2px;vertical-align:middle}.bootstrap-select.btn-group>.disabled,.bootstrap-select.btn-group .dropdown-menu li.disabled>a{cursor:not-allowed}.bootstrap-select.btn-group>.disabled:focus{outline:none !important}.bootstrap-select.btn-group[class*="span"] .btn{width:100%}.bootstrap-select.btn-group .dropdown-menu{min-width:100%;z-index:2000;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select.btn-group .dropdown-menu.inner{position:static;border:0;padding:0;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.bootstrap-select.btn-group .dropdown-menu dt{display:block;padding:3px 20px;cursor:default}.bootstrap-select.btn-group .div-contain{overflow:hidden}.bootstrap-select.btn-group .dropdown-menu li{position:relative}.bootstrap-select.btn-group .dropdown-menu li>a.opt{position:relative;padding-left:35px}.bootstrap-select.btn-group .dropdown-menu li>a{cursor:pointer}.bootstrap-select.btn-group .dropdown-menu li>dt small{font-weight:normal}.bootstrap-select.btn-group.show-tick .dropdown-menu li.selected a i.check-mark{position:absolute;display:inline-block;right:15px;margin-top:2.5px}.bootstrap-select.btn-group .dropdown-menu li a i.check-mark{display:none}.bootstrap-select.btn-group.show-tick .dropdown-menu li a span.text{margin-right:34px}.bootstrap-select.btn-group .dropdown-menu li small{padding-left:.5em}.bootstrap-select.btn-group .dropdown-menu li:not(.disabled)>a:hover small,.bootstrap-select.btn-group .dropdown-menu li:not(.disabled)>a:focus small,.bootstrap-select.btn-group .dropdown-menu li.active:not(.disabled)>a small{color:#64b1d8;color:rgba(255,255,255,0.4)}.bootstrap-select.btn-group .dropdown-menu li>dt small{font-weight:normal}.bootstrap-select.show-menu-arrow .dropdown-toggle:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #CCC;border-bottom-color:rgba(0,0,0,0.2);position:absolute;bottom:-4px;left:9px;display:none}.bootstrap-select.show-menu-arrow .dropdown-toggle:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid white;position:absolute;bottom:-4px;left:10px;display:none}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:before{bottom:auto;top:-3px;border-top:7px solid #ccc;border-bottom:0;border-top-color:rgba(0,0,0,0.2)}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle:after{bottom:auto;top:-3px;border-top:6px solid #fff;border-bottom:0}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:before{right:12px;left:auto}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle:after{right:13px;left:auto}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:before,.bootstrap-select.show-menu-arrow.open>.dropdown-toggle:after{display:block}.bootstrap-select.btn-group .no-results{padding:3px;background:#f5f5f5;margin:0 5px}.bootstrap-select.btn-group .dropdown-menu .notify{position:absolute;bottom:5px;width:96%;margin:0 2%;min-height:26px;padding:3px 5px;background:#f5f5f5;border:1px solid #e3e3e3;box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);pointer-events:none;opacity:.9;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.mobile-device{position:absolute;top:0;left:0;display:block !important;width:100%;height:100% !important;opacity:0}.bootstrap-select.fit-width{width:auto !important}.bootstrap-select.btn-group.fit-width .btn .filter-option{position:static}.bootstrap-select.btn-group.fit-width .btn .caret{position:static;top:auto;margin-top:-1px}.control-group.error .bootstrap-select .dropdown-toggle{border-color:#b94a48}.bootstrap-select-searchbox,.bootstrap-select .bs-actionsbox{padding:4px 8px}.bootstrap-select .bs-actionsbox{float:left;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select-searchbox+.bs-actionsbox{padding:0 8px 4px}.bootstrap-select-searchbox input{margin-bottom:0}.bootstrap-select .bs-actionsbox .btn-group button{width:50%} \ No newline at end of file diff --git a/triplestores/fuseki/webapp/css/bootstrap-theme.css.map b/triplestores/fuseki/webapp/css/bootstrap-theme.css.map deleted file mode 100644 index b36fc9a497..0000000000 --- a/triplestores/fuseki/webapp/css/bootstrap-theme.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["less/theme.less","less/mixins.less"],"names":[],"mappings":"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","sourcesContent":["\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-bg, 5%); @end-color: darken(@navbar-default-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-bg; @end-color: lighten(@navbar-inverse-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n}\n\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","//\n// Mixins\n// --------------------------------------------------\n\n\n// Utilities\n// -------------------------\n\n// Clearfix\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n// contenteditable attribute is included anywhere else in the document.\n// Otherwise it causes space to appear at the top and bottom of elements\n// that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n// `:before` to contain the top-margins of child elements.\n.clearfix() {\n &:before,\n &:after {\n content: \" \"; // 1\n display: table; // 2\n }\n &:after {\n clear: both;\n }\n}\n\n// WebKit-style focus\n.tab-focus() {\n // Default\n outline: thin dotted;\n // WebKit\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n\n// Center-align a block level element\n.center-block() {\n display: block;\n margin-left: auto;\n margin-right: auto;\n}\n\n// Sizing shortcuts\n.size(@width; @height) {\n width: @width;\n height: @height;\n}\n.square(@size) {\n .size(@size; @size);\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n &::-moz-placeholder { color: @color; // Firefox\n opacity: 1; } // See https://github.com/twbs/bootstrap/pull/11526\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Text overflow\n// Requires inline-block or block for proper styling\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n// CSS image replacement\n//\n// Heads up! v3 launched with with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`. Note\n// that we cannot chain the mixins together in Less, so they are repeated.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (will be removed in v4)\n.hide-text() {\n font: ~\"0/0\" a;\n color: transparent;\n text-shadow: none;\n background-color: transparent;\n border: 0;\n}\n// New mixin to use as of v3.0.1\n.text-hide() {\n .hide-text();\n}\n\n\n\n// CSS3 PROPERTIES\n// --------------------------------------------------\n\n// Single side border-radius\n.border-top-radius(@radius) {\n border-top-right-radius: @radius;\n border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n border-bottom-right-radius: @radius;\n border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n border-bottom-left-radius: @radius;\n border-top-left-radius: @radius;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support the\n// standard `box-shadow` property.\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Transitions\n.transition(@transition) {\n -webkit-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n// Transformations\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n transform: rotate(@degrees);\n}\n.scale(@ratio; @ratio-y...) {\n -webkit-transform: scale(@ratio, @ratio-y);\n -ms-transform: scale(@ratio, @ratio-y); // IE9 only\n transform: scale(@ratio, @ratio-y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n transform: translate(@x, @y);\n}\n.skew(@x; @y) {\n -webkit-transform: skew(@x, @y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n transform: skew(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n.backface-visibility(@visibility){\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// User select\n// For selecting text on the page\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n\n// Resize anything\n.resizable(@direction) {\n resize: @direction; // Options: horizontal, vertical, both\n overflow: auto; // Safari fix\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Opacity\n.opacity(@opacity) {\n opacity: @opacity;\n // IE8 filter\n @opacity-ie: (@opacity * 100);\n filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n\n\n\n// GRADIENTS\n// --------------------------------------------------\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, color-stop(@start-color @start-percent), color-stop(@end-color @end-percent)); // Safari 5.1-6, Chrome 10+\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n\n// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n\n\n\n// Retina images\n//\n// Short retina mixin for setting background-image and -size\n\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n.img-responsive(@display: block) {\n display: @display;\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// COMPONENT MIXINS\n// --------------------------------------------------\n\n// Horizontal dividers\n// -------------------------\n// Dividers (basically an hr) within dropdowns and nav lists\n.nav-divider(@color: #e5e5e5) {\n height: 1px;\n margin: ((@line-height-computed / 2) - 1) 0;\n overflow: hidden;\n background-color: @color;\n}\n\n// Panels\n// -------------------------\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n border-color: @border;\n\n & > .panel-heading {\n color: @heading-text-color;\n background-color: @heading-bg-color;\n border-color: @heading-border;\n\n + .panel-collapse .panel-body {\n border-top-color: @border;\n }\n }\n & > .panel-footer {\n + .panel-collapse .panel-body {\n border-bottom-color: @border;\n }\n }\n}\n\n// Alerts\n// -------------------------\n.alert-variant(@background; @border; @text-color) {\n background-color: @background;\n border-color: @border;\n color: @text-color;\n\n hr {\n border-top-color: darken(@border, 5%);\n }\n .alert-link {\n color: darken(@text-color, 10%);\n }\n}\n\n// Tables\n// -------------------------\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n\n// List Groups\n// -------------------------\n.list-group-item-variant(@state; @background; @color) {\n .list-group-item-@{state} {\n color: @color;\n background-color: @background;\n\n a& {\n color: @color;\n\n .list-group-item-heading { color: inherit; }\n\n &:hover,\n &:focus {\n color: @color;\n background-color: darken(@background, 5%);\n }\n &.active,\n &.active:hover,\n &.active:focus {\n color: #fff;\n background-color: @color;\n border-color: @color;\n }\n }\n }\n}\n\n// Button variants\n// -------------------------\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n.button-variant(@color; @background; @border) {\n color: @color;\n background-color: @background;\n border-color: @border;\n\n &:hover,\n &:focus,\n &:active,\n &.active,\n .open .dropdown-toggle& {\n color: @color;\n background-color: darken(@background, 8%);\n border-color: darken(@border, 12%);\n }\n &:active,\n &.active,\n .open .dropdown-toggle& {\n background-image: none;\n }\n &.disabled,\n &[disabled],\n fieldset[disabled] & {\n &,\n &:hover,\n &:focus,\n &:active,\n &.active {\n background-color: @background;\n border-color: @border;\n }\n }\n\n .badge {\n color: @background;\n background-color: @color;\n }\n}\n\n// Button sizes\n// -------------------------\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n}\n\n// Pagination\n// -------------------------\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @border-radius) {\n > li {\n > a,\n > span {\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n }\n &:first-child {\n > a,\n > span {\n .border-left-radius(@border-radius);\n }\n }\n &:last-child {\n > a,\n > span {\n .border-right-radius(@border-radius);\n }\n }\n }\n}\n\n// Labels\n// -------------------------\n.label-variant(@color) {\n background-color: @color;\n &[href] {\n &:hover,\n &:focus {\n background-color: darken(@color, 10%);\n }\n }\n}\n\n// Contextual backgrounds\n// -------------------------\n.bg-variant(@color) {\n background-color: @color;\n a&:hover {\n background-color: darken(@color, 10%);\n }\n}\n\n// Typography\n// -------------------------\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover {\n color: darken(@color, 10%);\n }\n}\n\n// Navbar vertical align\n// -------------------------\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n.navbar-vertical-align(@element-height) {\n margin-top: ((@navbar-height - @element-height) / 2);\n margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n\n// Progress bars\n// -------------------------\n.progress-bar-variant(@color) {\n background-color: @color;\n .progress-striped & {\n #gradient > .striped();\n }\n}\n\n// Responsive utilities\n// -------------------------\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n display: block !important;\n table& { display: table; }\n tr& { display: table-row !important; }\n th&,\n td& { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n display: none !important;\n}\n\n\n// Grid System\n// -----------\n\n// Centered container element\n.container-fixed() {\n margin-right: auto;\n margin-left: auto;\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: (@gutter / -2);\n margin-right: (@gutter / -2);\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n @media (min-width: @screen-xs-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-xs-column-push(@columns) {\n @media (min-width: @screen-xs-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-xs-column-pull(@columns) {\n @media (min-width: @screen-xs-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n\n// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) when (@index = 1) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) when (@index = 1) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n\n// Form validation states\n//\n// Used in forms.less to generate the form validation CSS for warnings, errors,\n// and successes.\n\n.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {\n // Color the label and help text\n .help-block,\n .control-label,\n .radio,\n .checkbox,\n .radio-inline,\n .checkbox-inline {\n color: @text-color;\n }\n // Set the border and box shadow on specific inputs to match\n .form-control {\n border-color: @border-color;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work\n &:focus {\n border-color: darken(@border-color, 10%);\n @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);\n .box-shadow(@shadow);\n }\n }\n // Set validation states also for addons\n .input-group-addon {\n color: @text-color;\n border-color: @border-color;\n background-color: @background-color;\n }\n // Optional feedback icon\n .form-control-feedback {\n color: @text-color;\n }\n}\n\n// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `@input-focus-border` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n\n.form-control-focus(@color: @input-border-focus) {\n @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);\n &:focus {\n border-color: @color;\n outline: 0;\n .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n }\n}\n\n// Form control sizing\n//\n// Relative text size, padding, and border-radii changes for form controls. For\n// horizontal sizing, wrap controls in the predefined grid classes. ``\n// element gets special love because it's special, and that's a fact!\n\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n height: @input-height;\n padding: @padding-vertical @padding-horizontal;\n font-size: @font-size;\n line-height: @line-height;\n border-radius: @border-radius;\n\n select& {\n height: @input-height;\n line-height: @input-height;\n }\n\n textarea&,\n select[multiple]& {\n height: auto;\n }\n}\n","//\n// Variables\n// --------------------------------------------------\n\n\n//== Colors\n//\n//## Gray and brand colors for use across Bootstrap.\n\n@gray-darker: lighten(#000, 13.5%); // #222\n@gray-dark: lighten(#000, 20%); // #333\n@gray: lighten(#000, 33.5%); // #555\n@gray-light: lighten(#000, 60%); // #999\n@gray-lighter: lighten(#000, 93.5%); // #eee\n\n@brand-primary: #428bca;\n@brand-success: #5cb85c;\n@brand-info: #5bc0de;\n@brand-warning: #f0ad4e;\n@brand-danger: #d9534f;\n\n\n//== Scaffolding\n//\n// ## Settings for some of the most global styles.\n\n//** Background color for ``.\n@body-bg: #fff;\n//** Global text color on ``.\n@text-color: @gray-dark;\n\n//** Global textual link color.\n@link-color: @brand-primary;\n//** Link hover color set via `darken()` function.\n@link-hover-color: darken(@link-color, 15%);\n\n\n//== Typography\n//\n//## Font, line-height, and color for body text, headings, and more.\n\n@font-family-sans-serif: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n@font-family-serif: Georgia, \"Times New Roman\", Times, serif;\n//** Default monospace fonts for ``, ``, and `
`.\n@font-family-monospace:   Menlo, Monaco, Consolas, \"Courier New\", monospace;\n@font-family-base:        @font-family-sans-serif;\n\n@font-size-base:          14px;\n@font-size-large:         ceil((@font-size-base * 1.25)); // ~18px\n@font-size-small:         ceil((@font-size-base * 0.85)); // ~12px\n\n@font-size-h1:            floor((@font-size-base * 2.6)); // ~36px\n@font-size-h2:            floor((@font-size-base * 2.15)); // ~30px\n@font-size-h3:            ceil((@font-size-base * 1.7)); // ~24px\n@font-size-h4:            ceil((@font-size-base * 1.25)); // ~18px\n@font-size-h5:            @font-size-base;\n@font-size-h6:            ceil((@font-size-base * 0.85)); // ~12px\n\n//** Unit-less `line-height` for use in components like buttons.\n@line-height-base:        1.428571429; // 20/14\n//** Computed \"line-height\" (`font-size` * `line-height`) for use with `margin`, `padding`, etc.\n@line-height-computed:    floor((@font-size-base * @line-height-base)); // ~20px\n\n//** By default, this inherits from the ``.\n@headings-font-family:    inherit;\n@headings-font-weight:    500;\n@headings-line-height:    1.1;\n@headings-color:          inherit;\n\n\n//-- Iconography\n//\n//## Specify custom locations of the include Glyphicons icon font. Useful for those including Bootstrap via Bower.\n\n@icon-font-path:          \"../fonts/\";\n@icon-font-name:          \"glyphicons-halflings-regular\";\n@icon-font-svg-id:        \"glyphicons_halflingsregular\";\n\n//== Components\n//\n//## Define common padding and border radius sizes and more. Values based on 14px text and 1.428 line-height (~20px to start).\n\n@padding-base-vertical:     6px;\n@padding-base-horizontal:   12px;\n\n@padding-large-vertical:    10px;\n@padding-large-horizontal:  16px;\n\n@padding-small-vertical:    5px;\n@padding-small-horizontal:  10px;\n\n@padding-xs-vertical:       1px;\n@padding-xs-horizontal:     5px;\n\n@line-height-large:         1.33;\n@line-height-small:         1.5;\n\n@border-radius-base:        4px;\n@border-radius-large:       6px;\n@border-radius-small:       3px;\n\n//** Global color for active items (e.g., navs or dropdowns).\n@component-active-color:    #fff;\n//** Global background color for active items (e.g., navs or dropdowns).\n@component-active-bg:       @brand-primary;\n\n//** Width of the `border` for generating carets that indicator dropdowns.\n@caret-width-base:          4px;\n//** Carets increase slightly in size for larger components.\n@caret-width-large:         5px;\n\n\n//== Tables\n//\n//## Customizes the `.table` component with basic values, each used across all table variations.\n\n//** Padding for ``s and ``s.\n@table-cell-padding:            8px;\n//** Padding for cells in `.table-condensed`.\n@table-condensed-cell-padding:  5px;\n\n//** Default background color used for all tables.\n@table-bg:                      transparent;\n//** Background color used for `.table-striped`.\n@table-bg-accent:               #f9f9f9;\n//** Background color used for `.table-hover`.\n@table-bg-hover:                #f5f5f5;\n@table-bg-active:               @table-bg-hover;\n\n//** Border color for table and cell borders.\n@table-border-color:            #ddd;\n\n\n//== Buttons\n//\n//## For each of Bootstrap's buttons, define text, background and border color.\n\n@btn-font-weight:                normal;\n\n@btn-default-color:              #333;\n@btn-default-bg:                 #fff;\n@btn-default-border:             #ccc;\n\n@btn-primary-color:              #fff;\n@btn-primary-bg:                 @brand-primary;\n@btn-primary-border:             darken(@btn-primary-bg, 5%);\n\n@btn-success-color:              #fff;\n@btn-success-bg:                 @brand-success;\n@btn-success-border:             darken(@btn-success-bg, 5%);\n\n@btn-info-color:                 #fff;\n@btn-info-bg:                    @brand-info;\n@btn-info-border:                darken(@btn-info-bg, 5%);\n\n@btn-warning-color:              #fff;\n@btn-warning-bg:                 @brand-warning;\n@btn-warning-border:             darken(@btn-warning-bg, 5%);\n\n@btn-danger-color:               #fff;\n@btn-danger-bg:                  @brand-danger;\n@btn-danger-border:              darken(@btn-danger-bg, 5%);\n\n@btn-link-disabled-color:        @gray-light;\n\n\n//== Forms\n//\n//##\n\n//** `` background color\n@input-bg:                       #fff;\n//** `` background color\n@input-bg-disabled:              @gray-lighter;\n\n//** Text color for ``s\n@input-color:                    @gray;\n//** `` border color\n@input-border:                   #ccc;\n//** `` border radius\n@input-border-radius:            @border-radius-base;\n//** Border color for inputs on focus\n@input-border-focus:             #66afe9;\n\n//** Placeholder text color\n@input-color-placeholder:        @gray-light;\n\n//** Default `.form-control` height\n@input-height-base:              (@line-height-computed + (@padding-base-vertical * 2) + 2);\n//** Large `.form-control` height\n@input-height-large:             (ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2);\n//** Small `.form-control` height\n@input-height-small:             (floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2);\n\n@legend-color:                   @gray-dark;\n@legend-border-color:            #e5e5e5;\n\n//** Background color for textual input addons\n@input-group-addon-bg:           @gray-lighter;\n//** Border color for textual input addons\n@input-group-addon-border-color: @input-border;\n\n\n//== Dropdowns\n//\n//## Dropdown menu container and contents.\n\n//** Background for the dropdown menu.\n@dropdown-bg:                    #fff;\n//** Dropdown menu `border-color`.\n@dropdown-border:                rgba(0,0,0,.15);\n//** Dropdown menu `border-color` **for IE8**.\n@dropdown-fallback-border:       #ccc;\n//** Divider color for between dropdown items.\n@dropdown-divider-bg:            #e5e5e5;\n\n//** Dropdown link text color.\n@dropdown-link-color:            @gray-dark;\n//** Hover color for dropdown links.\n@dropdown-link-hover-color:      darken(@gray-dark, 5%);\n//** Hover background for dropdown links.\n@dropdown-link-hover-bg:         #f5f5f5;\n\n//** Active dropdown menu item text color.\n@dropdown-link-active-color:     @component-active-color;\n//** Active dropdown menu item background color.\n@dropdown-link-active-bg:        @component-active-bg;\n\n//** Disabled dropdown menu item background color.\n@dropdown-link-disabled-color:   @gray-light;\n\n//** Text color for headers within dropdown menus.\n@dropdown-header-color:          @gray-light;\n\n// Note: Deprecated @dropdown-caret-color as of v3.1.0\n@dropdown-caret-color:           #000;\n\n\n//-- Z-index master list\n//\n// Warning: Avoid customizing these values. They're used for a bird's eye view\n// of components dependent on the z-axis and are designed to all work together.\n//\n// Note: These variables are not generated into the Customizer.\n\n@zindex-navbar:            1000;\n@zindex-dropdown:          1000;\n@zindex-popover:           1010;\n@zindex-tooltip:           1030;\n@zindex-navbar-fixed:      1030;\n@zindex-modal-background:  1040;\n@zindex-modal:             1050;\n\n\n//== Media queries breakpoints\n//\n//## Define the breakpoints at which your layout will change, adapting to different screen sizes.\n\n// Extra small screen / phone\n// Note: Deprecated @screen-xs and @screen-phone as of v3.0.1\n@screen-xs:                  480px;\n@screen-xs-min:              @screen-xs;\n@screen-phone:               @screen-xs-min;\n\n// Small screen / tablet\n// Note: Deprecated @screen-sm and @screen-tablet as of v3.0.1\n@screen-sm:                  768px;\n@screen-sm-min:              @screen-sm;\n@screen-tablet:              @screen-sm-min;\n\n// Medium screen / desktop\n// Note: Deprecated @screen-md and @screen-desktop as of v3.0.1\n@screen-md:                  992px;\n@screen-md-min:              @screen-md;\n@screen-desktop:             @screen-md-min;\n\n// Large screen / wide desktop\n// Note: Deprecated @screen-lg and @screen-lg-desktop as of v3.0.1\n@screen-lg:                  1200px;\n@screen-lg-min:              @screen-lg;\n@screen-lg-desktop:          @screen-lg-min;\n\n// So media queries don't overlap when required, provide a maximum\n@screen-xs-max:              (@screen-sm-min - 1);\n@screen-sm-max:              (@screen-md-min - 1);\n@screen-md-max:              (@screen-lg-min - 1);\n\n\n//== Grid system\n//\n//## Define your custom responsive grid.\n\n//** Number of columns in the grid.\n@grid-columns:              12;\n//** Padding between columns. Gets divided in half for the left and right.\n@grid-gutter-width:         30px;\n// Navbar collapse\n//** Point at which the navbar becomes uncollapsed.\n@grid-float-breakpoint:     @screen-sm-min;\n//** Point at which the navbar begins collapsing.\n@grid-float-breakpoint-max: (@grid-float-breakpoint - 1);\n\n\n//== Container sizes\n//\n//## Define the maximum width of `.container` for different screen sizes.\n\n// Small screen / tablet\n@container-tablet:             ((720px + @grid-gutter-width));\n//** For `@screen-sm-min` and up.\n@container-sm:                 @container-tablet;\n\n// Medium screen / desktop\n@container-desktop:            ((940px + @grid-gutter-width));\n//** For `@screen-md-min` and up.\n@container-md:                 @container-desktop;\n\n// Large screen / wide desktop\n@container-large-desktop:      ((1140px + @grid-gutter-width));\n//** For `@screen-lg-min` and up.\n@container-lg:                 @container-large-desktop;\n\n\n//== Navbar\n//\n//##\n\n// Basics of a navbar\n@navbar-height:                    50px;\n@navbar-margin-bottom:             @line-height-computed;\n@navbar-border-radius:             @border-radius-base;\n@navbar-padding-horizontal:        floor((@grid-gutter-width / 2));\n@navbar-padding-vertical:          ((@navbar-height - @line-height-computed) / 2);\n@navbar-collapse-max-height:       340px;\n\n@navbar-default-color:             #777;\n@navbar-default-bg:                #f8f8f8;\n@navbar-default-border:            darken(@navbar-default-bg, 6.5%);\n\n// Navbar links\n@navbar-default-link-color:                #777;\n@navbar-default-link-hover-color:          #333;\n@navbar-default-link-hover-bg:             transparent;\n@navbar-default-link-active-color:         #555;\n@navbar-default-link-active-bg:            darken(@navbar-default-bg, 6.5%);\n@navbar-default-link-disabled-color:       #ccc;\n@navbar-default-link-disabled-bg:          transparent;\n\n// Navbar brand label\n@navbar-default-brand-color:               @navbar-default-link-color;\n@navbar-default-brand-hover-color:         darken(@navbar-default-brand-color, 10%);\n@navbar-default-brand-hover-bg:            transparent;\n\n// Navbar toggle\n@navbar-default-toggle-hover-bg:           #ddd;\n@navbar-default-toggle-icon-bar-bg:        #888;\n@navbar-default-toggle-border-color:       #ddd;\n\n\n// Inverted navbar\n// Reset inverted navbar basics\n@navbar-inverse-color:                      @gray-light;\n@navbar-inverse-bg:                         #222;\n@navbar-inverse-border:                     darken(@navbar-inverse-bg, 10%);\n\n// Inverted navbar links\n@navbar-inverse-link-color:                 @gray-light;\n@navbar-inverse-link-hover-color:           #fff;\n@navbar-inverse-link-hover-bg:              transparent;\n@navbar-inverse-link-active-color:          @navbar-inverse-link-hover-color;\n@navbar-inverse-link-active-bg:             darken(@navbar-inverse-bg, 10%);\n@navbar-inverse-link-disabled-color:        #444;\n@navbar-inverse-link-disabled-bg:           transparent;\n\n// Inverted navbar brand label\n@navbar-inverse-brand-color:                @navbar-inverse-link-color;\n@navbar-inverse-brand-hover-color:          #fff;\n@navbar-inverse-brand-hover-bg:             transparent;\n\n// Inverted navbar toggle\n@navbar-inverse-toggle-hover-bg:            #333;\n@navbar-inverse-toggle-icon-bar-bg:         #fff;\n@navbar-inverse-toggle-border-color:        #333;\n\n\n//== Navs\n//\n//##\n\n//=== Shared nav styles\n@nav-link-padding:                          10px 15px;\n@nav-link-hover-bg:                         @gray-lighter;\n\n@nav-disabled-link-color:                   @gray-light;\n@nav-disabled-link-hover-color:             @gray-light;\n\n@nav-open-link-hover-color:                 #fff;\n\n//== Tabs\n@nav-tabs-border-color:                     #ddd;\n\n@nav-tabs-link-hover-border-color:          @gray-lighter;\n\n@nav-tabs-active-link-hover-bg:             @body-bg;\n@nav-tabs-active-link-hover-color:          @gray;\n@nav-tabs-active-link-hover-border-color:   #ddd;\n\n@nav-tabs-justified-link-border-color:            #ddd;\n@nav-tabs-justified-active-link-border-color:     @body-bg;\n\n//== Pills\n@nav-pills-border-radius:                   @border-radius-base;\n@nav-pills-active-link-hover-bg:            @component-active-bg;\n@nav-pills-active-link-hover-color:         @component-active-color;\n\n\n//== Pagination\n//\n//##\n\n@pagination-color:                     @link-color;\n@pagination-bg:                        #fff;\n@pagination-border:                    #ddd;\n\n@pagination-hover-color:               @link-hover-color;\n@pagination-hover-bg:                  @gray-lighter;\n@pagination-hover-border:              #ddd;\n\n@pagination-active-color:              #fff;\n@pagination-active-bg:                 @brand-primary;\n@pagination-active-border:             @brand-primary;\n\n@pagination-disabled-color:            @gray-light;\n@pagination-disabled-bg:               #fff;\n@pagination-disabled-border:           #ddd;\n\n\n//== Pager\n//\n//##\n\n@pager-bg:                             @pagination-bg;\n@pager-border:                         @pagination-border;\n@pager-border-radius:                  15px;\n\n@pager-hover-bg:                       @pagination-hover-bg;\n\n@pager-active-bg:                      @pagination-active-bg;\n@pager-active-color:                   @pagination-active-color;\n\n@pager-disabled-color:                 @pagination-disabled-color;\n\n\n//== Jumbotron\n//\n//##\n\n@jumbotron-padding:              30px;\n@jumbotron-color:                inherit;\n@jumbotron-bg:                   @gray-lighter;\n@jumbotron-heading-color:        inherit;\n@jumbotron-font-size:            ceil((@font-size-base * 1.5));\n\n\n//== Form states and alerts\n//\n//## Define colors for form feedback states and, by default, alerts.\n\n@state-success-text:             #3c763d;\n@state-success-bg:               #dff0d8;\n@state-success-border:           darken(spin(@state-success-bg, -10), 5%);\n\n@state-info-text:                #31708f;\n@state-info-bg:                  #d9edf7;\n@state-info-border:              darken(spin(@state-info-bg, -10), 7%);\n\n@state-warning-text:             #8a6d3b;\n@state-warning-bg:               #fcf8e3;\n@state-warning-border:           darken(spin(@state-warning-bg, -10), 5%);\n\n@state-danger-text:              #a94442;\n@state-danger-bg:                #f2dede;\n@state-danger-border:            darken(spin(@state-danger-bg, -10), 5%);\n\n\n//== Tooltips\n//\n//##\n\n//** Tooltip max width\n@tooltip-max-width:           200px;\n//** Tooltip text color\n@tooltip-color:               #fff;\n//** Tooltip background color\n@tooltip-bg:                  #000;\n@tooltip-opacity:             .9;\n\n//** Tooltip arrow width\n@tooltip-arrow-width:         5px;\n//** Tooltip arrow color\n@tooltip-arrow-color:         @tooltip-bg;\n\n\n//== Popovers\n//\n//##\n\n//** Popover body background color\n@popover-bg:                          #fff;\n//** Popover maximum width\n@popover-max-width:                   276px;\n//** Popover border color\n@popover-border-color:                rgba(0,0,0,.2);\n//** Popover fallback border color\n@popover-fallback-border-color:       #ccc;\n\n//** Popover title background color\n@popover-title-bg:                    darken(@popover-bg, 3%);\n\n//** Popover arrow width\n@popover-arrow-width:                 10px;\n//** Popover arrow color\n@popover-arrow-color:                 #fff;\n\n//** Popover outer arrow width\n@popover-arrow-outer-width:           (@popover-arrow-width + 1);\n//** Popover outer arrow color\n@popover-arrow-outer-color:           fadein(@popover-border-color, 5%);\n//** Popover outer arrow fallback color\n@popover-arrow-outer-fallback-color:  darken(@popover-fallback-border-color, 20%);\n\n\n//== Labels\n//\n//##\n\n//** Default label background color\n@label-default-bg:            @gray-light;\n//** Primary label background color\n@label-primary-bg:            @brand-primary;\n//** Success label background color\n@label-success-bg:            @brand-success;\n//** Info label background color\n@label-info-bg:               @brand-info;\n//** Warning label background color\n@label-warning-bg:            @brand-warning;\n//** Danger label background color\n@label-danger-bg:             @brand-danger;\n\n//** Default label text color\n@label-color:                 #fff;\n//** Default text color of a linked label\n@label-link-hover-color:      #fff;\n\n\n//== Modals\n//\n//##\n\n//** Padding applied to the modal body\n@modal-inner-padding:         20px;\n\n//** Padding applied to the modal title\n@modal-title-padding:         15px;\n//** Modal title line-height\n@modal-title-line-height:     @line-height-base;\n\n//** Background color of modal content area\n@modal-content-bg:                             #fff;\n//** Modal content border color\n@modal-content-border-color:                   rgba(0,0,0,.2);\n//** Modal content border color **for IE8**\n@modal-content-fallback-border-color:          #999;\n\n//** Modal backdrop background color\n@modal-backdrop-bg:           #000;\n//** Modal backdrop opacity\n@modal-backdrop-opacity:      .5;\n//** Modal header border color\n@modal-header-border-color:   #e5e5e5;\n//** Modal footer border color\n@modal-footer-border-color:   @modal-header-border-color;\n\n@modal-lg:                    900px;\n@modal-md:                    600px;\n@modal-sm:                    300px;\n\n\n//== Alerts\n//\n//## Define alert colors, border radius, and padding.\n\n@alert-padding:               15px;\n@alert-border-radius:         @border-radius-base;\n@alert-link-font-weight:      bold;\n\n@alert-success-bg:            @state-success-bg;\n@alert-success-text:          @state-success-text;\n@alert-success-border:        @state-success-border;\n\n@alert-info-bg:               @state-info-bg;\n@alert-info-text:             @state-info-text;\n@alert-info-border:           @state-info-border;\n\n@alert-warning-bg:            @state-warning-bg;\n@alert-warning-text:          @state-warning-text;\n@alert-warning-border:        @state-warning-border;\n\n@alert-danger-bg:             @state-danger-bg;\n@alert-danger-text:           @state-danger-text;\n@alert-danger-border:         @state-danger-border;\n\n\n//== Progress bars\n//\n//##\n\n//** Background color of the whole progress component\n@progress-bg:                 #f5f5f5;\n//** Progress bar text color\n@progress-bar-color:          #fff;\n\n//** Default progress bar color\n@progress-bar-bg:             @brand-primary;\n//** Success progress bar color\n@progress-bar-success-bg:     @brand-success;\n//** Warning progress bar color\n@progress-bar-warning-bg:     @brand-warning;\n//** Danger progress bar color\n@progress-bar-danger-bg:      @brand-danger;\n//** Info progress bar color\n@progress-bar-info-bg:        @brand-info;\n\n\n//== List group\n//\n//##\n\n//** Background color on `.list-group-item`\n@list-group-bg:                 #fff;\n//** `.list-group-item` border color\n@list-group-border:             #ddd;\n//** List group border radius\n@list-group-border-radius:      @border-radius-base;\n\n//** Background color of single list elements on hover\n@list-group-hover-bg:           #f5f5f5;\n//** Text color of active list elements\n@list-group-active-color:       @component-active-color;\n//** Background color of active list elements\n@list-group-active-bg:          @component-active-bg;\n//** Border color of active list elements\n@list-group-active-border:      @list-group-active-bg;\n@list-group-active-text-color:  lighten(@list-group-active-bg, 40%);\n\n@list-group-link-color:         #555;\n@list-group-link-heading-color: #333;\n\n\n//== Panels\n//\n//##\n\n@panel-bg:                    #fff;\n@panel-body-padding:          15px;\n@panel-border-radius:         @border-radius-base;\n\n//** Border color for elements within panels\n@panel-inner-border:          #ddd;\n@panel-footer-bg:             #f5f5f5;\n\n@panel-default-text:          @gray-dark;\n@panel-default-border:        #ddd;\n@panel-default-heading-bg:    #f5f5f5;\n\n@panel-primary-text:          #fff;\n@panel-primary-border:        @brand-primary;\n@panel-primary-heading-bg:    @brand-primary;\n\n@panel-success-text:          @state-success-text;\n@panel-success-border:        @state-success-border;\n@panel-success-heading-bg:    @state-success-bg;\n\n@panel-info-text:             @state-info-text;\n@panel-info-border:           @state-info-border;\n@panel-info-heading-bg:       @state-info-bg;\n\n@panel-warning-text:          @state-warning-text;\n@panel-warning-border:        @state-warning-border;\n@panel-warning-heading-bg:    @state-warning-bg;\n\n@panel-danger-text:           @state-danger-text;\n@panel-danger-border:         @state-danger-border;\n@panel-danger-heading-bg:     @state-danger-bg;\n\n\n//== Thumbnails\n//\n//##\n\n//** Padding around the thumbnail image\n@thumbnail-padding:           4px;\n//** Thumbnail background color\n@thumbnail-bg:                @body-bg;\n//** Thumbnail border color\n@thumbnail-border:            #ddd;\n//** Thumbnail border radius\n@thumbnail-border-radius:     @border-radius-base;\n\n//** Custom text color for thumbnail captions\n@thumbnail-caption-color:     @text-color;\n//** Padding around the thumbnail caption\n@thumbnail-caption-padding:   9px;\n\n\n//== Wells\n//\n//##\n\n@well-bg:                     #f5f5f5;\n@well-border:                 darken(@well-bg, 7%);\n\n\n//== Badges\n//\n//##\n\n@badge-color:                 #fff;\n//** Linked badge text color on hover\n@badge-link-hover-color:      #fff;\n@badge-bg:                    @gray-light;\n\n//** Badge text color in active nav link\n@badge-active-color:          @link-color;\n//** Badge background color in active nav link\n@badge-active-bg:             #fff;\n\n@badge-font-weight:           bold;\n@badge-line-height:           1;\n@badge-border-radius:         10px;\n\n\n//== Breadcrumbs\n//\n//##\n\n@breadcrumb-padding-vertical:   8px;\n@breadcrumb-padding-horizontal: 15px;\n//** Breadcrumb background color\n@breadcrumb-bg:                 #f5f5f5;\n//** Breadcrumb text color\n@breadcrumb-color:              #ccc;\n//** Text color of current page in the breadcrumb\n@breadcrumb-active-color:       @gray-light;\n//** Textual separator for between breadcrumb elements\n@breadcrumb-separator:          \"/\";\n\n\n//== Carousel\n//\n//##\n\n@carousel-text-shadow:                        0 1px 2px rgba(0,0,0,.6);\n\n@carousel-control-color:                      #fff;\n@carousel-control-width:                      15%;\n@carousel-control-opacity:                    .5;\n@carousel-control-font-size:                  20px;\n\n@carousel-indicator-active-bg:                #fff;\n@carousel-indicator-border-color:             #fff;\n\n@carousel-caption-color:                      #fff;\n\n\n//== Close\n//\n//##\n\n@close-font-weight:           bold;\n@close-color:                 #000;\n@close-text-shadow:           0 1px 0 #fff;\n\n\n//== Code\n//\n//##\n\n@code-color:                  #c7254e;\n@code-bg:                     #f9f2f4;\n\n@kbd-color:                   #fff;\n@kbd-bg:                      #333;\n\n@pre-bg:                      #f5f5f5;\n@pre-color:                   @gray-dark;\n@pre-border-color:            #ccc;\n@pre-scrollable-max-height:   340px;\n\n\n//== Type\n//\n//##\n\n//** Text muted color\n@text-muted:                  @gray-light;\n//** Abbreviations and acronyms border color\n@abbr-border-color:           @gray-light;\n//** Headings small color\n@headings-small-color:        @gray-light;\n//** Blockquote small color\n@blockquote-small-color:      @gray-light;\n//** Blockquote font size\n@blockquote-font-size:        (@font-size-base * 1.25);\n//** Blockquote border color\n@blockquote-border-color:     @gray-lighter;\n//** Page header border color\n@page-header-border-color:    @gray-lighter;\n\n\n//== Miscellaneous\n//\n//##\n\n//** Horizontal line color.\n@hr-border:                   @gray-lighter;\n\n//** Horizontal offset for forms and lists.\n@component-offset-horizontal: 180px;\n","//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n  display: block;\n  padding: @thumbnail-padding;\n  margin-bottom: @line-height-computed;\n  line-height: @line-height-base;\n  background-color: @thumbnail-bg;\n  border: 1px solid @thumbnail-border;\n  border-radius: @thumbnail-border-radius;\n  .transition(all .2s ease-in-out);\n\n  > img,\n  a > img {\n    &:extend(.img-responsive);\n    margin-left: auto;\n    margin-right: auto;\n  }\n\n  // Add a hover state for linked versions only\n  a&:hover,\n  a&:focus,\n  a&.active {\n    border-color: @link-color;\n  }\n\n  // Image captions\n  .caption {\n    padding: @thumbnail-caption-padding;\n    color: @thumbnail-caption-color;\n  }\n}\n","//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n  position: relative;\n}\n\n.carousel-inner {\n  position: relative;\n  overflow: hidden;\n  width: 100%;\n\n  > .item {\n    display: none;\n    position: relative;\n    .transition(.6s ease-in-out left);\n\n    // Account for jankitude on images\n    > img,\n    > a > img {\n      &:extend(.img-responsive);\n      line-height: 1;\n    }\n  }\n\n  > .active,\n  > .next,\n  > .prev { display: block; }\n\n  > .active {\n    left: 0;\n  }\n\n  > .next,\n  > .prev {\n    position: absolute;\n    top: 0;\n    width: 100%;\n  }\n\n  > .next {\n    left: 100%;\n  }\n  > .prev {\n    left: -100%;\n  }\n  > .next.left,\n  > .prev.right {\n    left: 0;\n  }\n\n  > .active.left {\n    left: -100%;\n  }\n  > .active.right {\n    left: 100%;\n  }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  width: @carousel-control-width;\n  .opacity(@carousel-control-opacity);\n  font-size: @carousel-control-font-size;\n  color: @carousel-control-color;\n  text-align: center;\n  text-shadow: @carousel-text-shadow;\n  // We can't have this transition here because WebKit cancels the carousel\n  // animation if you trip this while in the middle of another animation.\n\n  // Set gradients for backgrounds\n  &.left {\n    #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n  }\n  &.right {\n    left: auto;\n    right: 0;\n    #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n  }\n\n  // Hover/focus state\n  &:hover,\n  &:focus {\n    outline: none;\n    color: @carousel-control-color;\n    text-decoration: none;\n    .opacity(.9);\n  }\n\n  // Toggles\n  .icon-prev,\n  .icon-next,\n  .glyphicon-chevron-left,\n  .glyphicon-chevron-right {\n    position: absolute;\n    top: 50%;\n    z-index: 5;\n    display: inline-block;\n  }\n  .icon-prev,\n  .glyphicon-chevron-left {\n    left: 50%;\n  }\n  .icon-next,\n  .glyphicon-chevron-right {\n    right: 50%;\n  }\n  .icon-prev,\n  .icon-next {\n    width:  20px;\n    height: 20px;\n    margin-top: -10px;\n    margin-left: -10px;\n    font-family: serif;\n  }\n\n  .icon-prev {\n    &:before {\n      content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n    }\n  }\n  .icon-next {\n    &:before {\n      content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n    }\n  }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  margin-left: -30%;\n  padding-left: 0;\n  list-style: none;\n  text-align: center;\n\n  li {\n    display: inline-block;\n    width:  10px;\n    height: 10px;\n    margin: 1px;\n    text-indent: -999px;\n    border: 1px solid @carousel-indicator-border-color;\n    border-radius: 10px;\n    cursor: pointer;\n\n    // IE8-9 hack for event handling\n    //\n    // Internet Explorer 8-9 does not support clicks on elements without a set\n    // `background-color`. We cannot use `filter` since that's not viewed as a\n    // background color by the browser. Thus, a hack is needed.\n    //\n    // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n    // set alpha transparency for the best results possible.\n    background-color: #000 \\9; // IE8\n    background-color: rgba(0,0,0,0); // IE9\n  }\n  .active {\n    margin: 0;\n    width:  12px;\n    height: 12px;\n    background-color: @carousel-indicator-active-bg;\n  }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n  position: absolute;\n  left: 15%;\n  right: 15%;\n  bottom: 20px;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: @carousel-caption-color;\n  text-align: center;\n  text-shadow: @carousel-text-shadow;\n  & .btn {\n    text-shadow: none; // No shadow for button elements in carousel-caption\n  }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-sm-min) {\n\n  // Scale up the controls a smidge\n  .carousel-control {\n    .glyphicon-chevron-left,\n    .glyphicon-chevron-right,\n    .icon-prev,\n    .icon-next {\n      width: 30px;\n      height: 30px;\n      margin-top: -15px;\n      margin-left: -15px;\n      font-size: 30px;\n    }\n  }\n\n  // Show and left align the captions\n  .carousel-caption {\n    left: 20%;\n    right: 20%;\n    padding-bottom: 30px;\n  }\n\n  // Move up the indicators\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n  font-family: @headings-font-family;\n  font-weight: @headings-font-weight;\n  line-height: @headings-line-height;\n  color: @headings-color;\n\n  small,\n  .small {\n    font-weight: normal;\n    line-height: 1;\n    color: @headings-small-color;\n  }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n  margin-top: @line-height-computed;\n  margin-bottom: (@line-height-computed / 2);\n\n  small,\n  .small {\n    font-size: 65%;\n  }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n  margin-top: (@line-height-computed / 2);\n  margin-bottom: (@line-height-computed / 2);\n\n  small,\n  .small {\n    font-size: 75%;\n  }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n  margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n  margin-bottom: @line-height-computed;\n  font-size: floor((@font-size-base * 1.15));\n  font-weight: 200;\n  line-height: 1.4;\n\n  @media (min-width: @screen-sm-min) {\n    font-size: (@font-size-base * 1.5);\n  }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: 14px base font * 85% = about 12px\nsmall,\n.small  { font-size: 85%; }\n\n// Undo browser default styling\ncite    { font-style: normal; }\n\n// Alignment\n.text-left           { text-align: left; }\n.text-right          { text-align: right; }\n.text-center         { text-align: center; }\n.text-justify        { text-align: justify; }\n\n// Contextual colors\n.text-muted {\n  color: @text-muted;\n}\n.text-primary {\n  .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n  .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n  .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n  .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n  .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n  // Given the contrast here, this is the only class to have its color inverted\n  // automatically.\n  color: #fff;\n  .bg-variant(@brand-primary);\n}\n.bg-success {\n  .bg-variant(@state-success-bg);\n}\n.bg-info {\n  .bg-variant(@state-info-bg);\n}\n.bg-warning {\n  .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n  .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n  padding-bottom: ((@line-height-computed / 2) - 1);\n  margin: (@line-height-computed * 2) 0 @line-height-computed;\n  border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// --------------------------------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n  margin-top: 0;\n  margin-bottom: (@line-height-computed / 2);\n  ul,\n  ol {\n    margin-bottom: 0;\n  }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n  .list-unstyled();\n  margin-left: -5px;\n\n  > li {\n    display: inline-block;\n    padding-left: 5px;\n    padding-right: 5px;\n  }\n}\n\n// Description Lists\ndl {\n  margin-top: 0; // Remove browser default\n  margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n  line-height: @line-height-base;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n@media (min-width: @grid-float-breakpoint) {\n  .dl-horizontal {\n    dt {\n      float: left;\n      width: (@component-offset-horizontal - 20);\n      clear: left;\n      text-align: right;\n      .text-overflow();\n    }\n    dd {\n      margin-left: @component-offset-horizontal;\n      &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n    }\n  }\n}\n\n// MISC\n// ----\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\n\n// Blockquotes\nblockquote {\n  padding: (@line-height-computed / 2) @line-height-computed;\n  margin: 0 0 @line-height-computed;\n  font-size: @blockquote-font-size;\n  border-left: 5px solid @blockquote-border-color;\n\n  p,\n  ul,\n  ol {\n    &:last-child {\n      margin-bottom: 0;\n    }\n  }\n\n  // Note: Deprecated small and .small as of v3.1.0\n  // Context: https://github.com/twbs/bootstrap/issues/11660\n  footer,\n  small,\n  .small {\n    display: block;\n    font-size: 80%; // back to default font-size\n    line-height: @line-height-base;\n    color: @blockquote-small-color;\n\n    &:before {\n      content: '\\2014 \\00A0'; // em dash, nbsp\n    }\n  }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  border-right: 5px solid @blockquote-border-color;\n  border-left: 0;\n  text-align: right;\n\n  // Account for citation\n  footer,\n  small,\n  .small {\n    &:before { content: ''; }\n    &:after {\n      content: '\\00A0 \\2014'; // nbsp, em dash\n    }\n  }\n}\n\n// Quotes\nblockquote:before,\nblockquote:after {\n  content: \"\";\n}\n\n// Addresses\naddress {\n  margin-bottom: @line-height-computed;\n  font-style: normal;\n  line-height: @line-height-base;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n  font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: @code-color;\n  background-color: @code-bg;\n  white-space: nowrap;\n  border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: @kbd-color;\n  background-color: @kbd-bg;\n  border-radius: @border-radius-small;\n  box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n}\n\n// Blocks of code\npre {\n  display: block;\n  padding: ((@line-height-computed - 1) / 2);\n  margin: 0 0 (@line-height-computed / 2);\n  font-size: (@font-size-base - 1); // 14px to 13px\n  line-height: @line-height-base;\n  word-break: break-all;\n  word-wrap: break-word;\n  color: @pre-color;\n  background-color: @pre-bg;\n  border: 1px solid @pre-border-color;\n  border-radius: @border-radius-base;\n\n  // Account for some code outputs that place code tags in pre tags\n  code {\n    padding: 0;\n    font-size: inherit;\n    color: inherit;\n    white-space: pre-wrap;\n    background-color: transparent;\n    border-radius: 0;\n  }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n  max-height: @pre-scrollable-max-height;\n  overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n  .container-fixed();\n\n  @media (min-width: @screen-sm-min) {\n    width: @container-sm;\n  }\n  @media (min-width: @screen-md-min) {\n    width: @container-md;\n  }\n  @media (min-width: @screen-lg-min) {\n    width: @container-lg;\n  }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n  .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n  .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n  .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n  .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n  .make-grid(lg);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n  max-width: 100%;\n  background-color: @table-bg;\n}\nth {\n  text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n  width: 100%;\n  margin-bottom: @line-height-computed;\n  // Cells\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        padding: @table-cell-padding;\n        line-height: @line-height-base;\n        vertical-align: top;\n        border-top: 1px solid @table-border-color;\n      }\n    }\n  }\n  // Bottom align for column headings\n  > thead > tr > th {\n    vertical-align: bottom;\n    border-bottom: 2px solid @table-border-color;\n  }\n  // Remove top border from thead by default\n  > caption + thead,\n  > colgroup + thead,\n  > thead:first-child {\n    > tr:first-child {\n      > th,\n      > td {\n        border-top: 0;\n      }\n    }\n  }\n  // Account for multiple tbody instances\n  > tbody + tbody {\n    border-top: 2px solid @table-border-color;\n  }\n\n  // Nesting\n  .table {\n    background-color: @body-bg;\n  }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        padding: @table-condensed-cell-padding;\n      }\n    }\n  }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n  border: 1px solid @table-border-color;\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        border: 1px solid @table-border-color;\n      }\n    }\n  }\n  > thead > tr {\n    > th,\n    > td {\n      border-bottom-width: 2px;\n    }\n  }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n  > tbody > tr:nth-child(odd) {\n    > td,\n    > th {\n      background-color: @table-bg-accent;\n    }\n  }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n  > tbody > tr:hover {\n    > td,\n    > th {\n      background-color: @table-bg-hover;\n    }\n  }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n  position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n  float: none;\n  display: table-column;\n}\ntable {\n  td,\n  th {\n    &[class*=\"col-\"] {\n      position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n      float: none;\n      display: table-cell;\n    }\n  }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n@media (max-width: @screen-xs-max) {\n  .table-responsive {\n    width: 100%;\n    margin-bottom: (@line-height-computed * 0.75);\n    overflow-y: hidden;\n    overflow-x: scroll;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid @table-border-color;\n    -webkit-overflow-scrolling: touch;\n\n    // Tighten up spacing\n    > .table {\n      margin-bottom: 0;\n\n      // Ensure the content doesn't wrap\n      > thead,\n      > tbody,\n      > tfoot {\n        > tr {\n          > th,\n          > td {\n            white-space: nowrap;\n          }\n        }\n      }\n    }\n\n    // Special overrides for the bordered tables\n    > .table-bordered {\n      border: 0;\n\n      // Nuke the appropriate borders so that the parent can handle them\n      > thead,\n      > tbody,\n      > tfoot {\n        > tr {\n          > th:first-child,\n          > td:first-child {\n            border-left: 0;\n          }\n          > th:last-child,\n          > td:last-child {\n            border-right: 0;\n          }\n        }\n      }\n\n      // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n      // chances are there will be only one `tr` in a `thead` and that would\n      // remove the border altogether.\n      > tbody,\n      > tfoot {\n        > tr:last-child {\n          > th,\n          > td {\n            border-bottom: 0;\n          }\n        }\n      }\n\n    }\n  }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n  padding: 0;\n  margin: 0;\n  border: 0;\n  // Chrome and Firefox set a `min-width: -webkit-min-content;` on fieldsets,\n  // so we reset that to ensure it behaves more like a standard block element.\n  // See https://github.com/twbs/bootstrap/issues/12359.\n  min-width: 0;\n}\n\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: @line-height-computed;\n  font-size: (@font-size-base * 1.5);\n  line-height: inherit;\n  color: @legend-color;\n  border: 0;\n  border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n  display: inline-block;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n  .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9; /* IE8-9 */\n  line-height: normal;\n}\n\n// Set the height of file controls to match text inputs\ninput[type=\"file\"] {\n  display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n  display: block;\n  width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n  height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  .tab-focus();\n}\n\n// Adjust output element\noutput {\n  display: block;\n  padding-top: (@padding-base-vertical + 1);\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n  display: block;\n  width: 100%;\n  height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n  padding: @padding-base-vertical @padding-base-horizontal;\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @input-color;\n  background-color: @input-bg;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid @input-border;\n  border-radius: @input-border-radius;\n  .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n  .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n  // Customize the `:focus` state to imitate native WebKit styles.\n  .form-control-focus();\n\n  // Placeholder\n  .placeholder();\n\n  // Disabled and read-only inputs\n  //\n  // HTML5 says that controls under a fieldset > legend:first-child won't be\n  // disabled if the fieldset is disabled. Due to implementation difficulty, we\n  // don't honor that edge case; we style them as disabled anyway.\n  &[disabled],\n  &[readonly],\n  fieldset[disabled] & {\n    cursor: not-allowed;\n    background-color: @input-bg-disabled;\n    opacity: 1; // iOS fix for unreadable disabled content\n  }\n\n  // Reset height for `textarea`s\n  textarea& {\n    height: auto;\n  }\n}\n\n\n// Search inputs in iOS\n//\n// This overrides the extra rounded corners on search inputs in iOS so that our\n// `.form-control` class can properly style them. Note that this cannot simply\n// be added to `.form-control` as it's not specific enough. For details, see\n// https://github.com/twbs/bootstrap/issues/11586.\n\ninput[type=\"search\"] {\n  -webkit-appearance: none;\n}\n\n\n// Special styles for iOS date input\n//\n// In Mobile Safari, date inputs require a pixel line-height that matches the\n// given height of the input.\n\ninput[type=\"date\"] {\n  line-height: @input-height-base;\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n  margin-bottom: 15px;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n  display: block;\n  min-height: @line-height-computed; // clear the floating input if there is no label text\n  margin-top: 10px;\n  margin-bottom: 10px;\n  padding-left: 20px;\n  label {\n    display: inline;\n    font-weight: normal;\n    cursor: pointer;\n  }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  float: left;\n  margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  vertical-align: middle;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n//\n// Note: Neither radios nor checkboxes can be readonly.\ninput[type=\"radio\"],\ninput[type=\"checkbox\"],\n.radio,\n.radio-inline,\n.checkbox,\n.checkbox-inline {\n  &[disabled],\n  fieldset[disabled] & {\n    cursor: not-allowed;\n  }\n}\n\n\n// Form control sizing\n//\n// Build on `.form-control` with modifier classes to decrease or increase the\n// height and font-size of form controls.\n\n.input-sm {\n  .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n\n.input-lg {\n  .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n\n// Form control feedback states\n//\n// Apply contextual and semantic states to individual form controls.\n\n.has-feedback {\n  // Enable absolute positioning\n  position: relative;\n\n  // Ensure icons don't overlap text\n  .form-control {\n    padding-right: (@input-height-base * 1.25);\n  }\n\n  // Feedback icon (requires .glyphicon classes)\n  .form-control-feedback {\n    position: absolute;\n    top: (@line-height-computed + 5); // Height of the `label` and its margin\n    right: 0;\n    display: block;\n    width: @input-height-base;\n    height: @input-height-base;\n    line-height: @input-height-base;\n    text-align: center;\n  }\n}\n\n// Feedback states\n.has-success {\n  .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);\n}\n.has-warning {\n  .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);\n}\n.has-error {\n  .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);\n}\n\n\n// Static form control text\n//\n// Apply class to a `p` element to make any string of text align with labels in\n// a horizontal form layout.\n\n.form-control-static {\n  margin-bottom: 0; // Remove default margin from `p`\n}\n\n\n// Help text\n//\n// Apply to any element you wish to create light text for placement immediately\n// below a form control. Use for general help, formatting, or instructional text.\n\n.help-block {\n  display: block; // account for any element using help-block\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: lighten(@text-color, 25%); // lighten the text some for contrast\n}\n\n\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n//\n// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.\n\n.form-inline {\n\n  // Kick in the inline\n  @media (min-width: @screen-sm-min) {\n    // Inline-block all the things for \"inline\"\n    .form-group {\n      display: inline-block;\n      margin-bottom: 0;\n      vertical-align: middle;\n    }\n\n    // In navbar-form, allow folks to *not* use `.form-group`\n    .form-control {\n      display: inline-block;\n      width: auto; // Prevent labels from stacking above inputs in `.form-group`\n      vertical-align: middle;\n    }\n    // Input groups need that 100% width though\n    .input-group > .form-control {\n      width: 100%;\n    }\n\n    .control-label {\n      margin-bottom: 0;\n      vertical-align: middle;\n    }\n\n    // Remove default margin on radios/checkboxes that were used for stacking, and\n    // then undo the floating of radios and checkboxes to match (which also avoids\n    // a bug in WebKit: https://github.com/twbs/bootstrap/issues/1969).\n    .radio,\n    .checkbox {\n      display: inline-block;\n      margin-top: 0;\n      margin-bottom: 0;\n      padding-left: 0;\n      vertical-align: middle;\n    }\n    .radio input[type=\"radio\"],\n    .checkbox input[type=\"checkbox\"] {\n      float: none;\n      margin-left: 0;\n    }\n\n    // Validation states\n    //\n    // Reposition the icon because it's now within a grid column and columns have\n    // `position: relative;` on them. Also accounts for the grid gutter padding.\n    .has-feedback .form-control-feedback {\n      top: 0;\n    }\n  }\n}\n\n\n// Horizontal forms\n//\n// Horizontal forms are built on grid classes and allow you to create forms with\n// labels on the left and inputs on the right.\n\n.form-horizontal {\n\n  // Consistent vertical alignment of labels, radios, and checkboxes\n  .control-label,\n  .radio,\n  .checkbox,\n  .radio-inline,\n  .checkbox-inline {\n    margin-top: 0;\n    margin-bottom: 0;\n    padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n  }\n  // Account for padding we're adding to ensure the alignment and of help text\n  // and other content below items\n  .radio,\n  .checkbox {\n    min-height: (@line-height-computed + (@padding-base-vertical + 1));\n  }\n\n  // Make form groups behave like rows\n  .form-group {\n    .make-row();\n  }\n\n  .form-control-static {\n    padding-top: (@padding-base-vertical + 1);\n  }\n\n  // Only right align form labels here when the columns stop stacking\n  @media (min-width: @screen-sm-min) {\n    .control-label {\n      text-align: right;\n    }\n  }\n\n  // Validation states\n  //\n  // Reposition the icon because it's now within a grid column and columns have\n  // `position: relative;` on them. Also accounts for the grid gutter padding.\n  .has-feedback .form-control-feedback {\n    top: 0;\n    right: (@grid-gutter-width / 2);\n  }\n}\n","//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n  display: inline-block;\n  margin-bottom: 0; // For input.btn\n  font-weight: @btn-font-weight;\n  text-align: center;\n  vertical-align: middle;\n  cursor: pointer;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid transparent;\n  white-space: nowrap;\n  .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base);\n  .user-select(none);\n\n  &,\n  &:active,\n  &.active {\n    &:focus {\n      .tab-focus();\n    }\n  }\n\n  &:hover,\n  &:focus {\n    color: @btn-default-color;\n    text-decoration: none;\n  }\n\n  &:active,\n  &.active {\n    outline: 0;\n    background-image: none;\n    .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n  }\n\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    cursor: not-allowed;\n    pointer-events: none; // Future-proof disabling of clicks\n    .opacity(.65);\n    .box-shadow(none);\n  }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n  .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n  .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Success appears as green\n.btn-success {\n  .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n  .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n// Warning appears as orange\n.btn-warning {\n  .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n  .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n  color: @link-color;\n  font-weight: normal;\n  cursor: pointer;\n  border-radius: 0;\n\n  &,\n  &:active,\n  &[disabled],\n  fieldset[disabled] & {\n    background-color: transparent;\n    .box-shadow(none);\n  }\n  &,\n  &:hover,\n  &:focus,\n  &:active {\n    border-color: transparent;\n  }\n  &:hover,\n  &:focus {\n    color: @link-hover-color;\n    text-decoration: underline;\n    background-color: transparent;\n  }\n  &[disabled],\n  fieldset[disabled] & {\n    &:hover,\n    &:focus {\n      color: @btn-link-disabled-color;\n      text-decoration: none;\n    }\n  }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n  // line-height: ensure even-numbered height of button next to large input\n  .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n.btn-sm {\n  // line-height: ensure proper height of button next to small input\n  .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n.btn-xs {\n  .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n  display: block;\n  width: 100%;\n  padding-left: 0;\n  padding-right: 0;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n  &.btn-block {\n    width: 100%;\n  }\n}\n","//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle; // match .btn alignment given font-size hack above\n  > .btn {\n    position: relative;\n    float: left;\n    // Bring the \"active\" button to the front\n    &:hover,\n    &:focus,\n    &:active,\n    &.active {\n      z-index: 2;\n    }\n    &:focus {\n      // Remove focus outline when dropdown JS adds it after closing the menu\n      outline: none;\n    }\n  }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n  .btn + .btn,\n  .btn + .btn-group,\n  .btn-group + .btn,\n  .btn-group + .btn-group {\n    margin-left: -1px;\n  }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n  margin-left: -5px; // Offset the first child's margin\n  &:extend(.clearfix all);\n\n  .btn-group,\n  .input-group {\n    float: left;\n  }\n  > .btn,\n  > .btn-group,\n  > .input-group {\n    margin-left: 5px;\n  }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n  margin-left: 0;\n  &:not(:last-child):not(.dropdown-toggle) {\n    .border-right-radius(0);\n  }\n}\n// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n  float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group > .btn-group:first-child {\n  > .btn:last-child,\n  > .dropdown-toggle {\n    .border-right-radius(0);\n  }\n}\n.btn-group > .btn-group:last-child > .btn:first-child {\n  .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { &:extend(.btn-xs); }\n.btn-group-sm > .btn { &:extend(.btn-sm); }\n.btn-group-lg > .btn { &:extend(.btn-lg); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n  padding-left: 8px;\n  padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-left: 12px;\n  padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n  .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n  // Show no shadow for `.btn-link` since it has no other button styles.\n  &.btn-link {\n    .box-shadow(none);\n  }\n}\n\n\n// Reposition the caret\n.btn .caret {\n  margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n  border-width: @caret-width-large @caret-width-large 0;\n  border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n  border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n  > .btn,\n  > .btn-group,\n  > .btn-group > .btn {\n    display: block;\n    float: none;\n    width: 100%;\n    max-width: 100%;\n  }\n\n  // Clear floats so dropdown menus can be properly placed\n  > .btn-group {\n    &:extend(.clearfix all);\n    > .btn {\n      float: none;\n    }\n  }\n\n  > .btn + .btn,\n  > .btn + .btn-group,\n  > .btn-group + .btn,\n  > .btn-group + .btn-group {\n    margin-top: -1px;\n    margin-left: 0;\n  }\n}\n\n.btn-group-vertical > .btn {\n  &:not(:first-child):not(:last-child) {\n    border-radius: 0;\n  }\n  &:first-child:not(:last-child) {\n    border-top-right-radius: @border-radius-base;\n    .border-bottom-radius(0);\n  }\n  &:last-child:not(:first-child) {\n    border-bottom-left-radius: @border-radius-base;\n    .border-top-radius(0);\n  }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) {\n  > .btn:last-child,\n  > .dropdown-toggle {\n    .border-bottom-radius(0);\n  }\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  .border-top-radius(0);\n}\n\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n  > .btn,\n  > .btn-group {\n    float: none;\n    display: table-cell;\n    width: 1%;\n  }\n  > .btn-group .btn {\n    width: 100%;\n  }\n}\n\n\n// Checkbox and radio options\n[data-toggle=\"buttons\"] > .btn > input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn > input[type=\"checkbox\"] {\n  display: none;\n}\n","//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twitter/bootstrap/pull/3552.\n\n.fade {\n  opacity: 0;\n  .transition(opacity .15s linear);\n  &.in {\n    opacity: 1;\n  }\n}\n\n.collapse {\n  display: none;\n  &.in {\n    display: block;\n  }\n}\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  .transition(height .35s ease);\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n//  Star\n\n// Import the fonts\n@font-face {\n  font-family: 'Glyphicons Halflings';\n  src: ~\"url('@{icon-font-path}@{icon-font-name}.eot')\";\n  src: ~\"url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype')\",\n       ~\"url('@{icon-font-path}@{icon-font-name}.woff') format('woff')\",\n       ~\"url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype')\",\n       ~\"url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg')\";\n}\n\n// Catchall baseclass\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk               { &:before { content: \"\\2a\"; } }\n.glyphicon-plus                   { &:before { content: \"\\2b\"; } }\n.glyphicon-euro                   { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus                  { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud                  { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope               { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil                 { &:before { content: \"\\270f\"; } }\n.glyphicon-glass                  { &:before { content: \"\\e001\"; } }\n.glyphicon-music                  { &:before { content: \"\\e002\"; } }\n.glyphicon-search                 { &:before { content: \"\\e003\"; } }\n.glyphicon-heart                  { &:before { content: \"\\e005\"; } }\n.glyphicon-star                   { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty             { &:before { content: \"\\e007\"; } }\n.glyphicon-user                   { &:before { content: \"\\e008\"; } }\n.glyphicon-film                   { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large               { &:before { content: \"\\e010\"; } }\n.glyphicon-th                     { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list                { &:before { content: \"\\e012\"; } }\n.glyphicon-ok                     { &:before { content: \"\\e013\"; } }\n.glyphicon-remove                 { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in                { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out               { &:before { content: \"\\e016\"; } }\n.glyphicon-off                    { &:before { content: \"\\e017\"; } }\n.glyphicon-signal                 { &:before { content: \"\\e018\"; } }\n.glyphicon-cog                    { &:before { content: \"\\e019\"; } }\n.glyphicon-trash                  { &:before { content: \"\\e020\"; } }\n.glyphicon-home                   { &:before { content: \"\\e021\"; } }\n.glyphicon-file                   { &:before { content: \"\\e022\"; } }\n.glyphicon-time                   { &:before { content: \"\\e023\"; } }\n.glyphicon-road                   { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt           { &:before { content: \"\\e025\"; } }\n.glyphicon-download               { &:before { content: \"\\e026\"; } }\n.glyphicon-upload                 { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox                  { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle            { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat                 { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh                { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt               { &:before { content: \"\\e032\"; } }\n.glyphicon-lock                   { &:before { content: \"\\e033\"; } }\n.glyphicon-flag                   { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones             { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off             { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down            { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up              { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode                 { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode                { &:before { content: \"\\e040\"; } }\n.glyphicon-tag                    { &:before { content: \"\\e041\"; } }\n.glyphicon-tags                   { &:before { content: \"\\e042\"; } }\n.glyphicon-book                   { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark               { &:before { content: \"\\e044\"; } }\n.glyphicon-print                  { &:before { content: \"\\e045\"; } }\n.glyphicon-camera                 { &:before { content: \"\\e046\"; } }\n.glyphicon-font                   { &:before { content: \"\\e047\"; } }\n.glyphicon-bold                   { &:before { content: \"\\e048\"; } }\n.glyphicon-italic                 { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height            { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width             { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left             { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center           { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right            { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify          { &:before { content: \"\\e055\"; } }\n.glyphicon-list                   { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left            { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right           { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video         { &:before { content: \"\\e059\"; } }\n.glyphicon-picture                { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker             { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust                 { &:before { content: \"\\e063\"; } }\n.glyphicon-tint                   { &:before { content: \"\\e064\"; } }\n.glyphicon-edit                   { &:before { content: \"\\e065\"; } }\n.glyphicon-share                  { &:before { content: \"\\e066\"; } }\n.glyphicon-check                  { &:before { content: \"\\e067\"; } }\n.glyphicon-move                   { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward          { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward          { &:before { content: \"\\e070\"; } }\n.glyphicon-backward               { &:before { content: \"\\e071\"; } }\n.glyphicon-play                   { &:before { content: \"\\e072\"; } }\n.glyphicon-pause                  { &:before { content: \"\\e073\"; } }\n.glyphicon-stop                   { &:before { content: \"\\e074\"; } }\n.glyphicon-forward                { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward           { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward           { &:before { content: \"\\e077\"; } }\n.glyphicon-eject                  { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left           { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right          { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign              { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign             { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign            { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign                { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign          { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign              { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot             { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle          { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle              { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle             { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left             { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right            { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up               { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down             { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt              { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full            { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small           { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign       { &:before { content: \"\\e101\"; } }\n.glyphicon-gift                   { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf                   { &:before { content: \"\\e103\"; } }\n.glyphicon-fire                   { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open               { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close              { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign           { &:before { content: \"\\e107\"; } }\n.glyphicon-plane                  { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar               { &:before { content: \"\\e109\"; } }\n.glyphicon-random                 { &:before { content: \"\\e110\"; } }\n.glyphicon-comment                { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet                 { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up             { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down           { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet                { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart          { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close           { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open            { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical        { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal      { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd                    { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn               { &:before { content: \"\\e122\"; } }\n.glyphicon-bell                   { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate            { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up              { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down            { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right             { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left              { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up                { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down              { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right     { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left      { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up        { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down      { &:before { content: \"\\e134\"; } }\n.glyphicon-globe                  { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench                 { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks                  { &:before { content: \"\\e137\"; } }\n.glyphicon-filter                 { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase              { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen             { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard              { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip              { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty            { &:before { content: \"\\e143\"; } }\n.glyphicon-link                   { &:before { content: \"\\e144\"; } }\n.glyphicon-phone                  { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin                { &:before { content: \"\\e146\"; } }\n.glyphicon-usd                    { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp                    { &:before { content: \"\\e149\"; } }\n.glyphicon-sort                   { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet       { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt   { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order          { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt      { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes     { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked              { &:before { content: \"\\e157\"; } }\n.glyphicon-expand                 { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down          { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up            { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in                 { &:before { content: \"\\e161\"; } }\n.glyphicon-flash                  { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out                { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window             { &:before { content: \"\\e164\"; } }\n.glyphicon-record                 { &:before { content: \"\\e165\"; } }\n.glyphicon-save                   { &:before { content: \"\\e166\"; } }\n.glyphicon-open                   { &:before { content: \"\\e167\"; } }\n.glyphicon-saved                  { &:before { content: \"\\e168\"; } }\n.glyphicon-import                 { &:before { content: \"\\e169\"; } }\n.glyphicon-export                 { &:before { content: \"\\e170\"; } }\n.glyphicon-send                   { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk            { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved           { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove          { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save            { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open            { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card            { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer               { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery                { &:before { content: \"\\e179\"; } }\n.glyphicon-header                 { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed             { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone               { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt              { &:before { content: \"\\e183\"; } }\n.glyphicon-tower                  { &:before { content: \"\\e184\"; } }\n.glyphicon-stats                  { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video               { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video               { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles              { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo           { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby            { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1              { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1              { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1              { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark         { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark      { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download         { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload           { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer           { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous         { &:before { content: \"\\e200\"; } }\n","//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top:   @caret-width-base solid;\n  border-right: @caret-width-base solid transparent;\n  border-left:  @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropdown {\n  position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n  outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: @zindex-dropdown;\n  display: none; // none by default, but block on \"open\" of the menu\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0; // override default ul\n  list-style: none;\n  font-size: @font-size-base;\n  background-color: @dropdown-bg;\n  border: 1px solid @dropdown-fallback-border; // IE8 fallback\n  border: 1px solid @dropdown-border;\n  border-radius: @border-radius-base;\n  .box-shadow(0 6px 12px rgba(0,0,0,.175));\n  background-clip: padding-box;\n\n  // Aligns the dropdown menu to right\n  //\n  // Deprecated as of 3.1.0 in favor of `.dropdown-menu-[dir]`\n  &.pull-right {\n    right: 0;\n    left: auto;\n  }\n\n  // Dividers (basically an hr) within the dropdown\n  .divider {\n    .nav-divider(@dropdown-divider-bg);\n  }\n\n  // Links within the dropdown menu\n  > li > a {\n    display: block;\n    padding: 3px 20px;\n    clear: both;\n    font-weight: normal;\n    line-height: @line-height-base;\n    color: @dropdown-link-color;\n    white-space: nowrap; // prevent links from randomly breaking onto new lines\n  }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    color: @dropdown-link-hover-color;\n    background-color: @dropdown-link-hover-bg;\n  }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n  &,\n  &:hover,\n  &:focus {\n    color: @dropdown-link-active-color;\n    text-decoration: none;\n    outline: 0;\n    background-color: @dropdown-link-active-bg;\n  }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n  &,\n  &:hover,\n  &:focus {\n    color: @dropdown-link-disabled-color;\n  }\n}\n// Nuke hover/focus effects\n.dropdown-menu > .disabled > a {\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    background-color: transparent;\n    background-image: none; // Remove CSS gradient\n    .reset-filter();\n    cursor: not-allowed;\n  }\n}\n\n// Open state for the dropdown\n.open {\n  // Show the menu\n  > .dropdown-menu {\n    display: block;\n  }\n\n  // Remove the outline when :focus is triggered\n  > a {\n    outline: 0;\n  }\n}\n\n// Menu positioning\n//\n// Add extra class to `.dropdown-menu` to flip the alignment of the dropdown\n// menu with the parent.\n.dropdown-menu-right {\n  left: auto; // Reset the default from `.dropdown-menu`\n  right: 0;\n}\n// With v3, we enabled auto-flipping if you have a dropdown within a right\n// aligned nav component. To enable the undoing of that, we provide an override\n// to restore the default dropdown menu alignment.\n//\n// This is only for left-aligning a dropdown menu within a `.navbar-right` or\n// `.pull-right` nav component.\n.dropdown-menu-left {\n  left: 0;\n  right: auto;\n}\n\n// Dropdown section headers\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: @font-size-small;\n  line-height: @line-height-base;\n  color: @dropdown-header-color;\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n  position: fixed;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  top: 0;\n  z-index: (@zindex-dropdown - 10);\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n  // Reverse the caret\n  .caret {\n    border-top: 0;\n    border-bottom: @caret-width-base solid;\n    content: \"\";\n  }\n  // Different positioning for bottom up menu\n  .dropdown-menu {\n    top: auto;\n    bottom: 100%;\n    margin-bottom: 1px;\n  }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n  .navbar-right {\n    .dropdown-menu {\n      .dropdown-menu-right();\n    }\n    // Necessary for overrides of the default right aligned menu.\n    // Will remove come v4 in all likelihood.\n    .dropdown-menu-left {\n      .dropdown-menu-left();\n    }\n  }\n}\n\n","//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n  position: relative; // For dropdowns\n  display: table;\n  border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n  // Undo padding and float of grid classes\n  &[class*=\"col-\"] {\n    float: none;\n    padding-left: 0;\n    padding-right: 0;\n  }\n\n  .form-control {\n    // Ensure that the input is always above the *appended* addon button for\n    // proper border colors.\n    position: relative;\n    z-index: 2;\n\n    // IE9 fubars the placeholder attribute in text inputs and the arrows on\n    // select elements in input groups. To fix it, we float the input. Details:\n    // https://github.com/twbs/bootstrap/issues/11561#issuecomment-28936855\n    float: left;\n\n    width: 100%;\n    margin-bottom: 0;\n  }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn { .input-lg(); }\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn { .input-sm(); }\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n\n  &:not(:first-child):not(:last-child) {\n    border-radius: 0;\n  }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n  padding: @padding-base-vertical @padding-base-horizontal;\n  font-size: @font-size-base;\n  font-weight: normal;\n  line-height: 1;\n  color: @input-color;\n  text-align: center;\n  background-color: @input-group-addon-bg;\n  border: 1px solid @input-group-addon-border-color;\n  border-radius: @border-radius-base;\n\n  // Sizing\n  &.input-sm {\n    padding: @padding-small-vertical @padding-small-horizontal;\n    font-size: @font-size-small;\n    border-radius: @border-radius-small;\n  }\n  &.input-lg {\n    padding: @padding-large-vertical @padding-large-horizontal;\n    font-size: @font-size-large;\n    border-radius: @border-radius-large;\n  }\n\n  // Nuke default margins from checkboxes and radios to vertically center within.\n  input[type=\"radio\"],\n  input[type=\"checkbox\"] {\n    margin-top: 0;\n  }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n  .border-right-radius(0);\n}\n.input-group-addon:first-child {\n  border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n  .border-left-radius(0);\n}\n.input-group-addon:last-child {\n  border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n  position: relative;\n  // Jankily prevent input button groups from wrapping with `white-space` and\n  // `font-size` in combination with `inline-block` on buttons.\n  font-size: 0;\n  white-space: nowrap;\n\n  // Negative margin for spacing, position for bringing hovered/focused/actived\n  // element above the siblings.\n  > .btn {\n    position: relative;\n    + .btn {\n      margin-left: -1px;\n    }\n    // Bring the \"active\" button to the front\n    &:hover,\n    &:focus,\n    &:active {\n      z-index: 2;\n    }\n  }\n\n  // Negative margin to only have a 1px border between the two\n  &:first-child {\n    > .btn,\n    > .btn-group {\n      margin-right: -1px;\n    }\n  }\n  &:last-child {\n    > .btn,\n    > .btn-group {\n      margin-left: -1px;\n    }\n  }\n}\n","//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n  margin-bottom: 0;\n  padding-left: 0; // Override default ul/ol\n  list-style: none;\n  &:extend(.clearfix all);\n\n  > li {\n    position: relative;\n    display: block;\n\n    > a {\n      position: relative;\n      display: block;\n      padding: @nav-link-padding;\n      &:hover,\n      &:focus {\n        text-decoration: none;\n        background-color: @nav-link-hover-bg;\n      }\n    }\n\n    // Disabled state sets text to gray and nukes hover/tab effects\n    &.disabled > a {\n      color: @nav-disabled-link-color;\n\n      &:hover,\n      &:focus {\n        color: @nav-disabled-link-hover-color;\n        text-decoration: none;\n        background-color: transparent;\n        cursor: not-allowed;\n      }\n    }\n  }\n\n  // Open dropdowns\n  .open > a {\n    &,\n    &:hover,\n    &:focus {\n      background-color: @nav-link-hover-bg;\n      border-color: @link-color;\n    }\n  }\n\n  // Nav dividers (deprecated with v3.0.1)\n  //\n  // This should have been removed in v3 with the dropping of `.nav-list`, but\n  // we missed it. We don't currently support this anywhere, but in the interest\n  // of maintaining backward compatibility in case you use it, it's deprecated.\n  .nav-divider {\n    .nav-divider();\n  }\n\n  // Prevent IE8 from misplacing imgs\n  //\n  // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n  > li > a > img {\n    max-width: none;\n  }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n  border-bottom: 1px solid @nav-tabs-border-color;\n  > li {\n    float: left;\n    // Make the list-items overlay the bottom border\n    margin-bottom: -1px;\n\n    // Actual tabs (as links)\n    > a {\n      margin-right: 2px;\n      line-height: @line-height-base;\n      border: 1px solid transparent;\n      border-radius: @border-radius-base @border-radius-base 0 0;\n      &:hover {\n        border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n      }\n    }\n\n    // Active state, and its :hover to override normal :hover\n    &.active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @nav-tabs-active-link-hover-color;\n        background-color: @nav-tabs-active-link-hover-bg;\n        border: 1px solid @nav-tabs-active-link-hover-border-color;\n        border-bottom-color: transparent;\n        cursor: default;\n      }\n    }\n  }\n  // pulling this in mainly for less shorthand\n  &.nav-justified {\n    .nav-justified();\n    .nav-tabs-justified();\n  }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n  > li {\n    float: left;\n\n    // Links rendered as pills\n    > a {\n      border-radius: @nav-pills-border-radius;\n    }\n    + li {\n      margin-left: 2px;\n    }\n\n    // Active state\n    &.active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @nav-pills-active-link-hover-color;\n        background-color: @nav-pills-active-link-hover-bg;\n      }\n    }\n  }\n}\n\n\n// Stacked pills\n.nav-stacked {\n  > li {\n    float: none;\n    + li {\n      margin-top: 2px;\n      margin-left: 0; // no need for this gap between nav items\n    }\n  }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n  width: 100%;\n\n  > li {\n    float: none;\n     > a {\n      text-align: center;\n      margin-bottom: 5px;\n    }\n  }\n\n  > .dropdown .dropdown-menu {\n    top: auto;\n    left: auto;\n  }\n\n  @media (min-width: @screen-sm-min) {\n    > li {\n      display: table-cell;\n      width: 1%;\n      > a {\n        margin-bottom: 0;\n      }\n    }\n  }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n  border-bottom: 0;\n\n  > li > a {\n    // Override margin from .nav-tabs\n    margin-right: 0;\n    border-radius: @border-radius-base;\n  }\n\n  > .active > a,\n  > .active > a:hover,\n  > .active > a:focus {\n    border: 1px solid @nav-tabs-justified-link-border-color;\n  }\n\n  @media (min-width: @screen-sm-min) {\n    > li > a {\n      border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n      border-radius: @border-radius-base @border-radius-base 0 0;\n    }\n    > .active > a,\n    > .active > a:hover,\n    > .active > a:focus {\n      border-bottom-color: @nav-tabs-justified-active-link-border-color;\n    }\n  }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n  > .tab-pane {\n    display: none;\n  }\n  > .active {\n    display: block;\n  }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n  // make dropdown border overlap tab border\n  margin-top: -1px;\n  // Remove the top rounded corners here since there is a hard edge above the menu\n  .border-top-radius(0);\n}\n","//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n  position: relative;\n  min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n  margin-bottom: @navbar-margin-bottom;\n  border: 1px solid transparent;\n\n  // Prevent floats from breaking the navbar\n  &:extend(.clearfix all);\n\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: @navbar-border-radius;\n  }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n  &:extend(.clearfix all);\n\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n  }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n  max-height: @navbar-collapse-max-height;\n  overflow-x: visible;\n  padding-right: @navbar-padding-horizontal;\n  padding-left:  @navbar-padding-horizontal;\n  border-top: 1px solid transparent;\n  box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n  &:extend(.clearfix all);\n  -webkit-overflow-scrolling: touch;\n\n  &.in {\n    overflow-y: auto;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    width: auto;\n    border-top: 0;\n    box-shadow: none;\n\n    &.collapse {\n      display: block !important;\n      height: auto !important;\n      padding-bottom: 0; // Override default setting\n      overflow: visible !important;\n    }\n\n    &.in {\n      overflow-y: visible;\n    }\n\n    // Undo the collapse side padding for navbars with containers to ensure\n    // alignment of right-aligned contents.\n    .navbar-fixed-top &,\n    .navbar-static-top &,\n    .navbar-fixed-bottom & {\n      padding-left: 0;\n      padding-right: 0;\n    }\n  }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container,\n.container-fluid {\n  > .navbar-header,\n  > .navbar-collapse {\n    margin-right: -@navbar-padding-horizontal;\n    margin-left:  -@navbar-padding-horizontal;\n\n    @media (min-width: @grid-float-breakpoint) {\n      margin-right: 0;\n      margin-left:  0;\n    }\n  }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n  z-index: @zindex-navbar;\n  border-width: 0 0 1px;\n\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: 0;\n  }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: @zindex-navbar-fixed;\n\n  // Undo the rounded corners\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0; // override .navbar defaults\n  border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n  float: left;\n  padding: @navbar-padding-vertical @navbar-padding-horizontal;\n  font-size: @font-size-large;\n  line-height: @line-height-computed;\n  height: @navbar-height;\n\n  &:hover,\n  &:focus {\n    text-decoration: none;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    .navbar > .container &,\n    .navbar > .container-fluid & {\n      margin-left: -@navbar-padding-horizontal;\n    }\n  }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n  position: relative;\n  float: right;\n  margin-right: @navbar-padding-horizontal;\n  padding: 9px 10px;\n  .navbar-vertical-align(34px);\n  background-color: transparent;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid transparent;\n  border-radius: @border-radius-base;\n\n  // We remove the `outline` here, but later compensate by attaching `:hover`\n  // styles to `:focus`.\n  &:focus {\n    outline: none;\n  }\n\n  // Bars\n  .icon-bar {\n    display: block;\n    width: 22px;\n    height: 2px;\n    border-radius: 1px;\n  }\n  .icon-bar + .icon-bar {\n    margin-top: 4px;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    display: none;\n  }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with its own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n  margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n  > li > a {\n    padding-top:    10px;\n    padding-bottom: 10px;\n    line-height: @line-height-computed;\n  }\n\n  @media (max-width: @grid-float-breakpoint-max) {\n    // Dropdowns get custom display when collapsed\n    .open .dropdown-menu {\n      position: static;\n      float: none;\n      width: auto;\n      margin-top: 0;\n      background-color: transparent;\n      border: 0;\n      box-shadow: none;\n      > li > a,\n      .dropdown-header {\n        padding: 5px 15px 5px 25px;\n      }\n      > li > a {\n        line-height: @line-height-computed;\n        &:hover,\n        &:focus {\n          background-image: none;\n        }\n      }\n    }\n  }\n\n  // Uncollapse the nav\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n    margin: 0;\n\n    > li {\n      float: left;\n      > a {\n        padding-top:    @navbar-padding-vertical;\n        padding-bottom: @navbar-padding-vertical;\n      }\n    }\n\n    &.navbar-right:last-child {\n      margin-right: -@navbar-padding-horizontal;\n    }\n  }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n\n@media (min-width: @grid-float-breakpoint) {\n  .navbar-left  { .pull-left(); }\n  .navbar-right { .pull-right(); }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n  margin-left: -@navbar-padding-horizontal;\n  margin-right: -@navbar-padding-horizontal;\n  padding: 10px @navbar-padding-horizontal;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n  .box-shadow(@shadow);\n\n  // Mixin behavior for optimum display\n  .form-inline();\n\n  .form-group {\n    @media (max-width: @grid-float-breakpoint-max) {\n      margin-bottom: 5px;\n    }\n  }\n\n  // Vertically center in expanded, horizontal navbar\n  .navbar-vertical-align(@input-height-base);\n\n  // Undo 100% width for pull classes\n  @media (min-width: @grid-float-breakpoint) {\n    width: auto;\n    border: 0;\n    margin-left: 0;\n    margin-right: 0;\n    padding-top: 0;\n    padding-bottom: 0;\n    .box-shadow(none);\n\n    // Outdent the form if last child to line up with content down the page\n    &.navbar-right:last-child {\n      margin-right: -@navbar-padding-horizontal;\n    }\n  }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  .border-bottom-radius(0);\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n  .navbar-vertical-align(@input-height-base);\n\n  &.btn-sm {\n    .navbar-vertical-align(@input-height-small);\n  }\n  &.btn-xs {\n    .navbar-vertical-align(22);\n  }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n  .navbar-vertical-align(@line-height-computed);\n\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n    margin-left: @navbar-padding-horizontal;\n    margin-right: @navbar-padding-horizontal;\n\n    // Outdent the form if last child to line up with content down the page\n    &.navbar-right:last-child {\n      margin-right: 0;\n    }\n  }\n}\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n  background-color: @navbar-default-bg;\n  border-color: @navbar-default-border;\n\n  .navbar-brand {\n    color: @navbar-default-brand-color;\n    &:hover,\n    &:focus {\n      color: @navbar-default-brand-hover-color;\n      background-color: @navbar-default-brand-hover-bg;\n    }\n  }\n\n  .navbar-text {\n    color: @navbar-default-color;\n  }\n\n  .navbar-nav {\n    > li > a {\n      color: @navbar-default-link-color;\n\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-hover-color;\n        background-color: @navbar-default-link-hover-bg;\n      }\n    }\n    > .active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-active-color;\n        background-color: @navbar-default-link-active-bg;\n      }\n    }\n    > .disabled > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-disabled-color;\n        background-color: @navbar-default-link-disabled-bg;\n      }\n    }\n  }\n\n  .navbar-toggle {\n    border-color: @navbar-default-toggle-border-color;\n    &:hover,\n    &:focus {\n      background-color: @navbar-default-toggle-hover-bg;\n    }\n    .icon-bar {\n      background-color: @navbar-default-toggle-icon-bar-bg;\n    }\n  }\n\n  .navbar-collapse,\n  .navbar-form {\n    border-color: @navbar-default-border;\n  }\n\n  // Dropdown menu items\n  .navbar-nav {\n    // Remove background color from open dropdown\n    > .open > a {\n      &,\n      &:hover,\n      &:focus {\n        background-color: @navbar-default-link-active-bg;\n        color: @navbar-default-link-active-color;\n      }\n    }\n\n    @media (max-width: @grid-float-breakpoint-max) {\n      // Dropdowns get custom display when collapsed\n      .open .dropdown-menu {\n        > li > a {\n          color: @navbar-default-link-color;\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-hover-color;\n            background-color: @navbar-default-link-hover-bg;\n          }\n        }\n        > .active > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-active-color;\n            background-color: @navbar-default-link-active-bg;\n          }\n        }\n        > .disabled > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-disabled-color;\n            background-color: @navbar-default-link-disabled-bg;\n          }\n        }\n      }\n    }\n  }\n\n\n  // Links in navbars\n  //\n  // Add a class to ensure links outside the navbar nav are colored correctly.\n\n  .navbar-link {\n    color: @navbar-default-link-color;\n    &:hover {\n      color: @navbar-default-link-hover-color;\n    }\n  }\n\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n  background-color: @navbar-inverse-bg;\n  border-color: @navbar-inverse-border;\n\n  .navbar-brand {\n    color: @navbar-inverse-brand-color;\n    &:hover,\n    &:focus {\n      color: @navbar-inverse-brand-hover-color;\n      background-color: @navbar-inverse-brand-hover-bg;\n    }\n  }\n\n  .navbar-text {\n    color: @navbar-inverse-color;\n  }\n\n  .navbar-nav {\n    > li > a {\n      color: @navbar-inverse-link-color;\n\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-hover-color;\n        background-color: @navbar-inverse-link-hover-bg;\n      }\n    }\n    > .active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-active-color;\n        background-color: @navbar-inverse-link-active-bg;\n      }\n    }\n    > .disabled > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-disabled-color;\n        background-color: @navbar-inverse-link-disabled-bg;\n      }\n    }\n  }\n\n  // Darken the responsive nav toggle\n  .navbar-toggle {\n    border-color: @navbar-inverse-toggle-border-color;\n    &:hover,\n    &:focus {\n      background-color: @navbar-inverse-toggle-hover-bg;\n    }\n    .icon-bar {\n      background-color: @navbar-inverse-toggle-icon-bar-bg;\n    }\n  }\n\n  .navbar-collapse,\n  .navbar-form {\n    border-color: darken(@navbar-inverse-bg, 7%);\n  }\n\n  // Dropdowns\n  .navbar-nav {\n    > .open > a {\n      &,\n      &:hover,\n      &:focus {\n        background-color: @navbar-inverse-link-active-bg;\n        color: @navbar-inverse-link-active-color;\n      }\n    }\n\n    @media (max-width: @grid-float-breakpoint-max) {\n      // Dropdowns get custom display\n      .open .dropdown-menu {\n        > .dropdown-header {\n          border-color: @navbar-inverse-border;\n        }\n        .divider {\n          background-color: @navbar-inverse-border;\n        }\n        > li > a {\n          color: @navbar-inverse-link-color;\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-hover-color;\n            background-color: @navbar-inverse-link-hover-bg;\n          }\n        }\n        > .active > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-active-color;\n            background-color: @navbar-inverse-link-active-bg;\n          }\n        }\n        > .disabled > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-disabled-color;\n            background-color: @navbar-inverse-link-disabled-bg;\n          }\n        }\n      }\n    }\n  }\n\n  .navbar-link {\n    color: @navbar-inverse-link-color;\n    &:hover {\n      color: @navbar-inverse-link-hover-color;\n    }\n  }\n\n}\n","//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n  .clearfix();\n}\n.center-block {\n  .center-block();\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n  display: none !important;\n  visibility: hidden !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n  position: fixed;\n}\n","//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n  padding: @breadcrumb-padding-vertical @breadcrumb-padding-horizontal;\n  margin-bottom: @line-height-computed;\n  list-style: none;\n  background-color: @breadcrumb-bg;\n  border-radius: @border-radius-base;\n\n  > li {\n    display: inline-block;\n\n    + li:before {\n      content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n      padding: 0 5px;\n      color: @breadcrumb-color;\n    }\n  }\n\n  > .active {\n    color: @breadcrumb-active-color;\n  }\n}\n","//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: @line-height-computed 0;\n  border-radius: @border-radius-base;\n\n  > li {\n    display: inline; // Remove list-style and block-level defaults\n    > a,\n    > span {\n      position: relative;\n      float: left; // Collapse white-space\n      padding: @padding-base-vertical @padding-base-horizontal;\n      line-height: @line-height-base;\n      text-decoration: none;\n      color: @pagination-color;\n      background-color: @pagination-bg;\n      border: 1px solid @pagination-border;\n      margin-left: -1px;\n    }\n    &:first-child {\n      > a,\n      > span {\n        margin-left: 0;\n        .border-left-radius(@border-radius-base);\n      }\n    }\n    &:last-child {\n      > a,\n      > span {\n        .border-right-radius(@border-radius-base);\n      }\n    }\n  }\n\n  > li > a,\n  > li > span {\n    &:hover,\n    &:focus {\n      color: @pagination-hover-color;\n      background-color: @pagination-hover-bg;\n      border-color: @pagination-hover-border;\n    }\n  }\n\n  > .active > a,\n  > .active > span {\n    &,\n    &:hover,\n    &:focus {\n      z-index: 2;\n      color: @pagination-active-color;\n      background-color: @pagination-active-bg;\n      border-color: @pagination-active-border;\n      cursor: default;\n    }\n  }\n\n  > .disabled {\n    > span,\n    > span:hover,\n    > span:focus,\n    > a,\n    > a:hover,\n    > a:focus {\n      color: @pagination-disabled-color;\n      background-color: @pagination-disabled-bg;\n      border-color: @pagination-disabled-border;\n      cursor: not-allowed;\n    }\n  }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n  .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n  .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @border-radius-small);\n}\n","//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n  padding-left: 0;\n  margin: @line-height-computed 0;\n  list-style: none;\n  text-align: center;\n  &:extend(.clearfix all);\n  li {\n    display: inline;\n    > a,\n    > span {\n      display: inline-block;\n      padding: 5px 14px;\n      background-color: @pager-bg;\n      border: 1px solid @pager-border;\n      border-radius: @pager-border-radius;\n    }\n\n    > a:hover,\n    > a:focus {\n      text-decoration: none;\n      background-color: @pager-hover-bg;\n    }\n  }\n\n  .next {\n    > a,\n    > span {\n      float: right;\n    }\n  }\n\n  .previous {\n    > a,\n    > span {\n      float: left;\n    }\n  }\n\n  .disabled {\n    > a,\n    > a:hover,\n    > a:focus,\n    > span {\n      color: @pager-disabled-color;\n      background-color: @pager-bg;\n      cursor: not-allowed;\n    }\n  }\n\n}\n","//\n// Labels\n// --------------------------------------------------\n\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: @label-color;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n\n  // Add hover effects, but only for links\n  &[href] {\n    &:hover,\n    &:focus {\n      color: @label-link-hover-color;\n      text-decoration: none;\n      cursor: pointer;\n    }\n  }\n\n  // Empty labels collapse automatically (not available in IE8)\n  &:empty {\n    display: none;\n  }\n\n  // Quick fix for labels in buttons\n  .btn & {\n    position: relative;\n    top: -1px;\n  }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n  .label-variant(@label-default-bg);\n}\n\n.label-primary {\n  .label-variant(@label-primary-bg);\n}\n\n.label-success {\n  .label-variant(@label-success-bg);\n}\n\n.label-info {\n  .label-variant(@label-info-bg);\n}\n\n.label-warning {\n  .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n  .label-variant(@label-danger-bg);\n}\n","//\n// Badges\n// --------------------------------------------------\n\n\n// Base classes\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: @font-size-small;\n  font-weight: @badge-font-weight;\n  color: @badge-color;\n  line-height: @badge-line-height;\n  vertical-align: baseline;\n  white-space: nowrap;\n  text-align: center;\n  background-color: @badge-bg;\n  border-radius: @badge-border-radius;\n\n  // Empty badges collapse automatically (not available in IE8)\n  &:empty {\n    display: none;\n  }\n\n  // Quick fix for badges in buttons\n  .btn & {\n    position: relative;\n    top: -1px;\n  }\n  .btn-xs & {\n    top: 0;\n    padding: 1px 5px;\n  }\n}\n\n// Hover state, but only for links\na.badge {\n  &:hover,\n  &:focus {\n    color: @badge-link-hover-color;\n    text-decoration: none;\n    cursor: pointer;\n  }\n}\n\n// Account for counters in navs\na.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n  color: @badge-active-color;\n  background-color: @badge-active-bg;\n}\n.nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n","//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n  padding: @jumbotron-padding;\n  margin-bottom: @jumbotron-padding;\n  color: @jumbotron-color;\n  background-color: @jumbotron-bg;\n\n  h1,\n  .h1 {\n    color: @jumbotron-heading-color;\n  }\n  p {\n    margin-bottom: (@jumbotron-padding / 2);\n    font-size: @jumbotron-font-size;\n    font-weight: 200;\n  }\n\n  .container & {\n    border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n  }\n\n  .container {\n    max-width: 100%;\n  }\n\n  @media screen and (min-width: @screen-sm-min) {\n    padding-top:    (@jumbotron-padding * 1.6);\n    padding-bottom: (@jumbotron-padding * 1.6);\n\n    .container & {\n      padding-left:  (@jumbotron-padding * 2);\n      padding-right: (@jumbotron-padding * 2);\n    }\n\n    h1,\n    .h1 {\n      font-size: (@font-size-base * 4.5);\n    }\n  }\n}\n","//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n  padding: @alert-padding;\n  margin-bottom: @line-height-computed;\n  border: 1px solid transparent;\n  border-radius: @alert-border-radius;\n\n  // Headings for larger alerts\n  h4 {\n    margin-top: 0;\n    // Specified for the h4 to prevent conflicts of changing @headings-color\n    color: inherit;\n  }\n  // Provide class for links that match alerts\n  .alert-link {\n    font-weight: @alert-link-font-weight;\n  }\n\n  // Improve alignment and spacing of inner content\n  > p,\n  > ul {\n    margin-bottom: 0;\n  }\n  > p + p {\n    margin-top: 5px;\n  }\n}\n\n// Dismissable alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable {\n padding-right: (@alert-padding + 20);\n\n  // Adjust close link position\n  .close {\n    position: relative;\n    top: -2px;\n    right: -21px;\n    color: inherit;\n  }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n  .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n.alert-info {\n  .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n.alert-warning {\n  .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n.alert-danger {\n  .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n","//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n  from  { background-position: 40px 0; }\n  to    { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n  from  { background-position: 40px 0; }\n  to    { background-position: 0 0; }\n}\n\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n  overflow: hidden;\n  height: @line-height-computed;\n  margin-bottom: @line-height-computed;\n  background-color: @progress-bg;\n  border-radius: @border-radius-base;\n  .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n  float: left;\n  width: 0%;\n  height: 100%;\n  font-size: @font-size-small;\n  line-height: @line-height-computed;\n  color: @progress-bar-color;\n  text-align: center;\n  background-color: @progress-bar-bg;\n  .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n  .transition(width .6s ease);\n}\n\n// Striped bars\n.progress-striped .progress-bar {\n  #gradient > .striped();\n  background-size: 40px 40px;\n}\n\n// Call animation for the active one\n.progress.active .progress-bar {\n  .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n  .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n  .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n  .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n  .progress-bar-variant(@progress-bar-danger-bg);\n}\n","// Media objects\n// Source: http://stubbornella.org/content/?p=497\n// --------------------------------------------------\n\n\n// Common styles\n// -------------------------\n\n// Clear the floats\n.media,\n.media-body {\n  overflow: hidden;\n  zoom: 1;\n}\n\n// Proper spacing between instances of .media\n.media,\n.media .media {\n  margin-top: 15px;\n}\n.media:first-child {\n  margin-top: 0;\n}\n\n// For images and videos, set to block\n.media-object {\n  display: block;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n  margin: 0 0 5px;\n}\n\n\n// Media image alignment\n// -------------------------\n\n.media {\n  > .pull-left {\n    margin-right: 10px;\n  }\n  > .pull-right {\n    margin-left: 10px;\n  }\n}\n\n\n// Media list variation\n// -------------------------\n\n// Undo default ul/ol styles\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n","//\n// List groups\n// --------------------------------------------------\n\n\n// Base class\n//\n// Easily usable on 
    ,
      , or
      .\n\n.list-group {\n // No need to set list-style: none; since .list-group-item is block level\n margin-bottom: 20px;\n padding-left: 0; // reset padding because ul and ol\n}\n\n\n// Individual list items\n//\n// Use on `li`s or `div`s within the `.list-group` parent.\n\n.list-group-item {\n position: relative;\n display: block;\n padding: 10px 15px;\n // Place the border on the list items and negative margin up for better styling\n margin-bottom: -1px;\n background-color: @list-group-bg;\n border: 1px solid @list-group-border;\n\n // Round the first and last items\n &:first-child {\n .border-top-radius(@list-group-border-radius);\n }\n &:last-child {\n margin-bottom: 0;\n .border-bottom-radius(@list-group-border-radius);\n }\n\n // Align badges within list items\n > .badge {\n float: right;\n }\n > .badge + .badge {\n margin-right: 5px;\n }\n}\n\n\n// Linked list items\n//\n// Use anchor elements instead of `li`s or `div`s to create linked list items.\n// Includes an extra `.active` modifier class for showing selected items.\n\na.list-group-item {\n color: @list-group-link-color;\n\n .list-group-item-heading {\n color: @list-group-link-heading-color;\n }\n\n // Hover state\n &:hover,\n &:focus {\n text-decoration: none;\n background-color: @list-group-hover-bg;\n }\n\n // Active class on item itself, not parent\n &.active,\n &.active:hover,\n &.active:focus {\n z-index: 2; // Place active items above their siblings for proper border styling\n color: @list-group-active-color;\n background-color: @list-group-active-bg;\n border-color: @list-group-active-border;\n\n // Force color to inherit for custom content\n .list-group-item-heading {\n color: inherit;\n }\n .list-group-item-text {\n color: @list-group-active-text-color;\n }\n }\n}\n\n\n// Contextual variants\n//\n// Add modifier classes to change text and background color on individual items.\n// Organizationally, this must come after the `:hover` states.\n\n.list-group-item-variant(success; @state-success-bg; @state-success-text);\n.list-group-item-variant(info; @state-info-bg; @state-info-text);\n.list-group-item-variant(warning; @state-warning-bg; @state-warning-text);\n.list-group-item-variant(danger; @state-danger-bg; @state-danger-text);\n\n\n// Custom content options\n//\n// Extra classes for creating well-formatted content within `.list-group-item`s.\n\n.list-group-item-heading {\n margin-top: 0;\n margin-bottom: 5px;\n}\n.list-group-item-text {\n margin-bottom: 0;\n line-height: 1.3;\n}\n","//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n margin-bottom: @line-height-computed;\n background-color: @panel-bg;\n border: 1px solid transparent;\n border-radius: @panel-border-radius;\n .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n padding: @panel-body-padding;\n &:extend(.clearfix all);\n}\n\n// Optional heading\n.panel-heading {\n padding: 10px 15px;\n border-bottom: 1px solid transparent;\n .border-top-radius((@panel-border-radius - 1));\n\n > .dropdown .dropdown-toggle {\n color: inherit;\n }\n}\n\n// Within heading, strip any `h*` tag of its default margins for spacing.\n.panel-title {\n margin-top: 0;\n margin-bottom: 0;\n font-size: ceil((@font-size-base * 1.125));\n color: inherit;\n\n > a {\n color: inherit;\n }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n padding: 10px 15px;\n background-color: @panel-footer-bg;\n border-top: 1px solid @panel-inner-border;\n .border-bottom-radius((@panel-border-radius - 1));\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n > .list-group {\n margin-bottom: 0;\n\n .list-group-item {\n border-width: 1px 0;\n border-radius: 0;\n }\n\n // Add border top radius for first one\n &:first-child {\n .list-group-item:first-child {\n border-top: 0;\n .border-top-radius((@panel-border-radius - 1));\n }\n }\n // Add border bottom radius for last one\n &:last-child {\n .list-group-item:last-child {\n border-bottom: 0;\n .border-bottom-radius((@panel-border-radius - 1));\n }\n }\n }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n .list-group-item:first-child {\n border-top-width: 0;\n }\n}\n\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n > .table,\n > .table-responsive > .table {\n margin-bottom: 0;\n }\n // Add border top radius for first one\n > .table:first-child,\n > .table-responsive:first-child > .table:first-child {\n .border-top-radius((@panel-border-radius - 1));\n\n > thead:first-child,\n > tbody:first-child {\n > tr:first-child {\n td:first-child,\n th:first-child {\n border-top-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-top-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n // Add border bottom radius for last one\n > .table:last-child,\n > .table-responsive:last-child > .table:last-child {\n .border-bottom-radius((@panel-border-radius - 1));\n\n > tbody:last-child,\n > tfoot:last-child {\n > tr:last-child {\n td:first-child,\n th:first-child {\n border-bottom-left-radius: (@panel-border-radius - 1);\n }\n td:last-child,\n th:last-child {\n border-bottom-right-radius: (@panel-border-radius - 1);\n }\n }\n }\n }\n > .panel-body + .table,\n > .panel-body + .table-responsive {\n border-top: 1px solid @table-border-color;\n }\n > .table > tbody:first-child > tr:first-child th,\n > .table > tbody:first-child > tr:first-child td {\n border-top: 0;\n }\n > .table-bordered,\n > .table-responsive > .table-bordered {\n border: 0;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n > thead,\n > tbody {\n > tr:first-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n > tbody,\n > tfoot {\n > tr:last-child {\n > td,\n > th {\n border-bottom: 0;\n }\n }\n }\n }\n > .table-responsive {\n border: 0;\n margin-bottom: 0;\n }\n}\n\n\n// Collapsable panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n margin-bottom: @line-height-computed;\n\n // Tighten up margin so it's only between panels\n .panel {\n margin-bottom: 0;\n border-radius: @panel-border-radius;\n overflow: hidden; // crop contents when collapsed\n + .panel {\n margin-top: 5px;\n }\n }\n\n .panel-heading {\n border-bottom: 0;\n + .panel-collapse .panel-body {\n border-top: 1px solid @panel-inner-border;\n }\n }\n .panel-footer {\n border-top: 0;\n + .panel-collapse .panel-body {\n border-bottom: 1px solid @panel-inner-border;\n }\n }\n}\n\n\n// Contextual variations\n.panel-default {\n .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-info {\n .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n.panel-warning {\n .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n","//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n min-height: 20px;\n padding: 19px;\n margin-bottom: 20px;\n background-color: @well-bg;\n border: 1px solid @well-border;\n border-radius: @border-radius-base;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n blockquote {\n border-color: #ddd;\n border-color: rgba(0,0,0,.15);\n }\n}\n\n// Sizes\n.well-lg {\n padding: 24px;\n border-radius: @border-radius-large;\n}\n.well-sm {\n padding: 9px;\n border-radius: @border-radius-small;\n}\n","//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n float: right;\n font-size: (@font-size-base * 1.5);\n font-weight: @close-font-weight;\n line-height: 1;\n color: @close-color;\n text-shadow: @close-text-shadow;\n .opacity(.2);\n\n &:hover,\n &:focus {\n color: @close-color;\n text-decoration: none;\n cursor: pointer;\n .opacity(.5);\n }\n\n // Additional properties for button version\n // iOS requires the button element instead of an anchor tag.\n // If you want the anchor version, it requires `href=\"#\"`.\n button& {\n padding: 0;\n cursor: pointer;\n background: transparent;\n border: 0;\n -webkit-appearance: none;\n }\n}\n","//\n// Modals\n// --------------------------------------------------\n\n// .modal-open - body class for killing the scroll\n// .modal - container to scroll within\n// .modal-dialog - positioning shell for the actual modal\n// .modal-content - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n display: none;\n overflow: auto;\n overflow-y: scroll;\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal;\n -webkit-overflow-scrolling: touch;\n\n // Prevent Chrome on Windows from adding a focus outline. For details, see\n // https://github.com/twbs/bootstrap/pull/10951.\n outline: 0;\n\n // When fading in the modal, animate it to slide down\n &.fade .modal-dialog {\n .translate(0, -25%);\n .transition-transform(~\"0.3s ease-out\");\n }\n &.in .modal-dialog { .translate(0, 0)}\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n position: relative;\n width: auto;\n margin: 10px;\n}\n\n// Actual modal\n.modal-content {\n position: relative;\n background-color: @modal-content-bg;\n border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n border: 1px solid @modal-content-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 3px 9px rgba(0,0,0,.5));\n background-clip: padding-box;\n // Remove focus outline from opened modal\n outline: none;\n}\n\n// Modal background\n.modal-backdrop {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n z-index: @zindex-modal-background;\n background-color: @modal-backdrop-bg;\n // Fade for backdrop\n &.fade { .opacity(0); }\n &.in { .opacity(@modal-backdrop-opacity); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n padding: @modal-title-padding;\n border-bottom: 1px solid @modal-header-border-color;\n min-height: (@modal-title-padding + @modal-title-line-height);\n}\n// Close icon\n.modal-header .close {\n margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n margin: 0;\n line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n position: relative;\n padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n margin-top: 15px;\n padding: (@modal-inner-padding - 1) @modal-inner-padding @modal-inner-padding;\n text-align: right; // right align buttons\n border-top: 1px solid @modal-footer-border-color;\n &:extend(.clearfix all); // clear it in case folks use .pull-* classes on buttons\n\n // Properly space out buttons\n .btn + .btn {\n margin-left: 5px;\n margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n }\n // but override that for button groups\n .btn-group .btn + .btn {\n margin-left: -1px;\n }\n // and override it for block buttons as well\n .btn-block + .btn-block {\n margin-left: 0;\n }\n}\n\n// Scale up the modal\n@media (min-width: @screen-sm-min) {\n // Automatically set modal's width for larger viewports\n .modal-dialog {\n width: @modal-md;\n margin: 30px auto;\n }\n .modal-content {\n .box-shadow(0 5px 15px rgba(0,0,0,.5));\n }\n\n // Modal sizes\n .modal-sm { width: @modal-sm; }\n}\n\n@media (min-width: @screen-md-min) {\n .modal-lg { width: @modal-lg; }\n}\n","//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n position: absolute;\n z-index: @zindex-tooltip;\n display: block;\n visibility: visible;\n font-size: @font-size-small;\n line-height: 1.4;\n .opacity(0);\n\n &.in { .opacity(@tooltip-opacity); }\n &.top { margin-top: -3px; padding: @tooltip-arrow-width 0; }\n &.right { margin-left: 3px; padding: 0 @tooltip-arrow-width; }\n &.bottom { margin-top: 3px; padding: @tooltip-arrow-width 0; }\n &.left { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n max-width: @tooltip-max-width;\n padding: 3px 8px;\n color: @tooltip-color;\n text-align: center;\n text-decoration: none;\n background-color: @tooltip-bg;\n border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n position: absolute;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n}\n.tooltip {\n &.top .tooltip-arrow {\n bottom: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-left .tooltip-arrow {\n bottom: 0;\n left: @tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.top-right .tooltip-arrow {\n bottom: 0;\n right: @tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n border-top-color: @tooltip-arrow-color;\n }\n &.right .tooltip-arrow {\n top: 50%;\n left: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n border-right-color: @tooltip-arrow-color;\n }\n &.left .tooltip-arrow {\n top: 50%;\n right: 0;\n margin-top: -@tooltip-arrow-width;\n border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-left-color: @tooltip-arrow-color;\n }\n &.bottom .tooltip-arrow {\n top: 0;\n left: 50%;\n margin-left: -@tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-left .tooltip-arrow {\n top: 0;\n left: @tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n &.bottom-right .tooltip-arrow {\n top: 0;\n right: @tooltip-arrow-width;\n border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n border-bottom-color: @tooltip-arrow-color;\n }\n}\n","//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n position: absolute;\n top: 0;\n left: 0;\n z-index: @zindex-popover;\n display: none;\n max-width: @popover-max-width;\n padding: 1px;\n text-align: left; // Reset given new insertion method\n background-color: @popover-bg;\n background-clip: padding-box;\n border: 1px solid @popover-fallback-border-color;\n border: 1px solid @popover-border-color;\n border-radius: @border-radius-large;\n .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n // Overrides for proper insertion\n white-space: normal;\n\n // Offset the popover to account for the popover arrow\n &.top { margin-top: -@popover-arrow-width; }\n &.right { margin-left: @popover-arrow-width; }\n &.bottom { margin-top: @popover-arrow-width; }\n &.left { margin-left: -@popover-arrow-width; }\n}\n\n.popover-title {\n margin: 0; // reset heading margin\n padding: 8px 14px;\n font-size: @font-size-base;\n font-weight: normal;\n line-height: 18px;\n background-color: @popover-title-bg;\n border-bottom: 1px solid darken(@popover-title-bg, 5%);\n border-radius: 5px 5px 0 0;\n}\n\n.popover-content {\n padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover > .arrow {\n &,\n &:after {\n position: absolute;\n display: block;\n width: 0;\n height: 0;\n border-color: transparent;\n border-style: solid;\n }\n}\n.popover > .arrow {\n border-width: @popover-arrow-outer-width;\n}\n.popover > .arrow:after {\n border-width: @popover-arrow-width;\n content: \"\";\n}\n\n.popover {\n &.top > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-top-color: @popover-arrow-outer-color;\n bottom: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n bottom: 1px;\n margin-left: -@popover-arrow-width;\n border-bottom-width: 0;\n border-top-color: @popover-arrow-color;\n }\n }\n &.right > .arrow {\n top: 50%;\n left: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-right-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n left: 1px;\n bottom: -@popover-arrow-width;\n border-left-width: 0;\n border-right-color: @popover-arrow-color;\n }\n }\n &.bottom > .arrow {\n left: 50%;\n margin-left: -@popover-arrow-outer-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-bottom-color: @popover-arrow-outer-color;\n top: -@popover-arrow-outer-width;\n &:after {\n content: \" \";\n top: 1px;\n margin-left: -@popover-arrow-width;\n border-top-width: 0;\n border-bottom-color: @popover-arrow-color;\n }\n }\n\n &.left > .arrow {\n top: 50%;\n right: -@popover-arrow-outer-width;\n margin-top: -@popover-arrow-outer-width;\n border-right-width: 0;\n border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n border-left-color: @popover-arrow-outer-color;\n &:after {\n content: \" \";\n right: 1px;\n border-right-width: 0;\n border-left-color: @popover-arrow-color;\n bottom: -@popover-arrow-width;\n }\n }\n\n}\n","//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#browsers\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n width: device-width;\n}\n\n\n// Visibility utilities\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n .responsive-invisibility();\n}\n\n.visible-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-visibility();\n }\n}\n.visible-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-visibility();\n }\n}\n.visible-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-visibility();\n }\n}\n.visible-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-visibility();\n }\n}\n\n.hidden-xs {\n @media (max-width: @screen-xs-max) {\n .responsive-invisibility();\n }\n}\n.hidden-sm {\n @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n .responsive-invisibility();\n }\n}\n.hidden-md {\n @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n .responsive-invisibility();\n }\n}\n.hidden-lg {\n @media (min-width: @screen-lg-min) {\n .responsive-invisibility();\n }\n}\n\n\n// Print utilities\n//\n// Media queries are placed on the inside to be mixin-friendly.\n\n.visible-print {\n .responsive-invisibility();\n\n @media print {\n .responsive-visibility();\n }\n}\n\n.hidden-print {\n @media print {\n .responsive-invisibility();\n }\n}\n"]} \ No newline at end of file diff --git a/triplestores/fuseki/webapp/css/bootstrap.min.css b/triplestores/fuseki/webapp/css/bootstrap.min.css deleted file mode 100644 index 679272d258..0000000000 --- a/triplestores/fuseki/webapp/css/bootstrap.min.css +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v3.1.1 (http://getbootstrap.com) - * Copyright 2011-2014 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */ - -/*! normalize.css v3.0.0 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}@media print{*{text-shadow:none!important;color:#000!important;background:transparent!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.table td,.table th{background-color:#fff!important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);border:0}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#999}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:200;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}cite{font-style:normal}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-muted{color:#999}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#999}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}blockquote:before,blockquote:after{content:""}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;white-space:nowrap;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:0}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:0}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:0}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:0}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:0}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:0}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:0}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:0}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{max-width:100%;background-color:transparent}th{text-align:left}.table{width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*=col-]{position:static;float:none;display:table-column}table td[class*=col-],table th[class*=col-]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}@media (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;overflow-x:scroll;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd;-webkit-overflow-scrolling:touch}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}input[type=date]{line-height:34px}.form-group{margin-bottom:15px}.radio,.checkbox{display:block;min-height:20px;margin-top:10px;margin-bottom:10px;padding-left:20px}.radio label,.checkbox label{display:inline;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{float:left;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:400;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.has-feedback .form-control-feedback{position:absolute;top:25px;right:0;display:block;width:34px;height:34px;line-height:34px;text-align:center}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.form-control-static{margin-bottom:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{float:none;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}.form-horizontal .form-control-static{padding-top:7px}@media (min-width:768px){.form-horizontal .control-label{text-align:right}}.form-horizontal .has-feedback .form-control-feedback{top:0;right:15px}.btn{display:inline-block;margin-bottom:0;font-weight:400;text-align:center;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333;background-color:#ebebeb;border-color:#adadad}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#fff;background-color:#3276b1;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#fff;background-color:#47a447;border-color:#398439}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#fff;background-color:#39b3d7;border-color:#269abc}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#fff;background-color:#ed9c28;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#fff;background-color:#d2322d;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{color:#428bca;font-weight:400;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%;padding-left:0;padding-right:0}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;transition:height .35s ease}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175);background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;outline:0;background-color:#428bca}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#999}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-bottom-left-radius:4px;border-top-right-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}[data-toggle=buttons]>.btn>input[type=radio],[data-toggle=buttons]>.btn>input[type=checkbox]{display:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{max-height:340px;overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255,255,255,.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:15px;font-size:18px;line-height:20px;height:50px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);margin-top:8px;margin-bottom:8px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;vertical-align:middle}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{float:none;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#e7e7e7;color:#555}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#999}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#999}.navbar-inverse .navbar-nav>li>a{color:#999}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#080808;color:#fff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#999}.navbar-inverse .navbar-link:hover{color:#fff}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#ccc}.breadcrumb>.active{color:#999}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.42857143;text-decoration:none;color:#428bca;background-color:#fff;border:1px solid #ddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999;background-color:#fff;border-color:#ddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999;background-color:#fff;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}.label[href]:hover,.label[href]:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#999}.label-default[href]:hover,.label-default[href]:focus{background-color:gray}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;color:#fff;line-height:1;vertical-align:baseline;white-space:nowrap;text-align:center;background-color:#999;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.container .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable{padding-right:35px}.alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:40px 40px}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5}a.list-group-item.active,a.list-group-item.active:hover,a.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}a.list-group-item.active .list-group-item-heading,a.list-group-item.active:hover .list-group-item-heading,a.list-group-item.active:focus .list-group-item-heading{color:inherit}a.list-group-item.active .list-group-item-text,a.list-group-item.active:hover .list-group-item-text,a.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:3px;border-top-left-radius:3px}.panel>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px;overflow:hidden}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#ddd}.panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6}.panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1}.panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#faebcc}.panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#ebccd1}.panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ebccd1}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;opacity:.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:auto;overflow-y:scroll;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);transform:translate(0,-25%);-webkit-transition:-webkit-transform .3s ease-out;-moz-transition:-moz-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);transform:translate(0,0)}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5);background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5;min-height:16.42857143px}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:20px}.modal-footer{margin-top:15px;padding:19px 20px 20px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;right:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;background-color:#fff;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);white-space:normal}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999;border-top-color:rgba(0,0,0,.25);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#fff}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999;border-right-color:rgba(0,0,0,.25)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#fff}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#fff;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;left:0;bottom:0;width:15%;opacity:.5;filter:alpha(opacity=50);font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-control.left{background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.5) 0),color-stop(rgba(0,0,0,.0001) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left,color-stop(rgba(0,0,0,.0001) 0),color-stop(rgba(0,0,0,.5) 100%));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#fff;text-decoration:none;opacity:.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;margin-left:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #fff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#fff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;margin-left:-15px;font-size:30px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/triplestores/fuseki/webapp/css/codemirror.css b/triplestores/fuseki/webapp/css/codemirror.css deleted file mode 100644 index c0897771aa..0000000000 --- a/triplestores/fuseki/webapp/css/codemirror.css +++ /dev/null @@ -1,301 +0,0 @@ -/* BASICS */ - -.CodeMirror { - /* Set height, width, borders, and global font properties here */ - font-family: monospace; - height: 300px; -} -.CodeMirror-scroll { - /* Set scrolling behaviour here */ - overflow: auto; -} - -/* PADDING */ - -.CodeMirror-lines { - padding: 4px 0; /* Vertical padding around content */ -} -.CodeMirror pre { - padding: 0 4px; /* Horizontal padding of content */ -} - -.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { - background-color: white; /* The little square between H and V scrollbars */ -} - -/* GUTTER */ - -.CodeMirror-gutters { - border-right: 1px solid #ddd; - background-color: #f7f7f7; - white-space: nowrap; -} -.CodeMirror-linenumbers {} -.CodeMirror-linenumber { - padding: 0 3px 0 5px; - min-width: 20px; - text-align: right; - color: #999; - -moz-box-sizing: content-box; - box-sizing: content-box; -} - -.CodeMirror-guttermarker { color: black; } -.CodeMirror-guttermarker-subtle { color: #999; } - -/* CURSOR */ - -.CodeMirror div.CodeMirror-cursor { - border-left: 1px solid black; -} -/* Shown when moving in bi-directional text */ -.CodeMirror div.CodeMirror-secondarycursor { - border-left: 1px solid silver; -} -.CodeMirror.cm-keymap-fat-cursor div.CodeMirror-cursor { - width: auto; - border: 0; - background: #7e7; -} -.cm-animate-fat-cursor { - width: auto; - border: 0; - -webkit-animation: blink 1.06s steps(1) infinite; - -moz-animation: blink 1.06s steps(1) infinite; - animation: blink 1.06s steps(1) infinite; -} -@-moz-keyframes blink { - 0% { background: #7e7; } - 50% { background: none; } - 100% { background: #7e7; } -} -@-webkit-keyframes blink { - 0% { background: #7e7; } - 50% { background: none; } - 100% { background: #7e7; } -} -@keyframes blink { - 0% { background: #7e7; } - 50% { background: none; } - 100% { background: #7e7; } -} - -/* Can style cursor different in overwrite (non-insert) mode */ -div.CodeMirror-overwrite div.CodeMirror-cursor {} - -.cm-tab { display: inline-block; } - -.CodeMirror-ruler { - border-left: 1px solid #ccc; - position: absolute; -} - -/* DEFAULT THEME */ - -.cm-s-default .cm-keyword {color: #708;} -.cm-s-default .cm-atom {color: #219;} -.cm-s-default .cm-number {color: #164;} -.cm-s-default .cm-def {color: #00f;} -.cm-s-default .cm-variable, -.cm-s-default .cm-punctuation, -.cm-s-default .cm-property, -.cm-s-default .cm-operator {} -.cm-s-default .cm-variable-2 {color: #05a;} -.cm-s-default .cm-variable-3 {color: #085;} -.cm-s-default .cm-comment {color: #a50;} -.cm-s-default .cm-string {color: #a11;} -.cm-s-default .cm-string-2 {color: #f50;} -.cm-s-default .cm-meta {color: #555;} -.cm-s-default .cm-qualifier {color: #555;} -.cm-s-default .cm-builtin {color: #30a;} -.cm-s-default .cm-bracket {color: #997;} -.cm-s-default .cm-tag {color: #170;} -.cm-s-default .cm-attribute {color: #00c;} -.cm-s-default .cm-header {color: blue;} -.cm-s-default .cm-quote {color: #090;} -.cm-s-default .cm-hr {color: #999;} -.cm-s-default .cm-link {color: #00c;} - -.cm-negative {color: #d44;} -.cm-positive {color: #292;} -.cm-header, .cm-strong {font-weight: bold;} -.cm-em {font-style: italic;} -.cm-link {text-decoration: underline;} - -.cm-s-default .cm-error {color: #f00;} -.cm-invalidchar {color: #f00;} - -/* Default styles for common addons */ - -div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;} -div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;} -.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); } -.CodeMirror-activeline-background {background: #e8f2ff;} - -/* STOP */ - -/* The rest of this file contains styles related to the mechanics of - the editor. You probably shouldn't touch them. */ - -.CodeMirror { - line-height: 1; - position: relative; - overflow: hidden; - background: white; - color: black; -} - -.CodeMirror-scroll { - /* 30px is the magic margin used to hide the element's real scrollbars */ - /* See overflow: hidden in .CodeMirror */ - margin-bottom: -30px; margin-right: -30px; - padding-bottom: 30px; - height: 100%; - outline: none; /* Prevent dragging from highlighting the element */ - position: relative; - -moz-box-sizing: content-box; - box-sizing: content-box; -} -.CodeMirror-sizer { - position: relative; - border-right: 30px solid transparent; - -moz-box-sizing: content-box; - box-sizing: content-box; -} - -/* The fake, visible scrollbars. Used to force redraw during scrolling - before actuall scrolling happens, thus preventing shaking and - flickering artifacts. */ -.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler { - position: absolute; - z-index: 6; - display: none; -} -.CodeMirror-vscrollbar { - right: 0; top: 0; - overflow-x: hidden; - overflow-y: scroll; -} -.CodeMirror-hscrollbar { - bottom: 0; left: 0; - overflow-y: hidden; - overflow-x: scroll; -} -.CodeMirror-scrollbar-filler { - right: 0; bottom: 0; -} -.CodeMirror-gutter-filler { - left: 0; bottom: 0; -} - -.CodeMirror-gutters { - position: absolute; left: 0; top: 0; - padding-bottom: 30px; - z-index: 3; -} -.CodeMirror-gutter { - white-space: normal; - height: 100%; - -moz-box-sizing: content-box; - box-sizing: content-box; - padding-bottom: 30px; - margin-bottom: -32px; - display: inline-block; - /* Hack to make IE7 behave */ - *zoom:1; - *display:inline; -} -.CodeMirror-gutter-elt { - position: absolute; - cursor: default; - z-index: 4; -} - -.CodeMirror-lines { - cursor: text; -} -.CodeMirror pre { - /* Reset some styles that the rest of the page might have set */ - -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0; - border-width: 0; - background: transparent; - font-family: inherit; - font-size: inherit; - margin: 0; - white-space: pre; - word-wrap: normal; - line-height: inherit; - color: inherit; - z-index: 2; - position: relative; - overflow: visible; -} -.CodeMirror-wrap pre { - word-wrap: break-word; - white-space: pre-wrap; - word-break: normal; -} - -.CodeMirror-linebackground { - position: absolute; - left: 0; right: 0; top: 0; bottom: 0; - z-index: 0; -} - -.CodeMirror-linewidget { - position: relative; - z-index: 2; - overflow: auto; -} - -.CodeMirror-widget {} - -.CodeMirror-wrap .CodeMirror-scroll { - overflow-x: hidden; -} - -.CodeMirror-measure { - position: absolute; - width: 100%; - height: 0; - overflow: hidden; - visibility: hidden; -} -.CodeMirror-measure pre { position: static; } - -.CodeMirror div.CodeMirror-cursor { - position: absolute; - border-right: none; - width: 0; -} - -div.CodeMirror-cursors { - visibility: hidden; - position: relative; - z-index: 1; -} -.CodeMirror-focused div.CodeMirror-cursors { - visibility: visible; -} - -.CodeMirror-selected { background: #d9d9d9; } -.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; } -.CodeMirror-crosshair { cursor: crosshair; } - -.cm-searching { - background: #ffa; - background: rgba(255, 255, 0, .4); -} - -/* IE7 hack to prevent it from returning funny offsetTops on the spans */ -.CodeMirror span { *vertical-align: text-bottom; } - -/* Used to force a border model for a node */ -.cm-force-border { padding-right: .1px; } - -@media print { - /* Hide the cursor when printing */ - .CodeMirror div.CodeMirror-cursors { - visibility: hidden; - } -} diff --git a/triplestores/fuseki/webapp/css/codemirror.min.css b/triplestores/fuseki/webapp/css/codemirror.min.css deleted file mode 100644 index d2366ca776..0000000000 --- a/triplestores/fuseki/webapp/css/codemirror.min.css +++ /dev/null @@ -1 +0,0 @@ -.CodeMirror{font-family:monospace;height:300px}.CodeMirror-scroll{overflow:auto}.CodeMirror-lines{padding:4px 0}.CodeMirror pre{padding:0 4px}.CodeMirror-gutter-filler,.CodeMirror-scrollbar-filler{background-color:#fff}.CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-guttermarker{color:#000}.CodeMirror-guttermarker-subtle{color:#999}.CodeMirror div.CodeMirror-cursor{border-left:1px solid #000}.CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.CodeMirror.cm-fat-cursor div.CodeMirror-cursor{width:auto;border:0;background:#7e7}.CodeMirror.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.cm-animate-fat-cursor{width:auto;border:0;-webkit-animation:blink 1.06s steps(1) infinite;-moz-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}@-moz-keyframes blink{0%{background:#7e7}50%{background:0 0}100%{background:#7e7}}@-webkit-keyframes blink{0%{background:#7e7}50%{background:0 0}100%{background:#7e7}}@keyframes blink{0%{background:#7e7}50%{background:0 0}100%{background:#7e7}}.cm-tab{display:inline-block;text-decoration:inherit}.CodeMirror-ruler{border-left:1px solid #ccc;position:absolute}.cm-s-default .cm-keyword{color:#708}.cm-s-default .cm-atom{color:#219}.cm-s-default .cm-number{color:#164}.cm-s-default .cm-def{color:#00f}.cm-s-default .cm-variable-2{color:#05a}.cm-s-default .cm-variable-3{color:#085}.cm-s-default .cm-comment{color:#a50}.cm-s-default .cm-string{color:#a11}.cm-s-default .cm-string-2{color:#f50}.cm-s-default .cm-meta,.cm-s-default .cm-qualifier{color:#555}.cm-s-default .cm-builtin{color:#30a}.cm-s-default .cm-bracket{color:#997}.cm-s-default .cm-tag{color:#170}.cm-s-default .cm-attribute{color:#00c}.cm-s-default .cm-header{color:#00f}.cm-s-default .cm-quote{color:#090}.cm-s-default .cm-hr{color:#999}.cm-s-default .cm-link{color:#00c}.cm-negative{color:#d44}.cm-positive{color:#292}.cm-header,.cm-strong{font-weight:700}.cm-em{font-style:italic}.cm-link{text-decoration:underline}.cm-strikethrough{text-decoration:line-through}.cm-invalidchar,.cm-s-default .cm-error{color:red}div.CodeMirror span.CodeMirror-matchingbracket{color:#0f0}div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#f22}.CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.CodeMirror-activeline-background{background:#e8f2ff}.CodeMirror{line-height:1;position:relative;overflow:hidden;background:#fff;color:#000}.CodeMirror-scroll{margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:0;position:relative;-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-sizer{position:relative;border-right:30px solid transparent;-moz-box-sizing:content-box;box-sizing:content-box}.CodeMirror-gutter-filler,.CodeMirror-hscrollbar,.CodeMirror-scrollbar-filler,.CodeMirror-vscrollbar{position:absolute;z-index:6;display:none}.CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.CodeMirror-scrollbar-filler{right:0;bottom:0}.CodeMirror-gutter-filler{left:0;bottom:0}.CodeMirror-gutters{position:absolute;left:0;top:0;padding-bottom:30px;z-index:3}.CodeMirror-gutter{white-space:normal;height:100%;-moz-box-sizing:content-box;box-sizing:content-box;padding-bottom:30px;margin-bottom:-32px;display:inline-block}.CodeMirror-gutter-wrapper{position:absolute;z-index:4;height:100%}.CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.CodeMirror-lines{cursor:text;min-height:1px}.CodeMirror pre{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;border-width:0;background:0 0;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible}.CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.CodeMirror-linewidget{position:relative;z-index:2;overflow:auto}.CodeMirror-wrap .CodeMirror-scroll{overflow-x:hidden}.CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.CodeMirror-measure pre{position:static}.CodeMirror div.CodeMirror-cursor{position:absolute;border-right:none;width:0}div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}.CodeMirror-focused div.CodeMirror-cursors{visibility:visible}.CodeMirror-selected{background:#d9d9d9}.CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.CodeMirror-crosshair{cursor:crosshair}.cm-searching{background:#ffa;background:rgba(255,255,0,.4)}.cm-force-border{padding-right:.1px}@media print{.CodeMirror div.CodeMirror-cursors{visibility:hidden}}.cm-tab-wrap-hack:after{content:''}span.CodeMirror-selectedtext{background:0 0} \ No newline at end of file diff --git a/triplestores/fuseki/webapp/css/font-awesome.min.css b/triplestores/fuseki/webapp/css/font-awesome.min.css deleted file mode 100644 index 3d920fc87c..0000000000 --- a/triplestores/fuseki/webapp/css/font-awesome.min.css +++ /dev/null @@ -1,4 +0,0 @@ -/*! - * Font Awesome 4.1.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.1.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.1.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.1.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.1.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.1.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:spin 2s infinite linear;-moz-animation:spin 2s infinite linear;-o-animation:spin 2s infinite linear;animation:spin 2s infinite linear}@-moz-keyframes spin{0%{-moz-transform:rotate(0deg)}100%{-moz-transform:rotate(359deg)}}@-webkit-keyframes spin{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg)}}@-o-keyframes spin{0%{-o-transform:rotate(0deg)}100%{-o-transform:rotate(359deg)}}@keyframes spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-moz-transform:scale(-1, 1);-ms-transform:scale(-1, 1);-o-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-moz-transform:scale(1, -1);-ms-transform:scale(1, -1);-o-transform:scale(1, -1);transform:scale(1, -1)}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-square:before,.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"} \ No newline at end of file diff --git a/triplestores/fuseki/webapp/css/fui.css b/triplestores/fuseki/webapp/css/fui.css deleted file mode 100644 index b2445e3446..0000000000 --- a/triplestores/fuseki/webapp/css/fui.css +++ /dev/null @@ -1,191 +0,0 @@ -h1 { - margin-top: 0; - font-size: 18pt; -} - -h1 + p { - margin-bottom: 20px; -} - -h2 { - margin-top: 0; - font-size: 16pt; -} - -h2 + p { - margin-bottom: 18px; -} - -h3 { - font-size: 13pt; -} - -a#server-status-light { - display: inline-block; - margin: 0; - padding-left: 8px; - padding-top: 2px; -} -#server-status-light span { - width: 24px; - height: 24px; - border-radius: 12px; - display: inline-block; - margin-bottom: -8px; -} -#server-status-light span.server-up { - background-color: #38a800; - border:1px solid #4b9b23; - - background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #59e811), color-stop(1, #38a800)); - background:-moz-linear-gradient(top, #59e811 5%, #38a800 100%); - background:-webkit-linear-gradient(top, #59e811 5%, #38a800 100%); - background:-o-linear-gradient(top, #59e811 5%, #38a800 100%); - background:-ms-linear-gradient(top, #59e811 5%, #38a800 100%); - background:linear-gradient(to bottom, #59e811 5%, #38a800 100%); - filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#59e811', endColorstr='#38a800',GradientType=0); -} - -#server-status-light span.server-down { - background-color: #d21e1e; - border:1px solid #a02323; - - background:-webkit-gradient(linear, left top, left bottom, color-stop(0.05, #ed2424), color-stop(1, #d21e1e)); - background:-moz-linear-gradient(top, #ed2424 5%, #d21e1e 100%); - background:-webkit-linear-gradient(top, #ed2424 5%, #d21e1e 100%); - background:-o-linear-gradient(top, #ed2424 5%, #d21e1e 100%); - background:-ms-linear-gradient(top, #ed2424 5%, #d21e1e 100%); - background:linear-gradient(to bottom, #ed2424 5%, #d21e1e 100%); - filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fbb450', endColorstr='#f89306',GradientType=0); -} - -a.navbar-brand { - padding-top: 0; - padding-bottom: 0; - font-size: 15px; - line-height: 1.0; -} - -a.navbar-brand div { - display: inline-block; -} - -a.navbar-brand img { - margin-top: -25px; -} - -.navbar-right { - color: #777; - line-height: 1.0; -} - -.navbar-item { - padding-top: 15px; - padding-right: 4px; -} - -.navbar-nav > li > a > i { - color: #428bca; -} - -.options-list { - margin-bottom: 5px; -} - -.validation-warning { - display:none; -} -.has-error .validation-warning, .has-warning .validation-warning { - display:block; -} - -.current-dataset { - margin-right: 20px; -} - -.current-datasets { - margin-top: 20px; - margin-bottom: 20px; -} - -.status-indicator { - padding-top: 10px; -} - -.select-picker-label { - height: 30px; - vertical-align: middle; - display: inline-block; -} - -.content-frame { - background-color: #eee; - border: 1px solid #aaa; - border-radius: 5px; - padding: 5px; -} - -.tab-pane > div { - background-color: white; - border-radius: 3px; -} - -#sparqlEndpoint { - min-width: 300px; -} - -#fileuploadForm .progress { - margin-top: 0; - margin-bottom: 5px; -} - -.tab-pane .with-dataset { - padding: 5px; -} - -.file-description { - margin-top: 10px; -} - -.graph-label label { - text-align: right; - padding-top: 5px; -} - -.dl-horizontal dt { - width: 240px; -} - -.dl-horizontal dd { - margin-left: 260px -} - -dt span.heading, dd span.heading { - font-weight: bold; - background-color: #eee; - padding: 3px 8px; -} - -dt span.heading { - padding-right: 2px; -} -dd span.heading { - padding-left: 2px; -} -dt.font-weight-normal { - font-weight: normal; -} -dd .numeric { - display: inline-block; - min-width: 4em; - text-align: right; -} - -.bordered-box { - border: 1px solid #ccc; - border-radius: 5px; -} - -.pull-right > button { - margin: 10px 2px 0 0; -} diff --git a/triplestores/fuseki/webapp/css/jquery.dataTables.css b/triplestores/fuseki/webapp/css/jquery.dataTables.css deleted file mode 100644 index 86845c8e82..0000000000 --- a/triplestores/fuseki/webapp/css/jquery.dataTables.css +++ /dev/null @@ -1,220 +0,0 @@ - -/* - * Table - */ -table.dataTable { - margin: 0 auto; - clear: both; - width: 100%; -} - -table.dataTable thead th { - padding: 3px 18px 3px 10px; - border-bottom: 1px solid black; - font-weight: bold; - cursor: pointer; - *cursor: hand; -} - -table.dataTable tfoot th { - padding: 3px 18px 3px 10px; - border-top: 1px solid black; - font-weight: bold; -} - -table.dataTable td { - padding: 3px 10px; -} - -table.dataTable td.center, -table.dataTable td.dataTables_empty { - text-align: center; -} - -table.dataTable tr.odd { background-color: #E2E4FF; } -table.dataTable tr.even { background-color: white; } - -table.dataTable tr.odd td.sorting_1 { background-color: #D3D6FF; } -table.dataTable tr.odd td.sorting_2 { background-color: #DADCFF; } -table.dataTable tr.odd td.sorting_3 { background-color: #E0E2FF; } -table.dataTable tr.even td.sorting_1 { background-color: #EAEBFF; } -table.dataTable tr.even td.sorting_2 { background-color: #F2F3FF; } -table.dataTable tr.even td.sorting_3 { background-color: #F9F9FF; } - - -/* - * Table wrapper - */ -.dataTables_wrapper { - position: relative; - clear: both; - *zoom: 1; -} - - -/* - * Page length menu - */ -.dataTables_length { - float: left; -} - - -/* - * Filter - */ -.dataTables_filter { - float: right; - text-align: right; -} - - -/* - * Table information - */ -.dataTables_info { - clear: both; - float: left; -} - - -/* - * Pagination - */ -.dataTables_paginate { - float: right; - text-align: right; -} - -/* Two button pagination - previous / next */ -.paginate_disabled_previous, -.paginate_enabled_previous, -.paginate_disabled_next, -.paginate_enabled_next { - height: 19px; - float: left; - cursor: pointer; - *cursor: hand; - color: #111 !important; -} -.paginate_disabled_previous:hover, -.paginate_enabled_previous:hover, -.paginate_disabled_next:hover, -.paginate_enabled_next:hover { - text-decoration: none !important; -} -.paginate_disabled_previous:active, -.paginate_enabled_previous:active, -.paginate_disabled_next:active, -.paginate_enabled_next:active { - outline: none; -} - -.paginate_disabled_previous, -.paginate_disabled_next { - color: #666 !important; -} -.paginate_disabled_previous, -.paginate_enabled_previous { - padding-left: 23px; -} -.paginate_disabled_next, -.paginate_enabled_next { - padding-right: 23px; - margin-left: 10px; -} - -.paginate_enabled_previous { background: url('../images/back_enabled.png') no-repeat top left; } -.paginate_enabled_previous:hover { background: url('../images/back_enabled_hover.png') no-repeat top left; } -.paginate_disabled_previous { background: url('../images/back_disabled.png') no-repeat top left; } - -.paginate_enabled_next { background: url('../images/forward_enabled.png') no-repeat top right; } -.paginate_enabled_next:hover { background: url('../images/forward_enabled_hover.png') no-repeat top right; } -.paginate_disabled_next { background: url('../images/forward_disabled.png') no-repeat top right; } - -/* Full number pagination */ -.paging_full_numbers { - height: 22px; - line-height: 22px; -} -.paging_full_numbers a:active { - outline: none -} -.paging_full_numbers a:hover { - text-decoration: none; -} - -.paging_full_numbers a.paginate_button, -.paging_full_numbers a.paginate_active { - border: 1px solid #aaa; - -webkit-border-radius: 5px; - -moz-border-radius: 5px; - border-radius: 5px; - padding: 2px 5px; - margin: 0 3px; - cursor: pointer; - *cursor: hand; - color: #333 !important; -} - -.paging_full_numbers a.paginate_button { - background-color: #ddd; -} - -.paging_full_numbers a.paginate_button:hover { - background-color: #ccc; - text-decoration: none !important; -} - -.paging_full_numbers a.paginate_active { - background-color: #99B3FF; -} - - -/* - * Processing indicator - */ -.dataTables_processing { - position: absolute; - top: 50%; - left: 50%; - width: 250px; - height: 30px; - margin-left: -125px; - margin-top: -15px; - padding: 14px 0 2px 0; - border: 1px solid #ddd; - text-align: center; - color: #999; - font-size: 14px; - background-color: white; -} - - -/* - * Sorting - */ -.sorting { background: url('../images/sort_both.png') no-repeat center right; } -.sorting_asc { background: url('../images/sort_asc.png') no-repeat center right; } -.sorting_desc { background: url('../images/sort_desc.png') no-repeat center right; } - -.sorting_asc_disabled { background: url('../images/sort_asc_disabled.png') no-repeat center right; } -.sorting_desc_disabled { background: url('../images/sort_desc_disabled.png') no-repeat center right; } - -table.dataTable thead th:active, -table.dataTable thead td:active { - outline: none; -} - - -/* - * Scrolling - */ -.dataTables_scroll { - clear: both; -} - -.dataTables_scrollBody { - *margin-top: -1px; - -webkit-overflow-scrolling: touch; -} diff --git a/triplestores/fuseki/webapp/css/jquery.fileupload-noscript.css b/triplestores/fuseki/webapp/css/jquery.fileupload-noscript.css deleted file mode 100644 index 64d728fc31..0000000000 --- a/triplestores/fuseki/webapp/css/jquery.fileupload-noscript.css +++ /dev/null @@ -1,22 +0,0 @@ -@charset "UTF-8"; -/* - * jQuery File Upload Plugin NoScript CSS 1.2.0 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -.fileinput-button input { - position: static; - opacity: 1; - filter: none; - font-size: inherit; - direction: inherit; -} -.fileinput-button span { - display: none; -} diff --git a/triplestores/fuseki/webapp/css/jquery.fileupload-ui-noscript.css b/triplestores/fuseki/webapp/css/jquery.fileupload-ui-noscript.css deleted file mode 100644 index 87f110cdbd..0000000000 --- a/triplestores/fuseki/webapp/css/jquery.fileupload-ui-noscript.css +++ /dev/null @@ -1,17 +0,0 @@ -@charset "UTF-8"; -/* - * jQuery File Upload UI Plugin NoScript CSS 8.8.5 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2012, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -.fileinput-button i, -.fileupload-buttonbar .delete, -.fileupload-buttonbar .toggle { - display: none; -} diff --git a/triplestores/fuseki/webapp/css/jquery.fileupload-ui.css b/triplestores/fuseki/webapp/css/jquery.fileupload-ui.css deleted file mode 100644 index 76fb376de0..0000000000 --- a/triplestores/fuseki/webapp/css/jquery.fileupload-ui.css +++ /dev/null @@ -1,57 +0,0 @@ -@charset "UTF-8"; -/* - * jQuery File Upload UI Plugin CSS 9.0.0 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2010, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -.fileupload-buttonbar .btn, -.fileupload-buttonbar .toggle { - margin-bottom: 5px; -} -.progress-animated .progress-bar, -.progress-animated .bar { - background: url("../img/progressbar.gif") !important; - filter: none; -} -.fileupload-process { - float: right; - display: none; -} -.fileupload-processing .fileupload-process, -.files .processing .preview { - display: block; - width: 32px; - height: 32px; - background: url("../img/loading.gif") center no-repeat; - background-size: contain; -} -.files audio, -.files video { - max-width: 300px; -} - -@media (max-width: 767px) { - .fileupload-buttonbar .toggle, - .files .toggle, - .files .btn span { - display: none; - } - .files .name { - width: 80px; - word-wrap: break-word; - } - .files audio, - .files video { - max-width: 80px; - } - .files img, - .files canvas { - max-width: 100%; - } -} diff --git a/triplestores/fuseki/webapp/css/jquery.fileupload.css b/triplestores/fuseki/webapp/css/jquery.fileupload.css deleted file mode 100644 index fb6044d34f..0000000000 --- a/triplestores/fuseki/webapp/css/jquery.fileupload.css +++ /dev/null @@ -1,36 +0,0 @@ -@charset "UTF-8"; -/* - * jQuery File Upload Plugin CSS 1.3.0 - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2013, Sebastian Tschan - * https://blueimp.net - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -.fileinput-button { - position: relative; - overflow: hidden; -} -.fileinput-button input { - position: absolute; - top: 0; - right: 0; - margin: 0; - opacity: 0; - -ms-filter: 'alpha(opacity=0)'; - font-size: 200px; - direction: ltr; - cursor: pointer; -} - -/* Fixes for IE < 8 */ -@media screen\9 { - .fileinput-button input { - filter: alpha(opacity=0); - font-size: 100%; - height: 100%; - } -} diff --git a/triplestores/fuseki/webapp/css/pivot.min.css b/triplestores/fuseki/webapp/css/pivot.min.css deleted file mode 100644 index b489e1e90c..0000000000 --- a/triplestores/fuseki/webapp/css/pivot.min.css +++ /dev/null @@ -1 +0,0 @@ -table.pvtTable{font-family:arial;font-size:8pt;text-align:left;border-collapse:collapse}table.pvtTable tr th{background-color:#e6EEEE;border:1px solid #CDCDCD;font-size:8pt;padding:5px}table.pvtTable .pvtColLabel{text-align:center}table.pvtTable .pvtTotalLabel{text-align:right}table.pvtTable tr td{color:#3D3D3D;padding:5px;background-color:#FFF;border:1px solid #CDCDCD;vertical-align:top;text-align:right}.pvtGrandTotal,.pvtTotal{font-weight:700}.pvtVals{text-align:center}.pvtAggregator{margin-bottom:5px}.pvtAxisContainer,.pvtVals{border:1px solid gray;background:#EEE;padding:5px;min-width:20px;min-height:20px}.pvtAxisContainer li{padding:8px 6px;list-style-type:none;cursor:move}.pvtAxisContainer li.pvtPlaceholder{-webkit-border-radius:5px;padding:3px 15px;-moz-border-radius:5px;border-radius:5px;border:1px dashed #aaa}.pvtAxisContainer li span.pvtAttr{background:#F3F3F3;border:1px solid #DEDEDE;padding:2px 5px;white-space:nowrap;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.pvtTriangle{cursor:pointer;color:grey}.pvtHorizList li{display:inline}.pvtVertList{vertical-align:top}.pvtFilteredAttribute{font-style:italic}.pvtFilterBox{z-index:100;width:280px;border:1px solid gray;background-color:#fff;position:absolute;padding:20px;text-align:center}.pvtFilterBox h4{margin:0}.pvtCheckContainer{text-align:left;overflow:scroll;width:100%;max-height:200px}.pvtCheckContainer p{margin:5px} \ No newline at end of file diff --git a/triplestores/fuseki/webapp/css/qonsole.css b/triplestores/fuseki/webapp/css/qonsole.css deleted file mode 100644 index 99180cbfa3..0000000000 --- a/triplestores/fuseki/webapp/css/qonsole.css +++ /dev/null @@ -1,172 +0,0 @@ -/* Copyright (c) 2012-2013 Epimorphics Ltd. Released under Apache License 2.0 http://www.apache.org/licenses/ */ - -.qonsole h2, .query-chrome label { - font-size: 10px; - color: #666666; - margin: 0; - text-transform: uppercase; - display: block; - font-weight: normal; -} - -.qonsole .well { - padding: 5px; -} - -.qonsole h2+ul { - display: inline-block; -} - -.navbar h1.brand, .navbar h2.brand { - line-height: 12px; -} - -.navbar h1.brand { - font-weight: bold; - font-size: 16pt; - display: inline-block; -} - -h2.brand { - display: inline-block; - font-size: 14pt; -} - -.query-chrome { - margin-top: 1em; -} - -.timeTaken { - font-style: italic; - text-transform: none; - color: #666; - margin-bottom: 5px; -} - -pre.results-plain { - overflow: auto; - word-wrap: normal; - white-space: pre; -} - -.well ul { - margin-bottom: 0; -} - -.well ul li { - margin-bottom: 2px; - margin-top: 2px; -} - -a.run-query { - margin-left: 10px; -} - -footer { - font-size: smaller; - color: #99999f; - border: 1px solid #ddd; - border-radius: 5px; - padding: 5px; -} - -footer p { - margin: 0; -} - -/* Custom buttons */ - -.btn-custom1, .btn-custom2.active { - background-color: hsl(201, 91%, 39%) !important; - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#087ebd", endColorstr="#087ebd"); - background-image: -khtml-gradient(linear, left top, left bottom, from(#087ebd), to(#087ebd)); - background-image: -moz-linear-gradient(top, #087ebd, #087ebd); - background-image: -ms-linear-gradient(top, #087ebd, #087ebd); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #087ebd), color-stop(100%, #087ebd)); - background-image: -webkit-linear-gradient(top, #087ebd, #087ebd); - background-image: -o-linear-gradient(top, #087ebd, #087ebd); - background-image: linear-gradient(#087ebd, #087ebd); - border-color: #087ebd #087ebd hsl(201, 91%, 39%); - color: #fff !important; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.00); - -webkit-font-smoothing: antialiased; -} - -.btn-custom1:hover, .btn-custom2.active:hover { - background-color: hsl(201, 91%, 43%) !important; - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#098bd1", endColorstr="#098bd1"); - background-image: -khtml-gradient(linear, left top, left bottom, from(#098bd1), to(#098bd1)); - background-image: -moz-linear-gradient(top, #098bd1, #098bd1); - background-image: -ms-linear-gradient(top, #098bd1, #098bd1); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #098bd1), color-stop(100%, #098bd1)); - background-image: -webkit-linear-gradient(top, #098bd1, #098bd1); - background-image: -o-linear-gradient(top, #098bd1, #098bd1); - background-image: linear-gradient(#098bd1, #098bd1); - border-color: #098bd1 #098bd1 hsl(201, 91%, 43%); - color: #fff !important; - text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.00); - -webkit-font-smoothing: antialiased; -} - - -.btn-custom2 { - background-color: hsl(193, 32%, 75%) !important; - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#aacad3", endColorstr="#aacad3"); - background-image: -khtml-gradient(linear, left top, left bottom, from(#aacad3), to(#aacad3)); - background-image: -moz-linear-gradient(top, #aacad3, #aacad3); - background-image: -ms-linear-gradient(top, #aacad3, #aacad3); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #aacad3), color-stop(100%, #aacad3)); - background-image: -webkit-linear-gradient(top, #aacad3, #aacad3); - background-image: -o-linear-gradient(top, #aacad3, #aacad3); - background-image: linear-gradient(#aacad3, #aacad3); - border-color: #aacad3 #aacad3 hsl(193, 32%, 75%); - color: #333 !important; - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.00); - -webkit-font-smoothing: antialiased; -} - -.btn-custom2:hover { - background-color: hsl(193, 31%, 70%) !important; - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#9abfca", endColorstr="#9abfca"); - background-image: -khtml-gradient(linear, left top, left bottom, from(#9abfca), to(#9abfca)); - background-image: -moz-linear-gradient(top, #9abfca, #9abfca); - background-image: -ms-linear-gradient(top, #9abfca, #9abfca); - background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #9abfca), color-stop(100%, #9abfca)); - background-image: -webkit-linear-gradient(top, #9abfca, #9abfca); - background-image: -o-linear-gradient(top, #9abfca, #9abfca); - background-image: linear-gradient(#9abfca, #9abfca); - border-color: #9abfca #9abfca hsl(193, 31%, 70%); - color: #333 !important; - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.00); - -webkit-font-smoothing: antialiased; -} - -.auto-overflow { - overflow: auto; -} - -.CodeMirror-foldmarker { - color: blue; - text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px; - font-family: arial; - line-height: .3; - cursor: pointer; -} -.CodeMirror-foldgutter { - width: .7em; -} -.CodeMirror-foldgutter-open, -.CodeMirror-foldgutter-folded { - color: #555; - cursor: pointer; -} -.CodeMirror-foldgutter-open:after { - content: "\25BE"; -} -.CodeMirror-foldgutter-folded:after { - content: "\25B8"; -} diff --git a/triplestores/fuseki/webapp/css/yasqe.min.css b/triplestores/fuseki/webapp/css/yasqe.min.css deleted file mode 100644 index abebf2ca21..0000000000 --- a/triplestores/fuseki/webapp/css/yasqe.min.css +++ /dev/null @@ -1 +0,0 @@ -.yasqe{position:relative}.yasqe .CodeMirror{font-family:monospace;height:300px;color:#000}.yasqe .CodeMirror-lines{padding:4px 0}.yasqe .CodeMirror pre{padding:0 4px}.yasqe .CodeMirror-gutter-filler,.yasqe .CodeMirror-scrollbar-filler{background-color:#fff}.yasqe .CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.yasqe .CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;white-space:nowrap}.yasqe .CodeMirror-guttermarker{color:#000}.yasqe .CodeMirror-guttermarker-subtle{color:#999}.yasqe .CodeMirror-cursor{border-left:1px solid #000;border-right:none;width:0}.yasqe .CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.yasqe .cm-fat-cursor .CodeMirror-cursor{width:auto;border:0;background:#7e7}.yasqe .cm-fat-cursor div.CodeMirror-cursors{z-index:1}.yasqe .cm-animate-fat-cursor{width:auto;border:0;-webkit-animation:a 1.06s steps(1) infinite;animation:a 1.06s steps(1) infinite;background-color:#7e7}@-webkit-keyframes a{50%{background-color:transparent}}@keyframes a{50%{background-color:transparent}}.yasqe .cm-tab{display:inline-block;text-decoration:inherit}.yasqe .CodeMirror-ruler{border-left:1px solid #ccc;position:absolute}.yasqe .cm-s-default .cm-header{color:blue}.yasqe .cm-s-default .cm-quote{color:#090}.yasqe .cm-negative{color:#d44}.yasqe .cm-positive{color:#292}.yasqe .cm-header,.yasqe .cm-strong{font-weight:700}.yasqe .cm-em{font-style:italic}.yasqe .cm-link{text-decoration:underline}.yasqe .cm-strikethrough{text-decoration:line-through}.yasqe .cm-s-default .cm-keyword{color:#708}.yasqe .cm-s-default .cm-atom{color:#219}.yasqe .cm-s-default .cm-number{color:#164}.yasqe .cm-s-default .cm-def{color:#00f}.yasqe .cm-s-default .cm-variable-2{color:#05a}.yasqe .cm-s-default .cm-variable-3{color:#085}.yasqe .cm-s-default .cm-comment{color:#a50}.yasqe .cm-s-default .cm-string{color:#a11}.yasqe .cm-s-default .cm-string-2{color:#f50}.yasqe .cm-s-default .cm-meta,.yasqe .cm-s-default .cm-qualifier{color:#555}.yasqe .cm-s-default .cm-builtin{color:#30a}.yasqe .cm-s-default .cm-bracket{color:#997}.yasqe .cm-s-default .cm-tag{color:#170}.yasqe .cm-s-default .cm-attribute{color:#00c}.yasqe .cm-s-default .cm-hr{color:#999}.yasqe .cm-s-default .cm-link{color:#00c}.yasqe .cm-invalidchar,.yasqe .cm-s-default .cm-error{color:red}.yasqe .CodeMirror-composing{border-bottom:2px solid}.yasqe div.CodeMirror span.CodeMirror-matchingbracket{color:#0f0}.yasqe div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#f22}.yasqe .CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.yasqe .CodeMirror-activeline-background{background:#e8f2ff}.yasqe .CodeMirror{position:relative;overflow:hidden;background:#fff}.yasqe .CodeMirror-scroll{overflow:scroll!important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:none;position:relative}.yasqe .CodeMirror-sizer{position:relative;border-right:30px solid transparent}.yasqe .CodeMirror-gutter-filler,.yasqe .CodeMirror-hscrollbar,.yasqe .CodeMirror-scrollbar-filler,.yasqe .CodeMirror-vscrollbar{position:absolute;z-index:6;display:none}.yasqe .CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.yasqe .CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.yasqe .CodeMirror-scrollbar-filler{right:0;bottom:0}.yasqe .CodeMirror-gutter-filler{left:0;bottom:0}.yasqe .CodeMirror-gutters{position:absolute;left:0;top:0;z-index:3}.yasqe .CodeMirror-gutter{white-space:normal;height:100%;display:inline-block;margin-bottom:-30px;*zoom:1;*display:inline}.yasqe .CodeMirror-gutter-wrapper{position:absolute;z-index:4;background:none!important;border:none!important}.yasqe .CodeMirror-gutter-background{position:absolute;top:0;bottom:0;z-index:4}.yasqe .CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.yasqe .CodeMirror-gutter-wrapper{-webkit-user-select:none;-ms-user-select:none;user-select:none}.yasqe .CodeMirror-lines{cursor:text;min-height:1px}.yasqe .CodeMirror pre{border-radius:0;border-width:0;background:transparent;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible;-webkit-tap-highlight-color:transparent}.yasqe .CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.yasqe .CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.yasqe .CodeMirror-linewidget{position:relative;z-index:2;overflow:auto}.yasqe .CodeMirror-code{outline:none}.yasqe .CodeMirror-gutter,.yasqe .CodeMirror-gutters,.yasqe .CodeMirror-linenumber,.yasqe .CodeMirror-scroll,.yasqe .CodeMirror-sizer{box-sizing:content-box}.yasqe .CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.yasqe .CodeMirror-cursor{position:absolute}.yasqe .CodeMirror-measure pre{position:static}.yasqe div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}.yasqe .CodeMirror-focused div.CodeMirror-cursors,.yasqe div.CodeMirror-dragcursors{visibility:visible}.yasqe .CodeMirror-selected{background:#d9d9d9}.yasqe .CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.yasqe .CodeMirror-crosshair{cursor:crosshair}.yasqe .CodeMirror-line::selection,.yasqe .CodeMirror-line>span::selection,.yasqe .CodeMirror-line>span>span::selection{background:#d7d4f0}.yasqe .CodeMirror-line::-moz-selection,.yasqe .CodeMirror-line>span::-moz-selection,.yasqe .CodeMirror-line>span>span::-moz-selection{background:#d7d4f0}.yasqe .cm-searching{background:#ffa;background:rgba(255,255,0,.4)}.yasqe .CodeMirror span{*vertical-align:text-bottom}.yasqe .cm-force-border{padding-right:.1px}@media print{.yasqe .CodeMirror div.CodeMirror-cursors{visibility:hidden}}.yasqe .cm-tab-wrap-hack:after{content:''}.yasqe span.CodeMirror-selectedtext{background:none}.yasqe .CodeMirror-fullscreen{position:fixed;top:0;left:0;right:0;bottom:0;height:auto;z-index:7}.yasqe .CodeMirror-foldmarker{color:blue;text-shadow:#b9f 1px 1px 2px,#b9f -1px -1px 2px,#b9f 1px -1px 2px,#b9f -1px 1px 2px;font-family:arial;line-height:.3;cursor:pointer}.yasqe .CodeMirror-foldgutter{width:.7em}.yasqe .CodeMirror-foldgutter-folded,.yasqe .CodeMirror-foldgutter-open{cursor:pointer}.yasqe .CodeMirror-foldgutter-open:after{content:"\25BE"}.yasqe .CodeMirror-foldgutter-folded:after{content:"\25B8"}@-webkit-keyframes b{to{-webkit-transform:rotate(1turn)}}.yasqe .yasqe_btn{color:#333;border:1px solid transparent;background-color:#fff;border-color:#ccc;border-width:1px;display:inline-block;text-align:center;vertical-align:middle;cursor:pointer;white-space:nowrap;padding:6px 12px;border-radius:4px;-webkit-user-select:none;-ms-user-select:none;user-select:none;-webkit-appearance:button;overflow:visible;box-sizing:border-box}.yasqe .yasqe_btn.btn_icon{padding:4px 8px}.yasqe .yasqe_btn.disabled,.yasqe .yasqe_btn[disabled]{cursor:default;opacity:.5;filter:alpha(opacity=50);box-shadow:none}.yasqe .yasqe_btn:hover{outline:0;background-color:#ebebeb;border-color:#adadad}.yasqe .yasqe_btn.selected,.yasqe .yasqe_btn:focus{color:#fff;outline:0;background-color:#337ab7;border-color:#337ab7}.yasqe .yasqe_btn.btn_icon:focus{color:#333;border:1px solid transparent;background-color:#fff;border-color:#ccc}.yasqe .yasqe_btn.yasqe_btn-sm{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.yasqe .backdrop{background-color:#000;opacity:.5;position:absolute;top:0;left:0;right:0;bottom:0;z-index:5;display:none}.yasqe .svgImg{display:inline-block}.yasqe .CodeMirror{line-height:1.5em;border:1px solid #d1d1d1}.yasqe pre{font-size:13px}.yasqe span.cm-error{border-bottom:2px dotted red}.yasqe .gutterErrorBar{width:4px}.yasqe .yasqe_buttons{position:absolute;top:5px;right:5px;z-index:5}.yasqe .yasqe_buttons .yasqe_share{cursor:pointer;height:20px;width:20px;margin-top:3px}.yasqe .yasqe_buttons div{vertical-align:top;margin-left:5px}.yasqe .yasqe_buttons div.yasqe_sharePopup{position:absolute;padding:4px;margin-left:0;border:1px solid #e3e3e3;border-radius:4px;box-shadow:inset 0 1px 1px rgba(0,0,0,.05);width:600px;height:auto;display:-webkit-box;display:flex}.yasqe .yasqe_buttons div.yasqe_sharePopup .inputWrapper{-webkit-box-flex:100;flex-grow:100}.yasqe .yasqe_buttons div.yasqe_sharePopup input{float:left;width:100%;border:0;-ms-box-sizing:border-box;-khtml-box-sizing:border-box;box-sizing:border-box}.yasqe .yasqe_buttons div.yasqe_sharePopup button{float:right;margin-left:5px}.yasqe .yasqe_buttons div.yasqe_sharePopup textarea{width:100%}.yasqe .yasqe_buttons .yasqe_queryButton{display:inline-block;cursor:pointer;width:40px;height:40px;margin-left:10px}.yasqe .yasqe_buttons .yasqe_queryButton div{margin-left:0}.yasqe .yasqe_buttons .yasqe_queryButton .svgImg{display:block}.yasqe .yasqe_buttons .yasqe_queryButton .loader{width:36px;height:36px;border-radius:50%;box-sizing:border-box;border:4px solid rgba(0,0,0,.2);border-top-color:#000;-webkit-animation:b 1s infinite linear;animation:b 1s infinite linear}.yasqe span.shortlinkErr{font-size:small;color:red;font-weight:700;float:left}.yasqe .completionNotification{color:#999;background-color:#f7f7f7;position:absolute;padding:0 5px;right:0;bottom:0;font-size:90%}.yasqe .CodeMirror-fullscreen .fullscreenToggleBtns .yasqe_smallscreenBtn{display:inline-block}.yasqe .CodeMirror-fullscreen .fullscreenToggleBtns .yasqe_fullscreenBtn{display:none}.yasqe .fullscreenToggleBtns{display:inline-block;margin-top:3px}.yasqe .fullscreenToggleBtns div{cursor:pointer;width:20px;height:20px}.yasqe .fullscreenToggleBtns .yasqe_smallscreenBtn{display:none}.yasqe .parseErrorIcon{width:15px;height:15px}.yasqe .yasqe_tooltip{display:inline;background:#333;background:rgba(0,0,0,.8);border-radius:5px;bottom:26px;color:#fff;left:20%;padding:5px 15px;position:absolute;width:220px;white-space:-moz-pre-wrap!important;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;white-space:normal}.yasqe .notificationLoader{width:18px;height:18px;vertical-align:middle}.yasqe .CodeMirror-foldmarker{color:#6e2500;text-shadow:#ff935e 1px 1px 2px,#ff935e -1px -1px 2px,#ff935e 1px -1px 2px,#ff935e -1px 1px 2px;font-size:19px}.yasqe .matchingVar{background-color:#dbdeed;border-radius:6px;-webkit-transition:background .5s linear;transition:background .5s linear}.CodeMirror-hints{position:absolute;z-index:8;overflow:hidden;list-style:none;margin:0;padding:2px;box-shadow:2px 3px 5px rgba(0,0,0,.2);border-radius:3px;border:1px solid silver;background:#fff;font-size:90%;font-family:monospace;max-height:20em;overflow-y:auto}.CodeMirror-hint{margin:0;padding:0 4px;border-radius:2px;max-width:19em;overflow:hidden;white-space:pre;color:#000;cursor:pointer}li.CodeMirror-hint-active{background:#08f;color:#fff}.CodeMirror-hint{max-width:30em} \ No newline at end of file diff --git a/triplestores/fuseki/webapp/css/yasr.min.css b/triplestores/fuseki/webapp/css/yasr.min.css deleted file mode 100644 index 04fe1011a8..0000000000 --- a/triplestores/fuseki/webapp/css/yasr.min.css +++ /dev/null @@ -1 +0,0 @@ -.yasr{padding-top:5px;background-color:#fff;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429;color:#333}.yasr table.dataTable{width:100%;margin:0 auto;clear:both;border-collapse:separate;border-spacing:0}.yasr table.dataTable thead th,.yasr table.dataTable tfoot th{font-weight:700}.yasr table.dataTable thead th,.yasr table.dataTable thead td{padding:10px 18px;border-bottom:1px solid #111}.yasr table.dataTable thead th:active,.yasr table.dataTable thead td:active{outline:0}.yasr table.dataTable tfoot th,.yasr table.dataTable tfoot td{padding:10px 18px 6px 18px;border-top:1px solid #111}.yasr table.dataTable thead .sorting,.yasr table.dataTable thead .sorting_asc,.yasr table.dataTable thead .sorting_desc{cursor:pointer;}.yasr table.dataTable thead .sorting,.yasr table.dataTable thead .sorting_asc,.yasr table.dataTable thead .sorting_desc,.yasr table.dataTable thead .sorting_asc_disabled,.yasr table.dataTable thead .sorting_desc_disabled{background-repeat:no-repeat;background-position:center right}.yasr table.dataTable thead .sorting{background-image:url(../images/sort_both.png)}.yasr table.dataTable thead .sorting_asc{background-image:url(../images/sort_asc.png)}.yasr table.dataTable thead .sorting_desc{background-image:url(../images/sort_desc.png)}.yasr table.dataTable thead .sorting_asc_disabled{background-image:url(../images/sort_asc_disabled.png)}.yasr table.dataTable thead .sorting_desc_disabled{background-image:url(../images/sort_desc_disabled.png)}.yasr table.dataTable tbody tr{background-color:#fff}.yasr table.dataTable tbody tr.selected{background-color:#B0BED9}.yasr table.dataTable tbody th,.yasr table.dataTable tbody td{padding:8px 10px}.yasr table.dataTable.row-border tbody th,.yasr table.dataTable.row-border tbody td,.yasr table.dataTable.display tbody th,.yasr table.dataTable.display tbody td{border-top:1px solid #ddd}.yasr table.dataTable.row-border tbody tr:first-child th,.yasr table.dataTable.row-border tbody tr:first-child td,.yasr table.dataTable.display tbody tr:first-child th,.yasr table.dataTable.display tbody tr:first-child td{border-top:none}.yasr table.dataTable.cell-border tbody th,.yasr table.dataTable.cell-border tbody td{border-top:1px solid #ddd;border-right:1px solid #ddd}.yasr table.dataTable.cell-border tbody tr th:first-child,.yasr table.dataTable.cell-border tbody tr td:first-child{border-left:1px solid #ddd}.yasr table.dataTable.cell-border tbody tr:first-child th,.yasr table.dataTable.cell-border tbody tr:first-child td{border-top:none}.yasr table.dataTable.stripe tbody tr.odd,.yasr table.dataTable.display tbody tr.odd{background-color:#f9f9f9}.yasr table.dataTable.stripe tbody tr.odd.selected,.yasr table.dataTable.display tbody tr.odd.selected{background-color:#abb9d3}.yasr table.dataTable.hover tbody tr:hover,.yasr table.dataTable.display tbody tr:hover{background-color:#f5f5f5}.yasr table.dataTable.hover tbody tr:hover.selected,.yasr table.dataTable.display tbody tr:hover.selected{background-color:#a9b7d1}.yasr table.dataTable.order-column tbody tr>.sorting_1,.yasr table.dataTable.order-column tbody tr>.sorting_2,.yasr table.dataTable.order-column tbody tr>.sorting_3,.yasr table.dataTable.display tbody tr>.sorting_1,.yasr table.dataTable.display tbody tr>.sorting_2,.yasr table.dataTable.display tbody tr>.sorting_3{background-color:#f9f9f9}.yasr table.dataTable.order-column tbody tr.selected>.sorting_1,.yasr table.dataTable.order-column tbody tr.selected>.sorting_2,.yasr table.dataTable.order-column tbody tr.selected>.sorting_3,.yasr table.dataTable.display tbody tr.selected>.sorting_1,.yasr table.dataTable.display tbody tr.selected>.sorting_2,.yasr table.dataTable.display tbody tr.selected>.sorting_3{background-color:#acbad4}.yasr table.dataTable.display tbody tr.odd>.sorting_1,.yasr table.dataTable.order-column.stripe tbody tr.odd>.sorting_1{background-color:#f1f1f1}.yasr table.dataTable.display tbody tr.odd>.sorting_2,.yasr table.dataTable.order-column.stripe tbody tr.odd>.sorting_2{background-color:#f3f3f3}.yasr table.dataTable.display tbody tr.odd>.sorting_3,.yasr table.dataTable.order-column.stripe tbody tr.odd>.sorting_3{background-color:#f5f5f5}.yasr table.dataTable.display tbody tr.odd.selected>.sorting_1,.yasr table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_1{background-color:#a6b3cd}.yasr table.dataTable.display tbody tr.odd.selected>.sorting_2,.yasr table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_2{background-color:#a7b5ce}.yasr table.dataTable.display tbody tr.odd.selected>.sorting_3,.yasr table.dataTable.order-column.stripe tbody tr.odd.selected>.sorting_3{background-color:#a9b6d0}.yasr table.dataTable.display tbody tr.even>.sorting_1,.yasr table.dataTable.order-column.stripe tbody tr.even>.sorting_1{background-color:#f9f9f9}.yasr table.dataTable.display tbody tr.even>.sorting_2,.yasr table.dataTable.order-column.stripe tbody tr.even>.sorting_2{background-color:#fbfbfb}.yasr table.dataTable.display tbody tr.even>.sorting_3,.yasr table.dataTable.order-column.stripe tbody tr.even>.sorting_3{background-color:#fdfdfd}.yasr table.dataTable.display tbody tr.even.selected>.sorting_1,.yasr table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_1{background-color:#acbad4}.yasr table.dataTable.display tbody tr.even.selected>.sorting_2,.yasr table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_2{background-color:#adbbd6}.yasr table.dataTable.display tbody tr.even.selected>.sorting_3,.yasr table.dataTable.order-column.stripe tbody tr.even.selected>.sorting_3{background-color:#afbdd8}.yasr table.dataTable.display tbody tr:hover>.sorting_1,.yasr table.dataTable.order-column.hover tbody tr:hover>.sorting_1{background-color:#eaeaea}.yasr table.dataTable.display tbody tr:hover>.sorting_2,.yasr table.dataTable.order-column.hover tbody tr:hover>.sorting_2{background-color:#ebebeb}.yasr table.dataTable.display tbody tr:hover>.sorting_3,.yasr table.dataTable.order-column.hover tbody tr:hover>.sorting_3{background-color:#eee}.yasr table.dataTable.display tbody tr:hover.selected>.sorting_1,.yasr table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_1{background-color:#a1aec7}.yasr table.dataTable.display tbody tr:hover.selected>.sorting_2,.yasr table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_2{background-color:#a2afc8}.yasr table.dataTable.display tbody tr:hover.selected>.sorting_3,.yasr table.dataTable.order-column.hover tbody tr:hover.selected>.sorting_3{background-color:#a4b2cb}.yasr table.dataTable.no-footer{border-bottom:1px solid #111}.yasr table.dataTable.nowrap th,.yasr table.dataTable.nowrap td{white-space:nowrap}.yasr table.dataTable.compact thead th,.yasr table.dataTable.compact thead td{padding:4px 17px 4px 4px}.yasr table.dataTable.compact tfoot th,.yasr table.dataTable.compact tfoot td{padding:4px}.yasr table.dataTable.compact tbody th,.yasr table.dataTable.compact tbody td{padding:4px}.yasr table.dataTable th.dt-left,.yasr table.dataTable td.dt-left{text-align:left}.yasr table.dataTable th.dt-center,.yasr table.dataTable td.dt-center,.yasr table.dataTable td.dataTables_empty{text-align:center}.yasr table.dataTable th.dt-right,.yasr table.dataTable td.dt-right{text-align:right}.yasr table.dataTable th.dt-justify,.yasr table.dataTable td.dt-justify{text-align:justify}.yasr table.dataTable th.dt-nowrap,.yasr table.dataTable td.dt-nowrap{white-space:nowrap}.yasr table.dataTable thead th.dt-head-left,.yasr table.dataTable thead td.dt-head-left,.yasr table.dataTable tfoot th.dt-head-left,.yasr table.dataTable tfoot td.dt-head-left{text-align:left}.yasr table.dataTable thead th.dt-head-center,.yasr table.dataTable thead td.dt-head-center,.yasr table.dataTable tfoot th.dt-head-center,.yasr table.dataTable tfoot td.dt-head-center{text-align:center}.yasr table.dataTable thead th.dt-head-right,.yasr table.dataTable thead td.dt-head-right,.yasr table.dataTable tfoot th.dt-head-right,.yasr table.dataTable tfoot td.dt-head-right{text-align:right}.yasr table.dataTable thead th.dt-head-justify,.yasr table.dataTable thead td.dt-head-justify,.yasr table.dataTable tfoot th.dt-head-justify,.yasr table.dataTable tfoot td.dt-head-justify{text-align:justify}.yasr table.dataTable thead th.dt-head-nowrap,.yasr table.dataTable thead td.dt-head-nowrap,.yasr table.dataTable tfoot th.dt-head-nowrap,.yasr table.dataTable tfoot td.dt-head-nowrap{white-space:nowrap}.yasr table.dataTable tbody th.dt-body-left,.yasr table.dataTable tbody td.dt-body-left{text-align:left}.yasr table.dataTable tbody th.dt-body-center,.yasr table.dataTable tbody td.dt-body-center{text-align:center}.yasr table.dataTable tbody th.dt-body-right,.yasr table.dataTable tbody td.dt-body-right{text-align:right}.yasr table.dataTable tbody th.dt-body-justify,.yasr table.dataTable tbody td.dt-body-justify{text-align:justify}.yasr table.dataTable tbody th.dt-body-nowrap,.yasr table.dataTable tbody td.dt-body-nowrap{white-space:nowrap}.yasr table.dataTable,.yasr table.dataTable th,.yasr table.dataTable td{box-sizing:content-box}.yasr .dataTables_wrapper{position:relative;clear:both;;zoom:1}.yasr .dataTables_wrapper .dataTables_length{float:left}.yasr .dataTables_wrapper .dataTables_filter{float:right;text-align:right}.yasr .dataTables_wrapper .dataTables_filter input{margin-left:.5em}.yasr .dataTables_wrapper .dataTables_info{clear:both;float:left;padding-top:.755em}.yasr .dataTables_wrapper .dataTables_paginate{float:right;text-align:right;padding-top:.25em}.yasr .dataTables_wrapper .dataTables_paginate .paginate_button{box-sizing:border-box;display:inline-block;min-width:1.5em;padding:.5em 1em;margin-left:2px;text-align:center;text-decoration:none!important;cursor:pointer;;color:#333!important;border:1px solid transparent}.yasr .dataTables_wrapper .dataTables_paginate .paginate_button.current,.yasr .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover{color:#333!important;border:1px solid #cacaca;background-color:#fff;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#fff),color-stop(100%,#dcdcdc));background:-webkit-linear-gradient(top,#fff 0,#dcdcdc 100%);background:linear-gradient(to bottom,#fff 0,#dcdcdc 100%)}.yasr .dataTables_wrapper .dataTables_paginate .paginate_button.disabled,.yasr .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover,.yasr .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active{cursor:default;color:#666!important;border:1px solid transparent;background:0 0;box-shadow:none}.yasr .dataTables_wrapper .dataTables_paginate .paginate_button:hover{color:#fff!important;border:1px solid #111;background-color:#585858;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#585858),color-stop(100%,#111));background:-webkit-linear-gradient(top,#585858 0,#111 100%);background:linear-gradient(to bottom,#585858 0,#111 100%)}.yasr .dataTables_wrapper .dataTables_paginate .paginate_button:active{outline:0;background-color:#2b2b2b;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#2b2b2b),color-stop(100%,#0c0c0c));background:-webkit-linear-gradient(top,#2b2b2b 0,#0c0c0c 100%);background:linear-gradient(to bottom,#2b2b2b 0,#0c0c0c 100%);box-shadow:inset 0 0 3px #111}.yasr .dataTables_wrapper .dataTables_paginate .ellipsis{padding:0 1em}.yasr .dataTables_wrapper .dataTables_processing{position:absolute;top:50%;left:50%;width:100%;height:40px;margin-left:-50%;margin-top:-25px;padding-top:20px;text-align:center;font-size:1.2em;background-color:#fff;background:-webkit-gradient(linear,left top,right top,color-stop(0%,rgba(255,255,255,0)),color-stop(25%,rgba(255,255,255,.9)),color-stop(75%,rgba(255,255,255,.9)),color-stop(100%,rgba(255,255,255,0)));background:-webkit-linear-gradient(left,rgba(255,255,255,0) 0,rgba(255,255,255,.9) 25%,rgba(255,255,255,.9) 75%,rgba(255,255,255,0) 100%);background:linear-gradient(to right,rgba(255,255,255,0) 0,rgba(255,255,255,.9) 25%,rgba(255,255,255,.9) 75%,rgba(255,255,255,0) 100%)}.yasr .dataTables_wrapper .dataTables_length,.yasr .dataTables_wrapper .dataTables_filter,.yasr .dataTables_wrapper .dataTables_info,.yasr .dataTables_wrapper .dataTables_processing,.yasr .dataTables_wrapper .dataTables_paginate{color:#333}.yasr .dataTables_wrapper .dataTables_scroll{clear:both}.yasr .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody{;-webkit-overflow-scrolling:touch}.yasr .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th>div.dataTables_sizing,.yasr .dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td>div.dataTables_sizing{height:0;overflow:hidden;margin:0!important;padding:0!important}.yasr .dataTables_wrapper.no-footer .dataTables_scrollBody{border-bottom:1px solid #111}.yasr .dataTables_wrapper.no-footer div.dataTables_scrollHead table,.yasr .dataTables_wrapper.no-footer div.dataTables_scrollBody table{border-bottom:none}.yasr .dataTables_wrapper:after{visibility:hidden;display:block;content:"";clear:both;height:0}@media screen and (max-width:767px){.yasr .dataTables_wrapper .dataTables_info,.yasr .dataTables_wrapper .dataTables_paginate{float:none;text-align:center}.yasr .dataTables_wrapper .dataTables_paginate{margin-top:.5em}}@media screen and (max-width:640px){.yasr .dataTables_wrapper .dataTables_length,.yasr .dataTables_wrapper .dataTables_filter{float:none;text-align:center}.yasr .dataTables_wrapper .dataTables_filter{margin-top:.5em}}.yasr .pvtUi{color:#333}.yasr table.pvtTable{font-size:8pt;text-align:left;border-collapse:collapse}.yasr table.pvtTable tr th,.yasr table.pvtTable tr th{background-color:#e6EEEE;border:1px solid #CDCDCD;font-size:8pt;padding:5px}.yasr table.pvtTable .pvtColLabel{text-align:center}.yasr table.pvtTable .pvtTotalLabel{text-align:right}.yasr table.pvtTable tr td{color:#3D3D3D;padding:5px;background-color:#FFF;border:1px solid #CDCDCD;vertical-align:top;text-align:right}.yasr .pvtTotal,.yasr .pvtGrandTotal{font-weight:700}.yasr .pvtVals{text-align:center}.yasr .pvtAggregator{margin-bottom:5px}.yasr .pvtAxisContainer,.yasr .pvtVals{border:1px solid gray;background:#EEE;padding:5px;min-width:20px;min-height:20px}.yasr .pvtAxisContainer li{padding:8px 6px;list-style-type:none;cursor:move}.yasr .pvtAxisContainer li.pvtPlaceholder{-webkit-border-radius:5px;padding:3px 15px;border-radius:5px;border:1px dashed #aaa}.yasr .pvtAxisContainer li span.pvtAttr{background:#F3F3F3;border:1px solid #DEDEDE;padding:2px 5px;white-space:nowrap;border-radius:5px}.yasr .pvtTriangle{cursor:pointer;color:grey}.yasr .pvtHorizList li{display:inline}.yasr .pvtVertList{vertical-align:top}.yasr .pvtFilteredAttribute{font-style:italic}.yasr .pvtFilterBox{z-index:100;width:280px;border:1px solid gray;background-color:#fff;position:absolute;padding:20px;text-align:center}.yasr .pvtFilterBox h4{margin:0}.yasr .pvtFilterBox p{margin:1em auto}.yasr .pvtFilterBox label{font-weight:400}.yasr .pvtFilterBox input[type=checkbox]{margin-right:5px}.yasr .pvtCheckContainer{text-align:left;overflow:scroll;width:100%;max-height:200px}.yasr .pvtCheckContainer p{margin:5px}.yasr .pvtRendererArea{padding:5px}.yasr .CodeMirror{font-family:monospace;height:300px}.yasr .CodeMirror-lines{padding:4px 0}.yasr .CodeMirror pre{padding:0 4px}.yasr .CodeMirror-scrollbar-filler,.yasr .CodeMirror-gutter-filler{background-color:#fff}.yasr .CodeMirror-gutters{border-right:1px solid #ddd;background-color:#f7f7f7;white-space:nowrap}.yasr .CodeMirror-linenumber{padding:0 3px 0 5px;min-width:20px;text-align:right;color:#999;box-sizing:content-box}.yasr .CodeMirror-guttermarker{color:#000}.yasr .CodeMirror-guttermarker-subtle{color:#999}.yasr .CodeMirror div.CodeMirror-cursor{border-left:1px solid #000}.yasr .CodeMirror div.CodeMirror-secondarycursor{border-left:1px solid silver}.yasr .CodeMirror.cm-fat-cursor div.CodeMirror-cursor{width:auto;border:0;background:#7e7}.yasr .CodeMirror.cm-fat-cursor div.CodeMirror-cursors{z-index:1}.yasr .cm-animate-fat-cursor{width:auto;border:0;-webkit-animation:blink 1.06s steps(1) infinite;animation:blink 1.06s steps(1) infinite}@-webkit-keyframes blink{0%{background:#7e7}50%{background:0 0}100%{background:#7e7}}@keyframes blink{0%{background:#7e7}50%{background:0 0}100%{background:#7e7}}.yasr .cm-tab{display:inline-block;text-decoration:inherit}.yasr .CodeMirror-ruler{border-left:1px solid #ccc;position:absolute}.yasr .cm-s-default .cm-keyword{color:#708}.yasr .cm-s-default .cm-atom{color:#219}.yasr .cm-s-default .cm-number{color:#164}.yasr .cm-s-default .cm-def{color:#00f}.yasr .cm-s-default .cm-variable-2{color:#05a}.yasr .cm-s-default .cm-variable-3{color:#085}.yasr .cm-s-default .cm-comment{color:#a50}.yasr .cm-s-default .cm-string{color:#a11}.yasr .cm-s-default .cm-string-2{color:#f50}.yasr .cm-s-default .cm-meta{color:#555}.yasr .cm-s-default .cm-qualifier{color:#555}.yasr .cm-s-default .cm-builtin{color:#30a}.yasr .cm-s-default .cm-bracket{color:#997}.yasr .cm-s-default .cm-tag{color:#170}.yasr .cm-s-default .cm-attribute{color:#00c}.yasr .cm-s-default .cm-header{color:#00f}.yasr .cm-s-default .cm-quote{color:#090}.yasr .cm-s-default .cm-hr{color:#999}.yasr .cm-s-default .cm-link{color:#00c}.yasr .cm-negative{color:#d44}.yasr .cm-positive{color:#292}.yasr .cm-header,.yasr .cm-strong{font-weight:700}.yasr .cm-em{font-style:italic}.yasr .cm-link{text-decoration:underline}.yasr .cm-strikethrough{text-decoration:line-through}.yasr .cm-s-default .cm-error{color:red}.yasr .cm-invalidchar{color:red}.yasr div.CodeMirror span.CodeMirror-matchingbracket{color:#0f0}.yasr div.CodeMirror span.CodeMirror-nonmatchingbracket{color:#f22}.yasr .CodeMirror-matchingtag{background:rgba(255,150,0,.3)}.yasr .CodeMirror-activeline-background{background:#e8f2ff}.yasr .CodeMirror{line-height:1;position:relative;overflow:hidden;background:#fff;color:#000}.yasr .CodeMirror-scroll{overflow:scroll!important;margin-bottom:-30px;margin-right:-30px;padding-bottom:30px;height:100%;outline:0;position:relative;box-sizing:content-box}.yasr .CodeMirror-sizer{position:relative;border-right:30px solid transparent;box-sizing:content-box}.yasr .CodeMirror-vscrollbar,.yasr .CodeMirror-hscrollbar,.yasr .CodeMirror-scrollbar-filler,.yasr .CodeMirror-gutter-filler{position:absolute;z-index:6;display:none}.yasr .CodeMirror-vscrollbar{right:0;top:0;overflow-x:hidden;overflow-y:scroll}.yasr .CodeMirror-hscrollbar{bottom:0;left:0;overflow-y:hidden;overflow-x:scroll}.yasr .CodeMirror-scrollbar-filler{right:0;bottom:0}.yasr .CodeMirror-gutter-filler{left:0;bottom:0}.yasr .CodeMirror-gutters{position:absolute;left:0;top:0;z-index:3}.yasr .CodeMirror-gutter{white-space:normal;height:100%;box-sizing:content-box;display:inline-block;margin-bottom:-30px;;}.yasr .CodeMirror-gutter-wrapper{position:absolute;z-index:4;height:100%}.yasr .CodeMirror-gutter-elt{position:absolute;cursor:default;z-index:4}.yasr .CodeMirror-lines{cursor:text;min-height:1px}.yasr .CodeMirror pre{border-radius:0;border-width:0;background:0 0;font-family:inherit;font-size:inherit;margin:0;white-space:pre;word-wrap:normal;line-height:inherit;color:inherit;z-index:2;position:relative;overflow:visible}.yasr .CodeMirror-wrap pre{word-wrap:break-word;white-space:pre-wrap;word-break:normal}.yasr .CodeMirror-linebackground{position:absolute;left:0;right:0;top:0;bottom:0;z-index:0}.yasr .CodeMirror-linewidget{position:relative;z-index:2;overflow:auto}.yasr .CodeMirror-measure{position:absolute;width:100%;height:0;overflow:hidden;visibility:hidden}.yasr .CodeMirror-measure pre{position:static}.yasr .CodeMirror div.CodeMirror-cursor{position:absolute;border-right:none;width:0}.yasr div.CodeMirror-cursors{visibility:hidden;position:relative;z-index:3}.yasr .CodeMirror-focused div.CodeMirror-cursors{visibility:visible}.yasr .CodeMirror-selected{background:#d9d9d9}.yasr .CodeMirror-focused .CodeMirror-selected{background:#d7d4f0}.yasr .CodeMirror-crosshair{cursor:crosshair}.yasr .cm-searching{background:#ffa;background:rgba(255,255,0,.4)}.yasr .cm-force-border{padding-right:.1px}@media print{.yasr .CodeMirror div.CodeMirror-cursors{visibility:hidden}}.yasr .cm-tab-wrap-hack:after{content:''}.yasr span.CodeMirror-selectedtext{background:0 0}.yasr .CodeMirror-foldmarker{color:#00f;text-shadow:#b9f 1px 1px 2px,#b9f -1px -1px 2px,#b9f 1px -1px 2px,#b9f -1px 1px 2px;font-family:arial;line-height:.3;cursor:pointer}.yasr .CodeMirror-foldgutter{width:.7em}.yasr .CodeMirror-foldgutter-open,.yasr .CodeMirror-foldgutter-folded{cursor:pointer}.yasr .CodeMirror-foldgutter-open:after{content:"\25BE"}.yasr .CodeMirror-foldgutter-folded:after{content:"\25B8"}.yasr .svgImg{display:inline-block;bottom:-2px}.yasr button.btn_smallscreen{display:none}.yasr button.btn_smallscreen div,.yasr button.btn_fullscreen div{width:15px;height:15px}.yasr.yasr_fullscreen{z-index:10;position:fixed;overflow:auto;top:0;bottom:0;left:0;right:0}.yasr.yasr_fullscreen .btn_smallscreen{display:inline-block}.yasr.yasr_fullscreen .btn_fullscreen{display:none}.yasr a{color:#428bca;text-decoration:none}.yasr a:hover,.yasr a:active{outline:0;color:#2a6496;text-decoration:underline}.yasr th{text-align:left}.yasr .yasr_header *{z-index:5;position:relative}.yasr .yasr_header>*{margin-left:6px}.yasr .yasr_btn{color:#333;border:1px solid transparent;background-color:#fff;border-color:#ccc;border-width:1px;display:inline-block;text-align:center;vertical-align:middle;cursor:pointer;white-space:nowrap;padding:6px 12px;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-appearance:button;overflow:visible;box-sizing:border-box}.yasr .yasr_btn.btn_icon{padding:4px 8px}.yasr .yasr_btn[disabled],.yasr .yasr_btn.disabled{cursor:default;opacity:.5;filter:alpha(opacity=50);box-shadow:none}.yasr .yasr_btn:hover{outline:0;background-color:#ebebeb;border-color:#adadad}.yasr .yasr_btn:focus,.yasr .yasr_btn.selected{color:#fff;outline:0;background-color:#337ab7;border-color:#337ab7}.yasr .yasr_btn.btn_icon:focus{color:#333;border:1px solid transparent;background-color:#fff;border-color:#ccc}.yasr .yasr_downloadIcon.yasr_btn.btn_icon{padding-top:6px;padding-bottom:6px}.yasr .yasr_downloadIcon.yasr_btn.btn_icon div{height:14px;width:15px}.yasr .yasr_embedBtn.yasr_btn{font-family:Consolas,monospace;padding-left:4px;padding-right:4px}.yasr .yasr_embedPopup{position:absolute;padding:6px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;box-shadow:inset 0 1px 1px rgba(0,0,0,.05);width:700px;height:300px;font-family:Consolas,monospace}.yasr .yasr_embedPopup textarea{width:100%;height:100%;border:0}.yasr .yasr_btnGroup{display:inline-block;vertical-align:middle}.yasr .yasr_btnGroup>button:first-child:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.yasr .yasr_btnGroup>button:last-child:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.yasr .yasr_btnGroup>button:not(:first-child):not(:last-child){border-radius:0}.yasr .yasr_btnGroup button+button{margin-left:-1px}.yasr .toggableWarning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc;padding:15px 35px 15px 15px;border:1px solid transparent;border-radius:4px}.yasr .toggableWarning .toggleWarning{float:right;font-size:21px;cursor:pointer;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.2;position:relative;top:-2px;right:-21px;color:inherit}.yasr .toggableWarning .toggleWarning:hover{color:#000;cursor:pointer;filter:alpha(opacity=50);opacity:.5}.yasr .booleanResult{width:70px;margin:0 auto;vertical-align:middle}.yasr .booleanResult svg{margin-bottom:-10px;margin-right:7px}.yasr .errorResult{padding:10px}.yasr .errorResult .errorHeader{overflow:hidden}.yasr .errorResult .errorHeader .yasr_tryQuery{float:right;padding-top:3px;padding-bottom:3px}.yasr .errorResult .errorHeader span.exception{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em;background-color:#d9534f}.yasr .errorResult pre{display:block;padding:10px;margin:10px 0 10px;font-size:13px;line-height:1.42857;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}.yasr .errorResult .corsMessage{color:#a94442;background-color:#f2dede;margin-top:10px;padding:5px;border:1px solid #ebccd1;border-radius:4px}.yasr .yasr_results .CodeMirror{border:1px solid #d1d1d1;margin-top:5px;height:100%}.yasr .dataTables_wrapper{margin-top:10px}.yasr .dataTables_wrapper .dataTables_length{float:right;margin-left:10px}.yasr .dataTables_wrapper .dataTables_length label,.yasr .dataTables_wrapper .dataTables_length select{vertical-align:middle}.yasr table.dataTable thead th{background:none!important;border-right:1px dotted gray;padding:7px 0}.yasr table.dataTable thead th:first-child,.yasr table.dataTable thead th:last-child{border-right:0}.yasr table.dataTable thead th span{margin-left:5px}.yasr table.dataTable td div{-ms-word-break:break-all;word-break:break-all;word-break:break-word;-webkit-hyphens:auto;-moz-hyphens:auto;-ms-hyphens:auto;hyphens:auto;padding:0 5px}.yasr .sortIcons{float:right;width:8px;height:13px;margin-right:10px}.yasr .dtTopHeader .dataTables_info{padding-top:0;margin:0 10px}.yasr .pivotTable{margin-top:5px}.yasr .pivotTable>table{background-color:#fff}.yasr .pivotTable td.pvtAxisContainer,.yasr .pivotTable td.pvtVals{border:1px solid #ddd;background-color:transparent}.yasr .pivotTable li span.pvtAttr{background-color:#337ab7;color:#fff;padding:4px 7px}.yasr .pivotTable li span.pvtAttr svg{fill:#fff}.yasr .pivotTable li span.pvtAttr div{margin-left:6px;vertical-align:middle}.yasr .pivotTable .pvtCols{vertical-align:top}.yasr .pivotTable table.pvtTable tr th{background-color:#f2f2f2}.yasr .pivotTable table.pvtTable tr th.pvtAxisLabel{background-color:#337ab7;color:#fff}.yasr .pivotTable .containerHeader{margin-left:8px;margin-bottom:8px;font-style:italic;font-size:110%;color:#999;text-align:left}.yasr .pivotTable .pvtAttr .svgImg{width:14px;height:14px}.yasr .pivotTable .node{border:solid 1px #fff;font:10px sans-serif;line-height:12px;overflow:hidden;position:absolute;text-indent:2px}.yasr .openPivotGchart{float:right;position:relative;display:none;top:-38px;margin-bottom:-38px}.yasr .openGchartBtn{float:right;position:relative;top:-35px;margin-bottom:-35px}.yasr .gchartWrapper{width:100%;height:600px;margin-top:2px}.modal-dialog.google-visualization-charteditor-dialog{z-index:11;width:auto;margin:inherit}.modal-dialog.google-visualization-charteditor-dialog .charts-flat-menu-button{box-sizing:content-box} \ No newline at end of file diff --git a/triplestores/fuseki/webapp/dataset.html b/triplestores/fuseki/webapp/dataset.html deleted file mode 100644 index 229bcfca19..0000000000 --- a/triplestores/fuseki/webapp/dataset.html +++ /dev/null @@ -1,247 +0,0 @@ - - - - Apache Jena Fuseki - inspect dataset - - - - - - - - - - - - - - - - - - - - - -
      - -
      -
      -
      -
      -
      - -
      -
      -
      - - - -
      -
      -
      Please select a dataset.
      - -
      - -
      -
      Please select a dataset.
      - -
      - -
      -
      Please select a dataset.
      - -
      - -
      -
      Please select a dataset.
      - -
      - -
      -
      -
      -
      - -
      - - - diff --git a/triplestores/fuseki/webapp/documentation.html b/triplestores/fuseki/webapp/documentation.html deleted file mode 100644 index d12f1e74f1..0000000000 --- a/triplestores/fuseki/webapp/documentation.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - Apache Jena Fuseki - documentation - - - - - - - - - - - - - - - - - - - - diff --git a/triplestores/fuseki/webapp/fonts/FontAwesome.otf b/triplestores/fuseki/webapp/fonts/FontAwesome.otf deleted file mode 100644 index 3461e3fce6..0000000000 Binary files a/triplestores/fuseki/webapp/fonts/FontAwesome.otf and /dev/null differ diff --git a/triplestores/fuseki/webapp/fonts/fontawesome-webfont.eot b/triplestores/fuseki/webapp/fonts/fontawesome-webfont.eot deleted file mode 100755 index 6cfd566095..0000000000 Binary files a/triplestores/fuseki/webapp/fonts/fontawesome-webfont.eot and /dev/null differ diff --git a/triplestores/fuseki/webapp/fonts/fontawesome-webfont.svg b/triplestores/fuseki/webapp/fonts/fontawesome-webfont.svg deleted file mode 100755 index a9f8469503..0000000000 --- a/triplestores/fuseki/webapp/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,504 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/triplestores/fuseki/webapp/fonts/fontawesome-webfont.ttf b/triplestores/fuseki/webapp/fonts/fontawesome-webfont.ttf deleted file mode 100755 index 5cd6cff6d6..0000000000 Binary files a/triplestores/fuseki/webapp/fonts/fontawesome-webfont.ttf and /dev/null differ diff --git a/triplestores/fuseki/webapp/fonts/fontawesome-webfont.woff b/triplestores/fuseki/webapp/fonts/fontawesome-webfont.woff deleted file mode 100755 index 9eaecb3799..0000000000 Binary files a/triplestores/fuseki/webapp/fonts/fontawesome-webfont.woff and /dev/null differ diff --git a/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.eot b/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.eot deleted file mode 100644 index 4a4ca865d6..0000000000 Binary files a/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.eot and /dev/null differ diff --git a/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.svg b/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.svg deleted file mode 100644 index e3e2dc739d..0000000000 --- a/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.svg +++ /dev/null @@ -1,229 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.ttf b/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.ttf deleted file mode 100644 index 67fa00bf83..0000000000 Binary files a/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.ttf and /dev/null differ diff --git a/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.woff b/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.woff deleted file mode 100644 index 8c54182aa5..0000000000 Binary files a/triplestores/fuseki/webapp/fonts/glyphicons-halflings-regular.woff and /dev/null differ diff --git a/triplestores/fuseki/webapp/images/back_disabled.png b/triplestores/fuseki/webapp/images/back_disabled.png deleted file mode 100644 index 881de7976f..0000000000 Binary files a/triplestores/fuseki/webapp/images/back_disabled.png and /dev/null differ diff --git a/triplestores/fuseki/webapp/images/back_enabled.png b/triplestores/fuseki/webapp/images/back_enabled.png deleted file mode 100644 index c608682b04..0000000000 Binary files a/triplestores/fuseki/webapp/images/back_enabled.png and /dev/null differ diff --git a/triplestores/fuseki/webapp/images/back_enabled_hover.png b/triplestores/fuseki/webapp/images/back_enabled_hover.png deleted file mode 100644 index d300f1064b..0000000000 Binary files a/triplestores/fuseki/webapp/images/back_enabled_hover.png and /dev/null differ diff --git a/triplestores/fuseki/webapp/images/favicon.ico b/triplestores/fuseki/webapp/images/favicon.ico deleted file mode 100644 index f5d685e085..0000000000 Binary files a/triplestores/fuseki/webapp/images/favicon.ico and /dev/null differ diff --git a/triplestores/fuseki/webapp/images/forward_disabled.png b/triplestores/fuseki/webapp/images/forward_disabled.png deleted file mode 100644 index 6a6ded7de8..0000000000 Binary files a/triplestores/fuseki/webapp/images/forward_disabled.png and /dev/null differ diff --git a/triplestores/fuseki/webapp/images/forward_enabled.png b/triplestores/fuseki/webapp/images/forward_enabled.png deleted file mode 100644 index a4e6b5384b..0000000000 Binary files a/triplestores/fuseki/webapp/images/forward_enabled.png and /dev/null differ diff --git a/triplestores/fuseki/webapp/images/forward_enabled_hover.png b/triplestores/fuseki/webapp/images/forward_enabled_hover.png deleted file mode 100644 index fc46c5ebf0..0000000000 Binary files a/triplestores/fuseki/webapp/images/forward_enabled_hover.png and /dev/null differ diff --git a/triplestores/fuseki/webapp/images/jena-logo-notext-small.png b/triplestores/fuseki/webapp/images/jena-logo-notext-small.png deleted file mode 100644 index 2990c2d14e..0000000000 Binary files a/triplestores/fuseki/webapp/images/jena-logo-notext-small.png and /dev/null differ diff --git a/triplestores/fuseki/webapp/images/sort_asc.png b/triplestores/fuseki/webapp/images/sort_asc.png deleted file mode 100644 index a88d7975fe..0000000000 Binary files a/triplestores/fuseki/webapp/images/sort_asc.png and /dev/null differ diff --git a/triplestores/fuseki/webapp/images/sort_asc_disabled.png b/triplestores/fuseki/webapp/images/sort_asc_disabled.png deleted file mode 100644 index 4e144cf0b1..0000000000 Binary files a/triplestores/fuseki/webapp/images/sort_asc_disabled.png and /dev/null differ diff --git a/triplestores/fuseki/webapp/images/sort_both.png b/triplestores/fuseki/webapp/images/sort_both.png deleted file mode 100644 index 18670406bc..0000000000 Binary files a/triplestores/fuseki/webapp/images/sort_both.png and /dev/null differ diff --git a/triplestores/fuseki/webapp/images/sort_desc.png b/triplestores/fuseki/webapp/images/sort_desc.png deleted file mode 100644 index def071ed5a..0000000000 Binary files a/triplestores/fuseki/webapp/images/sort_desc.png and /dev/null differ diff --git a/triplestores/fuseki/webapp/images/sort_desc_disabled.png b/triplestores/fuseki/webapp/images/sort_desc_disabled.png deleted file mode 100644 index 7824973cc6..0000000000 Binary files a/triplestores/fuseki/webapp/images/sort_desc_disabled.png and /dev/null differ diff --git a/triplestores/fuseki/webapp/images/wait30.gif b/triplestores/fuseki/webapp/images/wait30.gif deleted file mode 100644 index 9337ee2162..0000000000 Binary files a/triplestores/fuseki/webapp/images/wait30.gif and /dev/null differ diff --git a/triplestores/fuseki/webapp/index.html b/triplestores/fuseki/webapp/index.html deleted file mode 100644 index d9aa2cb93a..0000000000 --- a/triplestores/fuseki/webapp/index.html +++ /dev/null @@ -1,101 +0,0 @@ - - - - Apache Jena Fuseki - - - - - - - - - - - - - - - - -
      -
      -
      -

      Apache Jena Fuseki

      -
      - -
      -
      -
      - -
      -
      -

      - Datasets on this server -

      -
      -
      -
      - -
      -
      -

      Use the following pages to perform actions or tasks on this server:

      -
      -
      Dataset
      -
      Run queries and modify datasets hosted by this server.
      -
      Manage datasets
      -
      Administer the datasets on this server, including adding datasets, - uploading data and performing backups.
      -
      Help
      -
      Summary of commands and links to online documentation.
      -
      -
      -
      -
      - - - diff --git a/triplestores/fuseki/webapp/js/app/controllers/.svnkeep b/triplestores/fuseki/webapp/js/app/controllers/.svnkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/triplestores/fuseki/webapp/js/app/controllers/dataset-controller.js b/triplestores/fuseki/webapp/js/app/controllers/dataset-controller.js deleted file mode 100644 index 4080c8467c..0000000000 --- a/triplestores/fuseki/webapp/js/app/controllers/dataset-controller.js +++ /dev/null @@ -1,69 +0,0 @@ -/** Controller for the dataset.html page */ - -define( - function( require ) { - - var Marionette = require( "marionette" ), - Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - DatasetSelectorView = require( "app/views/dataset-selector" ), - TabbedViewManagerView = require( "app/views/tabbed-view-manager" ), - FileUploadView = require( "app/views/file-upload" ), - DatasetInfoView = require( "app/views/dataset-info" ), - DatasetEditView = require( "app/views/dataset-edit" ), - QueryController = require( "app/controllers/query-controller" ), - UploadController = require( "app/controllers/upload-controller" ); - - var DatasetController = function() { - this.initEvents(); - }; - - // add the behaviours defined on the controller - _.extend( DatasetController.prototype, { - - initEvents: function() { - _.bindAll( this, "onServerModelReady", "onDatasetChanged" ); - - if (fui.models.fusekiServer && fui.models.fusekiServer.get( "ready" )) { - this.onServerModelReady(); - } - else { - fui.vent.on( "models.fuseki-server.ready", this.onServerModelReady ); - } - - fui.vent.on( "dataset.changed", this.onDatasetChanged ); - }, - - /** - * When the fuseki server is ready, we can list the initial datasets, and - * start the tab manager to manage the tabbed content. - **/ - onServerModelReady: function() { - fui.views.datasetSelectorView = new DatasetSelectorView( {model: fui.models.fusekiServer} ) - fui.views.datasetSelectorView.render(); - - fui.views.tabbedViewManagerView = new TabbedViewManagerView(); - fui.views.tabbedViewManagerView.render(); - - fui.controllers.queryController = new QueryController(); - fui.controllers.uploadController = new UploadController(); - - }, - - /** Dataset has changed */ - onDatasetChanged: function( dsName ) { - var dataset = fui.models.fusekiServer.dataset( dsName ); - fui.views.datasetInfoView = new DatasetInfoView( {model: dataset} ); - fui.views.datasetInfoView.render(); - - fui.views.datasetEditView = new DatasetEditView( {model: dataset} ); - fui.views.datasetEditView.render(); - } - - } ); - - return DatasetController; - - } -); \ No newline at end of file diff --git a/triplestores/fuseki/webapp/js/app/controllers/index-controller.js b/triplestores/fuseki/webapp/js/app/controllers/index-controller.js deleted file mode 100644 index 8dba423b77..0000000000 --- a/triplestores/fuseki/webapp/js/app/controllers/index-controller.js +++ /dev/null @@ -1,50 +0,0 @@ -/** Controller for the main index.html page */ -define( - function( require ) { - var Marionette = require( "marionette" ), - Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - sprintf = require( "sprintf" ), - DatasetSelectionListView = require( "app/views/dataset-selection-list" ); - - var IndexController = function() { - this.initEvents(); - }; - - // add the behaviours defined on the controller - _.extend( IndexController.prototype, { - - initEvents: function() { - _.bindAll( this, "onServerModelReady" ); - fui.vent.on( "models.fuseki-server.ready", this.onServerModelReady ); - }, - - onServerModelReady: function() { - new DatasetSelectionListView( {model: fui.models.fusekiServer} ).render(); - this.displayVersion(); - }, - - /** Display the fuseki software version */ - displayVersion: function() { - var sd = fui.models.fusekiServer.get( "serverDescription" ); - var version = sd.version; - var uptime = sd.uptime; - var s = uptime % 60; - var m = Math.floor( (uptime / 60) % 60 ); - var h = Math.floor( (uptime / (60 * 60)) % 24 ); - var d = Math.floor( (uptime / (60 * 60 * 24)) ); - - var status = sprintf( "Version %s. Uptime: %s %s %dm %02ds", - version, - (d > 0 ? d + "d" : ""), - (h > 0 ? h + "h" : ""), - m, s ); - $('.host-details').html( status ); - } - - } ); - - return IndexController; - } -); diff --git a/triplestores/fuseki/webapp/js/app/controllers/manage-controller.js b/triplestores/fuseki/webapp/js/app/controllers/manage-controller.js deleted file mode 100644 index e789844590..0000000000 --- a/triplestores/fuseki/webapp/js/app/controllers/manage-controller.js +++ /dev/null @@ -1,39 +0,0 @@ -/** Controller for the admin/data-management.html page */ -define( - function( require ) { - var Marionette = require( "marionette" ), - Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - TabbedViewManagerView = require( "app/views/tabbed-view-manager" ), - DatasetSimpleCreateView = require( "app/views/dataset-simple-create" ), - DatasetManagementView = require( "app/views/dataset-management" ); - - var ManageController = function() { - this.initEvents(); - }; - - _.extend( ManageController.prototype, { - - initEvents: function() { - _.bindAll( this, "onServerModelReady" ); - fui.vent.on( "models.fuseki-server.ready", this.onServerModelReady ); - }, - - /** When the fuseki server is ready, we can list the initial datasets */ - onServerModelReady: function( event ) { - fui.views.datasetManagement = new DatasetManagementView( {model: fui.models.fusekiServer} ); - fui.views.datasetManagement.render(); - - fui.views.tabbedViewManagerView = new TabbedViewManagerView(); - fui.views.tabbedViewManagerView.render(); - - fui.views.datasetSimpleCreate = new DatasetSimpleCreateView(); - fui.views.datasetSimpleCreate.render(); - } - - } ); - - return ManageController; - } -); diff --git a/triplestores/fuseki/webapp/js/app/controllers/query-controller.js b/triplestores/fuseki/webapp/js/app/controllers/query-controller.js deleted file mode 100644 index d2fd11b195..0000000000 --- a/triplestores/fuseki/webapp/js/app/controllers/query-controller.js +++ /dev/null @@ -1,72 +0,0 @@ -/** - * Controller for the embedded Qonsole component. - * - * Note: unlike some Qonsole installations, the endpoint URL selector dropdown - * has been removed in favour of the dataset selector control higher up the page. - **/ - -define( - function( require ) { - var Marionette = require( "marionette" ), - Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - qonsole = require( "qonsole" ), - pageUtils = require( "app/util/page-utils" ); - - var QueryController = function() { - this.initEvents(); - }; - - // add the behaviours defined on the controller - _.extend( QueryController.prototype, { - - initEvents: function() { - _.bindAll( this, "onServerModelReady", "onDatasetChanged" ); - - if (fui.models.fusekiServer && fui.models.fusekiServer.get( "ready" )) { - this.onServerModelReady(); - } - else { - fui.vent.on( "models.fuseki-server.ready", this.onServerModelReady ); - } - - fui.vent.on( "dataset.changed", this.onDatasetChanged ); - }, - - /** Initialise the qonsole component */ - initQonsole: function( datasetsConfig ) { - var qonfig = require( "app/qonsole-config" ); - qonsole.init( qonfig ); - - var dsName = fui.models.fusekiServer.selectedDatasetName(); - if (dsName) { - this.setEndpointURL( dsName ); - } - }, - - /** When the fuseki server is ready, we can init the qonsole */ - onServerModelReady: function( event ) { - var fusekiServer = fui.models.fusekiServer; - var endpoints = {}; - var datasets = fusekiServer.datasets(); - - this.initQonsole( {} ); - }, - - /** When notified that the selected dataset name has changed, update the endpoint URL */ - onDatasetChanged: function( dsName ) { - this.setEndpointURL( dsName ); - }, - - /** Set the endpoint URL based on the selected dataset name */ - setEndpointURL: function( dsName ) { - var dataset = fui.models.fusekiServer.dataset( dsName ); - qonsole.setCurrentEndpoint( dataset.queryURL() ); - } - - } ); - - return QueryController; - } -); diff --git a/triplestores/fuseki/webapp/js/app/controllers/upload-controller.js b/triplestores/fuseki/webapp/js/app/controllers/upload-controller.js deleted file mode 100644 index ace254726a..0000000000 --- a/triplestores/fuseki/webapp/js/app/controllers/upload-controller.js +++ /dev/null @@ -1,42 +0,0 @@ -/** Controller for the file uploader component */ - -define( - function( require ) { - var Marionette = require( "marionette" ), - Backbone = require( "backbone" ), - _ = require( "underscore" ), - sprintf = require("sprintf"), - pageUtils = require( "app/util/page-utils" ), - fui = require( "app/fui" ), - FileUploadView = require( "app/views/file-upload" ); - - var UploadController = function() { - this.initialize(); - }; - - _.extend( UploadController.prototype, { - - /** Initialize the controler */ - initialize: function() { - if (fui.models.fusekiServer && fui.models.fusekiServer.get( "ready" )) { - this.onServerModelReady(); - } - else { - _.bindAll( this, "onServerModelReady" ); - fui.vent.on( "models.fuseki-server.ready", this.onServerModelReady ); - } - - }, - - /** When the fuseki server is ready, we can set up the initial view */ - onServerModelReady: function( event ) { - var fusekiServer = fui.models.fusekiServer; - - fui.views.fileUploadView = new FileUploadView(); - fui.views.fileUploadView.render(); - }, - } ); - - return UploadController; - } -); diff --git a/triplestores/fuseki/webapp/js/app/controllers/validation-controller.js b/triplestores/fuseki/webapp/js/app/controllers/validation-controller.js deleted file mode 100644 index 43ed8ceaa3..0000000000 --- a/triplestores/fuseki/webapp/js/app/controllers/validation-controller.js +++ /dev/null @@ -1,38 +0,0 @@ -/** Controller for the main index.html page */ -define( - function( require ) { - var Marionette = require( "marionette" ), - Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - ValidationOptions = require( "app/views/validation-options" ), - ValidationService = require( "app/services/validation-service" ); - - var ValidationController = function() { - this.initServices(); - this.initEvents(); - }; - - // add the behaviours defined on the controller - _.extend( ValidationController.prototype, { - initEvents: function() { - fui.vent.on( "models.validation-options.ready", this.onValidationOptionsModelReady ); - $(".validation").on( "click", "a.perform-validation", function( event ) { - fui.services.validation.performValidation( fui.views.validationOptions.model ); - } ); - }, - - onValidationOptionsModelReady: function( e ) { - fui.views.validationOptions = new ValidationOptions( {model: fui.models.validationOptions} ); - }, - - initServices: function() { - fui.services.validation = new ValidationService( "#query-edit-cm", "#validation-output-cm" ); - fui.services.validation.init(); - } - - } ); - - return ValidationController; - } -); diff --git a/triplestores/fuseki/webapp/js/app/fui.js b/triplestores/fuseki/webapp/js/app/fui.js deleted file mode 100644 index e8bc41df5a..0000000000 --- a/triplestores/fuseki/webapp/js/app/fui.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Top-level application code module for Fuseki UI - */ - -define( ['require', 'backbone', 'marionette'], - function( require, Backbone, Marionette ) { - // define the application object, and add it to the global namespace - var fui = new Marionette.Application(); - - // define some Marionette modules, because they have a lifecycle component - // see https://github.com/marionettejs/backbone.marionette/wiki/AMD-Modules-vs-Marionette%27s-Modules - fui.module( "models" ); - fui.module( "views" ); - fui.module( "layouts" ); - fui.module( "controllers" ); - fui.module( "services" ); - - // define top-level regions where our layouts will go - fui.addRegions({ - }); - - fui.on('initialize:before', function( options ) { - }); - - fui.on('initialize:after', function( options ) { - // Backbone.history.start(); - this.initialized = true; - }); - - - return fui; - } -); diff --git a/triplestores/fuseki/webapp/js/app/layouts/.svnkeep b/triplestores/fuseki/webapp/js/app/layouts/.svnkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/triplestores/fuseki/webapp/js/app/main.dataset.js b/triplestores/fuseki/webapp/js/app/main.dataset.js deleted file mode 100644 index 50ba27bb08..0000000000 --- a/triplestores/fuseki/webapp/js/app/main.dataset.js +++ /dev/null @@ -1,31 +0,0 @@ -/** RequireJS dependency configuration for dataset.html page */ - -define( ['require', '../common-config'], - function( require ) { - require( - ['underscore', 'jquery', 'backbone', 'marionette', 'app/fui', 'app/controllers/dataset-controller', - 'sprintf', - 'bootstrap-select.min', - 'app/controllers/query-controller', - 'app/controllers/upload-controller', - 'app/models/fuseki-server', - 'app/models/dataset', - 'app/views/dataset-selector', - 'app/views/tabbed-view-manager', - 'app/services/ping-service', - 'jquery.xdomainrequest', - 'jquery.form', - 'jquery.fileupload' - ], - function( _, $, Backbone, Marionette, fui, DatasetController ) { - var options = { }; - - // initialise the backbone application - fui.controllers.datasetController = new DatasetController(); - fui.start( options ); - - // additional services - require( 'app/services/ping-service' ).start(); - }); - } -); diff --git a/triplestores/fuseki/webapp/js/app/main.index.js b/triplestores/fuseki/webapp/js/app/main.index.js deleted file mode 100644 index 56c8903d8a..0000000000 --- a/triplestores/fuseki/webapp/js/app/main.index.js +++ /dev/null @@ -1,24 +0,0 @@ - -define( ['require', '../common-config'], - function( require ) { - require( - ['underscore', 'jquery', 'backbone', 'marionette', - 'app/fui', 'app/controllers/index-controller', - 'sprintf', 'bootstrap', - 'app/models/fuseki-server', - 'app/models/dataset', - 'app/views/dataset-selection-list', - 'app/services/ping-service' - ], - function( _, $, Backbone, Marionette, fui, IndexController ) { - var options = { }; - - // initialise the backbone application - fui.controllers.indexController = new IndexController(); - fui.start( options ); - - // additional services - require( 'app/services/ping-service' ).start(); - }); - } -); \ No newline at end of file diff --git a/triplestores/fuseki/webapp/js/app/main.manage.js b/triplestores/fuseki/webapp/js/app/main.manage.js deleted file mode 100644 index 312972c71e..0000000000 --- a/triplestores/fuseki/webapp/js/app/main.manage.js +++ /dev/null @@ -1,27 +0,0 @@ - -define( ['require', '../common-config'], - function( require ) { - require( - ['underscore', 'jquery', 'backbone', 'marionette', - 'app/fui', 'app/controllers/manage-controller', - 'sprintf', 'bootstrap', - 'app/models/fuseki-server', - 'app/models/dataset', - 'app/models/task', - 'app/views/dataset-management', - 'app/services/ping-service', - 'jquery.xdomainrequest' - ], - function( _, $, Backbone, Marionette, fui, ManageController ) { - - var options = { } ; - - // initialise the backbone application - fui.controllers.manageController = new ManageController(); - fui.start( options ); - - // additional services - require( 'app/services/ping-service' ).start(); - }); - } -); diff --git a/triplestores/fuseki/webapp/js/app/main.validation.js b/triplestores/fuseki/webapp/js/app/main.validation.js deleted file mode 100644 index 0e30fad4c2..0000000000 --- a/triplestores/fuseki/webapp/js/app/main.validation.js +++ /dev/null @@ -1,24 +0,0 @@ - -define( ['require', '../common-config'], - function( require ) { - require( - ['underscore', 'jquery', 'backbone', 'marionette', - 'app/fui', 'app/controllers/validation-controller', - 'sprintf', 'bootstrap', - 'app/models/validation-options', - 'app/services/ping-service', - 'app/services/validation-service', - 'jquery.xdomainrequest' - ], - function( _, $, Backbone, Marionette, fui, ValidationController ) { - var options = { } ; - - // initialise the backbone application - fui.controllers.validationController = new ValidationController(); - fui.start( options ); - - // additional services -// require( 'services/ping-service' ).start(); TODO restore - }); - } -); \ No newline at end of file diff --git a/triplestores/fuseki/webapp/js/app/models/dataset-stats.js b/triplestores/fuseki/webapp/js/app/models/dataset-stats.js deleted file mode 100644 index 35527c7d0e..0000000000 --- a/triplestores/fuseki/webapp/js/app/models/dataset-stats.js +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Backbone model denoting statistics on a dataset - */ -define( - function( require ) { - "use strict"; - - var Marionette = require( "marionette" ), - Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - sprintf = require( "sprintf" ); - - /** - * This model represents the statistics available on a one or more datasets - */ - var DatasetStats = Backbone.Model.extend( { - initialize: function( dataset, stats ) { - this.set( {dataset: dataset, stats: stats} ); - }, - - /** Return the number of datasets we have statistics for */ - size: function() { - return _.keys( datasets() ).length; - }, - - toJSON: function() { - return this.asTable(); - }, - - /** Return a table of the statistics we have, one row per dataset */ - asTable: function() { - var ds = this.datasets(); - var endpoints = this.collectEndpoints( ds ); - var rows = []; - - _.each( ds, function( d, dsName ) { - var row = [dsName, d.Requests, d.RequestsGood, d.RequestsBad]; - var es = d.endpoints; - - _.each( endpoints, function( e ) { - if (es[e.key]) { - var servStats = es[e.key]; - - if (servStats.Requests === 0) { - row.push( "0" ); - } - else { - row.push( sprintf( "%d (%d bad)", servStats.Requests, servStats.RequestsBad )) - } - } - else { - row.push( "–" ); - } - } ); - - rows.push( row ); - } ); - - return {headings: this.columnHeadings( endpoints ), rows: rows}; - }, - - stats: function() { - return this.get( "stats" ); - }, - - datasets: function() { - return this.stats().datasets; - }, - - /** Reload the numbers from the server */ - refresh: function() { - var self = this; - - this.get( "dataset" ) - .statistics() - .done( function( data ) { - self.set( "stats", data ); - } ); - }, - - // internal methods - - collectEndpoints: function( ds ) { - var endpoints = []; - _.each( ds, function( d ) { - var ep = _.each( d.endpoints, function( v, k ) { - endpoints.push( {key: k, label: v.description} ); - } ); - } ); - - return _.uniq( endpoints ).sort(); - }, - - columnHeadings: function( services ) { - return ["Name", "Overall", "Overall good", "Overall bad"].concat( _.pluck( services, 'label' ) ); - } - } ); - - return DatasetStats; - } -); \ No newline at end of file diff --git a/triplestores/fuseki/webapp/js/app/models/dataset.js b/triplestores/fuseki/webapp/js/app/models/dataset.js deleted file mode 100644 index 9c911c2621..0000000000 --- a/triplestores/fuseki/webapp/js/app/models/dataset.js +++ /dev/null @@ -1,254 +0,0 @@ -/** - * Backbone model denoting the remote Fuseki server. - */ -define( - function( require ) { - "use strict"; - - var Marionette = require( "marionette" ), - Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - sprintf = require( "sprintf" ), - Task = require( "app/models/task" ); - - /** - * This model represents the core representation of the remote Fuseki - * server. Individual datasets have their own model. - */ - var Dataset = Backbone.Model.extend( { - initialize: function( datasetDescription, baseURL, mgmtURL ) { - this.set( datasetDescription ); - this.set( { - baseURL: baseURL, - mgmtURL: mgmtURL, - counts: {}, - countPerformed: false, - counting: false, - statistics: false - } ); - }, - - baseURL: function() { - return this.get( "baseURL" ); - }, - - mgmtURL: function() { - return this.get( "mgmtURL" ); - }, - - mgmtActionURL: function() { - return this.get( "mgmtURL" ) + this.name(); - }, - - statisticsURL: function() { - return sprintf( "%s/$/stats%s", this.baseURL(), this.name() ); - }, - - name: function() { - return this.get( "ds.name" ); - }, - - services: function() { - return this.get( "ds.services" ); - }, - - countPerformed: function() { - return this.get( "countPerformed" ); - }, - - counts: function() { - return this.get( "counts" ); - }, - - serviceTypes: function() { - return _.map( this.services(), function( s ) {return s["srv.type"];} ); - }, - - /** Return a descriptive data-structure listing all this datasets services */ - servicesDescription: function() { - var description = []; - var self = this; - - _.each( this.services(), function( s ) { - _.each( s["srv.endpoints"], function( e ) { - description.push( {label: s["srv.description"], - url: self.datasetEndpointURL( e ) - } ); - } ); - } ); - - description.sort( function( d0, d1 ) { - return (d0.label < d1.label) ? -1 : (d0.label > d1.label ? 1 : 0); - } ); - - return description; - }, - - /** Return the first service that has the given type */ - serviceOfType: function( serviceType ) { - return _.find( this.services(), function( s ) { - return s["srv.type"] === serviceType; - } ); - }, - - /** Return the first endpoint of the first service that has the given type */ - endpointOfType: function( serviceType ) { - var service = this.serviceOfType( serviceType ); - return service && _.first( service["srv.endpoints"] ); - }, - - /* Return URL for a service of a given type or null, if no such service */ - endpointURL: function( serviceType ) { - var endpoint = this.endpointOfType( serviceType ); - return endpoint ? this.datasetEndpointURL( endpoint ) : null; - }, - - /** Return the URL for the given endpoint */ - datasetEndpointURL: function( endpoint ) { - return sprintf( "%s%s/%s", this.baseURL(), this.name(), endpoint ); - }, - - /** Return the sparql query URL for this dataset, if it has one, or null */ - queryURL: function() { - return this.endpointURL( "Query" ) ; - }, - - /** Return the sparql query URL for this dataset, if it has one, or null */ - quadsURL: function() { - return this.endpointURL( "Quads" ) ; - }, - - /** Return the sparql update URL for this dataset, if it has one, or null */ - updateURL: function() { - return this.endpointURL( "Update" ) ; - }, - - /** Return the GSP write URL for this dataset, if it has one, or null */ - graphStoreProtocolURL: function() { - if ( this.endpointURL( "GSP" ) ) - // Old name - return this.endpointURL( "GSP" ) ; - return this.endpointURL( "GSP_RW" ) ; - }, - - /** Return the GSP read URL for this dataset, if it has one, or null */ - graphStoreProtocolReadURL: function() { - return this.endpointURL( "GSP_R" ) ; - }, - - /** Return the upload URL for this dataset, if it has one, or null */ - uploadURL: function( graphName ) { - if (this.graphStoreProtocolURL() !== null) { - return sprintf( "%s%s", this.graphStoreProtocolURL(), (graphName === "default" ? "" : ("?graph=" + graphName) )); - } - else { - return null; - } - }, - - /** Perform the action to delete the dataset. Returns the Ajax deferred object */ - deleteDataset: function() { - return $.ajax( { - url: this.mgmtActionURL(), - type: 'DELETE' - } ); - }, - - /** Perform the action of taking a backup of this dataset */ - backupDataset: function() { - var backupURL = sprintf( "%s/$/backup%s", this.baseURL(), this.name() ); - var ds = this; - - return $.ajax( { - url: backupURL, - type: 'POST' - } ) - .done( function( taskDescription ) { - new Task( ds, "backup", taskDescription ); - } ); - }, - - /** - * Request the statistics for this dataset, and return the promise object for the callback. - * @param keep If truthy, and we have existing statistics, re-use the existing stats - * */ - statistics: function( keep ) { - var self = this; - var currentStats = this.get( "statistics" ); - - if (currentStats && keep) { - return $.Deferred().resolveWith( null, currentStats ); - } - else { - return $.getJSON( this.statisticsURL() ) - .then( function( data ) { - self.set( "statistics", data ); - return data; - } ); - } - }, - - /** Perform a count query to determine the size of the dataset. Changes the size property when done, - * but also returns the JQuery promise object used to monitor the query response */ - count: function() { - var self = this; - var query1 = sprintf( "select (count(*) as ?count) {?s ?p ?o}" ); - var query2 = sprintf( "select ?g (count(*) as ?count) {graph ?g {?s ?p ?o}} group by ?g" ); - - self.set( "counting", true ); - - var updateCount = function( model, result, graph ) { - var n = parseInt( result.count.value ); - var counts = _.extend( {}, model.get( "counts" ) ); - counts[graph] = n; - model.set( "counts", counts ); - }; - - $.getJSON( sprintf( "%s?query=%s", self.queryURL(), query1 ) ) - .done( function( data ) { - updateCount( self, data.results.bindings[0], "default graph" ); - - $.getJSON( sprintf( "%s?query=%s", self.queryURL(), query2 ) ) - .done( function( data ) { - _.each( data.results.bindings, function( binding ) { - if (binding.g) { - updateCount( self, binding, binding.g.value ); - } - } ); - } ); - - self.set( {countPerformed: true, counting: false} ); - } ); - }, - - /** - * Fetch the content of the given graph as Turtle. Return the jQuery promise - * object for the Ajax call. - */ - fetchGraph: function( graphName ) { - return $.ajax( this.graphStoreProtocolReadURL(), - {method: "get", - headers: {Accept : "text/turtle; charset=utf-8"}, - dataType: "html", - data: {graph: graphName} - } ); - }, - - /** - * Put the given Turtle content back to the server using the given graph name - */ - putGraph: function( turtle, graphName ) { - return $.ajax( sprintf( "%s?graph=%s", this.graphStoreProtocolURL(), graphName ), - {method: "put", - dataType: "json", - data: turtle, - contentType: "text/turtle; charset=uft-8" - } ); - } - - } ); - - return Dataset; - } -); diff --git a/triplestores/fuseki/webapp/js/app/models/fuseki-server.js b/triplestores/fuseki/webapp/js/app/models/fuseki-server.js deleted file mode 100644 index 9c09574248..0000000000 --- a/triplestores/fuseki/webapp/js/app/models/fuseki-server.js +++ /dev/null @@ -1,184 +0,0 @@ -/** - * Backbone model denoting the remote Fuseki server. - */ - -define( - function( require ) { - "use strict"; - - var Marionette = require( "marionette" ), - Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - sprintf = require( "sprintf" ), - Dataset = require( "app/models/dataset" ), - PageUtils = require( "app/util/page-utils" ); - - var DATASETS_MANAGEMENT_PATH = "/$/datasets"; - - /** - * This model represents the core representation of the remote Fuseki - * server. Individual datasets have their own model. - */ - var FusekiServer = Backbone.Model.extend( { - /** This initializer occurs when the module starts, not when the constructor is invoked */ - init: function( options ) { - this._baseURL = this.currentRootPath(); - this._managementURL = null; - this.set( "selectedDatasetName", PageUtils.queryParam( "ds" ) ) - }, - - baseURL: function() { - return this._baseURL; - }, - - /** Return the URL from which we extract the details of the current server */ - serverDetailsURL: function() { - return sprintf( "%s/$/server", this.baseURL() ); - }, - - /** Return the URL for issuing commands to the management API, or null if no API defined */ - managementURL: function() { - return this._managementURL; - }, - - /** Return the URL for getting the stats for all datasets */ - statsURL: function() { - return sprintf( "%s/$/stats", this.managementURL() ); - }, - - /** Return the list of datasets that this server knows about. Each dataset will be a Dataset model object */ - datasets: function() { - return this.get( "datasets" ); - }, - - /** Return the dataset with the given name */ - dataset: function( dsName ) { - return _.find( this.datasets(), function( ds ) {return dsName === ds.name();} ) - }, - - /** Return the name of the currently selected dataset, if known */ - selectedDatasetName: function() { - return this.get( "selectedDatasetName" ); - }, - - /** Return the dataset that is currently selected, or null */ - selectedDataset: function() { - var dsName = this.selectedDatasetName(); - return dsName && this.dataset( dsName ); - }, - - /** Load and cache the remote server description. Trigger change event when done */ - loadServerDescription: function() { - var self = this; - return this.getJSON( this.serverDetailsURL() ) - .done( function( data ) { - self.saveServerDescription( data ); - } ) - .then( function() { - fui.vent.trigger( "models.fuseki-server.ready" ); - }); - }, - - /** Store the server description in this model */ - saveServerDescription: function( serverDesc ) { - // wrap each dataset JSON description as a dataset model - var bURL = this.baseURL(); - var mgmtURL = bURL; - - if (serverDesc.admin) { - // This is too simple. window.location.port may be empty and matches protocol. - //mgmtURL = bURL.replace( ":" + window.location.port, ":" + serverDesc.admin.port ); - //console.log("managementURL -- s/"+window.location.port+"/"+serverDesc.admin.port+"/") ; - var path = window.location.pathname.replace( /\/[^/]*$/, "" ) ; - mgmtURL = sprintf( "%s//%s:%s%s", window.location.protocol, window.location.hostname, serverDesc.admin, path ); - } - this._managementURL = mgmtURL ; - - var datasets = _.map( serverDesc.datasets, function( d ) { - return new Dataset( d, bURL, mgmtURL + DATASETS_MANAGEMENT_PATH ); - } ); - - datasets.sort( function( ds0, ds1 ) { - if (ds0.name() > ds1.name()) { - return 1; - } - else if (ds0.name() < ds1.name()) { - return -1; - } - else - return 0; - } ); - - this.set( { - serverDescription: serverDesc, - datasets: datasets, - ready: true - } ); - }, - - /** - * Get the given relative path from the server, and return a promise object which will - * complete with the JSON object denoted by the path. - */ - getJSON: function( path, data ) { - return $.getJSON( path, data ); - }, - - /** Update or create a dataset by posting to its endpoint */ - updateOrCreateDataset: function( datasetId, data ) { - var url = sprintf( "%s/$/datasets%s", this.managementURL(), - datasetId ? ("/" + datasetId) : "" - ); - - return $.ajax( url, - { data: data, - method: "post" - } - ); - }, - - /** Extract the server root path from the current window href */ - currentRootPath: function() { - var path = window.location.pathname.replace( /\/[^/]*$/, "" ); - - /* - console.log("window.location="+window.location) ; - console.log("window.location.href="+window.location.href) ; - console.log("window.location.protocol="+window.location.protocol) ; - console.log("window.location.host="+window.location.host) ; - console.log("window.location.hostname="+window.location.hostname) ; - console.log("window.location.port="+window.location.port) ; - console.log("window.location.pathname="+window.location.pathname) ; - console.log("window.location.origin="+window.location.origin) ; - console.log("window.location.hash="+window.location.hash) ; - console.log("window.location.search="+window.location.search) ; - console.log("path='"+path+"'") ; - */ - - var path2 ; - var port = window.location.port ; - //console.log("port='"+port+"'") ; - if ( !port || 0 === port.length ) { - // No explicit port. - path2 = sprintf( "%s//%s%s", window.location.protocol, window.location.hostname, path ) ; - } else { - path2 = sprintf( "%s//%s:%s%s", window.location.protocol, window.location.hostname, window.location.port, path ); - } - //console.log("path2='"+path2+"'") ; - return path2 ; - } - } ); - - // when the models module starts, automatically load the server description - fui.models.addInitializer( function( options ) { - var fusekiServer = new FusekiServer(); - fui.models.fusekiServer = fusekiServer; - - fusekiServer.init( options ); - fusekiServer.loadServerDescription(); - } ); - - return FusekiServer; - } -); diff --git a/triplestores/fuseki/webapp/js/app/models/task.js b/triplestores/fuseki/webapp/js/app/models/task.js deleted file mode 100644 index 10c05637de..0000000000 --- a/triplestores/fuseki/webapp/js/app/models/task.js +++ /dev/null @@ -1,105 +0,0 @@ -/** - * A long-running task, which periodically pings the server for its task status - */ - -define( - function( require ) { - "use strict"; - - var Marionette = require( "marionette" ), - Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - sprintf = require( "sprintf" ); - - /* Constants */ - - var MS = 1000; - var MAX_DELAY = 10 * MS; - - /** - * This model represents a long running task process - */ - var Task = function( ds, operationType, taskDescription ) { - this.taskDescription = taskDescription; - this.ds = ds; - this.operationType = operationType; - this.delay = 500; - - _.bindAll( this, "checkTaskStatus", "onCurrentTaskStatusFail", "onCurrentTaskStatus" ); - - this.checkTaskStatus(); - }; - - _.extend( Task.prototype, { - /** Return the unique ID (on this server) of the task */ - taskId: function() { - return this.taskDescription.taskId; - }, - - /** Return the URL for the task's API */ - taskURL: function() { - return sprintf( "%s/$/tasks/%s", this.ds.baseURL(), this.taskId() ); - }, - - /** Test the current status of the task */ - checkTaskStatus: function() { - $.getJSON( this.taskURL() ) - .done( this.onCurrentTaskStatus ) - .fail( this.onCurrentTaskStatusFail ) - }, - - /** Successful result from checking the task */ - onCurrentTaskStatus: function( taskDescription ) { - this.taskDescription = taskDescription; - - var status = { - task: this, - dsId: this.ds.name(), - finished: this.taskFinished() - }; - - fui.vent.trigger( "task.status", status ); - - this.queueTaskStatusCheck(); - }, - - /** Failed to check the task */ - onCurrentTaskStatusFail: function( jqxhr, msg, err ) { - var status = { - task: this, - dsId: this.ds.name(), - errorMessage: err || msg - }; - - fui.vent.trigger( "task.failed", status ); - }, - - /** Re-queue the status check if the task is not yet complete */ - queueTaskStatusCheck: function() { - if (!this.taskFinished()) { - _.delay( this.checkTaskStatus, this.statusDelay() ); - } - }, - - /** Return the completion time if the task has been fid, otherwise null */ - taskFinished: function() { - return this.taskDescription.finished; - }, - - /** Return the delay in ms until the next status check is due. */ - statusDelay: function() { - var t = this.delay; - - if (t < MAX_DELAY) { - this.delay = t * 2; - } - - return t; - } - } ); - - return Task; - } -); - diff --git a/triplestores/fuseki/webapp/js/app/models/validation-options.js b/triplestores/fuseki/webapp/js/app/models/validation-options.js deleted file mode 100644 index b114cf9404..0000000000 --- a/triplestores/fuseki/webapp/js/app/models/validation-options.js +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Backbone model denoting the remote Fuseki server. - */ -define( - function( require ) { - "use strict"; - - var Marionette = require( "marionette" ), - Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - sprintf = require( "sprintf" ); - - /** - * This model represents the users current choice of options to the - * validation service. - */ - var ValidationOptions = Backbone.Model.extend( { - initialize: function() { - this.set( {validateAs: "sparql"} ); - this.set( {outputFormat: "algebra"} ); - }, - - validateAs: function() { - return this.get( "validateAs" ); - }, - - validateAsQuery: function() { - return this.validateAs() === "sparql" || this.validateAs() === "arq"; - }, - - setValidateAs: function( va ) { - this.set( "validateAs", va ); - console.log( JSON.stringify( this.toJSON() )); - console.log( "----" ); - }, - - outputFormat: function() { - return this.get( "outputFormat" ); - }, - - setOutputFormat: function( of ) { - this.set( "outputFormat", of ); - }, - - validationURL: function() { - switch (this.get( "validateAs" )) { - case "sparql": return "/validate/query"; - case "arq": return "/validate/query"; - case "Turtle": return "/validate/data"; - case "TriG": return "/validate/data"; - case "N-Triples": return "/validate/data"; - case "N-Quads": return "/validate/data"; - } - }, - - payloadParam: function() { - return this.validateAsQuery() ? "query" : "data"; - }, - - toJSON: function() { - var json = { - languageSyntax: this.validateAs(), - lineNumbers: true - }; - - if (this.validateAsQuery()) { - json.outputFormat = this.outputFormat(); - } - - return json; - } - - } ); - - // when the models module starts, create the model - fui.models.addInitializer( function( options ) { - fui.models.validationOptions = new ValidationOptions(); - fui.vent.trigger( "models.validation-options.ready" ); - } ); - - - return ValidationOptions; - } -); \ No newline at end of file diff --git a/triplestores/fuseki/webapp/js/app/qonsole-config.js b/triplestores/fuseki/webapp/js/app/qonsole-config.js deleted file mode 100644 index 0c48273e8e..0000000000 --- a/triplestores/fuseki/webapp/js/app/qonsole-config.js +++ /dev/null @@ -1,27 +0,0 @@ -/** Standalone configuration for qonsole on index page */ - -define( [], function() { - return { - prefixes: { - "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", - "rdfs": "http://www.w3.org/2000/01/rdf-schema#", - "owl": "http://www.w3.org/2002/07/owl#", - "xsd": "http://www.w3.org/2001/XMLSchema#" - }, - queries: [ - { "name": "Selection of triples", - "query": "SELECT ?subject ?predicate ?object\nWHERE {\n" + - " ?subject ?predicate ?object\n}\n" + - "LIMIT 25" - }, - { "name": "Selection of classes", - "query": "SELECT DISTINCT ?class ?label ?description\nWHERE {\n" + - " ?class a owl:Class.\n" + - " OPTIONAL { ?class rdfs:label ?label}\n" + - " OPTIONAL { ?class rdfs:comment ?description}\n}\n" + - "LIMIT 25", - "prefixes": ["owl", "rdfs"] - } - ] - }; -} ); diff --git a/triplestores/fuseki/webapp/js/app/routers/.svnkeep b/triplestores/fuseki/webapp/js/app/routers/.svnkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/triplestores/fuseki/webapp/js/app/services/ping-service.js b/triplestores/fuseki/webapp/js/app/services/ping-service.js deleted file mode 100644 index 75ef6a4047..0000000000 --- a/triplestores/fuseki/webapp/js/app/services/ping-service.js +++ /dev/null @@ -1,54 +0,0 @@ -/** - * The ping service checks the status of the attached server and sets the light in the - * control bar accordingly. - */ -define( ['jquery', 'underscore', 'sprintf'], - function( $, _, sprintf ) { - - var PING_URL = "$/ping" - var DEFAULT_PING_TIME = 500000; // TODO slowed down during debugging phase - var _startTime = 0; - - var onBeforeSend = function() { - _startTime = new Date().getTime(); - }; - - var duration = function() { - return new Date().getTime() - _startTime; - }; - - var onPingSuccess = function( ) { - setPingStatus( "server-up", sprintf( "Last ping returned OK in %dms", duration() ) ); - }; - - var onPingFail = function( jqXHR, msg, errorThrown ) { - setPingStatus( "server-down", sprintf( "Last ping returned '%s' in %dms", errorThrown || msg, duration() ) ); - }; - - var setPingStatus = function( lampClass, statusText ) { - $( "a#server-status-light span").removeClass() - .addClass( lampClass ) - .attr( "title", statusText ); - }; - - /** Return a cache-defeating ping URL */ - var ping_url = function() { - return PING_URL + "?_=" + Math.random(); - }; - - var start = function( period ) { - ping( period || DEFAULT_PING_TIME ); - }; - - var ping = function( period ) { - onBeforeSend(); - $.get( ping_url() ).done( onPingSuccess ) - .fail( onPingFail ); - setTimeout( function() {ping( period );}, period ); - }; - - return { - start: start - } - } -); \ No newline at end of file diff --git a/triplestores/fuseki/webapp/js/app/services/validation-service.js b/triplestores/fuseki/webapp/js/app/services/validation-service.js deleted file mode 100644 index 1a5d9199c9..0000000000 --- a/triplestores/fuseki/webapp/js/app/services/validation-service.js +++ /dev/null @@ -1,98 +0,0 @@ -define( ['underscore', 'jquery', 'fui', - 'lib/codemirror', 'mode/javascript/javascript', 'mode/sparql/sparql'], - function( _, $, fui, CodeMirror ) { - - var ValidationService = function( editor_el, output_el ) { - this.editor_el = editor_el; - this.output_el = output_el; - }; - - _.extend( ValidationService.prototype, { - init: function() { - _.bindAll( this, "handleValidationOutput", "handleJsonValidationOutput" ); - this.editorElement(); - }, - - /** Return the DOM node representing the query editor */ - editorElement: function() { - if (!this._editor) { - this._editor = new CodeMirror( $(this.editor_el).get(0), { - lineNumbers: true, - mode: "text" - } ); - } - return this._editor; - }, - - /** Return the DOM node representing the output editor */ - outputElement: function( mode, lineNumbers, data ) { - $(this.output_el).empty(); - - var cm = new CodeMirror( $(this.output_el).get(0), { - lineNumbers: lineNumbers, - mode: mode || "text", - readOnly: true, - value: data - } ); - - return cm; - }, - - /** Return the current code editor contents */ - editorContent: function() { - return this.editorElement().getValue(); - }, - - /** Perform the given action to validate the current content */ - performValidation: function( optionsModel ) { - var context = {optionsModel: optionsModel}; - var self = this; - - var content = {}; - content[optionsModel.payloadParam()] = this.editorContent(); - - var options = { - data: _.extend( optionsModel.toJSON(), content ), - type: "POST" - }; - - $.ajax( optionsModel.validationURL(), options ) - .done( function( data, status, xhr ) { - self.handleValidationOutput( data, status, xhr, context ); - } ); - }, - - /** Respond to validation output from the server */ - handleValidationOutput: function( data, status, xhr, context ) { - var ct = xhr.getResponseHeader("content-type") || ""; - if (ct.match( /json/ )) { - this.handleJsonValidationOutput( data, context ); - } - else { - // in HTML output, we look for a .error div - var errors = $(data).find( "div.error" ).text(); - this.outputElement( "text", true, errors || "No warnings or errors reported." ); - } - }, - - handleJsonValidationOutput: function( json, context ) { - var outputFormat = context.optionsModel.outputFormat(); - console.log( "output format = " + outputFormat ); - var jsonString = null; - - if (outputFormat && json[outputFormat]) { - jsonString = json[outputFormat]; - } - else { - jsonString = JSON.stringify( json, null, ' ' ); - } - - this.outputElement( "application/json", false, jsonString ); - } - - } ); - - - return ValidationService; - } -); \ No newline at end of file diff --git a/triplestores/fuseki/webapp/js/app/templates/dataset-edit.tpl b/triplestores/fuseki/webapp/js/app/templates/dataset-edit.tpl deleted file mode 100644 index 8202831859..0000000000 --- a/triplestores/fuseki/webapp/js/app/templates/dataset-edit.tpl +++ /dev/null @@ -1,58 +0,0 @@ -
      -
      -
      - - - -

      Available graphs

      - - <% if (countPerformed()) { %> - - <% } else { %> -

      Click to list current graphs

      - <% } %> -
      -
      - -
      -
      -
      -
      -
      -
      graph:
      - -
      -
      -
      -
      - -
      -
      -
      -
      -
      - -
      -
      - -
      -
      - -
      -
      - - - - -
      -
      -
      -
      diff --git a/triplestores/fuseki/webapp/js/app/templates/dataset-info.tpl b/triplestores/fuseki/webapp/js/app/templates/dataset-info.tpl deleted file mode 100644 index c2c689138e..0000000000 --- a/triplestores/fuseki/webapp/js/app/templates/dataset-info.tpl +++ /dev/null @@ -1,40 +0,0 @@ -

      Available services

      - -
      - <% _.each( servicesDescription(), function( serviceDescription ) { %> -
      - <%= serviceDescription.label %>: -
      -
      - <%= serviceDescription.url %> -
      - <% } ); %> -
      - -

      Statistics

      -
      - -

      Dataset size

      -

      -Note this may be slow and impose a significant load on large datasets: - -

      -<% if (countPerformed()) { %> -
      -
      graph name:
      triples:
      - <% _.each( counts(), function( n, g ) { %> -
      - <%= g %> -
      -
      -
      <%= n %>
      -
      - <% } ); %> -
      - -<% } %> - -

      Ongoing operations

      - -

      TBD. Will list any long-lasting operations that are ongoing or recently completed, -e.g. backups.

      diff --git a/triplestores/fuseki/webapp/js/app/templates/dataset-management.tpl b/triplestores/fuseki/webapp/js/app/templates/dataset-management.tpl deleted file mode 100644 index 9a01812e49..0000000000 --- a/triplestores/fuseki/webapp/js/app/templates/dataset-management.tpl +++ /dev/null @@ -1,62 +0,0 @@ -<% if (datasets.length === 0) { %> -

      No datasets have been created yet. - add one -

      -<% } else { %> -
      -
      - - - - - - - <% _.each( datasets, function( ds ) { %> - - - - - - <% }) %> - -
      Name
      - <%= ds.name() %> - - -
      -
      -
      -<% } %> - - - - diff --git a/triplestores/fuseki/webapp/js/app/templates/dataset-selection-list.tpl b/triplestores/fuseki/webapp/js/app/templates/dataset-selection-list.tpl deleted file mode 100644 index 7eda02dcae..0000000000 --- a/triplestores/fuseki/webapp/js/app/templates/dataset-selection-list.tpl +++ /dev/null @@ -1,22 +0,0 @@ -
      - <% if (datasets.length > 0) { %> - - - <% _.each( datasets, function( ds ) { %> - - - - - <% }) %> - -
      dataset nameactions
      - <%= ds.name() %> - - query - add data - info -
      - <% } else { %> -

      There are no datasets on this server yet. Add one.

      - <% } %> -
      diff --git a/triplestores/fuseki/webapp/js/app/templates/dataset-selector.tpl b/triplestores/fuseki/webapp/js/app/templates/dataset-selector.tpl deleted file mode 100644 index d684995cd5..0000000000 --- a/triplestores/fuseki/webapp/js/app/templates/dataset-selector.tpl +++ /dev/null @@ -1,15 +0,0 @@ -
      - <% if (datasets.length == 0) { %> - <% } else { %> - - <% } %> -
      diff --git a/triplestores/fuseki/webapp/js/app/templates/dataset-simple-create.tpl b/triplestores/fuseki/webapp/js/app/templates/dataset-simple-create.tpl deleted file mode 100644 index 2611908c42..0000000000 --- a/triplestores/fuseki/webapp/js/app/templates/dataset-simple-create.tpl +++ /dev/null @@ -1,79 +0,0 @@ -
      -
      -
      -
      -
      - -
      -
      A name for the dataset is required
      - -
      -
      -
      - -
      -
      - -
      -
      - -
      -
      -
      - -
      -
      -
      -
      -
      - - -
      -
      - - - -
      -
      - - diff --git a/triplestores/fuseki/webapp/js/app/templates/dataset-stats.tpl b/triplestores/fuseki/webapp/js/app/templates/dataset-stats.tpl deleted file mode 100644 index fc3d7d9027..0000000000 --- a/triplestores/fuseki/webapp/js/app/templates/dataset-stats.tpl +++ /dev/null @@ -1,14 +0,0 @@ - - - <% _.each( headings, function( h ) { %> - - <% } ); %> - - <% _.each( rows, function( row ) { %> - - <% _.each( row, function( cell ) { %> - - <% } ); %> - - <% } ) %> -
      <%= h %>
      <%= cell %>
      \ No newline at end of file diff --git a/triplestores/fuseki/webapp/js/app/templates/file-upload.tpl b/triplestores/fuseki/webapp/js/app/templates/file-upload.tpl deleted file mode 100644 index 03d7dcc126..0000000000 --- a/triplestores/fuseki/webapp/js/app/templates/file-upload.tpl +++ /dev/null @@ -1,46 +0,0 @@ -
      -

      Upload files

      -

      Load data into the default graph of the currently selected dataset, - or the given named graph. - You may upload any RDF format, such as Turtle, RDF/XML or TRiG. -

      - -
      -
      - - -

      - -

      -
      -
      -
      - -
      -
      -
      - -
      - - - - select files... - - - - -
      -
      - -
      -
      -
        -
      -
      -
      -
      -
      -
      \ No newline at end of file diff --git a/triplestores/fuseki/webapp/js/app/templates/uploadable-file.tpl b/triplestores/fuseki/webapp/js/app/templates/uploadable-file.tpl deleted file mode 100644 index 83b844929c..0000000000 --- a/triplestores/fuseki/webapp/js/app/templates/uploadable-file.tpl +++ /dev/null @@ -1,23 +0,0 @@ -
      -
      - <%= file.name %> -
      -
      - - <%= file.readableFileSize %> - -
      -
      - - -
      -
      -
      -
      -
      -
      -
      -
      -
      - -
      diff --git a/triplestores/fuseki/webapp/js/app/util/page-utils.js b/triplestores/fuseki/webapp/js/app/util/page-utils.js deleted file mode 100644 index 45b4ffc35b..0000000000 --- a/triplestores/fuseki/webapp/js/app/util/page-utils.js +++ /dev/null @@ -1,33 +0,0 @@ -/** Utilities for managing HTML pages */ - -define( - function( require ) { - "use strict"; - - var _ = require( "underscore" ); - - /** Return true if a given query parameter is defined, otherwise null */ - var hasQueryParam = function( param ) { - return !!queryParam( param ); - }; - - /** Return the value of a query parameter, or null */ - var queryParam = function( param ) { - var p = param && queryParams()[param]; - return p ? p : null; - }; - - /** Return the current query params as a map */ - var queryParams = function() { - return _.chain( document.location.search.slice(1).split('&') ) - .invoke('split', '=') - .object() - .value(); - }; - - return { - hasQueryParam: hasQueryParam, - queryParam: queryParam - }; - } -); \ No newline at end of file diff --git a/triplestores/fuseki/webapp/js/app/views/.svnkeep b/triplestores/fuseki/webapp/js/app/views/.svnkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/triplestores/fuseki/webapp/js/app/views/dataset-edit.js b/triplestores/fuseki/webapp/js/app/views/dataset-edit.js deleted file mode 100644 index 017e0972c8..0000000000 --- a/triplestores/fuseki/webapp/js/app/views/dataset-edit.js +++ /dev/null @@ -1,205 +0,0 @@ -/** Component for showing detailed information about a dataset */ - -define( - function( require ) { - var Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - DatasetEditTpl = require( "plugins/text!app/templates/dataset-edit.tpl" ), - CodeMirror = require( "lib/codemirror" ), - CodeMirrorTurtle = require( "mode/turtle/turtle" ); - - var MAX_EDITABLE_SIZE = 10000; - - var DatasetEdit = Backbone.Marionette.ItemView.extend( { - - initialize: function() { - _.bindAll( this, "onCountGraphs", "onModelChanged", "onSelectDataset", - "onShownTab", "onShownEditTab", "onGraphContent", - "onSaveEdit", "onCancelEdit" ); - - this.model.on( "change", this.onModelChanged ); - this._editor = null; - - fui.vent.on( "shown.bs.tab", this.onShownTab ); - }, - - template: _.template( DatasetEditTpl ), - - ui: { - listGraphs: ".action.list-graphs", - editor: "#graph-editor", - graphName: "input.graph-name", - saveButton: "button.save-edit", - cancelButton: "button.cancel-edit" - }, - - el: "#edit .with-dataset", - - events: { - "click .list-graphs": "onCountGraphs", - "click .select-dataset": "onSelectDataset", - "click .save-edit": "onSaveEdit", - "click .cancel-edit": "onCancelEdit" - }, - - templateHelpers: { - }, - - serializeData: function() { - return this.model; - }, - - /** Alias for the model */ - dataset: function() { - return this.model; - }, - - // event handlers - - onModelChanged: function() { - if (!this.model.counting) { - this.render(); - } - }, - - onCountGraphs: function( e ) { - e.preventDefault(); - this.model.count(); - }, - - /** Event that triggers when any tab is shown */ - onShownTab: function( tab ) { - if (tab.attr("href") === "#edit") { - this.onShownEditTab(); - } - }, - - /** When the tab is show, ensure the editor element is initialised */ - onShownEditTab: function() { - this.showEditor(); - }, - - /** When rendering, only show the code mirror editor if the tab is visible */ - onRender: function() { - this.showEditor(); - }, - - /** Ensure the code mirror element is visible */ - showEditor: function() { - if (this.editorElementVisible() && this.editorNotYetInitialised()) { - this._editor = null; - this.editorElement(); - } - }, - - /** Return true if the editor container element is visible */ - editorElementVisible: function() { - return this.ui.editor.is( ":visible" ); - }, - - /** Return true if the CodeMirror element has not yet been initialised */ - editorNotYetInitialised: function() { - return this.ui.editor.is( ":not(:has(.CodeMirror))" ); - }, - - /** User has (attempted to) select a dataset */ - onSelectDataset: function( e ) { - e.preventDefault(); - var self = this; - var elem = $(e.currentTarget); - var graphName = elem.data( "graph-name" ); - var graphSize = parseInt( elem.data( "graph-size" )); - - if (graphSize > MAX_EDITABLE_SIZE) { - alert( "Sorry, that dataset is too large to load into the editor" ); - } - else { - if (this.dirtyCheck()) { - $(".nav.graphs").find( ".active" ).removeClass( "active" ); - elem.parent().addClass( "active" ); - - var gn = this.setGraphName( graphName ); - this.dataset() - .fetchGraph( gn ) - .done( self.onGraphContent ); - } - } - }, - - /** Return true if the edit buffer is not dirty, or if the user says OK */ - dirtyCheck: function() { - return true; // TODO - }, - - /** Return the DOM node representing the query editor */ - editorElement: function() { - if (!this._editor) { - this._editor = new CodeMirror( this.ui.editor.get(0), { - lineNumbers: true, - mode: "turtle" - } ); - } - return this._editor; - }, - - /** Set the graph name, return the actual name used */ - setGraphName: function( name ) { - var text = (name === "default" || name === "default graph") ? "default" : name; - - this.ui.graphName.val( text ); - - return text; - }, - - /** Get the graph name */ - graphName: function() { - return this.ui.graphName.val(); - }, - - /** Server has sent the content of the graph encoded as turtle */ - onGraphContent: function( data ) { - this.editorElement().setValue( data ); - }, - - /** User wants to save changes */ - onSaveEdit: function( e ) { - e.preventDefault(); - var self = this; - - var turtle = this.editorElement().getValue(); - this.dataset() - .putGraph( turtle, this.graphName() ) - .done( function( data ) { - var nq = parseInt( data.quadCount ); - var nt = parseInt( data.tripleCount ); - var typ = (nq > nt) ? "quad" : "triple"; - var s = (nq + nt) === 1 ? "" : "s"; - var msg = sprintf( "Added %d %s%s", nq + nt, typ, s ); - - self.showFeedback( msg, "" ); - } ) - .error( function( jqhxr, msg, err ) { - self.showFeedback( err || msg, "text-warning" ); - } ); - }, - - /** User wants to discard changes */ - onCancelEdit: function( e ) { - e.preventDefault(); - this.ui.graphName.val( "" ); - this.editorElement().setValue( "" ); - }, - - /** Show feedback from operations */ - showFeedback: function( msg, cls ) { - $(".feedback").html( sprintf( "%s", cls, msg ) ); - } - - - }); - - - return DatasetEdit; - } -); diff --git a/triplestores/fuseki/webapp/js/app/views/dataset-info.js b/triplestores/fuseki/webapp/js/app/views/dataset-info.js deleted file mode 100644 index 665725facf..0000000000 --- a/triplestores/fuseki/webapp/js/app/views/dataset-info.js +++ /dev/null @@ -1,76 +0,0 @@ -/** Component for showing detailed information about a dataset */ - -define( - function( require ) { - var Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - DatasetInfoTpl = require( "plugins/text!app/templates/dataset-info.tpl" ), - DatasetStatsView = require( "app/views/dataset-stats" ), - DatasetStatsModel = require( "app/models/dataset-stats" ); - - var DatasetInfo = Backbone.Marionette.ItemView.extend( { - - initialize: function() { - _.bindAll( this, "onModelChanged", "onCountGraphs" ); - - this.showStatistics( true ); - this.model.on( "change", this.onModelChanged ); - }, - - template: _.template( DatasetInfoTpl ), - - ui: { - stats: "#statistics", - count: ".count-graphs" - }, - - el: "#info .with-dataset", - - events: { - "click .count-graphs": "onCountGraphs" - }, - - templateHelpers: { - }, - - serializeData: function() { - return this.model; - }, - - /** Alias for the model */ - dataset: function() { - return this.model; - }, - - // event handlers - - onModelChanged: function() { - if (!this.model.counting) { - this.render(); - this.showStatistics( false ); - } - }, - - onCountGraphs: function( e ) { - e.preventDefault(); - this.model.count(); - }, - - showStatistics: function( keep ) { - var self = this; - - this.model - .statistics( keep ) - .done( function( data ) { - var statsModel = new DatasetStatsModel( self.dataset(), data ); - new DatasetStatsView( {model: statsModel} ).render(); - } ); - } - - }); - - - return DatasetInfo; - } -); diff --git a/triplestores/fuseki/webapp/js/app/views/dataset-management.js b/triplestores/fuseki/webapp/js/app/views/dataset-management.js deleted file mode 100644 index ca3af74882..0000000000 --- a/triplestores/fuseki/webapp/js/app/views/dataset-management.js +++ /dev/null @@ -1,173 +0,0 @@ -define( - function( require ) { - var Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - datasetManagementViewTpl = require( "plugins/text!app/templates/dataset-management.tpl" ); - - var DataManagementView = Backbone.Marionette.ItemView.extend( { - - initialize: function(){ - _.bindAll( this, "onRemoveDataset", "onConfirmAction", - "onDatasetRemoveSuccess", "onDatasetRemoveFail", - "onTaskStatus", "onTaskFailed", "cleanup" ); - - this.listenTo( this.model, "change", this.onModelChange, this ); - - fui.vent.on( "action.delete.confirm", this.onConfirmRemoveDataset, this ); - fui.vent.on( "action.backup.confirm", this.onConfirmBackupDataset, this ); - - fui.vent.on( "task.status", this.onTaskStatus, this ); - fui.vent.on( "task.failed", this.onTaskFailed, this ); - }, - - template: _.template( datasetManagementViewTpl ), - - ui: { - actionConfirmModal: "#actionConfirmModal" - }, - - el: "#dataset-management", - - events: { - "click .action.remove": "onRemoveDataset", - "click .action.confirm": "onConfirmAction", - "click .action.backup": "onBackupDataset" - }, - - templateHelpers: { - }, - - cleanup: function() { - this.unbind(); - this.undelegateEvents(); - this.model.unbind( 'change', this.onModelChange, this ); - fui.vent.unbind( 'action.delete.confirm', this.onConfirmRemoveDataset, this ); - }, - - /** If the model changes, update the summary */ - onModelChange: function( event ) { - this.cleanup(); - this.render(); - }, - - /** User has requested a dataset be removed */ - onRemoveDataset: function( e ) { - e.preventDefault(); - var elem = $(e.currentTarget); - var dsId = elem.data( "ds-id" ); - var msg = sprintf( "Are you sure you want to delete dataset %s? This action cannot be reversed.", dsId ); - - this.showConfirmationModal( msg, dsId, "action.delete.confirm" ); - }, - - /** User has requested a dataset be backed up */ - onBackupDataset: function( e ) { - e.preventDefault(); - var elem = $(e.currentTarget); - var dsId = elem.data( "ds-id" ); - var msg = sprintf( "Are you sure you want to create a backup of dataset %s? This action may take some time to complete", dsId ); - - this.showConfirmationModal( msg, dsId, "action.backup.confirm" ); - }, - - /** Show a generic modal confirmation */ - showConfirmationModal: function( msg, dsId, eventId ) { - this.ui.actionConfirmModal - .find( ".modal-body p" ) - .html( msg ); - - this.ui.actionConfirmModal - .find( ".action.confirm" ) - .data( "ds-id", dsId ) - .data( "event-id", eventId ); - - this.clearFeedback(); - this.ui.actionConfirmModal.modal( 'show' ); - }, - - /** Generic response to confirming the current modal dialogue */ - onConfirmAction: function( e ) { - e.preventDefault(); - var elem = $(e.currentTarget); - var dsId = elem.data( "ds-id" ); - var eventId = elem.data( "event-id" ); - - //this.ui.actionConfirmModal.modal( 'hide' ); - $('.modal.in').modal('hide'); - $('body').removeClass('modal-open'); - $('.modal-backdrop').remove(); - _.delay( function() { - fui.vent.trigger( eventId, dsId ); - }, 100 ); - }, - - /** User has confirmed that the dataset can be deleted */ - onConfirmRemoveDataset: function( dsId ) { - var self = this; - - fui.models - .fusekiServer - .dataset( dsId ) - .deleteDataset() - .done( function( data ) {self.onDatasetRemoveSuccess( data, dsId );} ) - .error( function( jqxhr, msg, err ) {self.onDatasetRemoveFail( jqxhr, msg, err, dsId );} ); - }, - - /** Callback after successfully removing a dataset */ - onDatasetRemoveSuccess: function( data, dsId ) { - this.model.loadServerDescription(); - }, - - /** Removing the dataset did not work: notify the user */ - onDatasetRemoveFail: function( jqxhr, msg, err, dsId ) { - this.feedbackArea( dsId ) - .html( sprintf( "

      Sorry, removing dataset %s did not work, because: '%s'

      ", dsId, err || msg ) ); - }, - - /** User has confirmed backing up the dataset */ - onConfirmBackupDataset: function( dsId ) { - var self = this; - - fui.models - .fusekiServer - .dataset( dsId ) - .backupDataset(); - }, - - /** Remove any current feedback content */ - clearFeedback: function() { - $(".action.feedback").empty(); - }, - - /** Long running task has updated status */ - onTaskStatus: function( status ) { - var task = status.task; - var msg = sprintf( "

      Task %s started at %s%s

      ", - task.operationType, - task.taskDescription.started, - status.finished ? sprintf( ", finished at %s", status.finished ) : " – ongoing" ); - - this.feedbackArea( status.dsId ) - .html( msg ); - }, - - /** Long running task has failed to start */ - onTaskFailed: function( status ) { - this.feedbackArea( status.dsId ) - .html( sprintf( "

      Task %s failed: '%s'

      ", task.operationType, task.errorMessage )); - }, - - /** Find the feedback area for a particular dataset */ - feedbackArea: function( dsId ) { - return $(sprintf( ".action[data-ds-id='%s']", dsId ) ) - .parent() - .siblings(".action.feedback"); - } - - }); - - - return DataManagementView; - } -); diff --git a/triplestores/fuseki/webapp/js/app/views/dataset-selection-list.js b/triplestores/fuseki/webapp/js/app/views/dataset-selection-list.js deleted file mode 100644 index ccad19d6e6..0000000000 --- a/triplestores/fuseki/webapp/js/app/views/dataset-selection-list.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * This view presents a list of the available datasets for the user to interact - * with. - */ - -define( - function( require ) { - var Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - datasetSelectionListTemplate = require( "plugins/text!app/templates/dataset-selection-list.tpl" ); - - var DatasetSelectionListView = Backbone.Marionette.ItemView.extend( { - initialize: function(){ -// _.bindAll(this, "onFilter", "onModelChange"); - this.listenTo( this.model, "change", this.onModelChange, this ); - }, - - template: _.template( datasetSelectionListTemplate ), - - el: "#dataset-selection-list", - - ui: { - }, - - events: { -// "change #independent-variable-selection": "selectVariable", -// "click a.action.filter": "onFilter" - }, - - templateHelpers: { - }, - -// /** Update the model when the user changes the selection */ -// selectVariable: function( event ) { -// this.model.set( "independentVarSelection", this.ui.variableSelection.val() ); -// }, -// -// /** User wants to open the filter dialog */ -// onFilter: function( event ) { -// var varModel = bgViz.models.variablesConfig.independentVar(); -// var rangeType = varModel.component.range().rangeType(); -// var viewName = rangeType.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(); -// -// bgViz.layouts.filterDialog.showFilter( viewName, varModel ); -// }, - - /** If the model changes, update the summary */ - onModelChange: function( event ) { -// this.ui.summary.html( this.model.independentVar().component.range().summarise() ); - } - - }); - - - return DatasetSelectionListView; - } -); diff --git a/triplestores/fuseki/webapp/js/app/views/dataset-selector.js b/triplestores/fuseki/webapp/js/app/views/dataset-selector.js deleted file mode 100644 index f14a74730d..0000000000 --- a/triplestores/fuseki/webapp/js/app/views/dataset-selector.js +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Reusable component that encapsulates selecting a dataset to work on in a given page. - * Takes the FusekiServer as a model, and populates a select control to choose one of the - * current datasets. If the dataset changes, this view will update the `selectedDatasetName` - * on the model, and trigger the event `dataset.changed`. - **/ - -define( - function( require ) { - "use strict"; - - var Marionette = require( "marionette" ), - Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - sprintf = require( "sprintf" ), - datasetSelectorTemplate = require( "plugins/text!app/templates/dataset-selector.tpl" ); - - var DatasetSelectorView = Backbone.Marionette.ItemView.extend( { - - initialize: function(){ - this.listenTo( this.model, "change", this.render, this ); - }, - - template: _.template( datasetSelectorTemplate ), - - el: ".dataset-selector-container", - - ui: { - select: ".dataset-selector select" - }, - - events: { - "change .dataset-selector select": "onChangeDataset" - }, - - /** - * After rendering, set up the dataset picker and notify the rest of the - * app if the default dataset name is known. - */ - onRender: function() { - var selector = $('.selectpicker'); - selector.selectpicker('refresh'); - - if (selector.val()) { - this.unHideDatasetElements(); - this.onChangeDataset(); - } - }, - - /** - * Respond to a change in the dataset name selection by updating - * the underlying model. TODO: should also update the application - * URL. - */ - onChangeDataset: function( e ) { - var newDatasetName = this.ui.select.val(); - this.model.set( "selectedDatasetName", newDatasetName ); - this.notifyDatasetName( newDatasetName ); - }, - - /** - * Ensure that elements that should be visible when a dataset is known - * are not hidden, and vice-versa. - */ - unHideDatasetElements: function() { - $(".no-dataset").addClass( "hidden" ); - $(".with-dataset").removeClass( "hidden" ); - }, - - /** Trigger an event to notify other components that the dataset - * name has been selected. - */ - notifyDatasetName: function( dsName ) { - fui.vent.trigger( "dataset.changed", dsName || this.ui.select.val() ); - } - - - }); - - - return DatasetSelectorView; - } -); diff --git a/triplestores/fuseki/webapp/js/app/views/dataset-simple-create.js b/triplestores/fuseki/webapp/js/app/views/dataset-simple-create.js deleted file mode 100644 index b7a591bda0..0000000000 --- a/triplestores/fuseki/webapp/js/app/views/dataset-simple-create.js +++ /dev/null @@ -1,102 +0,0 @@ -/** Component for creating a new dataset with a few simple options */ - -define( - function( require ) { - var Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - DatasetSimpleCreateTpl = require( "plugins/text!app/templates/dataset-simple-create.tpl" ); - - var DatasetSimpleCreate = Backbone.Marionette.ItemView.extend( { - - initialize: function() { - _.bindAll( this, "onCommitSimple", "clearWarnings" ); - }, - - template: _.template( DatasetSimpleCreateTpl ), - - ui: { - }, - - el: "#dataset-simple-create", - - events: { - "click a.action.commit.simple": "onCommitSimple", - "submit form": "onCommitSimple", - "keydown input[name=dbName]": "clearWarnings" - }, - - templateHelpers: { - }, - - serializeData: function() { - return this.model; - }, - - // event handlers - - onCommitSimple: function( e ) { - e.preventDefault(); - - if (this.validateSimpleForm()) { - var datasetName = $("input[name=dbName]").val().trim(); - $("input[name=dbName]").val(datasetName); - var options = $("#simple-edit form").serializeArray(); - fui.models.fusekiServer.updateOrCreateDataset( null, options ) - .done( this.showDataManagementPage ) - .fail( this.showFailureMessage ); - } - }, - -// onCommitUpload: function( e ) { -// e.preventDefault(); -// -// if (this.validateUploadForm()) { -// $("#uploadForm").ajaxSubmit( { -// success: this.showDataManagementPage, -// error: this.showFailureMessage -// }); -// } -// }, -// - showDataManagementPage: function( e ) { - location = "?tab=datasets"; - }, - - /** Todo: need to do a better job of responding to errors */ - showFailureMessage: function( jqXHR, textStatus, errorThrown ) { - $(".errorOutput").html( sprintf( "

      Sorry, that didn't work because:

      %s
      ", errorThrown || textStatus ) ); - }, - - /** Clear current warning states */ - clearWarnings: function() { - this.clearValidation(); - $(".errorOutput").empty(); - }, - - // validation - - validateSimpleForm: function() { - this.clearValidation(); - - if (! $("input[name=dbName]").val() || 0 === $("input[name=dbName]").val().trim().length) { - $(".dbNameValidation").removeClass("hidden") - .parents(".form-group" ) - .addClass( "has-error" ); - return false; - } - - return true; - }, - - clearValidation: function() { - $(".has-error").removeClass( "has-error" ); - $(".has-warning").removeClass( "has-warning" ); - } - - }); - - - return DatasetSimpleCreate; - } -); diff --git a/triplestores/fuseki/webapp/js/app/views/dataset-stats.js b/triplestores/fuseki/webapp/js/app/views/dataset-stats.js deleted file mode 100644 index f2dc198eab..0000000000 --- a/triplestores/fuseki/webapp/js/app/views/dataset-stats.js +++ /dev/null @@ -1,41 +0,0 @@ -define( - function( require ) { - var Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - datasetStatsViewTpl = require( "plugins/text!app/templates/dataset-stats.tpl" ); - - var DatasetStatsView = Backbone.Marionette.ItemView.extend( { - initialize: function() { - _.bindAll( this, "onShowTab" ); - - fui.vent.on( "shown.bs.tab", this.onShowTab ); - }, - - template: _.template( datasetStatsViewTpl ), - - ui: { - }, - - el: "#statistics", - - modelEvents: { - 'change': "modelChanged" - }, - - modelChanged: function() { - this.render(); - }, - - onShowTab: function( tab ) { - if (tab.attr("href") === "#info") { - this.model.refresh(); - } - } - - }); - - - return DatasetStatsView; - } -); diff --git a/triplestores/fuseki/webapp/js/app/views/datasets-dropdown-list.js b/triplestores/fuseki/webapp/js/app/views/datasets-dropdown-list.js deleted file mode 100644 index 92b2bf41ee..0000000000 --- a/triplestores/fuseki/webapp/js/app/views/datasets-dropdown-list.js +++ /dev/null @@ -1,43 +0,0 @@ -define( - function( require ) { - var Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ); - - var DatasetDropDownListView = Backbone.Marionette.ItemView.extend( { - initialize: function(){ - }, - - template:"", - - el: "ul.dropdown-menu.dataset-list", - - ui: { - }, - - events: { - }, - - render: function() { - var e = $(this.el).empty(); - _.each( this.model, function( ds ) { - e.append( sprintf( "
    1. %s
    2. ", ds.name(), ds.name() )); - } ); - }, - - /** Change the currently selected dataset name. If required, notify other units via an event */ - setCurrentDatasetName: function( dsName, notify ) { - if (dsName) { - $(".current-dataset").text( dsName ); - } - - if (notify) { - fui.vent.trigger( "views.datasets-dropdown-list.dataset-changed", dsName ) - } - } - }); - - - return DatasetDropDownListView; - } -); diff --git a/triplestores/fuseki/webapp/js/app/views/file-upload.js b/triplestores/fuseki/webapp/js/app/views/file-upload.js deleted file mode 100644 index f16e544c79..0000000000 --- a/triplestores/fuseki/webapp/js/app/views/file-upload.js +++ /dev/null @@ -1,225 +0,0 @@ -/** - * This view presents a control to upload files to the current dataset, and a recently-uploaded - * log to track what has been done. - */ - -define( - function( require ) { - var Backbone = require( "backbone" ), - _ = require( "underscore" ), - sprintf = require( "sprintf" ), - fui = require( "app/fui" ), - fileUploadTemplate = require( "plugins/text!app/templates/file-upload.tpl" ), - UploadableFileView = require( "app/views/uploadable-file" ); - - var FileUploadView = Backbone.Marionette.CompositeView.extend( { - initialize: function(){ - _.bindAll( this, - "onUploadAdd", "onRemoveUpload", "onUploadAll", - "onProgress", "onUploadDone", "onUploadFail", - "onPerformUpload" ); - - fui.vent.on( "upload.remove", this.onRemoveUpload ); - fui.vent.on( "upload.perform", this.onPerformUpload ); - }, - - template: _.template( fileUploadTemplate ), - - el: "#file-upload", - - itemViewContainer: "ul", - itemView: UploadableFileView, - collection: new Backbone.Collection(), - - ui: { - fileUpload: '#fileuploadForm', - graphLabel: '.graph-label input' - }, - - events: { - "click .action-upload-all": "onUploadAll" - }, - - templateHelpers: { - }, - - onRender: function() { - // initialise the file upload widget - this.ui.fileUpload.fileupload( { - dataType: 'json', - add: this.onUploadAdd, - progress: this.onProgress - } ); - }, - - /** User has added a file */ - onUploadAdd: function( e, data ) { - var collection = this.collection; - var self = this; - - _.each( data.files, function( file ) { - file.readableFileSize = self.readableFileSize( file ); - collection.add( new Backbone.Model( {file: file} ) ); - } ); - - this.enableUploadAll( true ); - }, - - /** Return file size in bytes in a human-readable form */ - readableFileSize: function( file ) { - var k = 1024; - var m = k * k; - - if (file.size >= m) { - return sprintf( "%.1fmb", file.size / m ); - } - else if (file.size >= k) { - return sprintf( "%.1fkb", file.size / k ); - } - else { - return sprintf( "%d bytes", file.size ); - } - }, - - /** User has requested to remove a selected upload */ - onRemoveUpload: function( file ) { - this.collection.remove( file ); - this.enableUploadAll( this.collection.size() > 0 ) - }, - - /** User has requested to perform a selected upload */ - onPerformUpload: function( model ) { - this.loadAll = false; - this.uploadFileFromModel( model ); - }, - - /** Return the list of active files waiting for upload */ - activeFiles: function() { - var activeModels = _.filter( this.collection.models, function( m ) { - return !m.completed; - } ); - - return _.map( activeModels, function( m ) { - return m.get( "file" ); - } ); - }, - - /** User action to upload all active files */ - onUploadAll: function( e ) { - if (e) { - e.preventDefault(); - } - - this.$el.find( ".file-description .action" ).attr( 'disabled', 'disabled' ); - this.loadNextAvailableFile( true ); - }, - - /** Load the next file in the sequence */ - loadNextAvailableFile: function( all ) { - this.loadAll = all; - var files = this.activeFiles(); - - if (files.length > 0) { - this.uploadFile( files.shift() ); - } - else { - this.enableUploadAll( false ); - } - }, - - /** Upload the given file to the server */ - uploadFile: function( file ) { - this.uploadFileFromModel( this.collection.findWhere( {file: file} ) ); - }, - - /** Upload the file attached to a given model */ - uploadFileFromModel: function( model ) { - this.cacheModel( model ); - - var file = model.get( "file" ); - var ds = fui.models.fusekiServer.selectedDataset(); - var url = ds.uploadURL( this.destinationGraphName() ); - - this.ui.fileUpload.fileupload( 'send', { - files: [file], - url: url - }) - .success( this.onUploadDone ) - .fail( this.onUploadFail ); - }, - - /** Return the selected graph name, or 'default' */ - destinationGraphName: function() { - var gName = this.ui.graphLabel.val(); - return (gName && gName !== "") ? gName : 'default'; - }, - - /** Callback on progress against an upload */ - onProgress: function( e, data ) { - var complete = Math.round( 100.0 * data.loaded/ data.total); - $(this.activeView.el).find( ".progress-bar" ) - .attr( 'aria-valuenow', complete ) - .css( 'width', sprintf( "%s%%", complete )); - }, - - /** Callback on successful completion */ - onUploadDone: function( data, response ) { - var label = "Data file was empty."; - if ((data.count) > 0) { - var s = (data.count === 1) ? "" : "s"; - label = sprintf( "%d %s%s", data.count, ((data.tripleCount > 0) ? "triple" : "quad"), s ); - } - - this.displayUploadResult( sprintf( "

      Result: success. %s

      ", label ), "" ); - - if (this.loadAll) { - this.loadNextAvailableFile( true ); - } - }, - - /** Callback on error */ - onUploadFail: function( jqxhr, error, msg ) { - $(this.activeView.el).find( ".progress-bar" ) - .removeClass( "progress-bar-success" ) - .addClass( "progress-bar-warning" ); - this.displayUploadResult( sprintf( "

      Result: failed with message "%s"

      ", msg ), "text-danger" ); - - if (this.loadAll) { - this.loadNextAvailableFile( true ); - } - }, - - /** Show the result of uploading a file */ - displayUploadResult: function( html, cls ) { - var el = $(this.activeView.el); - this.activeModel.completed = true; - el.find( ".action" ).hide(); - - el.find( ".result" ) - .addClass( cls ) - .append( html ); - }, - - /** Cache the currently active model so that we can attach actions to the corresponding view */ - cacheModel: function( model ) { - this.activeModel = model; - this.activeView = this.children.findByModel( model ); - }, - - /** Enable or disable the upload all button */ - enableUploadAll: function( enabled ) { - if (enabled) { - $(".action-upload-all").removeAttr( 'disabled' ); - } - else { - $(".action-upload-all").attr( 'disabled', 'disabled' ); - } - } - - - }); - - - return FileUploadView; - } -); diff --git a/triplestores/fuseki/webapp/js/app/views/tabbed-view-manager.js b/triplestores/fuseki/webapp/js/app/views/tabbed-view-manager.js deleted file mode 100644 index 5bba26d25b..0000000000 --- a/triplestores/fuseki/webapp/js/app/views/tabbed-view-manager.js +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Reusable component that encapsulates managing a collection of sub-views as - * tabs, with the active tab being selected via the URL query param `tab`. - **/ - -define( - function( require ) { - "use strict"; - - var Marionette = require( "marionette" ), - Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - sprintf = require( "sprintf" ), - PageUtils = require( "app/util/page-utils" ); - - var TabbedViewManagerView = Backbone.View.extend( { - - initialize: function(){ - this._tab = PageUtils.queryParam( "tab" ); - this._firstRender = false; - }, - - render: function() { - if (!this._firstRender) { - this._firstRender = true; - this.activateCurrentTab(); - - $(".nav-tabs").on( "shown.bs.tab", function( e ) { - fui.vent.trigger( "shown.bs.tab", $(e.target) ); - } ); - } - }, - - /** - * Make the tab named as the current tab active. If no named tab, make - * the first tab active by default. - */ - activateCurrentTab: function() { - var tabs = $(".nav-tabs"); - var tab = tabs.children().first(); - - if (this._tab) { - tab = tabs.find( sprintf( "a[href=#%s]", this._tab ) ) - .parent(); - } - - if (!tab.is(".active")) { - tabs.children( "li" ).removeClass( "active" ); - tabs.parent().children(".tab-pane").removeClass("active"); - - tab.addClass( "active" ); - $( tab.children( "a" ).attr( "href" ) ).addClass("active"); - } - } - - - }); - - - return TabbedViewManagerView; - } -); diff --git a/triplestores/fuseki/webapp/js/app/views/uploadable-file.js b/triplestores/fuseki/webapp/js/app/views/uploadable-file.js deleted file mode 100644 index 382a92ffc8..0000000000 --- a/triplestores/fuseki/webapp/js/app/views/uploadable-file.js +++ /dev/null @@ -1,39 +0,0 @@ -/** - * This view encapsulates a single uploadable file - */ - -define( - function( require ) { - var Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ), - uploadableFileTemplate = require( "plugins/text!app/templates/uploadable-file.tpl" ); - - var UploadableFileView = Backbone.Marionette.ItemView.extend( { - initialize: function(){ - }, - - tagName: "li", - - template: _.template( uploadableFileTemplate ), - - events: { - "click .action-remove-upload": "onActionRemoveUpload", - "click .action-upload-file": "onActionUploadFile" - }, - - onActionRemoveUpload: function( e ) { - e.preventDefault(); - fui.vent.trigger( "upload.remove", this.model ); - }, - - onActionUploadFile: function( e ) { - e.preventDefault(); - fui.vent.trigger( "upload.perform", this.model ); - } - - }); - - return UploadableFileView; - } -); diff --git a/triplestores/fuseki/webapp/js/app/views/validation-options.js b/triplestores/fuseki/webapp/js/app/views/validation-options.js deleted file mode 100644 index ef0f723d35..0000000000 --- a/triplestores/fuseki/webapp/js/app/views/validation-options.js +++ /dev/null @@ -1,54 +0,0 @@ -define( - function( require ) { - var Backbone = require( "backbone" ), - _ = require( "underscore" ), - fui = require( "app/fui" ); - - var ValidationOptions = Backbone.Marionette.ItemView.extend( { - initialize: function(){ - _.bindAll( this, "onValidateAs", "onOutputFormat", "onModelChange" ); - this.listenTo( this.model, "change", this.onModelChange, this ); - }, - - el: ".validation", - - events: { - "click .validate-as-options a": "onValidateAs", - "click .output-format-options a": "onOutputFormat", - }, - - templateHelpers: { - }, - - onValidateAs: function( e ) { - e.preventDefault(); - var elem = $(e.currentTarget); - this.model.setValidateAs( elem.data( "validate-as" ) ); - this.$el.find(".validate-as-options a").removeClass("active"); - elem.addClass("active"); - - if (this.model.validateAsQuery()) { - this.$el.find(".output-format-options").removeClass("hidden"); - } - else { - this.$el.find(".output-format-options").addClass("hidden"); - } - }, - - onOutputFormat: function( e ) { - e.preventDefault(); - var elem = $(e.currentTarget); - this.model.setOutputFormat( elem.data( "output-format" ) ); - this.$el.find(".output-format-options a").removeClass("active"); - elem.addClass("active"); - }, - - onModelChange: function( event ) { - } - - }); - - - return ValidationOptions; - } -); diff --git a/triplestores/fuseki/webapp/js/common-config.js b/triplestores/fuseki/webapp/js/common-config.js deleted file mode 100644 index eac4b27182..0000000000 --- a/triplestores/fuseki/webapp/js/common-config.js +++ /dev/null @@ -1,94 +0,0 @@ -require.config({ - baseUrl: 'js/lib', - paths: { - 'app': '../app', - // lib paths - 'bootstrap': 'bootstrap.min', - 'jquery': 'jquery-1.10.2.min', - 'marionette': 'backbone.marionette', - 'sprintf': 'sprintf-0.7-beta1', - 'datatables': 'jquery.dataTables.min', - 'yasqe': 'yasqe.min', - 'yasr': 'yasr.min', - 'pivottable': 'pivot.min', - 'jquery-ui': 'jquery-ui.min' - }, - map: { - '*': { - 'codemirror': 'lib/codemirror', - 'jquery.dataTables.min' : 'datatables', - 'jquery-ui': 'jquery-ui' - }, - }, - shim: { - 'underscore': { - exports: '_' - }, - 'backbone': { - deps: ['underscore', 'jquery'], - exports: 'Backbone' - }, - 'bootstrap': { - deps: ['jquery'] - }, - 'bootstrap-select.min': { - deps: ['bootstrap'] - }, - 'jquery.xdomainrequest': { - deps: ['jquery'] - }, - 'jquery.dataTables.min': { - deps: ['jquery'] - }, - 'jquery.form': { - deps: ['jquery'] - }, - 'jquery.ui.widget': { - deps: ['jquery'] - }, - 'qonsole': { - deps: ['yasqe', 'yasr'], - exports: 'qonsole' - }, - 'yasqe': { - deps: ['jquery', 'lib/codemirror'], - exports: 'YASQE' - }, - 'yasr': { -// deps: ['pivottable', 'jquery', 'lib/codemirror', 'datatables'], - deps: ['jquery', 'lib/codemirror', 'datatables'], - exports: 'YASR' - }, - 'pivottable': { - deps: ['jquery-ui'] - }, - 'jquery-ui': { - deps: ['jquery'] - }, - 'jquery.fileupload': { - deps: ['jquery.fileupload.local', 'jquery.iframe-transport', 'jquery.ui.widget'] - }, - 'jquery.fileupload.local': { - deps: ['jquery'] - }, - 'jquery.iframe-transport': { - deps: ['jquery'] - }, - 'sprintf': { - exports: 'sprintf' - }, - 'marionette': { - deps: ['backbone'], - exports: 'Marionette' - }, - 'addon/fold/foldcode': {deps: ['lib/codemirror']}, - 'addon/fold/brace-fold': {deps: ['addon/fold/foldcode']}, - 'addon/fold/comment-fold': {deps: ['addon/fold/foldcode']}, - 'addon/fold/foldgutter': {deps: ['addon/fold/foldcode']}, - 'addon/fold/xml-fold': {deps: ['addon/fold/foldcode']}, - 'mode/javascript/javascript': {deps: ['lib/codemirror']}, - 'mode/sparql/sparql': {deps: ['lib/codemirror']}, - 'mode/xml/xml': {deps: ['lib/codemirror']}, - 'mode/turtle/turtle': {deps: ['lib/codemirror']} - } -}); diff --git a/triplestores/fuseki/webapp/js/lib/addon/fold/brace-fold.js b/triplestores/fuseki/webapp/js/lib/addon/fold/brace-fold.js deleted file mode 100644 index 1605f6c2a9..0000000000 --- a/triplestores/fuseki/webapp/js/lib/addon/fold/brace-fold.js +++ /dev/null @@ -1,105 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.registerHelper("fold", "brace", function(cm, start) { - var line = start.line, lineText = cm.getLine(line); - var startCh, tokenType; - - function findOpening(openCh) { - for (var at = start.ch, pass = 0;;) { - var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1); - if (found == -1) { - if (pass == 1) break; - pass = 1; - at = lineText.length; - continue; - } - if (pass == 1 && found < start.ch) break; - tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)); - if (!/^(comment|string)/.test(tokenType)) return found + 1; - at = found - 1; - } - } - - var startToken = "{", endToken = "}", startCh = findOpening("{"); - if (startCh == null) { - startToken = "[", endToken = "]"; - startCh = findOpening("["); - } - - if (startCh == null) return; - var count = 1, lastLine = cm.lastLine(), end, endCh; - outer: for (var i = line; i <= lastLine; ++i) { - var text = cm.getLine(i), pos = i == line ? startCh : 0; - for (;;) { - var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos); - if (nextOpen < 0) nextOpen = text.length; - if (nextClose < 0) nextClose = text.length; - pos = Math.min(nextOpen, nextClose); - if (pos == text.length) break; - if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) { - if (pos == nextOpen) ++count; - else if (!--count) { end = i; endCh = pos; break outer; } - } - ++pos; - } - } - if (end == null || line == end && endCh == startCh) return; - return {from: CodeMirror.Pos(line, startCh), - to: CodeMirror.Pos(end, endCh)}; -}); - -CodeMirror.registerHelper("fold", "import", function(cm, start) { - function hasImport(line) { - if (line < cm.firstLine() || line > cm.lastLine()) return null; - var start = cm.getTokenAt(CodeMirror.Pos(line, 1)); - if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1)); - if (start.type != "keyword" || start.string != "import") return null; - // Now find closing semicolon, return its position - for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) { - var text = cm.getLine(i), semi = text.indexOf(";"); - if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)}; - } - } - - var start = start.line, has = hasImport(start), prev; - if (!has || hasImport(start - 1) || ((prev = hasImport(start - 2)) && prev.end.line == start - 1)) - return null; - for (var end = has.end;;) { - var next = hasImport(end.line + 1); - if (next == null) break; - end = next.end; - } - return {from: cm.clipPos(CodeMirror.Pos(start, has.startCh + 1)), to: end}; -}); - -CodeMirror.registerHelper("fold", "include", function(cm, start) { - function hasInclude(line) { - if (line < cm.firstLine() || line > cm.lastLine()) return null; - var start = cm.getTokenAt(CodeMirror.Pos(line, 1)); - if (!/\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1)); - if (start.type == "meta" && start.string.slice(0, 8) == "#include") return start.start + 8; - } - - var start = start.line, has = hasInclude(start); - if (has == null || hasInclude(start - 1) != null) return null; - for (var end = start;;) { - var next = hasInclude(end + 1); - if (next == null) break; - ++end; - } - return {from: CodeMirror.Pos(start, has + 1), - to: cm.clipPos(CodeMirror.Pos(end))}; -}); - -}); diff --git a/triplestores/fuseki/webapp/js/lib/addon/fold/comment-fold.js b/triplestores/fuseki/webapp/js/lib/addon/fold/comment-fold.js deleted file mode 100644 index b75db7ea25..0000000000 --- a/triplestores/fuseki/webapp/js/lib/addon/fold/comment-fold.js +++ /dev/null @@ -1,57 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.registerGlobalHelper("fold", "comment", function(mode) { - return mode.blockCommentStart && mode.blockCommentEnd; -}, function(cm, start) { - var mode = cm.getModeAt(start), startToken = mode.blockCommentStart, endToken = mode.blockCommentEnd; - if (!startToken || !endToken) return; - var line = start.line, lineText = cm.getLine(line); - - var startCh; - for (var at = start.ch, pass = 0;;) { - var found = at <= 0 ? -1 : lineText.lastIndexOf(startToken, at - 1); - if (found == -1) { - if (pass == 1) return; - pass = 1; - at = lineText.length; - continue; - } - if (pass == 1 && found < start.ch) return; - if (/comment/.test(cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1)))) { - startCh = found + startToken.length; - break; - } - at = found - 1; - } - - var depth = 1, lastLine = cm.lastLine(), end, endCh; - outer: for (var i = line; i <= lastLine; ++i) { - var text = cm.getLine(i), pos = i == line ? startCh : 0; - for (;;) { - var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos); - if (nextOpen < 0) nextOpen = text.length; - if (nextClose < 0) nextClose = text.length; - pos = Math.min(nextOpen, nextClose); - if (pos == text.length) break; - if (pos == nextOpen) ++depth; - else if (!--depth) { end = i; endCh = pos; break outer; } - ++pos; - } - } - if (end == null || line == end && endCh == startCh) return; - return {from: CodeMirror.Pos(line, startCh), - to: CodeMirror.Pos(end, endCh)}; -}); - -}); diff --git a/triplestores/fuseki/webapp/js/lib/addon/fold/foldcode.js b/triplestores/fuseki/webapp/js/lib/addon/fold/foldcode.js deleted file mode 100644 index 3abeb83e76..0000000000 --- a/triplestores/fuseki/webapp/js/lib/addon/fold/foldcode.js +++ /dev/null @@ -1,145 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - function doFold(cm, pos, options, force) { - if (options && options.call) { - var finder = options; - options = null; - } else { - var finder = getOption(cm, options, "rangeFinder"); - } - if (typeof pos == "number") pos = CodeMirror.Pos(pos, 0); - var minSize = getOption(cm, options, "minFoldSize"); - - function getRange(allowFolded) { - var range = finder(cm, pos); - if (!range || range.to.line - range.from.line < minSize) return null; - var marks = cm.findMarksAt(range.from); - for (var i = 0; i < marks.length; ++i) { - if (marks[i].__isFold && force !== "fold") { - if (!allowFolded) return null; - range.cleared = true; - marks[i].clear(); - } - } - return range; - } - - var range = getRange(true); - if (getOption(cm, options, "scanUp")) while (!range && pos.line > cm.firstLine()) { - pos = CodeMirror.Pos(pos.line - 1, 0); - range = getRange(false); - } - if (!range || range.cleared || force === "unfold") return; - - var myWidget = makeWidget(cm, options); - CodeMirror.on(myWidget, "mousedown", function(e) { - myRange.clear(); - CodeMirror.e_preventDefault(e); - }); - var myRange = cm.markText(range.from, range.to, { - replacedWith: myWidget, - clearOnEnter: true, - __isFold: true - }); - myRange.on("clear", function(from, to) { - CodeMirror.signal(cm, "unfold", cm, from, to); - }); - CodeMirror.signal(cm, "fold", cm, range.from, range.to); - } - - function makeWidget(cm, options) { - var widget = getOption(cm, options, "widget"); - if (typeof widget == "string") { - var text = document.createTextNode(widget); - widget = document.createElement("span"); - widget.appendChild(text); - widget.className = "CodeMirror-foldmarker"; - } - return widget; - } - - // Clumsy backwards-compatible interface - CodeMirror.newFoldFunction = function(rangeFinder, widget) { - return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); }; - }; - - // New-style interface - CodeMirror.defineExtension("foldCode", function(pos, options, force) { - doFold(this, pos, options, force); - }); - - CodeMirror.defineExtension("isFolded", function(pos) { - var marks = this.findMarksAt(pos); - for (var i = 0; i < marks.length; ++i) - if (marks[i].__isFold) return true; - }); - - CodeMirror.commands.toggleFold = function(cm) { - cm.foldCode(cm.getCursor()); - }; - CodeMirror.commands.fold = function(cm) { - cm.foldCode(cm.getCursor(), null, "fold"); - }; - CodeMirror.commands.unfold = function(cm) { - cm.foldCode(cm.getCursor(), null, "unfold"); - }; - CodeMirror.commands.foldAll = function(cm) { - cm.operation(function() { - for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++) - cm.foldCode(CodeMirror.Pos(i, 0), null, "fold"); - }); - }; - CodeMirror.commands.unfoldAll = function(cm) { - cm.operation(function() { - for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++) - cm.foldCode(CodeMirror.Pos(i, 0), null, "unfold"); - }); - }; - - CodeMirror.registerHelper("fold", "combine", function() { - var funcs = Array.prototype.slice.call(arguments, 0); - return function(cm, start) { - for (var i = 0; i < funcs.length; ++i) { - var found = funcs[i](cm, start); - if (found) return found; - } - }; - }); - - CodeMirror.registerHelper("fold", "auto", function(cm, start) { - var helpers = cm.getHelpers(start, "fold"); - for (var i = 0; i < helpers.length; i++) { - var cur = helpers[i](cm, start); - if (cur) return cur; - } - }); - - var defaultOptions = { - rangeFinder: CodeMirror.fold.auto, - widget: "\u2194", - minFoldSize: 0, - scanUp: false - }; - - CodeMirror.defineOption("foldOptions", null); - - function getOption(cm, options, name) { - if (options && options[name] !== undefined) - return options[name]; - var editorOptions = cm.options.foldOptions; - if (editorOptions && editorOptions[name] !== undefined) - return editorOptions[name]; - return defaultOptions[name]; - } -}); diff --git a/triplestores/fuseki/webapp/js/lib/addon/fold/foldgutter.js b/triplestores/fuseki/webapp/js/lib/addon/fold/foldgutter.js deleted file mode 100644 index bd31ec4d9b..0000000000 --- a/triplestores/fuseki/webapp/js/lib/addon/fold/foldgutter.js +++ /dev/null @@ -1,134 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror"), require("./foldcode")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror", "./foldcode"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - CodeMirror.defineOption("foldGutter", false, function(cm, val, old) { - if (old && old != CodeMirror.Init) { - cm.clearGutter(cm.state.foldGutter.options.gutter); - cm.state.foldGutter = null; - cm.off("gutterClick", onGutterClick); - cm.off("change", onChange); - cm.off("viewportChange", onViewportChange); - cm.off("fold", onFold); - cm.off("unfold", onFold); - cm.off("swapDoc", updateInViewport); - } - if (val) { - cm.state.foldGutter = new State(parseOptions(val)); - updateInViewport(cm); - cm.on("gutterClick", onGutterClick); - cm.on("change", onChange); - cm.on("viewportChange", onViewportChange); - cm.on("fold", onFold); - cm.on("unfold", onFold); - cm.on("swapDoc", updateInViewport); - } - }); - - var Pos = CodeMirror.Pos; - - function State(options) { - this.options = options; - this.from = this.to = 0; - } - - function parseOptions(opts) { - if (opts === true) opts = {}; - if (opts.gutter == null) opts.gutter = "CodeMirror-foldgutter"; - if (opts.indicatorOpen == null) opts.indicatorOpen = "CodeMirror-foldgutter-open"; - if (opts.indicatorFolded == null) opts.indicatorFolded = "CodeMirror-foldgutter-folded"; - return opts; - } - - function isFolded(cm, line) { - var marks = cm.findMarksAt(Pos(line)); - for (var i = 0; i < marks.length; ++i) - if (marks[i].__isFold && marks[i].find().from.line == line) return true; - } - - function marker(spec) { - if (typeof spec == "string") { - var elt = document.createElement("div"); - elt.className = spec + " CodeMirror-guttermarker-subtle"; - return elt; - } else { - return spec.cloneNode(true); - } - } - - function updateFoldInfo(cm, from, to) { - var opts = cm.state.foldGutter.options, cur = from; - cm.eachLine(from, to, function(line) { - var mark = null; - if (isFolded(cm, cur)) { - mark = marker(opts.indicatorFolded); - } else { - var pos = Pos(cur, 0), func = opts.rangeFinder || CodeMirror.fold.auto; - var range = func && func(cm, pos); - if (range && range.from.line + 1 < range.to.line) - mark = marker(opts.indicatorOpen); - } - cm.setGutterMarker(line, opts.gutter, mark); - ++cur; - }); - } - - function updateInViewport(cm) { - var vp = cm.getViewport(), state = cm.state.foldGutter; - if (!state) return; - cm.operation(function() { - updateFoldInfo(cm, vp.from, vp.to); - }); - state.from = vp.from; state.to = vp.to; - } - - function onGutterClick(cm, line, gutter) { - var opts = cm.state.foldGutter.options; - if (gutter != opts.gutter) return; - cm.foldCode(Pos(line, 0), opts.rangeFinder); - } - - function onChange(cm) { - var state = cm.state.foldGutter, opts = cm.state.foldGutter.options; - state.from = state.to = 0; - clearTimeout(state.changeUpdate); - state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600); - } - - function onViewportChange(cm) { - var state = cm.state.foldGutter, opts = cm.state.foldGutter.options; - clearTimeout(state.changeUpdate); - state.changeUpdate = setTimeout(function() { - var vp = cm.getViewport(); - if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) { - updateInViewport(cm); - } else { - cm.operation(function() { - if (vp.from < state.from) { - updateFoldInfo(cm, vp.from, state.from); - state.from = vp.from; - } - if (vp.to > state.to) { - updateFoldInfo(cm, state.to, vp.to); - state.to = vp.to; - } - }); - } - }, opts.updateViewportTimeSpan || 400); - } - - function onFold(cm, from) { - var state = cm.state.foldGutter, line = from.line; - if (line >= state.from && line < state.to) - updateFoldInfo(cm, line, line + 1); - } -}); diff --git a/triplestores/fuseki/webapp/js/lib/addon/fold/xml-fold.js b/triplestores/fuseki/webapp/js/lib/addon/fold/xml-fold.js deleted file mode 100644 index a45da58422..0000000000 --- a/triplestores/fuseki/webapp/js/lib/addon/fold/xml-fold.js +++ /dev/null @@ -1,181 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { - "use strict"; - - var Pos = CodeMirror.Pos; - function cmp(a, b) { return a.line - b.line || a.ch - b.ch; } - - var nameStartChar = "A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD"; - var nameChar = nameStartChar + "\-\:\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040"; - var xmlTagStart = new RegExp("<(/?)([" + nameStartChar + "][" + nameChar + "]*)", "g"); - - function Iter(cm, line, ch, range) { - this.line = line; this.ch = ch; - this.cm = cm; this.text = cm.getLine(line); - this.min = range ? range.from : cm.firstLine(); - this.max = range ? range.to - 1 : cm.lastLine(); - } - - function tagAt(iter, ch) { - var type = iter.cm.getTokenTypeAt(Pos(iter.line, ch)); - return type && /\btag\b/.test(type); - } - - function nextLine(iter) { - if (iter.line >= iter.max) return; - iter.ch = 0; - iter.text = iter.cm.getLine(++iter.line); - return true; - } - function prevLine(iter) { - if (iter.line <= iter.min) return; - iter.text = iter.cm.getLine(--iter.line); - iter.ch = iter.text.length; - return true; - } - - function toTagEnd(iter) { - for (;;) { - var gt = iter.text.indexOf(">", iter.ch); - if (gt == -1) { if (nextLine(iter)) continue; else return; } - if (!tagAt(iter, gt + 1)) { iter.ch = gt + 1; continue; } - var lastSlash = iter.text.lastIndexOf("/", gt); - var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt)); - iter.ch = gt + 1; - return selfClose ? "selfClose" : "regular"; - } - } - function toTagStart(iter) { - for (;;) { - var lt = iter.ch ? iter.text.lastIndexOf("<", iter.ch - 1) : -1; - if (lt == -1) { if (prevLine(iter)) continue; else return; } - if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; } - xmlTagStart.lastIndex = lt; - iter.ch = lt; - var match = xmlTagStart.exec(iter.text); - if (match && match.index == lt) return match; - } - } - - function toNextTag(iter) { - for (;;) { - xmlTagStart.lastIndex = iter.ch; - var found = xmlTagStart.exec(iter.text); - if (!found) { if (nextLine(iter)) continue; else return; } - if (!tagAt(iter, found.index + 1)) { iter.ch = found.index + 1; continue; } - iter.ch = found.index + found[0].length; - return found; - } - } - function toPrevTag(iter) { - for (;;) { - var gt = iter.ch ? iter.text.lastIndexOf(">", iter.ch - 1) : -1; - if (gt == -1) { if (prevLine(iter)) continue; else return; } - if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; } - var lastSlash = iter.text.lastIndexOf("/", gt); - var selfClose = lastSlash > -1 && !/\S/.test(iter.text.slice(lastSlash + 1, gt)); - iter.ch = gt + 1; - return selfClose ? "selfClose" : "regular"; - } - } - - function findMatchingClose(iter, tag) { - var stack = []; - for (;;) { - var next = toNextTag(iter), end, startLine = iter.line, startCh = iter.ch - (next ? next[0].length : 0); - if (!next || !(end = toTagEnd(iter))) return; - if (end == "selfClose") continue; - if (next[1]) { // closing tag - for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) { - stack.length = i; - break; - } - if (i < 0 && (!tag || tag == next[2])) return { - tag: next[2], - from: Pos(startLine, startCh), - to: Pos(iter.line, iter.ch) - }; - } else { // opening tag - stack.push(next[2]); - } - } - } - function findMatchingOpen(iter, tag) { - var stack = []; - for (;;) { - var prev = toPrevTag(iter); - if (!prev) return; - if (prev == "selfClose") { toTagStart(iter); continue; } - var endLine = iter.line, endCh = iter.ch; - var start = toTagStart(iter); - if (!start) return; - if (start[1]) { // closing tag - stack.push(start[2]); - } else { // opening tag - for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == start[2]) { - stack.length = i; - break; - } - if (i < 0 && (!tag || tag == start[2])) return { - tag: start[2], - from: Pos(iter.line, iter.ch), - to: Pos(endLine, endCh) - }; - } - } - } - - CodeMirror.registerHelper("fold", "xml", function(cm, start) { - var iter = new Iter(cm, start.line, 0); - for (;;) { - var openTag = toNextTag(iter), end; - if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return; - if (!openTag[1] && end != "selfClose") { - var start = Pos(iter.line, iter.ch); - var close = findMatchingClose(iter, openTag[2]); - return close && {from: start, to: close.from}; - } - } - }); - CodeMirror.findMatchingTag = function(cm, pos, range) { - var iter = new Iter(cm, pos.line, pos.ch, range); - if (iter.text.indexOf(">") == -1 && iter.text.indexOf("<") == -1) return; - var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch); - var start = end && toTagStart(iter); - if (!end || end == "selfClose" || !start || cmp(iter, pos) > 0) return; - var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]}; - - if (start[1]) { // closing tag - return {open: findMatchingOpen(iter, start[2]), close: here, at: "close"}; - } else { // opening tag - iter = new Iter(cm, to.line, to.ch, range); - return {open: here, close: findMatchingClose(iter, start[2]), at: "open"}; - } - }; - - CodeMirror.findEnclosingTag = function(cm, pos, range) { - var iter = new Iter(cm, pos.line, pos.ch, range); - for (;;) { - var open = findMatchingOpen(iter); - if (!open) break; - var forward = new Iter(cm, pos.line, pos.ch, range); - var close = findMatchingClose(forward, open.tag); - if (close) return {open: open, close: close}; - } - }; - - // Used by addon/edit/closetag.js - CodeMirror.scanForClosingTag = function(cm, pos, name, end) { - var iter = new Iter(cm, pos.line, pos.ch, end ? {from: 0, to: end} : null); - return findMatchingClose(iter, name); - }; -}); diff --git a/triplestores/fuseki/webapp/js/lib/backbone-min.js b/triplestores/fuseki/webapp/js/lib/backbone-min.js deleted file mode 100644 index 3b2593dd26..0000000000 --- a/triplestores/fuseki/webapp/js/lib/backbone-min.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(){var t=this;var e=t.Backbone;var i=[];var r=i.push;var s=i.slice;var n=i.splice;var a;if(typeof exports!=="undefined"){a=exports}else{a=t.Backbone={}}a.VERSION="1.1.0";var h=t._;if(!h&&typeof require!=="undefined")h=require("underscore");a.$=t.jQuery||t.Zepto||t.ender||t.$;a.noConflict=function(){t.Backbone=e;return this};a.emulateHTTP=false;a.emulateJSON=false;var o=a.Events={on:function(t,e,i){if(!l(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var r=this._events[t]||(this._events[t]=[]);r.push({callback:e,context:i,ctx:i||this});return this},once:function(t,e,i){if(!l(this,"once",t,[e,i])||!e)return this;var r=this;var s=h.once(function(){r.off(t,s);e.apply(this,arguments)});s._callback=e;return this.on(t,s,i)},off:function(t,e,i){var r,s,n,a,o,u,c,f;if(!this._events||!l(this,"off",t,[e,i]))return this;if(!t&&!e&&!i){this._events={};return this}a=t?[t]:h.keys(this._events);for(o=0,u=a.length;o").attr(t);this.setElement(e,false)}else{this.setElement(h.result(this,"el"),false)}}});a.sync=function(t,e,i){var r=T[t];h.defaults(i||(i={}),{emulateHTTP:a.emulateHTTP,emulateJSON:a.emulateJSON});var s={type:r,dataType:"json"};if(!i.url){s.url=h.result(e,"url")||U()}if(i.data==null&&e&&(t==="create"||t==="update"||t==="patch")){s.contentType="application/json";s.data=JSON.stringify(i.attrs||e.toJSON(i))}if(i.emulateJSON){s.contentType="application/x-www-form-urlencoded";s.data=s.data?{model:s.data}:{}}if(i.emulateHTTP&&(r==="PUT"||r==="DELETE"||r==="PATCH")){s.type="POST";if(i.emulateJSON)s.data._method=r;var n=i.beforeSend;i.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",r);if(n)return n.apply(this,arguments)}}if(s.type!=="GET"&&!i.emulateJSON){s.processData=false}if(s.type==="PATCH"&&E){s.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")}}var o=i.xhr=a.ajax(h.extend(s,i));e.trigger("request",e,o,i);return o};var E=typeof window!=="undefined"&&!!window.ActiveXObject&&!(window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent);var T={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};a.ajax=function(){return a.$.ajax.apply(a.$,arguments)};var k=a.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var S=/\((.*?)\)/g;var $=/(\(\?)?:\w+/g;var H=/\*\w+/g;var A=/[\-{}\[\]+?.,\\\^$|#\s]/g;h.extend(k.prototype,o,{initialize:function(){},route:function(t,e,i){if(!h.isRegExp(t))t=this._routeToRegExp(t);if(h.isFunction(e)){i=e;e=""}if(!i)i=this[e];var r=this;a.history.route(t,function(s){var n=r._extractParameters(t,s);i&&i.apply(r,n);r.trigger.apply(r,["route:"+e].concat(n));r.trigger("route",e,n);a.history.trigger("route",r,e,n)});return this},navigate:function(t,e){a.history.navigate(t,e);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=h.result(this,"routes");var t,e=h.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(A,"\\$&").replace(S,"(?:$1)?").replace($,function(t,e){return e?t:"([^/]+)"}).replace(H,"(.*?)");return new RegExp("^"+t+"$")},_extractParameters:function(t,e){var i=t.exec(e).slice(1);return h.map(i,function(t){return t?decodeURIComponent(t):null})}});var I=a.History=function(){this.handlers=[];h.bindAll(this,"checkUrl");if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var N=/^[#\/]|\s+$/g;var O=/^\/+|\/+$/g;var P=/msie [\w.]+/;var C=/\/$/;var j=/[?#].*$/;I.started=false;h.extend(I.prototype,o,{interval:50,getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(t==null){if(this._hasPushState||!this._wantsHashChange||e){t=this.location.pathname;var i=this.root.replace(C,"");if(!t.indexOf(i))t=t.slice(i.length)}else{t=this.getHash()}}return t.replace(N,"")},start:function(t){if(I.started)throw new Error("Backbone.history has already been started");I.started=true;this.options=h.extend({root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var e=this.getFragment();var i=document.documentMode;var r=P.exec(navigator.userAgent.toLowerCase())&&(!i||i<=7);this.root=("/"+this.root+"/").replace(O,"/");if(r&&this._wantsHashChange){this.iframe=a.$('' - ).bind('load', function () { - var fileInputClones, - paramNames = $.isArray(options.paramName) ? - options.paramName : [options.paramName]; - iframe - .unbind('load') - .bind('load', function () { - var response; - // Wrap in a try/catch block to catch exceptions thrown - // when trying to access cross-domain iframe contents: - try { - response = iframe.contents(); - // Google Chrome and Firefox do not throw an - // exception when calling iframe.contents() on - // cross-domain requests, so we unify the response: - if (!response.length || !response[0].firstChild) { - throw new Error(); - } - } catch (e) { - response = undefined; - } - // The complete callback returns the - // iframe content document as response object: - completeCallback( - 200, - 'success', - {'iframe': response} - ); - // Fix for IE endless progress bar activity bug - // (happens on form submits to iframe targets): - $('') - .appendTo(form); - window.setTimeout(function () { - // Removing the form in a setTimeout call - // allows Chrome's developer tools to display - // the response result - form.remove(); - }, 0); - }); - form - .prop('target', iframe.prop('name')) - .prop('action', options.url) - .prop('method', options.type); - if (options.formData) { - $.each(options.formData, function (index, field) { - $('') - .prop('name', field.name) - .val(field.value) - .appendTo(form); - }); - } - if (options.fileInput && options.fileInput.length && - options.type === 'POST') { - fileInputClones = options.fileInput.clone(); - // Insert a clone for each file input field: - options.fileInput.after(function (index) { - return fileInputClones[index]; - }); - if (options.paramName) { - options.fileInput.each(function (index) { - $(this).prop( - 'name', - paramNames[index] || options.paramName - ); - }); - } - // Appending the file input fields to the hidden form - // removes them from their original location: - form - .append(options.fileInput) - .prop('enctype', 'multipart/form-data') - // enctype must be set as encoding for IE: - .prop('encoding', 'multipart/form-data'); - // Remove the HTML5 form attribute from the input(s): - options.fileInput.removeAttr('form'); - } - form.submit(); - // Insert the file input fields at their original location - // by replacing the clones with the originals: - if (fileInputClones && fileInputClones.length) { - options.fileInput.each(function (index, input) { - var clone = $(fileInputClones[index]); - // Restore the original name and form properties: - $(input) - .prop('name', clone.prop('name')) - .attr('form', clone.attr('form')); - clone.replaceWith(input); - }); - } - }); - form.append(iframe).appendTo(document.body); - }, - abort: function () { - if (iframe) { - // javascript:false as iframe src aborts the request - // and prevents warning popups on HTTPS in IE6. - // concat is used to avoid the "Script URL" JSLint error: - iframe - .unbind('load') - .prop('src', initialIframeSrc); - } - if (form) { - form.remove(); - } - } - }; - } - }); - - // The iframe transport returns the iframe content document as response. - // The following adds converters from iframe to text, json, html, xml - // and script. - // Please note that the Content-Type for JSON responses has to be text/plain - // or text/html, if the browser doesn't include application/json in the - // Accept header, else IE will show a download dialog. - // The Content-Type for XML responses on the other hand has to be always - // application/xml or text/xml, so IE properly parses the XML response. - // See also - // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation - $.ajaxSetup({ - converters: { - 'iframe text': function (iframe) { - return iframe && $(iframe[0].body).text(); - }, - 'iframe json': function (iframe) { - return iframe && $.parseJSON($(iframe[0].body).text()); - }, - 'iframe html': function (iframe) { - return iframe && $(iframe[0].body).html(); - }, - 'iframe xml': function (iframe) { - var xmlDoc = iframe && iframe[0]; - return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc : - $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) || - $(xmlDoc.body).html()); - }, - 'iframe script': function (iframe) { - return iframe && $.globalEval($(iframe[0].body).text()); - } - } - }); - -})); diff --git a/triplestores/fuseki/webapp/js/lib/jquery.ui.widget.js b/triplestores/fuseki/webapp/js/lib/jquery.ui.widget.js deleted file mode 100644 index c430419971..0000000000 --- a/triplestores/fuseki/webapp/js/lib/jquery.ui.widget.js +++ /dev/null @@ -1,530 +0,0 @@ -/*! - * jQuery UI Widget 1.10.4+amd - * https://github.com/blueimp/jQuery-File-Upload - * - * Copyright 2014 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/jQuery.widget/ - */ - -(function (factory) { - if (typeof define === "function" && define.amd) { - // Register as an anonymous AMD module: - define(["jquery"], factory); - } else { - // Browser globals: - factory(jQuery); - } -}(function( $, undefined ) { - -var uuid = 0, - slice = Array.prototype.slice, - _cleanData = $.cleanData; -$.cleanData = function( elems ) { - for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { - try { - $( elem ).triggerHandler( "remove" ); - // http://bugs.jquery.com/ticket/8235 - } catch( e ) {} - } - _cleanData( elems ); -}; - -$.widget = function( name, base, prototype ) { - var fullName, existingConstructor, constructor, basePrototype, - // proxiedPrototype allows the provided prototype to remain unmodified - // so that it can be used as a mixin for multiple widgets (#8876) - proxiedPrototype = {}, - namespace = name.split( "." )[ 0 ]; - - name = name.split( "." )[ 1 ]; - fullName = namespace + "-" + name; - - if ( !prototype ) { - prototype = base; - base = $.Widget; - } - - // create selector for plugin - $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { - return !!$.data( elem, fullName ); - }; - - $[ namespace ] = $[ namespace ] || {}; - existingConstructor = $[ namespace ][ name ]; - constructor = $[ namespace ][ name ] = function( options, element ) { - // allow instantiation without "new" keyword - if ( !this._createWidget ) { - return new constructor( options, element ); - } - - // allow instantiation without initializing for simple inheritance - // must use "new" keyword (the code above always passes args) - if ( arguments.length ) { - this._createWidget( options, element ); - } - }; - // extend with the existing constructor to carry over any static properties - $.extend( constructor, existingConstructor, { - version: prototype.version, - // copy the object used to create the prototype in case we need to - // redefine the widget later - _proto: $.extend( {}, prototype ), - // track widgets that inherit from this widget in case this widget is - // redefined after a widget inherits from it - _childConstructors: [] - }); - - basePrototype = new base(); - // we need to make the options hash a property directly on the new instance - // otherwise we'll modify the options hash on the prototype that we're - // inheriting from - basePrototype.options = $.widget.extend( {}, basePrototype.options ); - $.each( prototype, function( prop, value ) { - if ( !$.isFunction( value ) ) { - proxiedPrototype[ prop ] = value; - return; - } - proxiedPrototype[ prop ] = (function() { - var _super = function() { - return base.prototype[ prop ].apply( this, arguments ); - }, - _superApply = function( args ) { - return base.prototype[ prop ].apply( this, args ); - }; - return function() { - var __super = this._super, - __superApply = this._superApply, - returnValue; - - this._super = _super; - this._superApply = _superApply; - - returnValue = value.apply( this, arguments ); - - this._super = __super; - this._superApply = __superApply; - - return returnValue; - }; - })(); - }); - constructor.prototype = $.widget.extend( basePrototype, { - // TODO: remove support for widgetEventPrefix - // always use the name + a colon as the prefix, e.g., draggable:start - // don't prefix for widgets that aren't DOM-based - widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name - }, proxiedPrototype, { - constructor: constructor, - namespace: namespace, - widgetName: name, - widgetFullName: fullName - }); - - // If this widget is being redefined then we need to find all widgets that - // are inheriting from it and redefine all of them so that they inherit from - // the new version of this widget. We're essentially trying to replace one - // level in the prototype chain. - if ( existingConstructor ) { - $.each( existingConstructor._childConstructors, function( i, child ) { - var childPrototype = child.prototype; - - // redefine the child widget using the same prototype that was - // originally used, but inherit from the new version of the base - $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); - }); - // remove the list of existing child constructors from the old constructor - // so the old child constructors can be garbage collected - delete existingConstructor._childConstructors; - } else { - base._childConstructors.push( constructor ); - } - - $.widget.bridge( name, constructor ); -}; - -$.widget.extend = function( target ) { - var input = slice.call( arguments, 1 ), - inputIndex = 0, - inputLength = input.length, - key, - value; - for ( ; inputIndex < inputLength; inputIndex++ ) { - for ( key in input[ inputIndex ] ) { - value = input[ inputIndex ][ key ]; - if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { - // Clone objects - if ( $.isPlainObject( value ) ) { - target[ key ] = $.isPlainObject( target[ key ] ) ? - $.widget.extend( {}, target[ key ], value ) : - // Don't extend strings, arrays, etc. with objects - $.widget.extend( {}, value ); - // Copy everything else by reference - } else { - target[ key ] = value; - } - } - } - } - return target; -}; - -$.widget.bridge = function( name, object ) { - var fullName = object.prototype.widgetFullName || name; - $.fn[ name ] = function( options ) { - var isMethodCall = typeof options === "string", - args = slice.call( arguments, 1 ), - returnValue = this; - - // allow multiple hashes to be passed on init - options = !isMethodCall && args.length ? - $.widget.extend.apply( null, [ options ].concat(args) ) : - options; - - if ( isMethodCall ) { - this.each(function() { - var methodValue, - instance = $.data( this, fullName ); - if ( !instance ) { - return $.error( "cannot call methods on " + name + " prior to initialization; " + - "attempted to call method '" + options + "'" ); - } - if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { - return $.error( "no such method '" + options + "' for " + name + " widget instance" ); - } - methodValue = instance[ options ].apply( instance, args ); - if ( methodValue !== instance && methodValue !== undefined ) { - returnValue = methodValue && methodValue.jquery ? - returnValue.pushStack( methodValue.get() ) : - methodValue; - return false; - } - }); - } else { - this.each(function() { - var instance = $.data( this, fullName ); - if ( instance ) { - instance.option( options || {} )._init(); - } else { - $.data( this, fullName, new object( options, this ) ); - } - }); - } - - return returnValue; - }; -}; - -$.Widget = function( /* options, element */ ) {}; -$.Widget._childConstructors = []; - -$.Widget.prototype = { - widgetName: "widget", - widgetEventPrefix: "", - defaultElement: "
      ", - options: { - disabled: false, - - // callbacks - create: null - }, - _createWidget: function( options, element ) { - element = $( element || this.defaultElement || this )[ 0 ]; - this.element = $( element ); - this.uuid = uuid++; - this.eventNamespace = "." + this.widgetName + this.uuid; - this.options = $.widget.extend( {}, - this.options, - this._getCreateOptions(), - options ); - - this.bindings = $(); - this.hoverable = $(); - this.focusable = $(); - - if ( element !== this ) { - $.data( element, this.widgetFullName, this ); - this._on( true, this.element, { - remove: function( event ) { - if ( event.target === element ) { - this.destroy(); - } - } - }); - this.document = $( element.style ? - // element within the document - element.ownerDocument : - // element is window or document - element.document || element ); - this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); - } - - this._create(); - this._trigger( "create", null, this._getCreateEventData() ); - this._init(); - }, - _getCreateOptions: $.noop, - _getCreateEventData: $.noop, - _create: $.noop, - _init: $.noop, - - destroy: function() { - this._destroy(); - // we can probably remove the unbind calls in 2.0 - // all event bindings should go through this._on() - this.element - .unbind( this.eventNamespace ) - // 1.9 BC for #7810 - // TODO remove dual storage - .removeData( this.widgetName ) - .removeData( this.widgetFullName ) - // support: jquery <1.6.3 - // http://bugs.jquery.com/ticket/9413 - .removeData( $.camelCase( this.widgetFullName ) ); - this.widget() - .unbind( this.eventNamespace ) - .removeAttr( "aria-disabled" ) - .removeClass( - this.widgetFullName + "-disabled " + - "ui-state-disabled" ); - - // clean up events and states - this.bindings.unbind( this.eventNamespace ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - }, - _destroy: $.noop, - - widget: function() { - return this.element; - }, - - option: function( key, value ) { - var options = key, - parts, - curOption, - i; - - if ( arguments.length === 0 ) { - // don't return a reference to the internal hash - return $.widget.extend( {}, this.options ); - } - - if ( typeof key === "string" ) { - // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } - options = {}; - parts = key.split( "." ); - key = parts.shift(); - if ( parts.length ) { - curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); - for ( i = 0; i < parts.length - 1; i++ ) { - curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; - curOption = curOption[ parts[ i ] ]; - } - key = parts.pop(); - if ( arguments.length === 1 ) { - return curOption[ key ] === undefined ? null : curOption[ key ]; - } - curOption[ key ] = value; - } else { - if ( arguments.length === 1 ) { - return this.options[ key ] === undefined ? null : this.options[ key ]; - } - options[ key ] = value; - } - } - - this._setOptions( options ); - - return this; - }, - _setOptions: function( options ) { - var key; - - for ( key in options ) { - this._setOption( key, options[ key ] ); - } - - return this; - }, - _setOption: function( key, value ) { - this.options[ key ] = value; - - if ( key === "disabled" ) { - this.widget() - .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value ) - .attr( "aria-disabled", value ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - } - - return this; - }, - - enable: function() { - return this._setOption( "disabled", false ); - }, - disable: function() { - return this._setOption( "disabled", true ); - }, - - _on: function( suppressDisabledCheck, element, handlers ) { - var delegateElement, - instance = this; - - // no suppressDisabledCheck flag, shuffle arguments - if ( typeof suppressDisabledCheck !== "boolean" ) { - handlers = element; - element = suppressDisabledCheck; - suppressDisabledCheck = false; - } - - // no element argument, shuffle and use this.element - if ( !handlers ) { - handlers = element; - element = this.element; - delegateElement = this.widget(); - } else { - // accept selectors, DOM elements - element = delegateElement = $( element ); - this.bindings = this.bindings.add( element ); - } - - $.each( handlers, function( event, handler ) { - function handlerProxy() { - // allow widgets to customize the disabled handling - // - disabled as an array instead of boolean - // - disabled class as method for disabling individual parts - if ( !suppressDisabledCheck && - ( instance.options.disabled === true || - $( this ).hasClass( "ui-state-disabled" ) ) ) { - return; - } - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - - // copy the guid so direct unbinding works - if ( typeof handler !== "string" ) { - handlerProxy.guid = handler.guid = - handler.guid || handlerProxy.guid || $.guid++; - } - - var match = event.match( /^(\w+)\s*(.*)$/ ), - eventName = match[1] + instance.eventNamespace, - selector = match[2]; - if ( selector ) { - delegateElement.delegate( selector, eventName, handlerProxy ); - } else { - element.bind( eventName, handlerProxy ); - } - }); - }, - - _off: function( element, eventName ) { - eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace; - element.unbind( eventName ).undelegate( eventName ); - }, - - _delay: function( handler, delay ) { - function handlerProxy() { - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - var instance = this; - return setTimeout( handlerProxy, delay || 0 ); - }, - - _hoverable: function( element ) { - this.hoverable = this.hoverable.add( element ); - this._on( element, { - mouseenter: function( event ) { - $( event.currentTarget ).addClass( "ui-state-hover" ); - }, - mouseleave: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-hover" ); - } - }); - }, - - _focusable: function( element ) { - this.focusable = this.focusable.add( element ); - this._on( element, { - focusin: function( event ) { - $( event.currentTarget ).addClass( "ui-state-focus" ); - }, - focusout: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-focus" ); - } - }); - }, - - _trigger: function( type, event, data ) { - var prop, orig, - callback = this.options[ type ]; - - data = data || {}; - event = $.Event( event ); - event.type = ( type === this.widgetEventPrefix ? - type : - this.widgetEventPrefix + type ).toLowerCase(); - // the original event may come from any element - // so we need to reset the target on the new event - event.target = this.element[ 0 ]; - - // copy original event properties over to the new event - orig = event.originalEvent; - if ( orig ) { - for ( prop in orig ) { - if ( !( prop in event ) ) { - event[ prop ] = orig[ prop ]; - } - } - } - - this.element.trigger( event, data ); - return !( $.isFunction( callback ) && - callback.apply( this.element[0], [ event ].concat( data ) ) === false || - event.isDefaultPrevented() ); - } -}; - -$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { - $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { - if ( typeof options === "string" ) { - options = { effect: options }; - } - var hasOptions, - effectName = !options ? - method : - options === true || typeof options === "number" ? - defaultEffect : - options.effect || defaultEffect; - options = options || {}; - if ( typeof options === "number" ) { - options = { duration: options }; - } - hasOptions = !$.isEmptyObject( options ); - options.complete = callback; - if ( options.delay ) { - element.delay( options.delay ); - } - if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { - element[ method ]( options ); - } else if ( effectName !== method && element[ effectName ] ) { - element[ effectName ]( options.duration, options.easing, callback ); - } else { - element.queue(function( next ) { - $( this )[ method ](); - if ( callback ) { - callback.call( element[ 0 ] ); - } - next(); - }); - } - }; -}); - -})); diff --git a/triplestores/fuseki/webapp/js/lib/jquery.xdomainrequest.js b/triplestores/fuseki/webapp/js/lib/jquery.xdomainrequest.js deleted file mode 100644 index 91a8c2fe98..0000000000 --- a/triplestores/fuseki/webapp/js/lib/jquery.xdomainrequest.js +++ /dev/null @@ -1,90 +0,0 @@ -// jQuery.XDomainRequest.js -// Author: Jason Moon - @JSONMOON -// IE8+ -if (!jQuery.support.cors && jQuery.ajaxTransport && window.XDomainRequest) { - var httpRegEx = /^https?:\/\//i; - var getOrPostRegEx = /^get|post$/i; - var sameSchemeRegEx = new RegExp('^'+location.protocol, 'i'); - var htmlRegEx = /text\/html/i; - var jsonRegEx = /\/json/i; - var xmlRegEx = /\/xml/i; - - // ajaxTransport exists in jQuery 1.5+ - jQuery.ajaxTransport('text html xml json', function(options, userOptions, jqXHR){ - // XDomainRequests must be: asynchronous, GET or POST methods, HTTP or HTTPS protocol, and same scheme as calling page - if (options.crossDomain && options.async && getOrPostRegEx.test(options.type) && httpRegEx.test(options.url) && sameSchemeRegEx.test(options.url)) { - var xdr = null; - var userType = (userOptions.dataType||'').toLowerCase(); - return { - send: function(headers, complete){ - xdr = new XDomainRequest(); - if (/^\d+$/.test(userOptions.timeout)) { - xdr.timeout = userOptions.timeout; - } - xdr.ontimeout = function(){ - complete(500, 'timeout'); - }; - xdr.onload = function(){ - var allResponseHeaders = 'Content-Length: ' + xdr.responseText.length + '\r\nContent-Type: ' + xdr.contentType; - var status = { - code: 200, - message: 'success' - }; - var responses = { - text: xdr.responseText - }; - try { - if (userType === 'html' || htmlRegEx.test(xdr.contentType)) { - responses.html = xdr.responseText; - } else if (userType === 'json' || (userType !== 'text' && jsonRegEx.test(xdr.contentType))) { - try { - responses.json = jQuery.parseJSON(xdr.responseText); - } catch(e) { - status.code = 500; - status.message = 'parseerror'; - //throw 'Invalid JSON: ' + xdr.responseText; - } - } else if (userType === 'xml' || (userType !== 'text' && xmlRegEx.test(xdr.contentType))) { - var doc = new ActiveXObject('Microsoft.XMLDOM'); - doc.async = false; - try { - doc.loadXML(xdr.responseText); - } catch(e) { - doc = undefined; - } - if (!doc || !doc.documentElement || doc.getElementsByTagName('parsererror').length) { - status.code = 500; - status.message = 'parseerror'; - throw 'Invalid XML: ' + xdr.responseText; - } - responses.xml = doc; - } - } catch(parseMessage) { - throw parseMessage; - } finally { - complete(status.code, status.message, responses, allResponseHeaders); - } - }; - // set an empty handler for 'onprogress' so requests don't get aborted - xdr.onprogress = function(){}; - xdr.onerror = function(){ - complete(500, 'error', { - text: xdr.responseText - }); - }; - var postData = ''; - if (userOptions.data) { - postData = (jQuery.type(userOptions.data) === 'string') ? userOptions.data : jQuery.param(userOptions.data); - } - xdr.open(options.type, options.url); - xdr.send(postData); - }, - abort: function(){ - if (xdr) { - xdr.abort(); - } - } - }; - } - }); -} diff --git a/triplestores/fuseki/webapp/js/lib/lib/codemirror.js b/triplestores/fuseki/webapp/js/lib/lib/codemirror.js deleted file mode 100644 index bafc9fa142..0000000000 --- a/triplestores/fuseki/webapp/js/lib/lib/codemirror.js +++ /dev/null @@ -1,7638 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// This is CodeMirror (http://codemirror.net), a code editor -// implemented in JavaScript on top of the browser's DOM. -// -// You can find some technical background for some of the code below -// at http://marijnhaverbeke.nl/blog/#cm-internals . - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - module.exports = mod(); - else if (typeof define == "function" && define.amd) // AMD - return define([], mod); - else // Plain browser env - this.CodeMirror = mod(); -})(function() { - "use strict"; - - // BROWSER SNIFFING - - // Kludges for bugs and behavior differences that can't be feature - // detected are enabled based on userAgent etc sniffing. - - var gecko = /gecko\/\d/i.test(navigator.userAgent); - // ie_uptoN means Internet Explorer version N or lower - var ie_upto10 = /MSIE \d/.test(navigator.userAgent); - var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent); - var ie = ie_upto10 || ie_11up; - var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]); - var webkit = /WebKit\//.test(navigator.userAgent); - var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent); - var chrome = /Chrome\//.test(navigator.userAgent); - var presto = /Opera\//.test(navigator.userAgent); - var safari = /Apple Computer/.test(navigator.vendor); - var khtml = /KHTML\//.test(navigator.userAgent); - var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent); - var phantom = /PhantomJS/.test(navigator.userAgent); - - var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent); - // This is woefully incomplete. Suggestions for alternative methods welcome. - var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent); - var mac = ios || /Mac/.test(navigator.platform); - var windows = /win/i.test(navigator.platform); - - var presto_version = presto && navigator.userAgent.match(/Version\/(\d*\.\d*)/); - if (presto_version) presto_version = Number(presto_version[1]); - if (presto_version && presto_version >= 15) { presto = false; webkit = true; } - // Some browsers use the wrong event properties to signal cmd/ctrl on OS X - var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11)); - var captureRightClick = gecko || (ie && ie_version >= 9); - - // Optimize some code when these features are not used. - var sawReadOnlySpans = false, sawCollapsedSpans = false; - - // EDITOR CONSTRUCTOR - - // A CodeMirror instance represents an editor. This is the object - // that user code is usually dealing with. - - function CodeMirror(place, options) { - if (!(this instanceof CodeMirror)) return new CodeMirror(place, options); - - this.options = options = options || {}; - // Determine effective options based on given values and defaults. - copyObj(defaults, options, false); - setGuttersForLineNumbers(options); - - var doc = options.value; - if (typeof doc == "string") doc = new Doc(doc, options.mode); - this.doc = doc; - - var display = this.display = new Display(place, doc); - display.wrapper.CodeMirror = this; - updateGutters(this); - themeChanged(this); - if (options.lineWrapping) - this.display.wrapper.className += " CodeMirror-wrap"; - if (options.autofocus && !mobile) focusInput(this); - - this.state = { - keyMaps: [], // stores maps added by addKeyMap - overlays: [], // highlighting overlays, as added by addOverlay - modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info - overwrite: false, focused: false, - suppressEdits: false, // used to disable editing during key handlers when in readOnly mode - pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in readInput - draggingText: false, - highlight: new Delayed() // stores highlight worker timeout - }; - - // Override magic textarea content restore that IE sometimes does - // on our hidden textarea on reload - if (ie && ie_version < 11) setTimeout(bind(resetInput, this, true), 20); - - registerEventHandlers(this); - ensureGlobalHandlers(); - - var cm = this; - runInOp(this, function() { - cm.curOp.forceUpdate = true; - attachDoc(cm, doc); - - if ((options.autofocus && !mobile) || activeElt() == display.input) - setTimeout(bind(onFocus, cm), 20); - else - onBlur(cm); - - for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt)) - optionHandlers[opt](cm, options[opt], Init); - for (var i = 0; i < initHooks.length; ++i) initHooks[i](cm); - }); - } - - // DISPLAY CONSTRUCTOR - - // The display handles the DOM integration, both for input reading - // and content drawing. It holds references to DOM nodes and - // display-related state. - - function Display(place, doc) { - var d = this; - - // The semihidden textarea that is focused when the editor is - // focused, and receives input. - var input = d.input = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none"); - // The textarea is kept positioned near the cursor to prevent the - // fact that it'll be scrolled into view on input from scrolling - // our fake cursor out of view. On webkit, when wrap=off, paste is - // very slow. So make the area wide instead. - if (webkit) input.style.width = "1000px"; - else input.setAttribute("wrap", "off"); - // If border: 0; -- iOS fails to open keyboard (issue #1287) - if (ios) input.style.border = "1px solid black"; - input.setAttribute("autocorrect", "off"); input.setAttribute("autocapitalize", "off"); input.setAttribute("spellcheck", "false"); - - // Wraps and hides input textarea - d.inputDiv = elt("div", [input], null, "overflow: hidden; position: relative; width: 3px; height: 0px;"); - // The fake scrollbar elements. - d.scrollbarH = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar"); - d.scrollbarV = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar"); - // Covers bottom-right square when both scrollbars are present. - d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler"); - // Covers bottom of gutter when coverGutterNextToScrollbar is on - // and h scrollbar is present. - d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler"); - // Will contain the actual code, positioned to cover the viewport. - d.lineDiv = elt("div", null, "CodeMirror-code"); - // Elements are added to these to represent selection and cursors. - d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1"); - d.cursorDiv = elt("div", null, "CodeMirror-cursors"); - // A visibility: hidden element used to find the size of things. - d.measure = elt("div", null, "CodeMirror-measure"); - // When lines outside of the viewport are measured, they are drawn in this. - d.lineMeasure = elt("div", null, "CodeMirror-measure"); - // Wraps everything that needs to exist inside the vertically-padded coordinate system - d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv], - null, "position: relative; outline: none"); - // Moved around its parent to cover visible view. - d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative"); - // Set to the height of the document, allowing scrolling. - d.sizer = elt("div", [d.mover], "CodeMirror-sizer"); - // Behavior of elts with overflow: auto and padding is - // inconsistent across browsers. This is used to ensure the - // scrollable area is big enough. - d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerCutOff + "px; width: 1px;"); - // Will contain the gutters, if any. - d.gutters = elt("div", null, "CodeMirror-gutters"); - d.lineGutter = null; - // Actual scrollable element. - d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll"); - d.scroller.setAttribute("tabIndex", "-1"); - // The element in which the editor lives. - d.wrapper = elt("div", [d.inputDiv, d.scrollbarH, d.scrollbarV, - d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror"); - - // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported) - if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; } - // Needed to hide big blue blinking cursor on Mobile Safari - if (ios) input.style.width = "0px"; - if (!webkit) d.scroller.draggable = true; - // Needed to handle Tab key in KHTML - if (khtml) { d.inputDiv.style.height = "1px"; d.inputDiv.style.position = "absolute"; } - // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8). - if (ie && ie_version < 8) d.scrollbarH.style.minHeight = d.scrollbarV.style.minWidth = "18px"; - - if (place.appendChild) place.appendChild(d.wrapper); - else place(d.wrapper); - - // Current rendered range (may be bigger than the view window). - d.viewFrom = d.viewTo = doc.first; - // Information about the rendered lines. - d.view = []; - // Holds info about a single rendered line when it was rendered - // for measurement, while not in view. - d.externalMeasured = null; - // Empty space (in pixels) above the view - d.viewOffset = 0; - d.lastSizeC = 0; - d.updateLineNumbers = null; - - // Used to only resize the line number gutter when necessary (when - // the amount of lines crosses a boundary that makes its width change) - d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null; - // See readInput and resetInput - d.prevInput = ""; - // Set to true when a non-horizontal-scrolling line widget is - // added. As an optimization, line widget aligning is skipped when - // this is false. - d.alignWidgets = false; - // Flag that indicates whether we expect input to appear real soon - // now (after some event like 'keypress' or 'input') and are - // polling intensively. - d.pollingFast = false; - // Self-resetting timeout for the poller - d.poll = new Delayed(); - - d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; - - // Tracks when resetInput has punted to just putting a short - // string into the textarea instead of the full selection. - d.inaccurateSelection = false; - - // Tracks the maximum line length so that the horizontal scrollbar - // can be kept static when scrolling. - d.maxLine = null; - d.maxLineLength = 0; - d.maxLineChanged = false; - - // Used for measuring wheel scrolling granularity - d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null; - - // True when shift is held down. - d.shift = false; - - // Used to track whether anything happened since the context menu - // was opened. - d.selForContextMenu = null; - } - - // STATE UPDATES - - // Used to get the editor into a consistent state again when options change. - - function loadMode(cm) { - cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption); - resetModeState(cm); - } - - function resetModeState(cm) { - cm.doc.iter(function(line) { - if (line.stateAfter) line.stateAfter = null; - if (line.styles) line.styles = null; - }); - cm.doc.frontier = cm.doc.first; - startWorker(cm, 100); - cm.state.modeGen++; - if (cm.curOp) regChange(cm); - } - - function wrappingChanged(cm) { - if (cm.options.lineWrapping) { - addClass(cm.display.wrapper, "CodeMirror-wrap"); - cm.display.sizer.style.minWidth = ""; - } else { - rmClass(cm.display.wrapper, "CodeMirror-wrap"); - findMaxLine(cm); - } - estimateLineHeights(cm); - regChange(cm); - clearCaches(cm); - setTimeout(function(){updateScrollbars(cm);}, 100); - } - - // Returns a function that estimates the height of a line, to use as - // first approximation until the line becomes visible (and is thus - // properly measurable). - function estimateHeight(cm) { - var th = textHeight(cm.display), wrapping = cm.options.lineWrapping; - var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3); - return function(line) { - if (lineIsHidden(cm.doc, line)) return 0; - - var widgetsHeight = 0; - if (line.widgets) for (var i = 0; i < line.widgets.length; i++) { - if (line.widgets[i].height) widgetsHeight += line.widgets[i].height; - } - - if (wrapping) - return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th; - else - return widgetsHeight + th; - }; - } - - function estimateLineHeights(cm) { - var doc = cm.doc, est = estimateHeight(cm); - doc.iter(function(line) { - var estHeight = est(line); - if (estHeight != line.height) updateLineHeight(line, estHeight); - }); - } - - function keyMapChanged(cm) { - var map = keyMap[cm.options.keyMap], style = map.style; - cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-keymap-\S+/g, "") + - (style ? " cm-keymap-" + style : ""); - } - - function themeChanged(cm) { - cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") + - cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-"); - clearCaches(cm); - } - - function guttersChanged(cm) { - updateGutters(cm); - regChange(cm); - setTimeout(function(){alignHorizontally(cm);}, 20); - } - - // Rebuild the gutter elements, ensure the margin to the left of the - // code matches their width. - function updateGutters(cm) { - var gutters = cm.display.gutters, specs = cm.options.gutters; - removeChildren(gutters); - for (var i = 0; i < specs.length; ++i) { - var gutterClass = specs[i]; - var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass)); - if (gutterClass == "CodeMirror-linenumbers") { - cm.display.lineGutter = gElt; - gElt.style.width = (cm.display.lineNumWidth || 1) + "px"; - } - } - gutters.style.display = i ? "" : "none"; - updateGutterSpace(cm); - } - - function updateGutterSpace(cm) { - var width = cm.display.gutters.offsetWidth; - cm.display.sizer.style.marginLeft = width + "px"; - cm.display.scrollbarH.style.left = cm.options.fixedGutter ? width + "px" : 0; - } - - // Compute the character length of a line, taking into account - // collapsed ranges (see markText) that might hide parts, and join - // other lines onto it. - function lineLength(line) { - if (line.height == 0) return 0; - var len = line.text.length, merged, cur = line; - while (merged = collapsedSpanAtStart(cur)) { - var found = merged.find(0, true); - cur = found.from.line; - len += found.from.ch - found.to.ch; - } - cur = line; - while (merged = collapsedSpanAtEnd(cur)) { - var found = merged.find(0, true); - len -= cur.text.length - found.from.ch; - cur = found.to.line; - len += cur.text.length - found.to.ch; - } - return len; - } - - // Find the longest line in the document. - function findMaxLine(cm) { - var d = cm.display, doc = cm.doc; - d.maxLine = getLine(doc, doc.first); - d.maxLineLength = lineLength(d.maxLine); - d.maxLineChanged = true; - doc.iter(function(line) { - var len = lineLength(line); - if (len > d.maxLineLength) { - d.maxLineLength = len; - d.maxLine = line; - } - }); - } - - // Make sure the gutters options contains the element - // "CodeMirror-linenumbers" when the lineNumbers option is true. - function setGuttersForLineNumbers(options) { - var found = indexOf(options.gutters, "CodeMirror-linenumbers"); - if (found == -1 && options.lineNumbers) { - options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]); - } else if (found > -1 && !options.lineNumbers) { - options.gutters = options.gutters.slice(0); - options.gutters.splice(found, 1); - } - } - - // SCROLLBARS - - function hScrollbarTakesSpace(cm) { - return cm.display.scroller.clientHeight - cm.display.wrapper.clientHeight < scrollerCutOff - 3; - } - - // Prepare DOM reads needed to update the scrollbars. Done in one - // shot to minimize update/measure roundtrips. - function measureForScrollbars(cm) { - var scroll = cm.display.scroller; - return { - clientHeight: scroll.clientHeight, - barHeight: cm.display.scrollbarV.clientHeight, - scrollWidth: scroll.scrollWidth, clientWidth: scroll.clientWidth, - hScrollbarTakesSpace: hScrollbarTakesSpace(cm), - barWidth: cm.display.scrollbarH.clientWidth, - docHeight: Math.round(cm.doc.height + paddingVert(cm.display)) - }; - } - - // Re-synchronize the fake scrollbars with the actual size of the - // content. - function updateScrollbars(cm, measure) { - if (!measure) measure = measureForScrollbars(cm); - var d = cm.display, sWidth = scrollbarWidth(d.measure); - var scrollHeight = measure.docHeight + scrollerCutOff; - var needsH = measure.scrollWidth > measure.clientWidth; - if (needsH && measure.scrollWidth <= measure.clientWidth + 1 && - sWidth > 0 && !measure.hScrollbarTakesSpace) - needsH = false; // (Issue #2562) - var needsV = scrollHeight > measure.clientHeight; - - if (needsV) { - d.scrollbarV.style.display = "block"; - d.scrollbarV.style.bottom = needsH ? sWidth + "px" : "0"; - // A bug in IE8 can cause this value to be negative, so guard it. - d.scrollbarV.firstChild.style.height = - Math.max(0, scrollHeight - measure.clientHeight + (measure.barHeight || d.scrollbarV.clientHeight)) + "px"; - } else { - d.scrollbarV.style.display = ""; - d.scrollbarV.firstChild.style.height = "0"; - } - if (needsH) { - d.scrollbarH.style.display = "block"; - d.scrollbarH.style.right = needsV ? sWidth + "px" : "0"; - d.scrollbarH.firstChild.style.width = - (measure.scrollWidth - measure.clientWidth + (measure.barWidth || d.scrollbarH.clientWidth)) + "px"; - } else { - d.scrollbarH.style.display = ""; - d.scrollbarH.firstChild.style.width = "0"; - } - if (needsH && needsV) { - d.scrollbarFiller.style.display = "block"; - d.scrollbarFiller.style.height = d.scrollbarFiller.style.width = sWidth + "px"; - } else d.scrollbarFiller.style.display = ""; - if (needsH && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) { - d.gutterFiller.style.display = "block"; - d.gutterFiller.style.height = sWidth + "px"; - d.gutterFiller.style.width = d.gutters.offsetWidth + "px"; - } else d.gutterFiller.style.display = ""; - - if (!cm.state.checkedOverlayScrollbar && measure.clientHeight > 0) { - if (sWidth === 0) { - var w = mac && !mac_geMountainLion ? "12px" : "18px"; - d.scrollbarV.style.minWidth = d.scrollbarH.style.minHeight = w; - var barMouseDown = function(e) { - if (e_target(e) != d.scrollbarV && e_target(e) != d.scrollbarH) - operation(cm, onMouseDown)(e); - }; - on(d.scrollbarV, "mousedown", barMouseDown); - on(d.scrollbarH, "mousedown", barMouseDown); - } - cm.state.checkedOverlayScrollbar = true; - } - } - - // Compute the lines that are visible in a given viewport (defaults - // the the current scroll position). viewPort may contain top, - // height, and ensure (see op.scrollToPos) properties. - function visibleLines(display, doc, viewPort) { - var top = viewPort && viewPort.top != null ? Math.max(0, viewPort.top) : display.scroller.scrollTop; - top = Math.floor(top - paddingTop(display)); - var bottom = viewPort && viewPort.bottom != null ? viewPort.bottom : top + display.wrapper.clientHeight; - - var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom); - // Ensure is a {from: {line, ch}, to: {line, ch}} object, and - // forces those lines into the viewport (if possible). - if (viewPort && viewPort.ensure) { - var ensureFrom = viewPort.ensure.from.line, ensureTo = viewPort.ensure.to.line; - if (ensureFrom < from) - return {from: ensureFrom, - to: lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight)}; - if (Math.min(ensureTo, doc.lastLine()) >= to) - return {from: lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight), - to: ensureTo}; - } - return {from: from, to: Math.max(to, from + 1)}; - } - - // LINE NUMBERS - - // Re-align line numbers and gutter marks to compensate for - // horizontal scrolling. - function alignHorizontally(cm) { - var display = cm.display, view = display.view; - if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return; - var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft; - var gutterW = display.gutters.offsetWidth, left = comp + "px"; - for (var i = 0; i < view.length; i++) if (!view[i].hidden) { - if (cm.options.fixedGutter && view[i].gutter) - view[i].gutter.style.left = left; - var align = view[i].alignable; - if (align) for (var j = 0; j < align.length; j++) - align[j].style.left = left; - } - if (cm.options.fixedGutter) - display.gutters.style.left = (comp + gutterW) + "px"; - } - - // Used to ensure that the line number gutter is still the right - // size for the current document size. Returns true when an update - // is needed. - function maybeUpdateLineNumberWidth(cm) { - if (!cm.options.lineNumbers) return false; - var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display; - if (last.length != display.lineNumChars) { - var test = display.measure.appendChild(elt("div", [elt("div", last)], - "CodeMirror-linenumber CodeMirror-gutter-elt")); - var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW; - display.lineGutter.style.width = ""; - display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding); - display.lineNumWidth = display.lineNumInnerWidth + padding; - display.lineNumChars = display.lineNumInnerWidth ? last.length : -1; - display.lineGutter.style.width = display.lineNumWidth + "px"; - updateGutterSpace(cm); - return true; - } - return false; - } - - function lineNumberFor(options, i) { - return String(options.lineNumberFormatter(i + options.firstLineNumber)); - } - - // Computes display.scroller.scrollLeft + display.gutters.offsetWidth, - // but using getBoundingClientRect to get a sub-pixel-accurate - // result. - function compensateForHScroll(display) { - return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left; - } - - // DISPLAY DRAWING - - // Updates the display, selection, and scrollbars, using the - // information in display.view to find out which nodes are no longer - // up-to-date. Tries to bail out early when no changes are needed, - // unless forced is true. - // Returns true if an actual update happened, false otherwise. - function updateDisplay(cm, viewPort, forced) { - var oldFrom = cm.display.viewFrom, oldTo = cm.display.viewTo, updated; - var visible = visibleLines(cm.display, cm.doc, viewPort); - for (var first = true;; first = false) { - var oldWidth = cm.display.scroller.clientWidth; - if (!updateDisplayInner(cm, visible, forced)) break; - updated = true; - - // If the max line changed since it was last measured, measure it, - // and ensure the document's width matches it. - if (cm.display.maxLineChanged && !cm.options.lineWrapping) - adjustContentWidth(cm); - - var barMeasure = measureForScrollbars(cm); - updateSelection(cm); - setDocumentHeight(cm, barMeasure); - updateScrollbars(cm, barMeasure); - if (webkit && cm.options.lineWrapping) - checkForWebkitWidthBug(cm, barMeasure); // (Issue #2420) - if (webkit && barMeasure.scrollWidth > barMeasure.clientWidth && - barMeasure.scrollWidth < barMeasure.clientWidth + 1 && - !hScrollbarTakesSpace(cm)) - updateScrollbars(cm); // (Issue #2562) - if (first && cm.options.lineWrapping && oldWidth != cm.display.scroller.clientWidth) { - forced = true; - continue; - } - forced = false; - - // Clip forced viewport to actual scrollable area. - if (viewPort && viewPort.top != null) - viewPort = {top: Math.min(barMeasure.docHeight - scrollerCutOff - barMeasure.clientHeight, viewPort.top)}; - // Updated line heights might result in the drawn area not - // actually covering the viewport. Keep looping until it does. - visible = visibleLines(cm.display, cm.doc, viewPort); - if (visible.from >= cm.display.viewFrom && visible.to <= cm.display.viewTo) - break; - } - - cm.display.updateLineNumbers = null; - if (updated) { - signalLater(cm, "update", cm); - if (cm.display.viewFrom != oldFrom || cm.display.viewTo != oldTo) - signalLater(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo); - } - return updated; - } - - // Does the actual updating of the line display. Bails out - // (returning false) when there is nothing to be done and forced is - // false. - function updateDisplayInner(cm, visible, forced) { - var display = cm.display, doc = cm.doc; - if (!display.wrapper.offsetWidth) { - resetView(cm); - return; - } - - // Bail out if the visible area is already rendered and nothing changed. - if (!forced && visible.from >= display.viewFrom && visible.to <= display.viewTo && - (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) && - countDirtyView(cm) == 0) - return; - - if (maybeUpdateLineNumberWidth(cm)) - resetView(cm); - var dims = getDimensions(cm); - - // Compute a suitable new viewport (from & to) - var end = doc.first + doc.size; - var from = Math.max(visible.from - cm.options.viewportMargin, doc.first); - var to = Math.min(end, visible.to + cm.options.viewportMargin); - if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom); - if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo); - if (sawCollapsedSpans) { - from = visualLineNo(cm.doc, from); - to = visualLineEndNo(cm.doc, to); - } - - var different = from != display.viewFrom || to != display.viewTo || - display.lastSizeC != display.wrapper.clientHeight; - adjustView(cm, from, to); - - display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom)); - // Position the mover div to align with the current scroll position - cm.display.mover.style.top = display.viewOffset + "px"; - - var toUpdate = countDirtyView(cm); - if (!different && toUpdate == 0 && !forced) return; - - // For big changes, we hide the enclosing element during the - // update, since that speeds up the operations on most browsers. - var focused = activeElt(); - if (toUpdate > 4) display.lineDiv.style.display = "none"; - patchDisplay(cm, display.updateLineNumbers, dims); - if (toUpdate > 4) display.lineDiv.style.display = ""; - // There might have been a widget with a focused element that got - // hidden or updated, if so re-focus it. - if (focused && activeElt() != focused && focused.offsetHeight) focused.focus(); - - // Prevent selection and cursors from interfering with the scroll - // width. - removeChildren(display.cursorDiv); - removeChildren(display.selectionDiv); - - if (different) { - display.lastSizeC = display.wrapper.clientHeight; - startWorker(cm, 400); - } - - updateHeightsInViewport(cm); - - return true; - } - - function adjustContentWidth(cm) { - var display = cm.display; - var width = measureChar(cm, display.maxLine, display.maxLine.text.length).left; - display.maxLineChanged = false; - var minWidth = Math.max(0, width + 3); - var maxScrollLeft = Math.max(0, display.sizer.offsetLeft + minWidth + scrollerCutOff - display.scroller.clientWidth); - display.sizer.style.minWidth = minWidth + "px"; - if (maxScrollLeft < cm.doc.scrollLeft) - setScrollLeft(cm, Math.min(display.scroller.scrollLeft, maxScrollLeft), true); - } - - function setDocumentHeight(cm, measure) { - cm.display.sizer.style.minHeight = cm.display.heightForcer.style.top = measure.docHeight + "px"; - cm.display.gutters.style.height = Math.max(measure.docHeight, measure.clientHeight - scrollerCutOff) + "px"; - } - - function checkForWebkitWidthBug(cm, measure) { - // Work around Webkit bug where it sometimes reserves space for a - // non-existing phantom scrollbar in the scroller (Issue #2420) - if (cm.display.sizer.offsetWidth + cm.display.gutters.offsetWidth < cm.display.scroller.clientWidth - 1) { - cm.display.sizer.style.minHeight = cm.display.heightForcer.style.top = "0px"; - cm.display.gutters.style.height = measure.docHeight + "px"; - } - } - - // Read the actual heights of the rendered lines, and update their - // stored heights to match. - function updateHeightsInViewport(cm) { - var display = cm.display; - var prevBottom = display.lineDiv.offsetTop; - for (var i = 0; i < display.view.length; i++) { - var cur = display.view[i], height; - if (cur.hidden) continue; - if (ie && ie_version < 8) { - var bot = cur.node.offsetTop + cur.node.offsetHeight; - height = bot - prevBottom; - prevBottom = bot; - } else { - var box = cur.node.getBoundingClientRect(); - height = box.bottom - box.top; - } - var diff = cur.line.height - height; - if (height < 2) height = textHeight(display); - if (diff > .001 || diff < -.001) { - updateLineHeight(cur.line, height); - updateWidgetHeight(cur.line); - if (cur.rest) for (var j = 0; j < cur.rest.length; j++) - updateWidgetHeight(cur.rest[j]); - } - } - } - - // Read and store the height of line widgets associated with the - // given line. - function updateWidgetHeight(line) { - if (line.widgets) for (var i = 0; i < line.widgets.length; ++i) - line.widgets[i].height = line.widgets[i].node.offsetHeight; - } - - // Do a bulk-read of the DOM positions and sizes needed to draw the - // view, so that we don't interleave reading and writing to the DOM. - function getDimensions(cm) { - var d = cm.display, left = {}, width = {}; - for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) { - left[cm.options.gutters[i]] = n.offsetLeft; - width[cm.options.gutters[i]] = n.offsetWidth; - } - return {fixedPos: compensateForHScroll(d), - gutterTotalWidth: d.gutters.offsetWidth, - gutterLeft: left, - gutterWidth: width, - wrapperWidth: d.wrapper.clientWidth}; - } - - // Sync the actual display DOM structure with display.view, removing - // nodes for lines that are no longer in view, and creating the ones - // that are not there yet, and updating the ones that are out of - // date. - function patchDisplay(cm, updateNumbersFrom, dims) { - var display = cm.display, lineNumbers = cm.options.lineNumbers; - var container = display.lineDiv, cur = container.firstChild; - - function rm(node) { - var next = node.nextSibling; - // Works around a throw-scroll bug in OS X Webkit - if (webkit && mac && cm.display.currentWheelTarget == node) - node.style.display = "none"; - else - node.parentNode.removeChild(node); - return next; - } - - var view = display.view, lineN = display.viewFrom; - // Loop over the elements in the view, syncing cur (the DOM nodes - // in display.lineDiv) with the view as we go. - for (var i = 0; i < view.length; i++) { - var lineView = view[i]; - if (lineView.hidden) { - } else if (!lineView.node) { // Not drawn yet - var node = buildLineElement(cm, lineView, lineN, dims); - container.insertBefore(node, cur); - } else { // Already drawn - while (cur != lineView.node) cur = rm(cur); - var updateNumber = lineNumbers && updateNumbersFrom != null && - updateNumbersFrom <= lineN && lineView.lineNumber; - if (lineView.changes) { - if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false; - updateLineForChanges(cm, lineView, lineN, dims); - } - if (updateNumber) { - removeChildren(lineView.lineNumber); - lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN))); - } - cur = lineView.node.nextSibling; - } - lineN += lineView.size; - } - while (cur) cur = rm(cur); - } - - // When an aspect of a line changes, a string is added to - // lineView.changes. This updates the relevant part of the line's - // DOM structure. - function updateLineForChanges(cm, lineView, lineN, dims) { - for (var j = 0; j < lineView.changes.length; j++) { - var type = lineView.changes[j]; - if (type == "text") updateLineText(cm, lineView); - else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims); - else if (type == "class") updateLineClasses(lineView); - else if (type == "widget") updateLineWidgets(lineView, dims); - } - lineView.changes = null; - } - - // Lines with gutter elements, widgets or a background class need to - // be wrapped, and have the extra elements added to the wrapper div - function ensureLineWrapped(lineView) { - if (lineView.node == lineView.text) { - lineView.node = elt("div", null, null, "position: relative"); - if (lineView.text.parentNode) - lineView.text.parentNode.replaceChild(lineView.node, lineView.text); - lineView.node.appendChild(lineView.text); - if (ie && ie_version < 8) lineView.node.style.zIndex = 2; - } - return lineView.node; - } - - function updateLineBackground(lineView) { - var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass; - if (cls) cls += " CodeMirror-linebackground"; - if (lineView.background) { - if (cls) lineView.background.className = cls; - else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; } - } else if (cls) { - var wrap = ensureLineWrapped(lineView); - lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild); - } - } - - // Wrapper around buildLineContent which will reuse the structure - // in display.externalMeasured when possible. - function getLineContent(cm, lineView) { - var ext = cm.display.externalMeasured; - if (ext && ext.line == lineView.line) { - cm.display.externalMeasured = null; - lineView.measure = ext.measure; - return ext.built; - } - return buildLineContent(cm, lineView); - } - - // Redraw the line's text. Interacts with the background and text - // classes because the mode may output tokens that influence these - // classes. - function updateLineText(cm, lineView) { - var cls = lineView.text.className; - var built = getLineContent(cm, lineView); - if (lineView.text == lineView.node) lineView.node = built.pre; - lineView.text.parentNode.replaceChild(built.pre, lineView.text); - lineView.text = built.pre; - if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) { - lineView.bgClass = built.bgClass; - lineView.textClass = built.textClass; - updateLineClasses(lineView); - } else if (cls) { - lineView.text.className = cls; - } - } - - function updateLineClasses(lineView) { - updateLineBackground(lineView); - if (lineView.line.wrapClass) - ensureLineWrapped(lineView).className = lineView.line.wrapClass; - else if (lineView.node != lineView.text) - lineView.node.className = ""; - var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass; - lineView.text.className = textClass || ""; - } - - function updateLineGutter(cm, lineView, lineN, dims) { - if (lineView.gutter) { - lineView.node.removeChild(lineView.gutter); - lineView.gutter = null; - } - var markers = lineView.line.gutterMarkers; - if (cm.options.lineNumbers || markers) { - var wrap = ensureLineWrapped(lineView); - var gutterWrap = lineView.gutter = - wrap.insertBefore(elt("div", null, "CodeMirror-gutter-wrapper", "position: absolute; left: " + - (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) + "px"), - lineView.text); - if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"])) - lineView.lineNumber = gutterWrap.appendChild( - elt("div", lineNumberFor(cm.options, lineN), - "CodeMirror-linenumber CodeMirror-gutter-elt", - "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: " - + cm.display.lineNumInnerWidth + "px")); - if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) { - var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id]; - if (found) - gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " + - dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px")); - } - } - } - - function updateLineWidgets(lineView, dims) { - if (lineView.alignable) lineView.alignable = null; - for (var node = lineView.node.firstChild, next; node; node = next) { - var next = node.nextSibling; - if (node.className == "CodeMirror-linewidget") - lineView.node.removeChild(node); - } - insertLineWidgets(lineView, dims); - } - - // Build a line's DOM representation from scratch - function buildLineElement(cm, lineView, lineN, dims) { - var built = getLineContent(cm, lineView); - lineView.text = lineView.node = built.pre; - if (built.bgClass) lineView.bgClass = built.bgClass; - if (built.textClass) lineView.textClass = built.textClass; - - updateLineClasses(lineView); - updateLineGutter(cm, lineView, lineN, dims); - insertLineWidgets(lineView, dims); - return lineView.node; - } - - // A lineView may contain multiple logical lines (when merged by - // collapsed spans). The widgets for all of them need to be drawn. - function insertLineWidgets(lineView, dims) { - insertLineWidgetsFor(lineView.line, lineView, dims, true); - if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) - insertLineWidgetsFor(lineView.rest[i], lineView, dims, false); - } - - function insertLineWidgetsFor(line, lineView, dims, allowAbove) { - if (!line.widgets) return; - var wrap = ensureLineWrapped(lineView); - for (var i = 0, ws = line.widgets; i < ws.length; ++i) { - var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget"); - if (!widget.handleMouseEvents) node.ignoreEvents = true; - positionLineWidget(widget, node, lineView, dims); - if (allowAbove && widget.above) - wrap.insertBefore(node, lineView.gutter || lineView.text); - else - wrap.appendChild(node); - signalLater(widget, "redraw"); - } - } - - function positionLineWidget(widget, node, lineView, dims) { - if (widget.noHScroll) { - (lineView.alignable || (lineView.alignable = [])).push(node); - var width = dims.wrapperWidth; - node.style.left = dims.fixedPos + "px"; - if (!widget.coverGutter) { - width -= dims.gutterTotalWidth; - node.style.paddingLeft = dims.gutterTotalWidth + "px"; - } - node.style.width = width + "px"; - } - if (widget.coverGutter) { - node.style.zIndex = 5; - node.style.position = "relative"; - if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px"; - } - } - - // POSITION OBJECT - - // A Pos instance represents a position within the text. - var Pos = CodeMirror.Pos = function(line, ch) { - if (!(this instanceof Pos)) return new Pos(line, ch); - this.line = line; this.ch = ch; - }; - - // Compare two positions, return 0 if they are the same, a negative - // number when a is less, and a positive number otherwise. - var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; }; - - function copyPos(x) {return Pos(x.line, x.ch);} - function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; } - function minPos(a, b) { return cmp(a, b) < 0 ? a : b; } - - // SELECTION / CURSOR - - // Selection objects are immutable. A new one is created every time - // the selection changes. A selection is one or more non-overlapping - // (and non-touching) ranges, sorted, and an integer that indicates - // which one is the primary selection (the one that's scrolled into - // view, that getCursor returns, etc). - function Selection(ranges, primIndex) { - this.ranges = ranges; - this.primIndex = primIndex; - } - - Selection.prototype = { - primary: function() { return this.ranges[this.primIndex]; }, - equals: function(other) { - if (other == this) return true; - if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false; - for (var i = 0; i < this.ranges.length; i++) { - var here = this.ranges[i], there = other.ranges[i]; - if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false; - } - return true; - }, - deepCopy: function() { - for (var out = [], i = 0; i < this.ranges.length; i++) - out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head)); - return new Selection(out, this.primIndex); - }, - somethingSelected: function() { - for (var i = 0; i < this.ranges.length; i++) - if (!this.ranges[i].empty()) return true; - return false; - }, - contains: function(pos, end) { - if (!end) end = pos; - for (var i = 0; i < this.ranges.length; i++) { - var range = this.ranges[i]; - if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0) - return i; - } - return -1; - } - }; - - function Range(anchor, head) { - this.anchor = anchor; this.head = head; - } - - Range.prototype = { - from: function() { return minPos(this.anchor, this.head); }, - to: function() { return maxPos(this.anchor, this.head); }, - empty: function() { - return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch; - } - }; - - // Take an unsorted, potentially overlapping set of ranges, and - // build a selection out of it. 'Consumes' ranges array (modifying - // it). - function normalizeSelection(ranges, primIndex) { - var prim = ranges[primIndex]; - ranges.sort(function(a, b) { return cmp(a.from(), b.from()); }); - primIndex = indexOf(ranges, prim); - for (var i = 1; i < ranges.length; i++) { - var cur = ranges[i], prev = ranges[i - 1]; - if (cmp(prev.to(), cur.from()) >= 0) { - var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to()); - var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head; - if (i <= primIndex) --primIndex; - ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to)); - } - } - return new Selection(ranges, primIndex); - } - - function simpleSelection(anchor, head) { - return new Selection([new Range(anchor, head || anchor)], 0); - } - - // Most of the external API clips given positions to make sure they - // actually exist within the document. - function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));} - function clipPos(doc, pos) { - if (pos.line < doc.first) return Pos(doc.first, 0); - var last = doc.first + doc.size - 1; - if (pos.line > last) return Pos(last, getLine(doc, last).text.length); - return clipToLen(pos, getLine(doc, pos.line).text.length); - } - function clipToLen(pos, linelen) { - var ch = pos.ch; - if (ch == null || ch > linelen) return Pos(pos.line, linelen); - else if (ch < 0) return Pos(pos.line, 0); - else return pos; - } - function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;} - function clipPosArray(doc, array) { - for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]); - return out; - } - - // SELECTION UPDATES - - // The 'scroll' parameter given to many of these indicated whether - // the new cursor position should be scrolled into view after - // modifying the selection. - - // If shift is held or the extend flag is set, extends a range to - // include a given position (and optionally a second position). - // Otherwise, simply returns the range between the given positions. - // Used for cursor motion and such. - function extendRange(doc, range, head, other) { - if (doc.cm && doc.cm.display.shift || doc.extend) { - var anchor = range.anchor; - if (other) { - var posBefore = cmp(head, anchor) < 0; - if (posBefore != (cmp(other, anchor) < 0)) { - anchor = head; - head = other; - } else if (posBefore != (cmp(head, other) < 0)) { - head = other; - } - } - return new Range(anchor, head); - } else { - return new Range(other || head, head); - } - } - - // Extend the primary selection range, discard the rest. - function extendSelection(doc, head, other, options) { - setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options); - } - - // Extend all selections (pos is an array of selections with length - // equal the number of selections) - function extendSelections(doc, heads, options) { - for (var out = [], i = 0; i < doc.sel.ranges.length; i++) - out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null); - var newSel = normalizeSelection(out, doc.sel.primIndex); - setSelection(doc, newSel, options); - } - - // Updates a single range in the selection. - function replaceOneSelection(doc, i, range, options) { - var ranges = doc.sel.ranges.slice(0); - ranges[i] = range; - setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options); - } - - // Reset the selection to a single range. - function setSimpleSelection(doc, anchor, head, options) { - setSelection(doc, simpleSelection(anchor, head), options); - } - - // Give beforeSelectionChange handlers a change to influence a - // selection update. - function filterSelectionChange(doc, sel) { - var obj = { - ranges: sel.ranges, - update: function(ranges) { - this.ranges = []; - for (var i = 0; i < ranges.length; i++) - this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor), - clipPos(doc, ranges[i].head)); - } - }; - signal(doc, "beforeSelectionChange", doc, obj); - if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj); - if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1); - else return sel; - } - - function setSelectionReplaceHistory(doc, sel, options) { - var done = doc.history.done, last = lst(done); - if (last && last.ranges) { - done[done.length - 1] = sel; - setSelectionNoUndo(doc, sel, options); - } else { - setSelection(doc, sel, options); - } - } - - // Set a new selection. - function setSelection(doc, sel, options) { - setSelectionNoUndo(doc, sel, options); - addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options); - } - - function setSelectionNoUndo(doc, sel, options) { - if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange")) - sel = filterSelectionChange(doc, sel); - - var bias = options && options.bias || - (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1); - setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true)); - - if (!(options && options.scroll === false) && doc.cm) - ensureCursorVisible(doc.cm); - } - - function setSelectionInner(doc, sel) { - if (sel.equals(doc.sel)) return; - - doc.sel = sel; - - if (doc.cm) { - doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true; - signalCursorActivity(doc.cm); - } - signalLater(doc, "cursorActivity", doc); - } - - // Verify that the selection does not partially select any atomic - // marked ranges. - function reCheckSelection(doc) { - setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll); - } - - // Return a selection that does not partially select any atomic - // ranges. - function skipAtomicInSelection(doc, sel, bias, mayClear) { - var out; - for (var i = 0; i < sel.ranges.length; i++) { - var range = sel.ranges[i]; - var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear); - var newHead = skipAtomic(doc, range.head, bias, mayClear); - if (out || newAnchor != range.anchor || newHead != range.head) { - if (!out) out = sel.ranges.slice(0, i); - out[i] = new Range(newAnchor, newHead); - } - } - return out ? normalizeSelection(out, sel.primIndex) : sel; - } - - // Ensure a given position is not inside an atomic range. - function skipAtomic(doc, pos, bias, mayClear) { - var flipped = false, curPos = pos; - var dir = bias || 1; - doc.cantEdit = false; - search: for (;;) { - var line = getLine(doc, curPos.line); - if (line.markedSpans) { - for (var i = 0; i < line.markedSpans.length; ++i) { - var sp = line.markedSpans[i], m = sp.marker; - if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) && - (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) { - if (mayClear) { - signal(m, "beforeCursorEnter"); - if (m.explicitlyCleared) { - if (!line.markedSpans) break; - else {--i; continue;} - } - } - if (!m.atomic) continue; - var newPos = m.find(dir < 0 ? -1 : 1); - if (cmp(newPos, curPos) == 0) { - newPos.ch += dir; - if (newPos.ch < 0) { - if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1)); - else newPos = null; - } else if (newPos.ch > line.text.length) { - if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0); - else newPos = null; - } - if (!newPos) { - if (flipped) { - // Driven in a corner -- no valid cursor position found at all - // -- try again *with* clearing, if we didn't already - if (!mayClear) return skipAtomic(doc, pos, bias, true); - // Otherwise, turn off editing until further notice, and return the start of the doc - doc.cantEdit = true; - return Pos(doc.first, 0); - } - flipped = true; newPos = pos; dir = -dir; - } - } - curPos = newPos; - continue search; - } - } - } - return curPos; - } - } - - // SELECTION DRAWING - - // Redraw the selection and/or cursor - function updateSelection(cm) { - var display = cm.display, doc = cm.doc; - var curFragment = document.createDocumentFragment(); - var selFragment = document.createDocumentFragment(); - - for (var i = 0; i < doc.sel.ranges.length; i++) { - var range = doc.sel.ranges[i]; - var collapsed = range.empty(); - if (collapsed || cm.options.showCursorWhenSelecting) - drawSelectionCursor(cm, range, curFragment); - if (!collapsed) - drawSelectionRange(cm, range, selFragment); - } - - // Move the hidden textarea near the cursor to prevent scrolling artifacts - if (cm.options.moveInputWithCursor) { - var headPos = cursorCoords(cm, doc.sel.primary().head, "div"); - var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect(); - var top = Math.max(0, Math.min(display.wrapper.clientHeight - 10, - headPos.top + lineOff.top - wrapOff.top)); - var left = Math.max(0, Math.min(display.wrapper.clientWidth - 10, - headPos.left + lineOff.left - wrapOff.left)); - display.inputDiv.style.top = top + "px"; - display.inputDiv.style.left = left + "px"; - } - - removeChildrenAndAdd(display.cursorDiv, curFragment); - removeChildrenAndAdd(display.selectionDiv, selFragment); - } - - // Draws a cursor for the given range - function drawSelectionCursor(cm, range, output) { - var pos = cursorCoords(cm, range.head, "div", null, null, !cm.options.singleCursorHeightPerLine); - - var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor")); - cursor.style.left = pos.left + "px"; - cursor.style.top = pos.top + "px"; - cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px"; - - if (pos.other) { - // Secondary cursor, shown when on a 'jump' in bi-directional text - var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor")); - otherCursor.style.display = ""; - otherCursor.style.left = pos.other.left + "px"; - otherCursor.style.top = pos.other.top + "px"; - otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px"; - } - } - - // Draws the given range as a highlighted selection - function drawSelectionRange(cm, range, output) { - var display = cm.display, doc = cm.doc; - var fragment = document.createDocumentFragment(); - var padding = paddingH(cm.display), leftSide = padding.left, rightSide = display.lineSpace.offsetWidth - padding.right; - - function add(left, top, width, bottom) { - if (top < 0) top = 0; - top = Math.round(top); - bottom = Math.round(bottom); - fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left + - "px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) + - "px; height: " + (bottom - top) + "px")); - } - - function drawForLine(line, fromArg, toArg) { - var lineObj = getLine(doc, line); - var lineLen = lineObj.text.length; - var start, end; - function coords(ch, bias) { - return charCoords(cm, Pos(line, ch), "div", lineObj, bias); - } - - iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) { - var leftPos = coords(from, "left"), rightPos, left, right; - if (from == to) { - rightPos = leftPos; - left = right = leftPos.left; - } else { - rightPos = coords(to - 1, "right"); - if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; } - left = leftPos.left; - right = rightPos.right; - } - if (fromArg == null && from == 0) left = leftSide; - if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part - add(left, leftPos.top, null, leftPos.bottom); - left = leftSide; - if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top); - } - if (toArg == null && to == lineLen) right = rightSide; - if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left) - start = leftPos; - if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right) - end = rightPos; - if (left < leftSide + 1) left = leftSide; - add(left, rightPos.top, right - left, rightPos.bottom); - }); - return {start: start, end: end}; - } - - var sFrom = range.from(), sTo = range.to(); - if (sFrom.line == sTo.line) { - drawForLine(sFrom.line, sFrom.ch, sTo.ch); - } else { - var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line); - var singleVLine = visualLine(fromLine) == visualLine(toLine); - var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end; - var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start; - if (singleVLine) { - if (leftEnd.top < rightStart.top - 2) { - add(leftEnd.right, leftEnd.top, null, leftEnd.bottom); - add(leftSide, rightStart.top, rightStart.left, rightStart.bottom); - } else { - add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom); - } - } - if (leftEnd.bottom < rightStart.top) - add(leftSide, leftEnd.bottom, null, rightStart.top); - } - - output.appendChild(fragment); - } - - // Cursor-blinking - function restartBlink(cm) { - if (!cm.state.focused) return; - var display = cm.display; - clearInterval(display.blinker); - var on = true; - display.cursorDiv.style.visibility = ""; - if (cm.options.cursorBlinkRate > 0) - display.blinker = setInterval(function() { - display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden"; - }, cm.options.cursorBlinkRate); - else if (cm.options.cursorBlinkRate < 0) - display.cursorDiv.style.visibility = "hidden"; - } - - // HIGHLIGHT WORKER - - function startWorker(cm, time) { - if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo) - cm.state.highlight.set(time, bind(highlightWorker, cm)); - } - - function highlightWorker(cm) { - var doc = cm.doc; - if (doc.frontier < doc.first) doc.frontier = doc.first; - if (doc.frontier >= cm.display.viewTo) return; - var end = +new Date + cm.options.workTime; - var state = copyState(doc.mode, getStateBefore(cm, doc.frontier)); - - runInOp(cm, function() { - doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) { - if (doc.frontier >= cm.display.viewFrom) { // Visible - var oldStyles = line.styles; - var highlighted = highlightLine(cm, line, state, true); - line.styles = highlighted.styles; - var oldCls = line.styleClasses, newCls = highlighted.classes; - if (newCls) line.styleClasses = newCls; - else if (oldCls) line.styleClasses = null; - var ischange = !oldStyles || oldStyles.length != line.styles.length || - oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass); - for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i]; - if (ischange) regLineChange(cm, doc.frontier, "text"); - line.stateAfter = copyState(doc.mode, state); - } else { - processLine(cm, line.text, state); - line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null; - } - ++doc.frontier; - if (+new Date > end) { - startWorker(cm, cm.options.workDelay); - return true; - } - }); - }); - } - - // Finds the line to start with when starting a parse. Tries to - // find a line with a stateAfter, so that it can start with a - // valid state. If that fails, it returns the line with the - // smallest indentation, which tends to need the least context to - // parse correctly. - function findStartLine(cm, n, precise) { - var minindent, minline, doc = cm.doc; - var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100); - for (var search = n; search > lim; --search) { - if (search <= doc.first) return doc.first; - var line = getLine(doc, search - 1); - if (line.stateAfter && (!precise || search <= doc.frontier)) return search; - var indented = countColumn(line.text, null, cm.options.tabSize); - if (minline == null || minindent > indented) { - minline = search - 1; - minindent = indented; - } - } - return minline; - } - - function getStateBefore(cm, n, precise) { - var doc = cm.doc, display = cm.display; - if (!doc.mode.startState) return true; - var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter; - if (!state) state = startState(doc.mode); - else state = copyState(doc.mode, state); - doc.iter(pos, n, function(line) { - processLine(cm, line.text, state); - var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo; - line.stateAfter = save ? copyState(doc.mode, state) : null; - ++pos; - }); - if (precise) doc.frontier = pos; - return state; - } - - // POSITION MEASUREMENT - - function paddingTop(display) {return display.lineSpace.offsetTop;} - function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;} - function paddingH(display) { - if (display.cachedPaddingH) return display.cachedPaddingH; - var e = removeChildrenAndAdd(display.measure, elt("pre", "x")); - var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle; - var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)}; - if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data; - return data; - } - - // Ensure the lineView.wrapping.heights array is populated. This is - // an array of bottom offsets for the lines that make up a drawn - // line. When lineWrapping is on, there might be more than one - // height. - function ensureLineHeights(cm, lineView, rect) { - var wrapping = cm.options.lineWrapping; - var curWidth = wrapping && cm.display.scroller.clientWidth; - if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) { - var heights = lineView.measure.heights = []; - if (wrapping) { - lineView.measure.width = curWidth; - var rects = lineView.text.firstChild.getClientRects(); - for (var i = 0; i < rects.length - 1; i++) { - var cur = rects[i], next = rects[i + 1]; - if (Math.abs(cur.bottom - next.bottom) > 2) - heights.push((cur.bottom + next.top) / 2 - rect.top); - } - } - heights.push(rect.bottom - rect.top); - } - } - - // Find a line map (mapping character offsets to text nodes) and a - // measurement cache for the given line number. (A line view might - // contain multiple lines when collapsed ranges are present.) - function mapFromLineView(lineView, line, lineN) { - if (lineView.line == line) - return {map: lineView.measure.map, cache: lineView.measure.cache}; - for (var i = 0; i < lineView.rest.length; i++) - if (lineView.rest[i] == line) - return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]}; - for (var i = 0; i < lineView.rest.length; i++) - if (lineNo(lineView.rest[i]) > lineN) - return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true}; - } - - // Render a line into the hidden node display.externalMeasured. Used - // when measurement is needed for a line that's not in the viewport. - function updateExternalMeasurement(cm, line) { - line = visualLine(line); - var lineN = lineNo(line); - var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN); - view.lineN = lineN; - var built = view.built = buildLineContent(cm, view); - view.text = built.pre; - removeChildrenAndAdd(cm.display.lineMeasure, built.pre); - return view; - } - - // Get a {top, bottom, left, right} box (in line-local coordinates) - // for a given character. - function measureChar(cm, line, ch, bias) { - return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias); - } - - // Find a line view that corresponds to the given line number. - function findViewForLine(cm, lineN) { - if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo) - return cm.display.view[findViewIndex(cm, lineN)]; - var ext = cm.display.externalMeasured; - if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size) - return ext; - } - - // Measurement can be split in two steps, the set-up work that - // applies to the whole line, and the measurement of the actual - // character. Functions like coordsChar, that need to do a lot of - // measurements in a row, can thus ensure that the set-up work is - // only done once. - function prepareMeasureForLine(cm, line) { - var lineN = lineNo(line); - var view = findViewForLine(cm, lineN); - if (view && !view.text) - view = null; - else if (view && view.changes) - updateLineForChanges(cm, view, lineN, getDimensions(cm)); - if (!view) - view = updateExternalMeasurement(cm, line); - - var info = mapFromLineView(view, line, lineN); - return { - line: line, view: view, rect: null, - map: info.map, cache: info.cache, before: info.before, - hasHeights: false - }; - } - - // Given a prepared measurement object, measures the position of an - // actual character (or fetches it from the cache). - function measureCharPrepared(cm, prepared, ch, bias, varHeight) { - if (prepared.before) ch = -1; - var key = ch + (bias || ""), found; - if (prepared.cache.hasOwnProperty(key)) { - found = prepared.cache[key]; - } else { - if (!prepared.rect) - prepared.rect = prepared.view.text.getBoundingClientRect(); - if (!prepared.hasHeights) { - ensureLineHeights(cm, prepared.view, prepared.rect); - prepared.hasHeights = true; - } - found = measureCharInner(cm, prepared, ch, bias); - if (!found.bogus) prepared.cache[key] = found; - } - return {left: found.left, right: found.right, - top: varHeight ? found.rtop : found.top, - bottom: varHeight ? found.rbottom : found.bottom}; - } - - var nullRect = {left: 0, right: 0, top: 0, bottom: 0}; - - function measureCharInner(cm, prepared, ch, bias) { - var map = prepared.map; - - var node, start, end, collapse; - // First, search the line map for the text node corresponding to, - // or closest to, the target character. - for (var i = 0; i < map.length; i += 3) { - var mStart = map[i], mEnd = map[i + 1]; - if (ch < mStart) { - start = 0; end = 1; - collapse = "left"; - } else if (ch < mEnd) { - start = ch - mStart; - end = start + 1; - } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) { - end = mEnd - mStart; - start = end - 1; - if (ch >= mEnd) collapse = "right"; - } - if (start != null) { - node = map[i + 2]; - if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right")) - collapse = bias; - if (bias == "left" && start == 0) - while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) { - node = map[(i -= 3) + 2]; - collapse = "left"; - } - if (bias == "right" && start == mEnd - mStart) - while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) { - node = map[(i += 3) + 2]; - collapse = "right"; - } - break; - } - } - - var rect; - if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates. - while (start && isExtendingChar(prepared.line.text.charAt(mStart + start))) --start; - while (mStart + end < mEnd && isExtendingChar(prepared.line.text.charAt(mStart + end))) ++end; - if (ie && ie_version < 9 && start == 0 && end == mEnd - mStart) { - rect = node.parentNode.getBoundingClientRect(); - } else if (ie && cm.options.lineWrapping) { - var rects = range(node, start, end).getClientRects(); - if (rects.length) - rect = rects[bias == "right" ? rects.length - 1 : 0]; - else - rect = nullRect; - } else { - rect = range(node, start, end).getBoundingClientRect() || nullRect; - } - } else { // If it is a widget, simply get the box for the whole widget. - if (start > 0) collapse = bias = "right"; - var rects; - if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1) - rect = rects[bias == "right" ? rects.length - 1 : 0]; - else - rect = node.getBoundingClientRect(); - } - if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) { - var rSpan = node.parentNode.getClientRects()[0]; - if (rSpan) - rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom}; - else - rect = nullRect; - } - - var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top; - var mid = (rtop + rbot) / 2; - var heights = prepared.view.measure.heights; - for (var i = 0; i < heights.length - 1; i++) - if (mid < heights[i]) break; - var top = i ? heights[i - 1] : 0, bot = heights[i]; - var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left, - right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left, - top: top, bottom: bot}; - if (!rect.left && !rect.right) result.bogus = true; - if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; } - return result; - } - - function clearLineMeasurementCacheFor(lineView) { - if (lineView.measure) { - lineView.measure.cache = {}; - lineView.measure.heights = null; - if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++) - lineView.measure.caches[i] = {}; - } - } - - function clearLineMeasurementCache(cm) { - cm.display.externalMeasure = null; - removeChildren(cm.display.lineMeasure); - for (var i = 0; i < cm.display.view.length; i++) - clearLineMeasurementCacheFor(cm.display.view[i]); - } - - function clearCaches(cm) { - clearLineMeasurementCache(cm); - cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null; - if (!cm.options.lineWrapping) cm.display.maxLineChanged = true; - cm.display.lineNumChars = null; - } - - function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; } - function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; } - - // Converts a {top, bottom, left, right} box from line-local - // coordinates into another coordinate system. Context may be one of - // "line", "div" (display.lineDiv), "local"/null (editor), or "page". - function intoCoordSystem(cm, lineObj, rect, context) { - if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) { - var size = widgetHeight(lineObj.widgets[i]); - rect.top += size; rect.bottom += size; - } - if (context == "line") return rect; - if (!context) context = "local"; - var yOff = heightAtLine(lineObj); - if (context == "local") yOff += paddingTop(cm.display); - else yOff -= cm.display.viewOffset; - if (context == "page" || context == "window") { - var lOff = cm.display.lineSpace.getBoundingClientRect(); - yOff += lOff.top + (context == "window" ? 0 : pageScrollY()); - var xOff = lOff.left + (context == "window" ? 0 : pageScrollX()); - rect.left += xOff; rect.right += xOff; - } - rect.top += yOff; rect.bottom += yOff; - return rect; - } - - // Coverts a box from "div" coords to another coordinate system. - // Context may be "window", "page", "div", or "local"/null. - function fromCoordSystem(cm, coords, context) { - if (context == "div") return coords; - var left = coords.left, top = coords.top; - // First move into "page" coordinate system - if (context == "page") { - left -= pageScrollX(); - top -= pageScrollY(); - } else if (context == "local" || !context) { - var localBox = cm.display.sizer.getBoundingClientRect(); - left += localBox.left; - top += localBox.top; - } - - var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect(); - return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top}; - } - - function charCoords(cm, pos, context, lineObj, bias) { - if (!lineObj) lineObj = getLine(cm.doc, pos.line); - return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context); - } - - // Returns a box for a given cursor position, which may have an - // 'other' property containing the position of the secondary cursor - // on a bidi boundary. - function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) { - lineObj = lineObj || getLine(cm.doc, pos.line); - if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj); - function get(ch, right) { - var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight); - if (right) m.left = m.right; else m.right = m.left; - return intoCoordSystem(cm, lineObj, m, context); - } - function getBidi(ch, partPos) { - var part = order[partPos], right = part.level % 2; - if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) { - part = order[--partPos]; - ch = bidiRight(part) - (part.level % 2 ? 0 : 1); - right = true; - } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) { - part = order[++partPos]; - ch = bidiLeft(part) - part.level % 2; - right = false; - } - if (right && ch == part.to && ch > part.from) return get(ch - 1); - return get(ch, right); - } - var order = getOrder(lineObj), ch = pos.ch; - if (!order) return get(ch); - var partPos = getBidiPartAt(order, ch); - var val = getBidi(ch, partPos); - if (bidiOther != null) val.other = getBidi(ch, bidiOther); - return val; - } - - // Used to cheaply estimate the coordinates for a position. Used for - // intermediate scroll updates. - function estimateCoords(cm, pos) { - var left = 0, pos = clipPos(cm.doc, pos); - if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch; - var lineObj = getLine(cm.doc, pos.line); - var top = heightAtLine(lineObj) + paddingTop(cm.display); - return {left: left, right: left, top: top, bottom: top + lineObj.height}; - } - - // Positions returned by coordsChar contain some extra information. - // xRel is the relative x position of the input coordinates compared - // to the found position (so xRel > 0 means the coordinates are to - // the right of the character position, for example). When outside - // is true, that means the coordinates lie outside the line's - // vertical range. - function PosWithInfo(line, ch, outside, xRel) { - var pos = Pos(line, ch); - pos.xRel = xRel; - if (outside) pos.outside = true; - return pos; - } - - // Compute the character position closest to the given coordinates. - // Input must be lineSpace-local ("div" coordinate system). - function coordsChar(cm, x, y) { - var doc = cm.doc; - y += cm.display.viewOffset; - if (y < 0) return PosWithInfo(doc.first, 0, true, -1); - var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1; - if (lineN > last) - return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1); - if (x < 0) x = 0; - - var lineObj = getLine(doc, lineN); - for (;;) { - var found = coordsCharInner(cm, lineObj, lineN, x, y); - var merged = collapsedSpanAtEnd(lineObj); - var mergedPos = merged && merged.find(0, true); - if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0)) - lineN = lineNo(lineObj = mergedPos.to.line); - else - return found; - } - } - - function coordsCharInner(cm, lineObj, lineNo, x, y) { - var innerOff = y - heightAtLine(lineObj); - var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth; - var preparedMeasure = prepareMeasureForLine(cm, lineObj); - - function getX(ch) { - var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure); - wrongLine = true; - if (innerOff > sp.bottom) return sp.left - adjust; - else if (innerOff < sp.top) return sp.left + adjust; - else wrongLine = false; - return sp.left; - } - - var bidi = getOrder(lineObj), dist = lineObj.text.length; - var from = lineLeft(lineObj), to = lineRight(lineObj); - var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine; - - if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1); - // Do a binary search between these bounds. - for (;;) { - if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) { - var ch = x < fromX || x - fromX <= toX - x ? from : to; - var xDiff = x - (ch == from ? fromX : toX); - while (isExtendingChar(lineObj.text.charAt(ch))) ++ch; - var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside, - xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0); - return pos; - } - var step = Math.ceil(dist / 2), middle = from + step; - if (bidi) { - middle = from; - for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1); - } - var middleX = getX(middle); - if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;} - else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;} - } - } - - var measureText; - // Compute the default text height. - function textHeight(display) { - if (display.cachedTextHeight != null) return display.cachedTextHeight; - if (measureText == null) { - measureText = elt("pre"); - // Measure a bunch of lines, for browsers that compute - // fractional heights. - for (var i = 0; i < 49; ++i) { - measureText.appendChild(document.createTextNode("x")); - measureText.appendChild(elt("br")); - } - measureText.appendChild(document.createTextNode("x")); - } - removeChildrenAndAdd(display.measure, measureText); - var height = measureText.offsetHeight / 50; - if (height > 3) display.cachedTextHeight = height; - removeChildren(display.measure); - return height || 1; - } - - // Compute the default character width. - function charWidth(display) { - if (display.cachedCharWidth != null) return display.cachedCharWidth; - var anchor = elt("span", "xxxxxxxxxx"); - var pre = elt("pre", [anchor]); - removeChildrenAndAdd(display.measure, pre); - var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10; - if (width > 2) display.cachedCharWidth = width; - return width || 10; - } - - // OPERATIONS - - // Operations are used to wrap a series of changes to the editor - // state in such a way that each change won't have to update the - // cursor and display (which would be awkward, slow, and - // error-prone). Instead, display updates are batched and then all - // combined and executed at once. - - var nextOpId = 0; - // Start a new operation. - function startOperation(cm) { - cm.curOp = { - viewChanged: false, // Flag that indicates that lines might need to be redrawn - startHeight: cm.doc.height, // Used to detect need to update scrollbar - forceUpdate: false, // Used to force a redraw - updateInput: null, // Whether to reset the input textarea - typing: false, // Whether this reset should be careful to leave existing text (for compositing) - changeObjs: null, // Accumulated changes, for firing change events - cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on - selectionChanged: false, // Whether the selection needs to be redrawn - updateMaxLine: false, // Set when the widest line needs to be determined anew - scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet - scrollToPos: null, // Used to scroll to a specific position - id: ++nextOpId // Unique ID - }; - if (!delayedCallbackDepth++) delayedCallbacks = []; - } - - // Finish an operation, updating the display and signalling delayed events - function endOperation(cm) { - var op = cm.curOp, doc = cm.doc, display = cm.display; - cm.curOp = null; - - if (op.updateMaxLine) findMaxLine(cm); - - // If it looks like an update might be needed, call updateDisplay - if (op.viewChanged || op.forceUpdate || op.scrollTop != null || - op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom || - op.scrollToPos.to.line >= display.viewTo) || - display.maxLineChanged && cm.options.lineWrapping) { - var updated = updateDisplay(cm, {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate); - if (cm.display.scroller.offsetHeight) cm.doc.scrollTop = cm.display.scroller.scrollTop; - } - // If no update was run, but the selection changed, redraw that. - if (!updated && op.selectionChanged) updateSelection(cm); - if (!updated && op.startHeight != cm.doc.height) updateScrollbars(cm); - - // Abort mouse wheel delta measurement, when scrolling explicitly - if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos)) - display.wheelStartX = display.wheelStartY = null; - - // Propagate the scroll position to the actual DOM scroller - if (op.scrollTop != null && display.scroller.scrollTop != op.scrollTop) { - var top = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop)); - display.scroller.scrollTop = display.scrollbarV.scrollTop = doc.scrollTop = top; - } - if (op.scrollLeft != null && display.scroller.scrollLeft != op.scrollLeft) { - var left = Math.max(0, Math.min(display.scroller.scrollWidth - display.scroller.clientWidth, op.scrollLeft)); - display.scroller.scrollLeft = display.scrollbarH.scrollLeft = doc.scrollLeft = left; - alignHorizontally(cm); - } - // If we need to scroll a specific position into view, do so. - if (op.scrollToPos) { - var coords = scrollPosIntoView(cm, clipPos(cm.doc, op.scrollToPos.from), - clipPos(cm.doc, op.scrollToPos.to), op.scrollToPos.margin); - if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords); - } - - if (op.selectionChanged) restartBlink(cm); - - if (cm.state.focused && op.updateInput) - resetInput(cm, op.typing); - - // Fire events for markers that are hidden/unidden by editing or - // undoing - var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers; - if (hidden) for (var i = 0; i < hidden.length; ++i) - if (!hidden[i].lines.length) signal(hidden[i], "hide"); - if (unhidden) for (var i = 0; i < unhidden.length; ++i) - if (unhidden[i].lines.length) signal(unhidden[i], "unhide"); - - var delayed; - if (!--delayedCallbackDepth) { - delayed = delayedCallbacks; - delayedCallbacks = null; - } - // Fire change events, and delayed event handlers - if (op.changeObjs) - signal(cm, "changes", cm, op.changeObjs); - if (delayed) for (var i = 0; i < delayed.length; ++i) delayed[i](); - if (op.cursorActivityHandlers) - for (var i = 0; i < op.cursorActivityHandlers.length; i++) - op.cursorActivityHandlers[i](cm); - } - - // Run the given function in an operation - function runInOp(cm, f) { - if (cm.curOp) return f(); - startOperation(cm); - try { return f(); } - finally { endOperation(cm); } - } - // Wraps a function in an operation. Returns the wrapped function. - function operation(cm, f) { - return function() { - if (cm.curOp) return f.apply(cm, arguments); - startOperation(cm); - try { return f.apply(cm, arguments); } - finally { endOperation(cm); } - }; - } - // Used to add methods to editor and doc instances, wrapping them in - // operations. - function methodOp(f) { - return function() { - if (this.curOp) return f.apply(this, arguments); - startOperation(this); - try { return f.apply(this, arguments); } - finally { endOperation(this); } - }; - } - function docMethodOp(f) { - return function() { - var cm = this.cm; - if (!cm || cm.curOp) return f.apply(this, arguments); - startOperation(cm); - try { return f.apply(this, arguments); } - finally { endOperation(cm); } - }; - } - - // VIEW TRACKING - - // These objects are used to represent the visible (currently drawn) - // part of the document. A LineView may correspond to multiple - // logical lines, if those are connected by collapsed ranges. - function LineView(doc, line, lineN) { - // The starting line - this.line = line; - // Continuing lines, if any - this.rest = visualLineContinued(line); - // Number of logical lines in this visual line - this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1; - this.node = this.text = null; - this.hidden = lineIsHidden(doc, line); - } - - // Create a range of LineView objects for the given lines. - function buildViewArray(cm, from, to) { - var array = [], nextPos; - for (var pos = from; pos < to; pos = nextPos) { - var view = new LineView(cm.doc, getLine(cm.doc, pos), pos); - nextPos = pos + view.size; - array.push(view); - } - return array; - } - - // Updates the display.view data structure for a given change to the - // document. From and to are in pre-change coordinates. Lendiff is - // the amount of lines added or subtracted by the change. This is - // used for changes that span multiple lines, or change the way - // lines are divided into visual lines. regLineChange (below) - // registers single-line changes. - function regChange(cm, from, to, lendiff) { - if (from == null) from = cm.doc.first; - if (to == null) to = cm.doc.first + cm.doc.size; - if (!lendiff) lendiff = 0; - - var display = cm.display; - if (lendiff && to < display.viewTo && - (display.updateLineNumbers == null || display.updateLineNumbers > from)) - display.updateLineNumbers = from; - - cm.curOp.viewChanged = true; - - if (from >= display.viewTo) { // Change after - if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo) - resetView(cm); - } else if (to <= display.viewFrom) { // Change before - if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) { - resetView(cm); - } else { - display.viewFrom += lendiff; - display.viewTo += lendiff; - } - } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap - resetView(cm); - } else if (from <= display.viewFrom) { // Top overlap - var cut = viewCuttingPoint(cm, to, to + lendiff, 1); - if (cut) { - display.view = display.view.slice(cut.index); - display.viewFrom = cut.lineN; - display.viewTo += lendiff; - } else { - resetView(cm); - } - } else if (to >= display.viewTo) { // Bottom overlap - var cut = viewCuttingPoint(cm, from, from, -1); - if (cut) { - display.view = display.view.slice(0, cut.index); - display.viewTo = cut.lineN; - } else { - resetView(cm); - } - } else { // Gap in the middle - var cutTop = viewCuttingPoint(cm, from, from, -1); - var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1); - if (cutTop && cutBot) { - display.view = display.view.slice(0, cutTop.index) - .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN)) - .concat(display.view.slice(cutBot.index)); - display.viewTo += lendiff; - } else { - resetView(cm); - } - } - - var ext = display.externalMeasured; - if (ext) { - if (to < ext.lineN) - ext.lineN += lendiff; - else if (from < ext.lineN + ext.size) - display.externalMeasured = null; - } - } - - // Register a change to a single line. Type must be one of "text", - // "gutter", "class", "widget" - function regLineChange(cm, line, type) { - cm.curOp.viewChanged = true; - var display = cm.display, ext = cm.display.externalMeasured; - if (ext && line >= ext.lineN && line < ext.lineN + ext.size) - display.externalMeasured = null; - - if (line < display.viewFrom || line >= display.viewTo) return; - var lineView = display.view[findViewIndex(cm, line)]; - if (lineView.node == null) return; - var arr = lineView.changes || (lineView.changes = []); - if (indexOf(arr, type) == -1) arr.push(type); - } - - // Clear the view. - function resetView(cm) { - cm.display.viewFrom = cm.display.viewTo = cm.doc.first; - cm.display.view = []; - cm.display.viewOffset = 0; - } - - // Find the view element corresponding to a given line. Return null - // when the line isn't visible. - function findViewIndex(cm, n) { - if (n >= cm.display.viewTo) return null; - n -= cm.display.viewFrom; - if (n < 0) return null; - var view = cm.display.view; - for (var i = 0; i < view.length; i++) { - n -= view[i].size; - if (n < 0) return i; - } - } - - function viewCuttingPoint(cm, oldN, newN, dir) { - var index = findViewIndex(cm, oldN), diff, view = cm.display.view; - if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size) - return {index: index, lineN: newN}; - for (var i = 0, n = cm.display.viewFrom; i < index; i++) - n += view[i].size; - if (n != oldN) { - if (dir > 0) { - if (index == view.length - 1) return null; - diff = (n + view[index].size) - oldN; - index++; - } else { - diff = n - oldN; - } - oldN += diff; newN += diff; - } - while (visualLineNo(cm.doc, newN) != newN) { - if (index == (dir < 0 ? 0 : view.length - 1)) return null; - newN += dir * view[index - (dir < 0 ? 1 : 0)].size; - index += dir; - } - return {index: index, lineN: newN}; - } - - // Force the view to cover a given range, adding empty view element - // or clipping off existing ones as needed. - function adjustView(cm, from, to) { - var display = cm.display, view = display.view; - if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) { - display.view = buildViewArray(cm, from, to); - display.viewFrom = from; - } else { - if (display.viewFrom > from) - display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view); - else if (display.viewFrom < from) - display.view = display.view.slice(findViewIndex(cm, from)); - display.viewFrom = from; - if (display.viewTo < to) - display.view = display.view.concat(buildViewArray(cm, display.viewTo, to)); - else if (display.viewTo > to) - display.view = display.view.slice(0, findViewIndex(cm, to)); - } - display.viewTo = to; - } - - // Count the number of lines in the view whose DOM representation is - // out of date (or nonexistent). - function countDirtyView(cm) { - var view = cm.display.view, dirty = 0; - for (var i = 0; i < view.length; i++) { - var lineView = view[i]; - if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty; - } - return dirty; - } - - // INPUT HANDLING - - // Poll for input changes, using the normal rate of polling. This - // runs as long as the editor is focused. - function slowPoll(cm) { - if (cm.display.pollingFast) return; - cm.display.poll.set(cm.options.pollInterval, function() { - readInput(cm); - if (cm.state.focused) slowPoll(cm); - }); - } - - // When an event has just come in that is likely to add or change - // something in the input textarea, we poll faster, to ensure that - // the change appears on the screen quickly. - function fastPoll(cm) { - var missed = false; - cm.display.pollingFast = true; - function p() { - var changed = readInput(cm); - if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);} - else {cm.display.pollingFast = false; slowPoll(cm);} - } - cm.display.poll.set(20, p); - } - - // Read input from the textarea, and update the document to match. - // When something is selected, it is present in the textarea, and - // selected (unless it is huge, in which case a placeholder is - // used). When nothing is selected, the cursor sits after previously - // seen text (can be empty), which is stored in prevInput (we must - // not reset the textarea when typing, because that breaks IME). - function readInput(cm) { - var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc; - // Since this is called a *lot*, try to bail out as cheaply as - // possible when it is clear that nothing happened. hasSelection - // will be the case when there is a lot of text in the textarea, - // in which case reading its value would be expensive. - if (!cm.state.focused || (hasSelection(input) && !prevInput) || isReadOnly(cm) || cm.options.disableInput) - return false; - // See paste handler for more on the fakedLastChar kludge - if (cm.state.pasteIncoming && cm.state.fakedLastChar) { - input.value = input.value.substring(0, input.value.length - 1); - cm.state.fakedLastChar = false; - } - var text = input.value; - // If nothing changed, bail. - if (text == prevInput && !cm.somethingSelected()) return false; - // Work around nonsensical selection resetting in IE9/10 - if (ie && ie_version >= 9 && cm.display.inputHasSelection === text) { - resetInput(cm); - return false; - } - - var withOp = !cm.curOp; - if (withOp) startOperation(cm); - cm.display.shift = false; - - if (text.charCodeAt(0) == 0x200b && doc.sel == cm.display.selForContextMenu && !prevInput) - prevInput = "\u200b"; - // Find the part of the input that is actually new - var same = 0, l = Math.min(prevInput.length, text.length); - while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same; - var inserted = text.slice(same), textLines = splitLines(inserted); - - // When pasing N lines into N selections, insert one line per selection - var multiPaste = cm.state.pasteIncoming && textLines.length > 1 && doc.sel.ranges.length == textLines.length; - - // Normal behavior is to insert the new text into every selection - for (var i = doc.sel.ranges.length - 1; i >= 0; i--) { - var range = doc.sel.ranges[i]; - var from = range.from(), to = range.to(); - // Handle deletion - if (same < prevInput.length) - from = Pos(from.line, from.ch - (prevInput.length - same)); - // Handle overwrite - else if (cm.state.overwrite && range.empty() && !cm.state.pasteIncoming) - to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length)); - var updateInput = cm.curOp.updateInput; - var changeEvent = {from: from, to: to, text: multiPaste ? [textLines[i]] : textLines, - origin: cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input"}; - makeChange(cm.doc, changeEvent); - signalLater(cm, "inputRead", cm, changeEvent); - // When an 'electric' character is inserted, immediately trigger a reindent - if (inserted && !cm.state.pasteIncoming && cm.options.electricChars && - cm.options.smartIndent && range.head.ch < 100 && - (!i || doc.sel.ranges[i - 1].head.line != range.head.line)) { - var mode = cm.getModeAt(range.head); - if (mode.electricChars) { - for (var j = 0; j < mode.electricChars.length; j++) - if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) { - indentLine(cm, range.head.line, "smart"); - break; - } - } else if (mode.electricInput) { - var end = changeEnd(changeEvent); - if (mode.electricInput.test(getLine(doc, end.line).text.slice(0, end.ch))) - indentLine(cm, range.head.line, "smart"); - } - } - } - ensureCursorVisible(cm); - cm.curOp.updateInput = updateInput; - cm.curOp.typing = true; - - // Don't leave long text in the textarea, since it makes further polling slow - if (text.length > 1000 || text.indexOf("\n") > -1) input.value = cm.display.prevInput = ""; - else cm.display.prevInput = text; - if (withOp) endOperation(cm); - cm.state.pasteIncoming = cm.state.cutIncoming = false; - return true; - } - - // Reset the input to correspond to the selection (or to be empty, - // when not typing and nothing is selected) - function resetInput(cm, typing) { - var minimal, selected, doc = cm.doc; - if (cm.somethingSelected()) { - cm.display.prevInput = ""; - var range = doc.sel.primary(); - minimal = hasCopyEvent && - (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000); - var content = minimal ? "-" : selected || cm.getSelection(); - cm.display.input.value = content; - if (cm.state.focused) selectInput(cm.display.input); - if (ie && ie_version >= 9) cm.display.inputHasSelection = content; - } else if (!typing) { - cm.display.prevInput = cm.display.input.value = ""; - if (ie && ie_version >= 9) cm.display.inputHasSelection = null; - } - cm.display.inaccurateSelection = minimal; - } - - function focusInput(cm) { - if (cm.options.readOnly != "nocursor" && (!mobile || activeElt() != cm.display.input)) - cm.display.input.focus(); - } - - function ensureFocus(cm) { - if (!cm.state.focused) { focusInput(cm); onFocus(cm); } - } - - function isReadOnly(cm) { - return cm.options.readOnly || cm.doc.cantEdit; - } - - // EVENT HANDLERS - - // Attach the necessary event handlers when initializing the editor - function registerEventHandlers(cm) { - var d = cm.display; - on(d.scroller, "mousedown", operation(cm, onMouseDown)); - // Older IE's will not fire a second mousedown for a double click - if (ie && ie_version < 11) - on(d.scroller, "dblclick", operation(cm, function(e) { - if (signalDOMEvent(cm, e)) return; - var pos = posFromMouse(cm, e); - if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return; - e_preventDefault(e); - var word = findWordAt(cm, pos); - extendSelection(cm.doc, word.anchor, word.head); - })); - else - on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); }); - // Prevent normal selection in the editor (we handle our own) - on(d.lineSpace, "selectstart", function(e) { - if (!eventInWidget(d, e)) e_preventDefault(e); - }); - // Some browsers fire contextmenu *after* opening the menu, at - // which point we can't mess with it anymore. Context menu is - // handled in onMouseDown for these browsers. - if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);}); - - // Sync scrolling between fake scrollbars and real scrollable - // area, ensure viewport is updated when scrolling. - on(d.scroller, "scroll", function() { - if (d.scroller.clientHeight) { - setScrollTop(cm, d.scroller.scrollTop); - setScrollLeft(cm, d.scroller.scrollLeft, true); - signal(cm, "scroll", cm); - } - }); - on(d.scrollbarV, "scroll", function() { - if (d.scroller.clientHeight) setScrollTop(cm, d.scrollbarV.scrollTop); - }); - on(d.scrollbarH, "scroll", function() { - if (d.scroller.clientHeight) setScrollLeft(cm, d.scrollbarH.scrollLeft); - }); - - // Listen to wheel events in order to try and update the viewport on time. - on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);}); - on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);}); - - // Prevent clicks in the scrollbars from killing focus - function reFocus() { if (cm.state.focused) setTimeout(bind(focusInput, cm), 0); } - on(d.scrollbarH, "mousedown", reFocus); - on(d.scrollbarV, "mousedown", reFocus); - // Prevent wrapper from ever scrolling - on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; }); - - on(d.input, "keyup", operation(cm, onKeyUp)); - on(d.input, "input", function() { - if (ie && ie_version >= 9 && cm.display.inputHasSelection) cm.display.inputHasSelection = null; - fastPoll(cm); - }); - on(d.input, "keydown", operation(cm, onKeyDown)); - on(d.input, "keypress", operation(cm, onKeyPress)); - on(d.input, "focus", bind(onFocus, cm)); - on(d.input, "blur", bind(onBlur, cm)); - - function drag_(e) { - if (!signalDOMEvent(cm, e)) e_stop(e); - } - if (cm.options.dragDrop) { - on(d.scroller, "dragstart", function(e){onDragStart(cm, e);}); - on(d.scroller, "dragenter", drag_); - on(d.scroller, "dragover", drag_); - on(d.scroller, "drop", operation(cm, onDrop)); - } - on(d.scroller, "paste", function(e) { - if (eventInWidget(d, e)) return; - cm.state.pasteIncoming = true; - focusInput(cm); - fastPoll(cm); - }); - on(d.input, "paste", function() { - // Workaround for webkit bug https://bugs.webkit.org/show_bug.cgi?id=90206 - // Add a char to the end of textarea before paste occur so that - // selection doesn't span to the end of textarea. - if (webkit && !cm.state.fakedLastChar && !(new Date - cm.state.lastMiddleDown < 200)) { - var start = d.input.selectionStart, end = d.input.selectionEnd; - d.input.value += "$"; - // The selection end needs to be set before the start, otherwise there - // can be an intermediate non-empty selection between the two, which - // can override the middle-click paste buffer on linux and cause the - // wrong thing to get pasted. - d.input.selectionEnd = end; - d.input.selectionStart = start; - cm.state.fakedLastChar = true; - } - cm.state.pasteIncoming = true; - fastPoll(cm); - }); - - function prepareCopyCut(e) { - if (cm.somethingSelected()) { - if (d.inaccurateSelection) { - d.prevInput = ""; - d.inaccurateSelection = false; - d.input.value = cm.getSelection(); - selectInput(d.input); - } - } else { - var text = "", ranges = []; - for (var i = 0; i < cm.doc.sel.ranges.length; i++) { - var line = cm.doc.sel.ranges[i].head.line; - var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)}; - ranges.push(lineRange); - text += cm.getRange(lineRange.anchor, lineRange.head); - } - if (e.type == "cut") { - cm.setSelections(ranges, null, sel_dontScroll); - } else { - d.prevInput = ""; - d.input.value = text; - selectInput(d.input); - } - } - if (e.type == "cut") cm.state.cutIncoming = true; - } - on(d.input, "cut", prepareCopyCut); - on(d.input, "copy", prepareCopyCut); - - // Needed to handle Tab key in KHTML - if (khtml) on(d.sizer, "mouseup", function() { - if (activeElt() == d.input) d.input.blur(); - focusInput(cm); - }); - } - - // Called when the window resizes - function onResize(cm) { - // Might be a text scaling operation, clear size caches. - var d = cm.display; - d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null; - cm.setSize(); - } - - // MOUSE EVENTS - - // Return true when the given mouse event happened in a widget - function eventInWidget(display, e) { - for (var n = e_target(e); n != display.wrapper; n = n.parentNode) { - if (!n || n.ignoreEvents || n.parentNode == display.sizer && n != display.mover) return true; - } - } - - // Given a mouse event, find the corresponding position. If liberal - // is false, it checks whether a gutter or scrollbar was clicked, - // and returns null if it was. forRect is used by rectangular - // selections, and tries to estimate a character position even for - // coordinates beyond the right of the text. - function posFromMouse(cm, e, liberal, forRect) { - var display = cm.display; - if (!liberal) { - var target = e_target(e); - if (target == display.scrollbarH || target == display.scrollbarV || - target == display.scrollbarFiller || target == display.gutterFiller) return null; - } - var x, y, space = display.lineSpace.getBoundingClientRect(); - // Fails unpredictably on IE[67] when mouse is dragged around quickly. - try { x = e.clientX - space.left; y = e.clientY - space.top; } - catch (e) { return null; } - var coords = coordsChar(cm, x, y), line; - if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) { - var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length; - coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff)); - } - return coords; - } - - // A mouse down can be a single click, double click, triple click, - // start of selection drag, start of text drag, new cursor - // (ctrl-click), rectangle drag (alt-drag), or xwin - // middle-click-paste. Or it might be a click on something we should - // not interfere with, such as a scrollbar or widget. - function onMouseDown(e) { - if (signalDOMEvent(this, e)) return; - var cm = this, display = cm.display; - display.shift = e.shiftKey; - - if (eventInWidget(display, e)) { - if (!webkit) { - // Briefly turn off draggability, to allow widgets to do - // normal dragging things. - display.scroller.draggable = false; - setTimeout(function(){display.scroller.draggable = true;}, 100); - } - return; - } - if (clickInGutter(cm, e)) return; - var start = posFromMouse(cm, e); - window.focus(); - - switch (e_button(e)) { - case 1: - if (start) - leftButtonDown(cm, e, start); - else if (e_target(e) == display.scroller) - e_preventDefault(e); - break; - case 2: - if (webkit) cm.state.lastMiddleDown = +new Date; - if (start) extendSelection(cm.doc, start); - setTimeout(bind(focusInput, cm), 20); - e_preventDefault(e); - break; - case 3: - if (captureRightClick) onContextMenu(cm, e); - break; - } - } - - var lastClick, lastDoubleClick; - function leftButtonDown(cm, e, start) { - setTimeout(bind(ensureFocus, cm), 0); - - var now = +new Date, type; - if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) { - type = "triple"; - } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) { - type = "double"; - lastDoubleClick = {time: now, pos: start}; - } else { - type = "single"; - lastClick = {time: now, pos: start}; - } - - var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey; - if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) && - type == "single" && sel.contains(start) > -1 && sel.somethingSelected()) - leftButtonStartDrag(cm, e, start, modifier); - else - leftButtonSelect(cm, e, start, type, modifier); - } - - // Start a text drag. When it ends, see if any dragging actually - // happen, and treat as a click if it didn't. - function leftButtonStartDrag(cm, e, start, modifier) { - var display = cm.display; - var dragEnd = operation(cm, function(e2) { - if (webkit) display.scroller.draggable = false; - cm.state.draggingText = false; - off(document, "mouseup", dragEnd); - off(display.scroller, "drop", dragEnd); - if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) { - e_preventDefault(e2); - if (!modifier) - extendSelection(cm.doc, start); - focusInput(cm); - // Work around unexplainable focus problem in IE9 (#2127) - if (ie && ie_version == 9) - setTimeout(function() {document.body.focus(); focusInput(cm);}, 20); - } - }); - // Let the drag handler handle this. - if (webkit) display.scroller.draggable = true; - cm.state.draggingText = dragEnd; - // IE's approach to draggable - if (display.scroller.dragDrop) display.scroller.dragDrop(); - on(document, "mouseup", dragEnd); - on(display.scroller, "drop", dragEnd); - } - - // Normal selection, as opposed to text dragging. - function leftButtonSelect(cm, e, start, type, addNew) { - var display = cm.display, doc = cm.doc; - e_preventDefault(e); - - var ourRange, ourIndex, startSel = doc.sel; - if (addNew && !e.shiftKey) { - ourIndex = doc.sel.contains(start); - if (ourIndex > -1) - ourRange = doc.sel.ranges[ourIndex]; - else - ourRange = new Range(start, start); - } else { - ourRange = doc.sel.primary(); - } - - if (e.altKey) { - type = "rect"; - if (!addNew) ourRange = new Range(start, start); - start = posFromMouse(cm, e, true, true); - ourIndex = -1; - } else if (type == "double") { - var word = findWordAt(cm, start); - if (cm.display.shift || doc.extend) - ourRange = extendRange(doc, ourRange, word.anchor, word.head); - else - ourRange = word; - } else if (type == "triple") { - var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0))); - if (cm.display.shift || doc.extend) - ourRange = extendRange(doc, ourRange, line.anchor, line.head); - else - ourRange = line; - } else { - ourRange = extendRange(doc, ourRange, start); - } - - if (!addNew) { - ourIndex = 0; - setSelection(doc, new Selection([ourRange], 0), sel_mouse); - startSel = doc.sel; - } else if (ourIndex > -1) { - replaceOneSelection(doc, ourIndex, ourRange, sel_mouse); - } else { - ourIndex = doc.sel.ranges.length; - setSelection(doc, normalizeSelection(doc.sel.ranges.concat([ourRange]), ourIndex), - {scroll: false, origin: "*mouse"}); - } - - var lastPos = start; - function extendTo(pos) { - if (cmp(lastPos, pos) == 0) return; - lastPos = pos; - - if (type == "rect") { - var ranges = [], tabSize = cm.options.tabSize; - var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize); - var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize); - var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol); - for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line)); - line <= end; line++) { - var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize); - if (left == right) - ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos))); - else if (text.length > leftPos) - ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize)))); - } - if (!ranges.length) ranges.push(new Range(start, start)); - setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex), - {origin: "*mouse", scroll: false}); - cm.scrollIntoView(pos); - } else { - var oldRange = ourRange; - var anchor = oldRange.anchor, head = pos; - if (type != "single") { - if (type == "double") - var range = findWordAt(cm, pos); - else - var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0))); - if (cmp(range.anchor, anchor) > 0) { - head = range.head; - anchor = minPos(oldRange.from(), range.anchor); - } else { - head = range.anchor; - anchor = maxPos(oldRange.to(), range.head); - } - } - var ranges = startSel.ranges.slice(0); - ranges[ourIndex] = new Range(clipPos(doc, anchor), head); - setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse); - } - } - - var editorSize = display.wrapper.getBoundingClientRect(); - // Used to ensure timeout re-tries don't fire when another extend - // happened in the meantime (clearTimeout isn't reliable -- at - // least on Chrome, the timeouts still happen even when cleared, - // if the clear happens after their scheduled firing time). - var counter = 0; - - function extend(e) { - var curCount = ++counter; - var cur = posFromMouse(cm, e, true, type == "rect"); - if (!cur) return; - if (cmp(cur, lastPos) != 0) { - ensureFocus(cm); - extendTo(cur); - var visible = visibleLines(display, doc); - if (cur.line >= visible.to || cur.line < visible.from) - setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150); - } else { - var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0; - if (outside) setTimeout(operation(cm, function() { - if (counter != curCount) return; - display.scroller.scrollTop += outside; - extend(e); - }), 50); - } - } - - function done(e) { - counter = Infinity; - e_preventDefault(e); - focusInput(cm); - off(document, "mousemove", move); - off(document, "mouseup", up); - doc.history.lastSelOrigin = null; - } - - var move = operation(cm, function(e) { - if (!e_button(e)) done(e); - else extend(e); - }); - var up = operation(cm, done); - on(document, "mousemove", move); - on(document, "mouseup", up); - } - - // Determines whether an event happened in the gutter, and fires the - // handlers for the corresponding event. - function gutterEvent(cm, e, type, prevent, signalfn) { - try { var mX = e.clientX, mY = e.clientY; } - catch(e) { return false; } - if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false; - if (prevent) e_preventDefault(e); - - var display = cm.display; - var lineBox = display.lineDiv.getBoundingClientRect(); - - if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e); - mY -= lineBox.top - display.viewOffset; - - for (var i = 0; i < cm.options.gutters.length; ++i) { - var g = display.gutters.childNodes[i]; - if (g && g.getBoundingClientRect().right >= mX) { - var line = lineAtHeight(cm.doc, mY); - var gutter = cm.options.gutters[i]; - signalfn(cm, type, cm, line, gutter, e); - return e_defaultPrevented(e); - } - } - } - - function clickInGutter(cm, e) { - return gutterEvent(cm, e, "gutterClick", true, signalLater); - } - - // Kludge to work around strange IE behavior where it'll sometimes - // re-fire a series of drag-related events right after the drop (#1551) - var lastDrop = 0; - - function onDrop(e) { - var cm = this; - if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) - return; - e_preventDefault(e); - if (ie) lastDrop = +new Date; - var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files; - if (!pos || isReadOnly(cm)) return; - // Might be a file drop, in which case we simply extract the text - // and insert it. - if (files && files.length && window.FileReader && window.File) { - var n = files.length, text = Array(n), read = 0; - var loadFile = function(file, i) { - var reader = new FileReader; - reader.onload = operation(cm, function() { - text[i] = reader.result; - if (++read == n) { - pos = clipPos(cm.doc, pos); - var change = {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"}; - makeChange(cm.doc, change); - setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change))); - } - }); - reader.readAsText(file); - }; - for (var i = 0; i < n; ++i) loadFile(files[i], i); - } else { // Normal drop - // Don't do a replace if the drop happened inside of the selected text. - if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) { - cm.state.draggingText(e); - // Ensure the editor is re-focused - setTimeout(bind(focusInput, cm), 20); - return; - } - try { - var text = e.dataTransfer.getData("Text"); - if (text) { - if (cm.state.draggingText && !(mac ? e.metaKey : e.ctrlKey)) - var selected = cm.listSelections(); - setSelectionNoUndo(cm.doc, simpleSelection(pos, pos)); - if (selected) for (var i = 0; i < selected.length; ++i) - replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag"); - cm.replaceSelection(text, "around", "paste"); - focusInput(cm); - } - } - catch(e){} - } - } - - function onDragStart(cm, e) { - if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; } - if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return; - - e.dataTransfer.setData("Text", cm.getSelection()); - - // Use dummy image instead of default browsers image. - // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there. - if (e.dataTransfer.setDragImage && !safari) { - var img = elt("img", null, null, "position: fixed; left: 0; top: 0;"); - img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; - if (presto) { - img.width = img.height = 1; - cm.display.wrapper.appendChild(img); - // Force a relayout, or Opera won't use our image for some obscure reason - img._top = img.offsetTop; - } - e.dataTransfer.setDragImage(img, 0, 0); - if (presto) img.parentNode.removeChild(img); - } - } - - // SCROLL EVENTS - - // Sync the scrollable area and scrollbars, ensure the viewport - // covers the visible area. - function setScrollTop(cm, val) { - if (Math.abs(cm.doc.scrollTop - val) < 2) return; - cm.doc.scrollTop = val; - if (!gecko) updateDisplay(cm, {top: val}); - if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val; - if (cm.display.scrollbarV.scrollTop != val) cm.display.scrollbarV.scrollTop = val; - if (gecko) updateDisplay(cm); - startWorker(cm, 100); - } - // Sync scroller and scrollbar, ensure the gutter elements are - // aligned. - function setScrollLeft(cm, val, isScroller) { - if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return; - val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth); - cm.doc.scrollLeft = val; - alignHorizontally(cm); - if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val; - if (cm.display.scrollbarH.scrollLeft != val) cm.display.scrollbarH.scrollLeft = val; - } - - // Since the delta values reported on mouse wheel events are - // unstandardized between browsers and even browser versions, and - // generally horribly unpredictable, this code starts by measuring - // the scroll effect that the first few mouse wheel events have, - // and, from that, detects the way it can convert deltas to pixel - // offsets afterwards. - // - // The reason we want to know the amount a wheel event will scroll - // is that it gives us a chance to update the display before the - // actual scrolling happens, reducing flickering. - - var wheelSamples = 0, wheelPixelsPerUnit = null; - // Fill in a browser-detected starting value on browsers where we - // know one. These don't have to be accurate -- the result of them - // being wrong would just be a slight flicker on the first wheel - // scroll (if it is large enough). - if (ie) wheelPixelsPerUnit = -.53; - else if (gecko) wheelPixelsPerUnit = 15; - else if (chrome) wheelPixelsPerUnit = -.7; - else if (safari) wheelPixelsPerUnit = -1/3; - - function onScrollWheel(cm, e) { - var dx = e.wheelDeltaX, dy = e.wheelDeltaY; - if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail; - if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail; - else if (dy == null) dy = e.wheelDelta; - - var display = cm.display, scroll = display.scroller; - // Quit if there's nothing to scroll here - if (!(dx && scroll.scrollWidth > scroll.clientWidth || - dy && scroll.scrollHeight > scroll.clientHeight)) return; - - // Webkit browsers on OS X abort momentum scrolls when the target - // of the scroll event is removed from the scrollable element. - // This hack (see related code in patchDisplay) makes sure the - // element is kept around. - if (dy && mac && webkit) { - outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) { - for (var i = 0; i < view.length; i++) { - if (view[i].node == cur) { - cm.display.currentWheelTarget = cur; - break outer; - } - } - } - } - - // On some browsers, horizontal scrolling will cause redraws to - // happen before the gutter has been realigned, causing it to - // wriggle around in a most unseemly way. When we have an - // estimated pixels/delta value, we just handle horizontal - // scrolling entirely here. It'll be slightly off from native, but - // better than glitching out. - if (dx && !gecko && !presto && wheelPixelsPerUnit != null) { - if (dy) - setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight))); - setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth))); - e_preventDefault(e); - display.wheelStartX = null; // Abort measurement, if in progress - return; - } - - // 'Project' the visible viewport to cover the area that is being - // scrolled into view (if we know enough to estimate it). - if (dy && wheelPixelsPerUnit != null) { - var pixels = dy * wheelPixelsPerUnit; - var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight; - if (pixels < 0) top = Math.max(0, top + pixels - 50); - else bot = Math.min(cm.doc.height, bot + pixels + 50); - updateDisplay(cm, {top: top, bottom: bot}); - } - - if (wheelSamples < 20) { - if (display.wheelStartX == null) { - display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop; - display.wheelDX = dx; display.wheelDY = dy; - setTimeout(function() { - if (display.wheelStartX == null) return; - var movedX = scroll.scrollLeft - display.wheelStartX; - var movedY = scroll.scrollTop - display.wheelStartY; - var sample = (movedY && display.wheelDY && movedY / display.wheelDY) || - (movedX && display.wheelDX && movedX / display.wheelDX); - display.wheelStartX = display.wheelStartY = null; - if (!sample) return; - wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1); - ++wheelSamples; - }, 200); - } else { - display.wheelDX += dx; display.wheelDY += dy; - } - } - } - - // KEY EVENTS - - // Run a handler that was bound to a key. - function doHandleBinding(cm, bound, dropShift) { - if (typeof bound == "string") { - bound = commands[bound]; - if (!bound) return false; - } - // Ensure previous input has been read, so that the handler sees a - // consistent view of the document - if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false; - var prevShift = cm.display.shift, done = false; - try { - if (isReadOnly(cm)) cm.state.suppressEdits = true; - if (dropShift) cm.display.shift = false; - done = bound(cm) != Pass; - } finally { - cm.display.shift = prevShift; - cm.state.suppressEdits = false; - } - return done; - } - - // Collect the currently active keymaps. - function allKeyMaps(cm) { - var maps = cm.state.keyMaps.slice(0); - if (cm.options.extraKeys) maps.push(cm.options.extraKeys); - maps.push(cm.options.keyMap); - return maps; - } - - var maybeTransition; - // Handle a key from the keydown event. - function handleKeyBinding(cm, e) { - // Handle automatic keymap transitions - var startMap = getKeyMap(cm.options.keyMap), next = startMap.auto; - clearTimeout(maybeTransition); - if (next && !isModifierKey(e)) maybeTransition = setTimeout(function() { - if (getKeyMap(cm.options.keyMap) == startMap) { - cm.options.keyMap = (next.call ? next.call(null, cm) : next); - keyMapChanged(cm); - } - }, 50); - - var name = keyName(e, true), handled = false; - if (!name) return false; - var keymaps = allKeyMaps(cm); - - if (e.shiftKey) { - // First try to resolve full name (including 'Shift-'). Failing - // that, see if there is a cursor-motion command (starting with - // 'go') bound to the keyname without 'Shift-'. - handled = lookupKey("Shift-" + name, keymaps, function(b) {return doHandleBinding(cm, b, true);}) - || lookupKey(name, keymaps, function(b) { - if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion) - return doHandleBinding(cm, b); - }); - } else { - handled = lookupKey(name, keymaps, function(b) { return doHandleBinding(cm, b); }); - } - - if (handled) { - e_preventDefault(e); - restartBlink(cm); - signalLater(cm, "keyHandled", cm, name, e); - } - return handled; - } - - // Handle a key from the keypress event - function handleCharBinding(cm, e, ch) { - var handled = lookupKey("'" + ch + "'", allKeyMaps(cm), - function(b) { return doHandleBinding(cm, b, true); }); - if (handled) { - e_preventDefault(e); - restartBlink(cm); - signalLater(cm, "keyHandled", cm, "'" + ch + "'", e); - } - return handled; - } - - var lastStoppedKey = null; - function onKeyDown(e) { - var cm = this; - ensureFocus(cm); - if (signalDOMEvent(cm, e)) return; - // IE does strange things with escape. - if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false; - var code = e.keyCode; - cm.display.shift = code == 16 || e.shiftKey; - var handled = handleKeyBinding(cm, e); - if (presto) { - lastStoppedKey = handled ? code : null; - // Opera has no cut event... we try to at least catch the key combo - if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey)) - cm.replaceSelection("", null, "cut"); - } - - // Turn mouse into crosshair when Alt is held on Mac. - if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className)) - showCrossHair(cm); - } - - function showCrossHair(cm) { - var lineDiv = cm.display.lineDiv; - addClass(lineDiv, "CodeMirror-crosshair"); - - function up(e) { - if (e.keyCode == 18 || !e.altKey) { - rmClass(lineDiv, "CodeMirror-crosshair"); - off(document, "keyup", up); - off(document, "mouseover", up); - } - } - on(document, "keyup", up); - on(document, "mouseover", up); - } - - function onKeyUp(e) { - if (signalDOMEvent(this, e)) return; - if (e.keyCode == 16) this.doc.sel.shift = false; - } - - function onKeyPress(e) { - var cm = this; - if (signalDOMEvent(cm, e) || e.ctrlKey || mac && e.metaKey) return; - var keyCode = e.keyCode, charCode = e.charCode; - if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;} - if (((presto && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return; - var ch = String.fromCharCode(charCode == null ? keyCode : charCode); - if (handleCharBinding(cm, e, ch)) return; - if (ie && ie_version >= 9) cm.display.inputHasSelection = null; - fastPoll(cm); - } - - // FOCUS/BLUR EVENTS - - function onFocus(cm) { - if (cm.options.readOnly == "nocursor") return; - if (!cm.state.focused) { - signal(cm, "focus", cm); - cm.state.focused = true; - addClass(cm.display.wrapper, "CodeMirror-focused"); - // The prevInput test prevents this from firing when a context - // menu is closed (since the resetInput would kill the - // select-all detection hack) - if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) { - resetInput(cm); - if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730 - } - } - slowPoll(cm); - restartBlink(cm); - } - function onBlur(cm) { - if (cm.state.focused) { - signal(cm, "blur", cm); - cm.state.focused = false; - rmClass(cm.display.wrapper, "CodeMirror-focused"); - } - clearInterval(cm.display.blinker); - setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150); - } - - // CONTEXT MENU HANDLING - - // To make the context menu work, we need to briefly unhide the - // textarea (making it as unobtrusive as possible) to let the - // right-click take effect on it. - function onContextMenu(cm, e) { - if (signalDOMEvent(cm, e, "contextmenu")) return; - var display = cm.display; - if (eventInWidget(display, e) || contextMenuInGutter(cm, e)) return; - - var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop; - if (!pos || presto) return; // Opera is difficult. - - // Reset the current text selection only if the click is done outside of the selection - // and 'resetSelectionOnContextMenu' option is true. - var reset = cm.options.resetSelectionOnContextMenu; - if (reset && cm.doc.sel.contains(pos) == -1) - operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll); - - var oldCSS = display.input.style.cssText; - display.inputDiv.style.position = "absolute"; - display.input.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) + - "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " + - (ie ? "rgba(255, 255, 255, .05)" : "transparent") + - "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);"; - focusInput(cm); - resetInput(cm); - // Adds "Select all" to context menu in FF - if (!cm.somethingSelected()) display.input.value = display.prevInput = " "; - display.selForContextMenu = cm.doc.sel; - clearTimeout(display.detectingSelectAll); - - // Select-all will be greyed out if there's nothing to select, so - // this adds a zero-width space so that we can later check whether - // it got selected. - function prepareSelectAllHack() { - if (display.input.selectionStart != null) { - var selected = cm.somethingSelected(); - var extval = display.input.value = "\u200b" + (selected ? display.input.value : ""); - display.prevInput = selected ? "" : "\u200b"; - display.input.selectionStart = 1; display.input.selectionEnd = extval.length; - // Re-set this, in case some other handler touched the - // selection in the meantime. - display.selForContextMenu = cm.doc.sel; - } - } - function rehide() { - display.inputDiv.style.position = "relative"; - display.input.style.cssText = oldCSS; - if (ie && ie_version < 9) display.scrollbarV.scrollTop = display.scroller.scrollTop = scrollPos; - slowPoll(cm); - - // Try to detect the user choosing select-all - if (display.input.selectionStart != null) { - if (!ie || (ie && ie_version < 9)) prepareSelectAllHack(); - var i = 0, poll = function() { - if (display.selForContextMenu == cm.doc.sel && display.input.selectionStart == 0) - operation(cm, commands.selectAll)(cm); - else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500); - else resetInput(cm); - }; - display.detectingSelectAll = setTimeout(poll, 200); - } - } - - if (ie && ie_version >= 9) prepareSelectAllHack(); - if (captureRightClick) { - e_stop(e); - var mouseup = function() { - off(window, "mouseup", mouseup); - setTimeout(rehide, 20); - }; - on(window, "mouseup", mouseup); - } else { - setTimeout(rehide, 50); - } - } - - function contextMenuInGutter(cm, e) { - if (!hasHandler(cm, "gutterContextMenu")) return false; - return gutterEvent(cm, e, "gutterContextMenu", false, signal); - } - - // UPDATING - - // Compute the position of the end of a change (its 'to' property - // refers to the pre-change end). - var changeEnd = CodeMirror.changeEnd = function(change) { - if (!change.text) return change.to; - return Pos(change.from.line + change.text.length - 1, - lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0)); - }; - - // Adjust a position to refer to the post-change position of the - // same text, or the end of the change if the change covers it. - function adjustForChange(pos, change) { - if (cmp(pos, change.from) < 0) return pos; - if (cmp(pos, change.to) <= 0) return changeEnd(change); - - var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch; - if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch; - return Pos(line, ch); - } - - function computeSelAfterChange(doc, change) { - var out = []; - for (var i = 0; i < doc.sel.ranges.length; i++) { - var range = doc.sel.ranges[i]; - out.push(new Range(adjustForChange(range.anchor, change), - adjustForChange(range.head, change))); - } - return normalizeSelection(out, doc.sel.primIndex); - } - - function offsetPos(pos, old, nw) { - if (pos.line == old.line) - return Pos(nw.line, pos.ch - old.ch + nw.ch); - else - return Pos(nw.line + (pos.line - old.line), pos.ch); - } - - // Used by replaceSelections to allow moving the selection to the - // start or around the replaced test. Hint may be "start" or "around". - function computeReplacedSel(doc, changes, hint) { - var out = []; - var oldPrev = Pos(doc.first, 0), newPrev = oldPrev; - for (var i = 0; i < changes.length; i++) { - var change = changes[i]; - var from = offsetPos(change.from, oldPrev, newPrev); - var to = offsetPos(changeEnd(change), oldPrev, newPrev); - oldPrev = change.to; - newPrev = to; - if (hint == "around") { - var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0; - out[i] = new Range(inv ? to : from, inv ? from : to); - } else { - out[i] = new Range(from, from); - } - } - return new Selection(out, doc.sel.primIndex); - } - - // Allow "beforeChange" event handlers to influence a change - function filterChange(doc, change, update) { - var obj = { - canceled: false, - from: change.from, - to: change.to, - text: change.text, - origin: change.origin, - cancel: function() { this.canceled = true; } - }; - if (update) obj.update = function(from, to, text, origin) { - if (from) this.from = clipPos(doc, from); - if (to) this.to = clipPos(doc, to); - if (text) this.text = text; - if (origin !== undefined) this.origin = origin; - }; - signal(doc, "beforeChange", doc, obj); - if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj); - - if (obj.canceled) return null; - return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin}; - } - - // Apply a change to a document, and add it to the document's - // history, and propagating it to all linked documents. - function makeChange(doc, change, ignoreReadOnly) { - if (doc.cm) { - if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly); - if (doc.cm.state.suppressEdits) return; - } - - if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) { - change = filterChange(doc, change, true); - if (!change) return; - } - - // Possibly split or suppress the update based on the presence - // of read-only spans in its range. - var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to); - if (split) { - for (var i = split.length - 1; i >= 0; --i) - makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text}); - } else { - makeChangeInner(doc, change); - } - } - - function makeChangeInner(doc, change) { - if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return; - var selAfter = computeSelAfterChange(doc, change); - addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN); - - makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change)); - var rebased = []; - - linkedDocs(doc, function(doc, sharedHist) { - if (!sharedHist && indexOf(rebased, doc.history) == -1) { - rebaseHist(doc.history, change); - rebased.push(doc.history); - } - makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change)); - }); - } - - // Revert a change stored in a document's history. - function makeChangeFromHistory(doc, type, allowSelectionOnly) { - if (doc.cm && doc.cm.state.suppressEdits) return; - - var hist = doc.history, event, selAfter = doc.sel; - var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done; - - // Verify that there is a useable event (so that ctrl-z won't - // needlessly clear selection events) - for (var i = 0; i < source.length; i++) { - event = source[i]; - if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) - break; - } - if (i == source.length) return; - hist.lastOrigin = hist.lastSelOrigin = null; - - for (;;) { - event = source.pop(); - if (event.ranges) { - pushSelectionToHistory(event, dest); - if (allowSelectionOnly && !event.equals(doc.sel)) { - setSelection(doc, event, {clearRedo: false}); - return; - } - selAfter = event; - } - else break; - } - - // Build up a reverse change object to add to the opposite history - // stack (redo when undoing, and vice versa). - var antiChanges = []; - pushSelectionToHistory(selAfter, dest); - dest.push({changes: antiChanges, generation: hist.generation}); - hist.generation = event.generation || ++hist.maxGeneration; - - var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange"); - - for (var i = event.changes.length - 1; i >= 0; --i) { - var change = event.changes[i]; - change.origin = type; - if (filter && !filterChange(doc, change, false)) { - source.length = 0; - return; - } - - antiChanges.push(historyChangeFromChange(doc, change)); - - var after = i ? computeSelAfterChange(doc, change, null) : lst(source); - makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)); - if (!i && doc.cm) doc.cm.scrollIntoView(change); - var rebased = []; - - // Propagate to the linked documents - linkedDocs(doc, function(doc, sharedHist) { - if (!sharedHist && indexOf(rebased, doc.history) == -1) { - rebaseHist(doc.history, change); - rebased.push(doc.history); - } - makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change)); - }); - } - } - - // Sub-views need their line numbers shifted when text is added - // above or below them in the parent document. - function shiftDoc(doc, distance) { - if (distance == 0) return; - doc.first += distance; - doc.sel = new Selection(map(doc.sel.ranges, function(range) { - return new Range(Pos(range.anchor.line + distance, range.anchor.ch), - Pos(range.head.line + distance, range.head.ch)); - }), doc.sel.primIndex); - if (doc.cm) { - regChange(doc.cm, doc.first, doc.first - distance, distance); - for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++) - regLineChange(doc.cm, l, "gutter"); - } - } - - // More lower-level change function, handling only a single document - // (not linked ones). - function makeChangeSingleDoc(doc, change, selAfter, spans) { - if (doc.cm && !doc.cm.curOp) - return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans); - - if (change.to.line < doc.first) { - shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line)); - return; - } - if (change.from.line > doc.lastLine()) return; - - // Clip the change to the size of this doc - if (change.from.line < doc.first) { - var shift = change.text.length - 1 - (doc.first - change.from.line); - shiftDoc(doc, shift); - change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch), - text: [lst(change.text)], origin: change.origin}; - } - var last = doc.lastLine(); - if (change.to.line > last) { - change = {from: change.from, to: Pos(last, getLine(doc, last).text.length), - text: [change.text[0]], origin: change.origin}; - } - - change.removed = getBetween(doc, change.from, change.to); - - if (!selAfter) selAfter = computeSelAfterChange(doc, change, null); - if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans); - else updateDoc(doc, change, spans); - setSelectionNoUndo(doc, selAfter, sel_dontScroll); - } - - // Handle the interaction of a change to a document with the editor - // that this document is part of. - function makeChangeSingleDocInEditor(cm, change, spans) { - var doc = cm.doc, display = cm.display, from = change.from, to = change.to; - - var recomputeMaxLength = false, checkWidthStart = from.line; - if (!cm.options.lineWrapping) { - checkWidthStart = lineNo(visualLine(getLine(doc, from.line))); - doc.iter(checkWidthStart, to.line + 1, function(line) { - if (line == display.maxLine) { - recomputeMaxLength = true; - return true; - } - }); - } - - if (doc.sel.contains(change.from, change.to) > -1) - signalCursorActivity(cm); - - updateDoc(doc, change, spans, estimateHeight(cm)); - - if (!cm.options.lineWrapping) { - doc.iter(checkWidthStart, from.line + change.text.length, function(line) { - var len = lineLength(line); - if (len > display.maxLineLength) { - display.maxLine = line; - display.maxLineLength = len; - display.maxLineChanged = true; - recomputeMaxLength = false; - } - }); - if (recomputeMaxLength) cm.curOp.updateMaxLine = true; - } - - // Adjust frontier, schedule worker - doc.frontier = Math.min(doc.frontier, from.line); - startWorker(cm, 400); - - var lendiff = change.text.length - (to.line - from.line) - 1; - // Remember that these lines changed, for updating the display - if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change)) - regLineChange(cm, from.line, "text"); - else - regChange(cm, from.line, to.line + 1, lendiff); - - var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change"); - if (changeHandler || changesHandler) { - var obj = { - from: from, to: to, - text: change.text, - removed: change.removed, - origin: change.origin - }; - if (changeHandler) signalLater(cm, "change", cm, obj); - if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj); - } - cm.display.selForContextMenu = null; - } - - function replaceRange(doc, code, from, to, origin) { - if (!to) to = from; - if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; } - if (typeof code == "string") code = splitLines(code); - makeChange(doc, {from: from, to: to, text: code, origin: origin}); - } - - // SCROLLING THINGS INTO VIEW - - // If an editor sits on the top or bottom of the window, partially - // scrolled out of view, this ensures that the cursor is visible. - function maybeScrollWindow(cm, coords) { - var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null; - if (coords.top + box.top < 0) doScroll = true; - else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false; - if (doScroll != null && !phantom) { - var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " + - (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " + - (coords.bottom - coords.top + scrollerCutOff) + "px; left: " + - coords.left + "px; width: 2px;"); - cm.display.lineSpace.appendChild(scrollNode); - scrollNode.scrollIntoView(doScroll); - cm.display.lineSpace.removeChild(scrollNode); - } - } - - // Scroll a given position into view (immediately), verifying that - // it actually became visible (as line heights are accurately - // measured, the position of something may 'drift' during drawing). - function scrollPosIntoView(cm, pos, end, margin) { - if (margin == null) margin = 0; - for (;;) { - var changed = false, coords = cursorCoords(cm, pos); - var endCoords = !end || end == pos ? coords : cursorCoords(cm, end); - var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left), - Math.min(coords.top, endCoords.top) - margin, - Math.max(coords.left, endCoords.left), - Math.max(coords.bottom, endCoords.bottom) + margin); - var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft; - if (scrollPos.scrollTop != null) { - setScrollTop(cm, scrollPos.scrollTop); - if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true; - } - if (scrollPos.scrollLeft != null) { - setScrollLeft(cm, scrollPos.scrollLeft); - if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true; - } - if (!changed) return coords; - } - } - - // Scroll a given set of coordinates into view (immediately). - function scrollIntoView(cm, x1, y1, x2, y2) { - var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2); - if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop); - if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft); - } - - // Calculate a new scroll position needed to scroll the given - // rectangle into view. Returns an object with scrollTop and - // scrollLeft properties. When these are undefined, the - // vertical/horizontal position does not need to be adjusted. - function calculateScrollPos(cm, x1, y1, x2, y2) { - var display = cm.display, snapMargin = textHeight(cm.display); - if (y1 < 0) y1 = 0; - var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop; - var screen = display.scroller.clientHeight - scrollerCutOff, result = {}; - var docBottom = cm.doc.height + paddingVert(display); - var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin; - if (y1 < screentop) { - result.scrollTop = atTop ? 0 : y1; - } else if (y2 > screentop + screen) { - var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen); - if (newTop != screentop) result.scrollTop = newTop; - } - - var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft; - var screenw = display.scroller.clientWidth - scrollerCutOff; - x1 += display.gutters.offsetWidth; x2 += display.gutters.offsetWidth; - var gutterw = display.gutters.offsetWidth; - var atLeft = x1 < gutterw + 10; - if (x1 < screenleft + gutterw || atLeft) { - if (atLeft) x1 = 0; - result.scrollLeft = Math.max(0, x1 - 10 - gutterw); - } else if (x2 > screenw + screenleft - 3) { - result.scrollLeft = x2 + 10 - screenw; - } - return result; - } - - // Store a relative adjustment to the scroll position in the current - // operation (to be applied when the operation finishes). - function addToScrollPos(cm, left, top) { - if (left != null || top != null) resolveScrollToPos(cm); - if (left != null) - cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left; - if (top != null) - cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top; - } - - // Make sure that at the end of the operation the current cursor is - // shown. - function ensureCursorVisible(cm) { - resolveScrollToPos(cm); - var cur = cm.getCursor(), from = cur, to = cur; - if (!cm.options.lineWrapping) { - from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur; - to = Pos(cur.line, cur.ch + 1); - } - cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true}; - } - - // When an operation has its scrollToPos property set, and another - // scroll action is applied before the end of the operation, this - // 'simulates' scrolling that position into view in a cheap way, so - // that the effect of intermediate scroll commands is not ignored. - function resolveScrollToPos(cm) { - var range = cm.curOp.scrollToPos; - if (range) { - cm.curOp.scrollToPos = null; - var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to); - var sPos = calculateScrollPos(cm, Math.min(from.left, to.left), - Math.min(from.top, to.top) - range.margin, - Math.max(from.right, to.right), - Math.max(from.bottom, to.bottom) + range.margin); - cm.scrollTo(sPos.scrollLeft, sPos.scrollTop); - } - } - - // API UTILITIES - - // Indent the given line. The how parameter can be "smart", - // "add"/null, "subtract", or "prev". When aggressive is false - // (typically set to true for forced single-line indents), empty - // lines are not indented, and places where the mode returns Pass - // are left alone. - function indentLine(cm, n, how, aggressive) { - var doc = cm.doc, state; - if (how == null) how = "add"; - if (how == "smart") { - // Fall back to "prev" when the mode doesn't have an indentation - // method. - if (!cm.doc.mode.indent) how = "prev"; - else state = getStateBefore(cm, n); - } - - var tabSize = cm.options.tabSize; - var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize); - if (line.stateAfter) line.stateAfter = null; - var curSpaceString = line.text.match(/^\s*/)[0], indentation; - if (!aggressive && !/\S/.test(line.text)) { - indentation = 0; - how = "not"; - } else if (how == "smart") { - indentation = cm.doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text); - if (indentation == Pass) { - if (!aggressive) return; - how = "prev"; - } - } - if (how == "prev") { - if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize); - else indentation = 0; - } else if (how == "add") { - indentation = curSpace + cm.options.indentUnit; - } else if (how == "subtract") { - indentation = curSpace - cm.options.indentUnit; - } else if (typeof how == "number") { - indentation = curSpace + how; - } - indentation = Math.max(0, indentation); - - var indentString = "", pos = 0; - if (cm.options.indentWithTabs) - for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";} - if (pos < indentation) indentString += spaceStr(indentation - pos); - - if (indentString != curSpaceString) { - replaceRange(cm.doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input"); - } else { - // Ensure that, if the cursor was in the whitespace at the start - // of the line, it is moved to the end of that space. - for (var i = 0; i < doc.sel.ranges.length; i++) { - var range = doc.sel.ranges[i]; - if (range.head.line == n && range.head.ch < curSpaceString.length) { - var pos = Pos(n, curSpaceString.length); - replaceOneSelection(doc, i, new Range(pos, pos)); - break; - } - } - } - line.stateAfter = null; - } - - // Utility for applying a change to a line by handle or number, - // returning the number and optionally registering the line as - // changed. - function changeLine(doc, handle, changeType, op) { - var no = handle, line = handle; - if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle)); - else no = lineNo(handle); - if (no == null) return null; - if (op(line, no) && doc.cm) regLineChange(doc.cm, no, changeType); - return line; - } - - // Helper for deleting text near the selection(s), used to implement - // backspace, delete, and similar functionality. - function deleteNearSelection(cm, compute) { - var ranges = cm.doc.sel.ranges, kill = []; - // Build up a set of ranges to kill first, merging overlapping - // ranges. - for (var i = 0; i < ranges.length; i++) { - var toKill = compute(ranges[i]); - while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) { - var replaced = kill.pop(); - if (cmp(replaced.from, toKill.from) < 0) { - toKill.from = replaced.from; - break; - } - } - kill.push(toKill); - } - // Next, remove those actual ranges. - runInOp(cm, function() { - for (var i = kill.length - 1; i >= 0; i--) - replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete"); - ensureCursorVisible(cm); - }); - } - - // Used for horizontal relative motion. Dir is -1 or 1 (left or - // right), unit can be "char", "column" (like char, but doesn't - // cross line boundaries), "word" (across next word), or "group" (to - // the start of next group of word or non-word-non-whitespace - // chars). The visually param controls whether, in right-to-left - // text, direction 1 means to move towards the next index in the - // string, or towards the character to the right of the current - // position. The resulting position will have a hitSide=true - // property if it reached the end of the document. - function findPosH(doc, pos, dir, unit, visually) { - var line = pos.line, ch = pos.ch, origDir = dir; - var lineObj = getLine(doc, line); - var possible = true; - function findNextLine() { - var l = line + dir; - if (l < doc.first || l >= doc.first + doc.size) return (possible = false); - line = l; - return lineObj = getLine(doc, l); - } - function moveOnce(boundToLine) { - var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true); - if (next == null) { - if (!boundToLine && findNextLine()) { - if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj); - else ch = dir < 0 ? lineObj.text.length : 0; - } else return (possible = false); - } else ch = next; - return true; - } - - if (unit == "char") moveOnce(); - else if (unit == "column") moveOnce(true); - else if (unit == "word" || unit == "group") { - var sawType = null, group = unit == "group"; - var helper = doc.cm && doc.cm.getHelper(pos, "wordChars"); - for (var first = true;; first = false) { - if (dir < 0 && !moveOnce(!first)) break; - var cur = lineObj.text.charAt(ch) || "\n"; - var type = isWordChar(cur, helper) ? "w" - : group && cur == "\n" ? "n" - : !group || /\s/.test(cur) ? null - : "p"; - if (group && !first && !type) type = "s"; - if (sawType && sawType != type) { - if (dir < 0) {dir = 1; moveOnce();} - break; - } - - if (type) sawType = type; - if (dir > 0 && !moveOnce(!first)) break; - } - } - var result = skipAtomic(doc, Pos(line, ch), origDir, true); - if (!possible) result.hitSide = true; - return result; - } - - // For relative vertical movement. Dir may be -1 or 1. Unit can be - // "page" or "line". The resulting position will have a hitSide=true - // property if it reached the end of the document. - function findPosV(cm, pos, dir, unit) { - var doc = cm.doc, x = pos.left, y; - if (unit == "page") { - var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight); - y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display)); - } else if (unit == "line") { - y = dir > 0 ? pos.bottom + 3 : pos.top - 3; - } - for (;;) { - var target = coordsChar(cm, x, y); - if (!target.outside) break; - if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; } - y += dir * 5; - } - return target; - } - - // Find the word at the given position (as returned by coordsChar). - function findWordAt(cm, pos) { - var doc = cm.doc, line = getLine(doc, pos.line).text; - var start = pos.ch, end = pos.ch; - if (line) { - var helper = cm.getHelper(pos, "wordChars"); - if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end; - var startChar = line.charAt(start); - var check = isWordChar(startChar, helper) - ? function(ch) { return isWordChar(ch, helper); } - : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);} - : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);}; - while (start > 0 && check(line.charAt(start - 1))) --start; - while (end < line.length && check(line.charAt(end))) ++end; - } - return new Range(Pos(pos.line, start), Pos(pos.line, end)); - } - - // EDITOR METHODS - - // The publicly visible API. Note that methodOp(f) means - // 'wrap f in an operation, performed on its `this` parameter'. - - // This is not the complete set of editor methods. Most of the - // methods defined on the Doc type are also injected into - // CodeMirror.prototype, for backwards compatibility and - // convenience. - - CodeMirror.prototype = { - constructor: CodeMirror, - focus: function(){window.focus(); focusInput(this); fastPoll(this);}, - - setOption: function(option, value) { - var options = this.options, old = options[option]; - if (options[option] == value && option != "mode") return; - options[option] = value; - if (optionHandlers.hasOwnProperty(option)) - operation(this, optionHandlers[option])(this, value, old); - }, - - getOption: function(option) {return this.options[option];}, - getDoc: function() {return this.doc;}, - - addKeyMap: function(map, bottom) { - this.state.keyMaps[bottom ? "push" : "unshift"](map); - }, - removeKeyMap: function(map) { - var maps = this.state.keyMaps; - for (var i = 0; i < maps.length; ++i) - if (maps[i] == map || (typeof maps[i] != "string" && maps[i].name == map)) { - maps.splice(i, 1); - return true; - } - }, - - addOverlay: methodOp(function(spec, options) { - var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec); - if (mode.startState) throw new Error("Overlays may not be stateful."); - this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque}); - this.state.modeGen++; - regChange(this); - }), - removeOverlay: methodOp(function(spec) { - var overlays = this.state.overlays; - for (var i = 0; i < overlays.length; ++i) { - var cur = overlays[i].modeSpec; - if (cur == spec || typeof spec == "string" && cur.name == spec) { - overlays.splice(i, 1); - this.state.modeGen++; - regChange(this); - return; - } - } - }), - - indentLine: methodOp(function(n, dir, aggressive) { - if (typeof dir != "string" && typeof dir != "number") { - if (dir == null) dir = this.options.smartIndent ? "smart" : "prev"; - else dir = dir ? "add" : "subtract"; - } - if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive); - }), - indentSelection: methodOp(function(how) { - var ranges = this.doc.sel.ranges, end = -1; - for (var i = 0; i < ranges.length; i++) { - var range = ranges[i]; - if (!range.empty()) { - var start = Math.max(end, range.from().line); - var to = range.to(); - end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1; - for (var j = start; j < end; ++j) - indentLine(this, j, how); - } else if (range.head.line > end) { - indentLine(this, range.head.line, how, true); - end = range.head.line; - if (i == this.doc.sel.primIndex) ensureCursorVisible(this); - } - } - }), - - // Fetch the parser token for a given character. Useful for hacks - // that want to inspect the mode state (say, for completion). - getTokenAt: function(pos, precise) { - var doc = this.doc; - pos = clipPos(doc, pos); - var state = getStateBefore(this, pos.line, precise), mode = this.doc.mode; - var line = getLine(doc, pos.line); - var stream = new StringStream(line.text, this.options.tabSize); - while (stream.pos < pos.ch && !stream.eol()) { - stream.start = stream.pos; - var style = readToken(mode, stream, state); - } - return {start: stream.start, - end: stream.pos, - string: stream.current(), - type: style || null, - state: state}; - }, - - getTokenTypeAt: function(pos) { - pos = clipPos(this.doc, pos); - var styles = getLineStyles(this, getLine(this.doc, pos.line)); - var before = 0, after = (styles.length - 1) / 2, ch = pos.ch; - var type; - if (ch == 0) type = styles[2]; - else for (;;) { - var mid = (before + after) >> 1; - if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid; - else if (styles[mid * 2 + 1] < ch) before = mid + 1; - else { type = styles[mid * 2 + 2]; break; } - } - var cut = type ? type.indexOf("cm-overlay ") : -1; - return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1); - }, - - getModeAt: function(pos) { - var mode = this.doc.mode; - if (!mode.innerMode) return mode; - return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode; - }, - - getHelper: function(pos, type) { - return this.getHelpers(pos, type)[0]; - }, - - getHelpers: function(pos, type) { - var found = []; - if (!helpers.hasOwnProperty(type)) return helpers; - var help = helpers[type], mode = this.getModeAt(pos); - if (typeof mode[type] == "string") { - if (help[mode[type]]) found.push(help[mode[type]]); - } else if (mode[type]) { - for (var i = 0; i < mode[type].length; i++) { - var val = help[mode[type][i]]; - if (val) found.push(val); - } - } else if (mode.helperType && help[mode.helperType]) { - found.push(help[mode.helperType]); - } else if (help[mode.name]) { - found.push(help[mode.name]); - } - for (var i = 0; i < help._global.length; i++) { - var cur = help._global[i]; - if (cur.pred(mode, this) && indexOf(found, cur.val) == -1) - found.push(cur.val); - } - return found; - }, - - getStateAfter: function(line, precise) { - var doc = this.doc; - line = clipLine(doc, line == null ? doc.first + doc.size - 1: line); - return getStateBefore(this, line + 1, precise); - }, - - cursorCoords: function(start, mode) { - var pos, range = this.doc.sel.primary(); - if (start == null) pos = range.head; - else if (typeof start == "object") pos = clipPos(this.doc, start); - else pos = start ? range.from() : range.to(); - return cursorCoords(this, pos, mode || "page"); - }, - - charCoords: function(pos, mode) { - return charCoords(this, clipPos(this.doc, pos), mode || "page"); - }, - - coordsChar: function(coords, mode) { - coords = fromCoordSystem(this, coords, mode || "page"); - return coordsChar(this, coords.left, coords.top); - }, - - lineAtHeight: function(height, mode) { - height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top; - return lineAtHeight(this.doc, height + this.display.viewOffset); - }, - heightAtLine: function(line, mode) { - var end = false, last = this.doc.first + this.doc.size - 1; - if (line < this.doc.first) line = this.doc.first; - else if (line > last) { line = last; end = true; } - var lineObj = getLine(this.doc, line); - return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page").top + - (end ? this.doc.height - heightAtLine(lineObj) : 0); - }, - - defaultTextHeight: function() { return textHeight(this.display); }, - defaultCharWidth: function() { return charWidth(this.display); }, - - setGutterMarker: methodOp(function(line, gutterID, value) { - return changeLine(this.doc, line, "gutter", function(line) { - var markers = line.gutterMarkers || (line.gutterMarkers = {}); - markers[gutterID] = value; - if (!value && isEmpty(markers)) line.gutterMarkers = null; - return true; - }); - }), - - clearGutter: methodOp(function(gutterID) { - var cm = this, doc = cm.doc, i = doc.first; - doc.iter(function(line) { - if (line.gutterMarkers && line.gutterMarkers[gutterID]) { - line.gutterMarkers[gutterID] = null; - regLineChange(cm, i, "gutter"); - if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null; - } - ++i; - }); - }), - - addLineWidget: methodOp(function(handle, node, options) { - return addLineWidget(this, handle, node, options); - }), - - removeLineWidget: function(widget) { widget.clear(); }, - - lineInfo: function(line) { - if (typeof line == "number") { - if (!isLine(this.doc, line)) return null; - var n = line; - line = getLine(this.doc, line); - if (!line) return null; - } else { - var n = lineNo(line); - if (n == null) return null; - } - return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers, - textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass, - widgets: line.widgets}; - }, - - getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};}, - - addWidget: function(pos, node, scroll, vert, horiz) { - var display = this.display; - pos = cursorCoords(this, clipPos(this.doc, pos)); - var top = pos.bottom, left = pos.left; - node.style.position = "absolute"; - display.sizer.appendChild(node); - if (vert == "over") { - top = pos.top; - } else if (vert == "above" || vert == "near") { - var vspace = Math.max(display.wrapper.clientHeight, this.doc.height), - hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth); - // Default to positioning above (if specified and possible); otherwise default to positioning below - if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight) - top = pos.top - node.offsetHeight; - else if (pos.bottom + node.offsetHeight <= vspace) - top = pos.bottom; - if (left + node.offsetWidth > hspace) - left = hspace - node.offsetWidth; - } - node.style.top = top + "px"; - node.style.left = node.style.right = ""; - if (horiz == "right") { - left = display.sizer.clientWidth - node.offsetWidth; - node.style.right = "0px"; - } else { - if (horiz == "left") left = 0; - else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2; - node.style.left = left + "px"; - } - if (scroll) - scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight); - }, - - triggerOnKeyDown: methodOp(onKeyDown), - triggerOnKeyPress: methodOp(onKeyPress), - triggerOnKeyUp: methodOp(onKeyUp), - - execCommand: function(cmd) { - if (commands.hasOwnProperty(cmd)) - return commands[cmd](this); - }, - - findPosH: function(from, amount, unit, visually) { - var dir = 1; - if (amount < 0) { dir = -1; amount = -amount; } - for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { - cur = findPosH(this.doc, cur, dir, unit, visually); - if (cur.hitSide) break; - } - return cur; - }, - - moveH: methodOp(function(dir, unit) { - var cm = this; - cm.extendSelectionsBy(function(range) { - if (cm.display.shift || cm.doc.extend || range.empty()) - return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually); - else - return dir < 0 ? range.from() : range.to(); - }, sel_move); - }), - - deleteH: methodOp(function(dir, unit) { - var sel = this.doc.sel, doc = this.doc; - if (sel.somethingSelected()) - doc.replaceSelection("", null, "+delete"); - else - deleteNearSelection(this, function(range) { - var other = findPosH(doc, range.head, dir, unit, false); - return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other}; - }); - }), - - findPosV: function(from, amount, unit, goalColumn) { - var dir = 1, x = goalColumn; - if (amount < 0) { dir = -1; amount = -amount; } - for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) { - var coords = cursorCoords(this, cur, "div"); - if (x == null) x = coords.left; - else coords.left = x; - cur = findPosV(this, coords, dir, unit); - if (cur.hitSide) break; - } - return cur; - }, - - moveV: methodOp(function(dir, unit) { - var cm = this, doc = this.doc, goals = []; - var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected(); - doc.extendSelectionsBy(function(range) { - if (collapse) - return dir < 0 ? range.from() : range.to(); - var headPos = cursorCoords(cm, range.head, "div"); - if (range.goalColumn != null) headPos.left = range.goalColumn; - goals.push(headPos.left); - var pos = findPosV(cm, headPos, dir, unit); - if (unit == "page" && range == doc.sel.primary()) - addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top); - return pos; - }, sel_move); - if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++) - doc.sel.ranges[i].goalColumn = goals[i]; - }), - - toggleOverwrite: function(value) { - if (value != null && value == this.state.overwrite) return; - if (this.state.overwrite = !this.state.overwrite) - addClass(this.display.cursorDiv, "CodeMirror-overwrite"); - else - rmClass(this.display.cursorDiv, "CodeMirror-overwrite"); - - signal(this, "overwriteToggle", this, this.state.overwrite); - }, - hasFocus: function() { return activeElt() == this.display.input; }, - - scrollTo: methodOp(function(x, y) { - if (x != null || y != null) resolveScrollToPos(this); - if (x != null) this.curOp.scrollLeft = x; - if (y != null) this.curOp.scrollTop = y; - }), - getScrollInfo: function() { - var scroller = this.display.scroller, co = scrollerCutOff; - return {left: scroller.scrollLeft, top: scroller.scrollTop, - height: scroller.scrollHeight - co, width: scroller.scrollWidth - co, - clientHeight: scroller.clientHeight - co, clientWidth: scroller.clientWidth - co}; - }, - - scrollIntoView: methodOp(function(range, margin) { - if (range == null) { - range = {from: this.doc.sel.primary().head, to: null}; - if (margin == null) margin = this.options.cursorScrollMargin; - } else if (typeof range == "number") { - range = {from: Pos(range, 0), to: null}; - } else if (range.from == null) { - range = {from: range, to: null}; - } - if (!range.to) range.to = range.from; - range.margin = margin || 0; - - if (range.from.line != null) { - resolveScrollToPos(this); - this.curOp.scrollToPos = range; - } else { - var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left), - Math.min(range.from.top, range.to.top) - range.margin, - Math.max(range.from.right, range.to.right), - Math.max(range.from.bottom, range.to.bottom) + range.margin); - this.scrollTo(sPos.scrollLeft, sPos.scrollTop); - } - }), - - setSize: methodOp(function(width, height) { - var cm = this; - function interpret(val) { - return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val; - } - if (width != null) cm.display.wrapper.style.width = interpret(width); - if (height != null) cm.display.wrapper.style.height = interpret(height); - if (cm.options.lineWrapping) clearLineMeasurementCache(this); - var lineNo = cm.display.viewFrom; - cm.doc.iter(lineNo, cm.display.viewTo, function(line) { - if (line.widgets) for (var i = 0; i < line.widgets.length; i++) - if (line.widgets[i].noHScroll) { regLineChange(cm, lineNo, "widget"); break; } - ++lineNo; - }); - cm.curOp.forceUpdate = true; - signal(cm, "refresh", this); - }), - - operation: function(f){return runInOp(this, f);}, - - refresh: methodOp(function() { - var oldHeight = this.display.cachedTextHeight; - regChange(this); - this.curOp.forceUpdate = true; - clearCaches(this); - this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop); - updateGutterSpace(this); - if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5) - estimateLineHeights(this); - signal(this, "refresh", this); - }), - - swapDoc: methodOp(function(doc) { - var old = this.doc; - old.cm = null; - attachDoc(this, doc); - clearCaches(this); - resetInput(this); - this.scrollTo(doc.scrollLeft, doc.scrollTop); - signalLater(this, "swapDoc", this, old); - return old; - }), - - getInputField: function(){return this.display.input;}, - getWrapperElement: function(){return this.display.wrapper;}, - getScrollerElement: function(){return this.display.scroller;}, - getGutterElement: function(){return this.display.gutters;} - }; - eventMixin(CodeMirror); - - // OPTION DEFAULTS - - // The default configuration options. - var defaults = CodeMirror.defaults = {}; - // Functions to run when options are changed. - var optionHandlers = CodeMirror.optionHandlers = {}; - - function option(name, deflt, handle, notOnInit) { - CodeMirror.defaults[name] = deflt; - if (handle) optionHandlers[name] = - notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle; - } - - // Passed to option handlers when there is no old value. - var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}}; - - // These two are, on init, called from the constructor because they - // have to be initialized before the editor can start at all. - option("value", "", function(cm, val) { - cm.setValue(val); - }, true); - option("mode", null, function(cm, val) { - cm.doc.modeOption = val; - loadMode(cm); - }, true); - - option("indentUnit", 2, loadMode, true); - option("indentWithTabs", false); - option("smartIndent", true); - option("tabSize", 4, function(cm) { - resetModeState(cm); - clearCaches(cm); - regChange(cm); - }, true); - option("specialChars", /[\t\u0000-\u0019\u00ad\u200b\u2028\u2029\ufeff]/g, function(cm, val) { - cm.options.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g"); - cm.refresh(); - }, true); - option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true); - option("electricChars", true); - option("rtlMoveVisually", !windows); - option("wholeLineUpdateBefore", true); - - option("theme", "default", function(cm) { - themeChanged(cm); - guttersChanged(cm); - }, true); - option("keyMap", "default", keyMapChanged); - option("extraKeys", null); - - option("lineWrapping", false, wrappingChanged, true); - option("gutters", [], function(cm) { - setGuttersForLineNumbers(cm.options); - guttersChanged(cm); - }, true); - option("fixedGutter", true, function(cm, val) { - cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0"; - cm.refresh(); - }, true); - option("coverGutterNextToScrollbar", false, updateScrollbars, true); - option("lineNumbers", false, function(cm) { - setGuttersForLineNumbers(cm.options); - guttersChanged(cm); - }, true); - option("firstLineNumber", 1, guttersChanged, true); - option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true); - option("showCursorWhenSelecting", false, updateSelection, true); - - option("resetSelectionOnContextMenu", true); - - option("readOnly", false, function(cm, val) { - if (val == "nocursor") { - onBlur(cm); - cm.display.input.blur(); - cm.display.disabled = true; - } else { - cm.display.disabled = false; - if (!val) resetInput(cm); - } - }); - option("disableInput", false, function(cm, val) {if (!val) resetInput(cm);}, true); - option("dragDrop", true); - - option("cursorBlinkRate", 530); - option("cursorScrollMargin", 0); - option("cursorHeight", 1, updateSelection, true); - option("singleCursorHeightPerLine", true, updateSelection, true); - option("workTime", 100); - option("workDelay", 100); - option("flattenSpans", true, resetModeState, true); - option("addModeClass", false, resetModeState, true); - option("pollInterval", 100); - option("undoDepth", 200, function(cm, val){cm.doc.history.undoDepth = val;}); - option("historyEventDelay", 1250); - option("viewportMargin", 10, function(cm){cm.refresh();}, true); - option("maxHighlightLength", 10000, resetModeState, true); - option("moveInputWithCursor", true, function(cm, val) { - if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0; - }); - - option("tabindex", null, function(cm, val) { - cm.display.input.tabIndex = val || ""; - }); - option("autofocus", null); - - // MODE DEFINITION AND QUERYING - - // Known modes, by name and by MIME - var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {}; - - // Extra arguments are stored as the mode's dependencies, which is - // used by (legacy) mechanisms like loadmode.js to automatically - // load a mode. (Preferred mechanism is the require/define calls.) - CodeMirror.defineMode = function(name, mode) { - if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name; - if (arguments.length > 2) { - mode.dependencies = []; - for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]); - } - modes[name] = mode; - }; - - CodeMirror.defineMIME = function(mime, spec) { - mimeModes[mime] = spec; - }; - - // Given a MIME type, a {name, ...options} config object, or a name - // string, return a mode config object. - CodeMirror.resolveMode = function(spec) { - if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) { - spec = mimeModes[spec]; - } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) { - var found = mimeModes[spec.name]; - if (typeof found == "string") found = {name: found}; - spec = createObj(found, spec); - spec.name = found.name; - } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) { - return CodeMirror.resolveMode("application/xml"); - } - if (typeof spec == "string") return {name: spec}; - else return spec || {name: "null"}; - }; - - // Given a mode spec (anything that resolveMode accepts), find and - // initialize an actual mode object. - CodeMirror.getMode = function(options, spec) { - var spec = CodeMirror.resolveMode(spec); - var mfactory = modes[spec.name]; - if (!mfactory) return CodeMirror.getMode(options, "text/plain"); - var modeObj = mfactory(options, spec); - if (modeExtensions.hasOwnProperty(spec.name)) { - var exts = modeExtensions[spec.name]; - for (var prop in exts) { - if (!exts.hasOwnProperty(prop)) continue; - if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop]; - modeObj[prop] = exts[prop]; - } - } - modeObj.name = spec.name; - if (spec.helperType) modeObj.helperType = spec.helperType; - if (spec.modeProps) for (var prop in spec.modeProps) - modeObj[prop] = spec.modeProps[prop]; - - return modeObj; - }; - - // Minimal default mode. - CodeMirror.defineMode("null", function() { - return {token: function(stream) {stream.skipToEnd();}}; - }); - CodeMirror.defineMIME("text/plain", "null"); - - // This can be used to attach properties to mode objects from - // outside the actual mode definition. - var modeExtensions = CodeMirror.modeExtensions = {}; - CodeMirror.extendMode = function(mode, properties) { - var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {}); - copyObj(properties, exts); - }; - - // EXTENSIONS - - CodeMirror.defineExtension = function(name, func) { - CodeMirror.prototype[name] = func; - }; - CodeMirror.defineDocExtension = function(name, func) { - Doc.prototype[name] = func; - }; - CodeMirror.defineOption = option; - - var initHooks = []; - CodeMirror.defineInitHook = function(f) {initHooks.push(f);}; - - var helpers = CodeMirror.helpers = {}; - CodeMirror.registerHelper = function(type, name, value) { - if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []}; - helpers[type][name] = value; - }; - CodeMirror.registerGlobalHelper = function(type, name, predicate, value) { - CodeMirror.registerHelper(type, name, value); - helpers[type]._global.push({pred: predicate, val: value}); - }; - - // MODE STATE HANDLING - - // Utility functions for working with state. Exported because nested - // modes need to do this for their inner modes. - - var copyState = CodeMirror.copyState = function(mode, state) { - if (state === true) return state; - if (mode.copyState) return mode.copyState(state); - var nstate = {}; - for (var n in state) { - var val = state[n]; - if (val instanceof Array) val = val.concat([]); - nstate[n] = val; - } - return nstate; - }; - - var startState = CodeMirror.startState = function(mode, a1, a2) { - return mode.startState ? mode.startState(a1, a2) : true; - }; - - // Given a mode and a state (for that mode), find the inner mode and - // state at the position that the state refers to. - CodeMirror.innerMode = function(mode, state) { - while (mode.innerMode) { - var info = mode.innerMode(state); - if (!info || info.mode == mode) break; - state = info.state; - mode = info.mode; - } - return info || {mode: mode, state: state}; - }; - - // STANDARD COMMANDS - - // Commands are parameter-less actions that can be performed on an - // editor, mostly used for keybindings. - var commands = CodeMirror.commands = { - selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);}, - singleSelection: function(cm) { - cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll); - }, - killLine: function(cm) { - deleteNearSelection(cm, function(range) { - if (range.empty()) { - var len = getLine(cm.doc, range.head.line).text.length; - if (range.head.ch == len && range.head.line < cm.lastLine()) - return {from: range.head, to: Pos(range.head.line + 1, 0)}; - else - return {from: range.head, to: Pos(range.head.line, len)}; - } else { - return {from: range.from(), to: range.to()}; - } - }); - }, - deleteLine: function(cm) { - deleteNearSelection(cm, function(range) { - return {from: Pos(range.from().line, 0), - to: clipPos(cm.doc, Pos(range.to().line + 1, 0))}; - }); - }, - delLineLeft: function(cm) { - deleteNearSelection(cm, function(range) { - return {from: Pos(range.from().line, 0), to: range.from()}; - }); - }, - undo: function(cm) {cm.undo();}, - redo: function(cm) {cm.redo();}, - undoSelection: function(cm) {cm.undoSelection();}, - redoSelection: function(cm) {cm.redoSelection();}, - goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));}, - goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));}, - goLineStart: function(cm) { - cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); }, - {origin: "+move", bias: 1}); - }, - goLineStartSmart: function(cm) { - cm.extendSelectionsBy(function(range) { - var start = lineStart(cm, range.head.line); - var line = cm.getLineHandle(start.line); - var order = getOrder(line); - if (!order || order[0].level == 0) { - var firstNonWS = Math.max(0, line.text.search(/\S/)); - var inWS = range.head.line == start.line && range.head.ch <= firstNonWS && range.head.ch; - return Pos(start.line, inWS ? 0 : firstNonWS); - } - return start; - }, {origin: "+move", bias: 1}); - }, - goLineEnd: function(cm) { - cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); }, - {origin: "+move", bias: -1}); - }, - goLineRight: function(cm) { - cm.extendSelectionsBy(function(range) { - var top = cm.charCoords(range.head, "div").top + 5; - return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div"); - }, sel_move); - }, - goLineLeft: function(cm) { - cm.extendSelectionsBy(function(range) { - var top = cm.charCoords(range.head, "div").top + 5; - return cm.coordsChar({left: 0, top: top}, "div"); - }, sel_move); - }, - goLineUp: function(cm) {cm.moveV(-1, "line");}, - goLineDown: function(cm) {cm.moveV(1, "line");}, - goPageUp: function(cm) {cm.moveV(-1, "page");}, - goPageDown: function(cm) {cm.moveV(1, "page");}, - goCharLeft: function(cm) {cm.moveH(-1, "char");}, - goCharRight: function(cm) {cm.moveH(1, "char");}, - goColumnLeft: function(cm) {cm.moveH(-1, "column");}, - goColumnRight: function(cm) {cm.moveH(1, "column");}, - goWordLeft: function(cm) {cm.moveH(-1, "word");}, - goGroupRight: function(cm) {cm.moveH(1, "group");}, - goGroupLeft: function(cm) {cm.moveH(-1, "group");}, - goWordRight: function(cm) {cm.moveH(1, "word");}, - delCharBefore: function(cm) {cm.deleteH(-1, "char");}, - delCharAfter: function(cm) {cm.deleteH(1, "char");}, - delWordBefore: function(cm) {cm.deleteH(-1, "word");}, - delWordAfter: function(cm) {cm.deleteH(1, "word");}, - delGroupBefore: function(cm) {cm.deleteH(-1, "group");}, - delGroupAfter: function(cm) {cm.deleteH(1, "group");}, - indentAuto: function(cm) {cm.indentSelection("smart");}, - indentMore: function(cm) {cm.indentSelection("add");}, - indentLess: function(cm) {cm.indentSelection("subtract");}, - insertTab: function(cm) {cm.replaceSelection("\t");}, - insertSoftTab: function(cm) { - var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize; - for (var i = 0; i < ranges.length; i++) { - var pos = ranges[i].from(); - var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize); - spaces.push(new Array(tabSize - col % tabSize + 1).join(" ")); - } - cm.replaceSelections(spaces); - }, - defaultTab: function(cm) { - if (cm.somethingSelected()) cm.indentSelection("add"); - else cm.execCommand("insertTab"); - }, - transposeChars: function(cm) { - runInOp(cm, function() { - var ranges = cm.listSelections(), newSel = []; - for (var i = 0; i < ranges.length; i++) { - var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text; - if (line) { - if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1); - if (cur.ch > 0) { - cur = new Pos(cur.line, cur.ch + 1); - cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2), - Pos(cur.line, cur.ch - 2), cur, "+transpose"); - } else if (cur.line > cm.doc.first) { - var prev = getLine(cm.doc, cur.line - 1).text; - if (prev) - cm.replaceRange(line.charAt(0) + "\n" + prev.charAt(prev.length - 1), - Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose"); - } - } - newSel.push(new Range(cur, cur)); - } - cm.setSelections(newSel); - }); - }, - newlineAndIndent: function(cm) { - runInOp(cm, function() { - var len = cm.listSelections().length; - for (var i = 0; i < len; i++) { - var range = cm.listSelections()[i]; - cm.replaceRange("\n", range.anchor, range.head, "+input"); - cm.indentLine(range.from().line + 1, null, true); - ensureCursorVisible(cm); - } - }); - }, - toggleOverwrite: function(cm) {cm.toggleOverwrite();} - }; - - // STANDARD KEYMAPS - - var keyMap = CodeMirror.keyMap = {}; - keyMap.basic = { - "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown", - "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown", - "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore", - "Tab": "defaultTab", "Shift-Tab": "indentAuto", - "Enter": "newlineAndIndent", "Insert": "toggleOverwrite", - "Esc": "singleSelection" - }; - // Note that the save and find-related commands aren't defined by - // default. User code or addons can define them. Unknown commands - // are simply ignored. - keyMap.pcDefault = { - "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo", - "Ctrl-Home": "goDocStart", "Ctrl-Up": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Down": "goDocEnd", - "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd", - "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find", - "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll", - "Ctrl-[": "indentLess", "Ctrl-]": "indentMore", - "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection", - fallthrough: "basic" - }; - keyMap.macDefault = { - "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo", - "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft", - "Alt-Right": "goGroupRight", "Cmd-Left": "goLineStart", "Cmd-Right": "goLineEnd", "Alt-Backspace": "delGroupBefore", - "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find", - "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll", - "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delLineLeft", - "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", - fallthrough: ["basic", "emacsy"] - }; - // Very basic readline/emacs-style bindings, which are standard on Mac. - keyMap.emacsy = { - "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown", - "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd", - "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore", - "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars" - }; - keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault; - - // KEYMAP DISPATCH - - function getKeyMap(val) { - if (typeof val == "string") return keyMap[val]; - else return val; - } - - // Given an array of keymaps and a key name, call handle on any - // bindings found, until that returns a truthy value, at which point - // we consider the key handled. Implements things like binding a key - // to false stopping further handling and keymap fallthrough. - var lookupKey = CodeMirror.lookupKey = function(name, maps, handle) { - function lookup(map) { - map = getKeyMap(map); - var found = map[name]; - if (found === false) return "stop"; - if (found != null && handle(found)) return true; - if (map.nofallthrough) return "stop"; - - var fallthrough = map.fallthrough; - if (fallthrough == null) return false; - if (Object.prototype.toString.call(fallthrough) != "[object Array]") - return lookup(fallthrough); - for (var i = 0; i < fallthrough.length; ++i) { - var done = lookup(fallthrough[i]); - if (done) return done; - } - return false; - } - - for (var i = 0; i < maps.length; ++i) { - var done = lookup(maps[i]); - if (done) return done != "stop"; - } - }; - - // Modifier key presses don't count as 'real' key presses for the - // purpose of keymap fallthrough. - var isModifierKey = CodeMirror.isModifierKey = function(event) { - var name = keyNames[event.keyCode]; - return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod"; - }; - - // Look up the name of a key as indicated by an event object. - var keyName = CodeMirror.keyName = function(event, noShift) { - if (presto && event.keyCode == 34 && event["char"]) return false; - var name = keyNames[event.keyCode]; - if (name == null || event.altGraphKey) return false; - if (event.altKey) name = "Alt-" + name; - if (flipCtrlCmd ? event.metaKey : event.ctrlKey) name = "Ctrl-" + name; - if (flipCtrlCmd ? event.ctrlKey : event.metaKey) name = "Cmd-" + name; - if (!noShift && event.shiftKey) name = "Shift-" + name; - return name; - }; - - // FROMTEXTAREA - - CodeMirror.fromTextArea = function(textarea, options) { - if (!options) options = {}; - options.value = textarea.value; - if (!options.tabindex && textarea.tabindex) - options.tabindex = textarea.tabindex; - if (!options.placeholder && textarea.placeholder) - options.placeholder = textarea.placeholder; - // Set autofocus to true if this textarea is focused, or if it has - // autofocus and no other element is focused. - if (options.autofocus == null) { - var hasFocus = activeElt(); - options.autofocus = hasFocus == textarea || - textarea.getAttribute("autofocus") != null && hasFocus == document.body; - } - - function save() {textarea.value = cm.getValue();} - if (textarea.form) { - on(textarea.form, "submit", save); - // Deplorable hack to make the submit method do the right thing. - if (!options.leaveSubmitMethodAlone) { - var form = textarea.form, realSubmit = form.submit; - try { - var wrappedSubmit = form.submit = function() { - save(); - form.submit = realSubmit; - form.submit(); - form.submit = wrappedSubmit; - }; - } catch(e) {} - } - } - - textarea.style.display = "none"; - var cm = CodeMirror(function(node) { - textarea.parentNode.insertBefore(node, textarea.nextSibling); - }, options); - cm.save = save; - cm.getTextArea = function() { return textarea; }; - cm.toTextArea = function() { - save(); - textarea.parentNode.removeChild(cm.getWrapperElement()); - textarea.style.display = ""; - if (textarea.form) { - off(textarea.form, "submit", save); - if (typeof textarea.form.submit == "function") - textarea.form.submit = realSubmit; - } - }; - return cm; - }; - - // STRING STREAM - - // Fed to the mode parsers, provides helper functions to make - // parsers more succinct. - - var StringStream = CodeMirror.StringStream = function(string, tabSize) { - this.pos = this.start = 0; - this.string = string; - this.tabSize = tabSize || 8; - this.lastColumnPos = this.lastColumnValue = 0; - this.lineStart = 0; - }; - - StringStream.prototype = { - eol: function() {return this.pos >= this.string.length;}, - sol: function() {return this.pos == this.lineStart;}, - peek: function() {return this.string.charAt(this.pos) || undefined;}, - next: function() { - if (this.pos < this.string.length) - return this.string.charAt(this.pos++); - }, - eat: function(match) { - var ch = this.string.charAt(this.pos); - if (typeof match == "string") var ok = ch == match; - else var ok = ch && (match.test ? match.test(ch) : match(ch)); - if (ok) {++this.pos; return ch;} - }, - eatWhile: function(match) { - var start = this.pos; - while (this.eat(match)){} - return this.pos > start; - }, - eatSpace: function() { - var start = this.pos; - while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos; - return this.pos > start; - }, - skipToEnd: function() {this.pos = this.string.length;}, - skipTo: function(ch) { - var found = this.string.indexOf(ch, this.pos); - if (found > -1) {this.pos = found; return true;} - }, - backUp: function(n) {this.pos -= n;}, - column: function() { - if (this.lastColumnPos < this.start) { - this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue); - this.lastColumnPos = this.start; - } - return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); - }, - indentation: function() { - return countColumn(this.string, null, this.tabSize) - - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0); - }, - match: function(pattern, consume, caseInsensitive) { - if (typeof pattern == "string") { - var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;}; - var substr = this.string.substr(this.pos, pattern.length); - if (cased(substr) == cased(pattern)) { - if (consume !== false) this.pos += pattern.length; - return true; - } - } else { - var match = this.string.slice(this.pos).match(pattern); - if (match && match.index > 0) return null; - if (match && consume !== false) this.pos += match[0].length; - return match; - } - }, - current: function(){return this.string.slice(this.start, this.pos);}, - hideFirstChars: function(n, inner) { - this.lineStart += n; - try { return inner(); } - finally { this.lineStart -= n; } - } - }; - - // TEXTMARKERS - - // Created with markText and setBookmark methods. A TextMarker is a - // handle that can be used to clear or find a marked position in the - // document. Line objects hold arrays (markedSpans) containing - // {from, to, marker} object pointing to such marker objects, and - // indicating that such a marker is present on that line. Multiple - // lines may point to the same marker when it spans across lines. - // The spans will have null for their from/to properties when the - // marker continues beyond the start/end of the line. Markers have - // links back to the lines they currently touch. - - var TextMarker = CodeMirror.TextMarker = function(doc, type) { - this.lines = []; - this.type = type; - this.doc = doc; - }; - eventMixin(TextMarker); - - // Clear the marker. - TextMarker.prototype.clear = function() { - if (this.explicitlyCleared) return; - var cm = this.doc.cm, withOp = cm && !cm.curOp; - if (withOp) startOperation(cm); - if (hasHandler(this, "clear")) { - var found = this.find(); - if (found) signalLater(this, "clear", found.from, found.to); - } - var min = null, max = null; - for (var i = 0; i < this.lines.length; ++i) { - var line = this.lines[i]; - var span = getMarkedSpanFor(line.markedSpans, this); - if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text"); - else if (cm) { - if (span.to != null) max = lineNo(line); - if (span.from != null) min = lineNo(line); - } - line.markedSpans = removeMarkedSpan(line.markedSpans, span); - if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm) - updateLineHeight(line, textHeight(cm.display)); - } - if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) { - var visual = visualLine(this.lines[i]), len = lineLength(visual); - if (len > cm.display.maxLineLength) { - cm.display.maxLine = visual; - cm.display.maxLineLength = len; - cm.display.maxLineChanged = true; - } - } - - if (min != null && cm && this.collapsed) regChange(cm, min, max + 1); - this.lines.length = 0; - this.explicitlyCleared = true; - if (this.atomic && this.doc.cantEdit) { - this.doc.cantEdit = false; - if (cm) reCheckSelection(cm.doc); - } - if (cm) signalLater(cm, "markerCleared", cm, this); - if (withOp) endOperation(cm); - if (this.parent) this.parent.clear(); - }; - - // Find the position of the marker in the document. Returns a {from, - // to} object by default. Side can be passed to get a specific side - // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the - // Pos objects returned contain a line object, rather than a line - // number (used to prevent looking up the same line twice). - TextMarker.prototype.find = function(side, lineObj) { - if (side == null && this.type == "bookmark") side = 1; - var from, to; - for (var i = 0; i < this.lines.length; ++i) { - var line = this.lines[i]; - var span = getMarkedSpanFor(line.markedSpans, this); - if (span.from != null) { - from = Pos(lineObj ? line : lineNo(line), span.from); - if (side == -1) return from; - } - if (span.to != null) { - to = Pos(lineObj ? line : lineNo(line), span.to); - if (side == 1) return to; - } - } - return from && {from: from, to: to}; - }; - - // Signals that the marker's widget changed, and surrounding layout - // should be recomputed. - TextMarker.prototype.changed = function() { - var pos = this.find(-1, true), widget = this, cm = this.doc.cm; - if (!pos || !cm) return; - runInOp(cm, function() { - var line = pos.line, lineN = lineNo(pos.line); - var view = findViewForLine(cm, lineN); - if (view) { - clearLineMeasurementCacheFor(view); - cm.curOp.selectionChanged = cm.curOp.forceUpdate = true; - } - cm.curOp.updateMaxLine = true; - if (!lineIsHidden(widget.doc, line) && widget.height != null) { - var oldHeight = widget.height; - widget.height = null; - var dHeight = widgetHeight(widget) - oldHeight; - if (dHeight) - updateLineHeight(line, line.height + dHeight); - } - }); - }; - - TextMarker.prototype.attachLine = function(line) { - if (!this.lines.length && this.doc.cm) { - var op = this.doc.cm.curOp; - if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) - (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this); - } - this.lines.push(line); - }; - TextMarker.prototype.detachLine = function(line) { - this.lines.splice(indexOf(this.lines, line), 1); - if (!this.lines.length && this.doc.cm) { - var op = this.doc.cm.curOp; - (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this); - } - }; - - // Collapsed markers have unique ids, in order to be able to order - // them, which is needed for uniquely determining an outer marker - // when they overlap (they may nest, but not partially overlap). - var nextMarkerId = 0; - - // Create a marker, wire it up to the right lines, and - function markText(doc, from, to, options, type) { - // Shared markers (across linked documents) are handled separately - // (markTextShared will call out to this again, once per - // document). - if (options && options.shared) return markTextShared(doc, from, to, options, type); - // Ensure we are in an operation. - if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type); - - var marker = new TextMarker(doc, type), diff = cmp(from, to); - if (options) copyObj(options, marker, false); - // Don't connect empty markers unless clearWhenEmpty is false - if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) - return marker; - if (marker.replacedWith) { - // Showing up as a widget implies collapsed (widget replaces text) - marker.collapsed = true; - marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget"); - if (!options.handleMouseEvents) marker.widgetNode.ignoreEvents = true; - if (options.insertLeft) marker.widgetNode.insertLeft = true; - } - if (marker.collapsed) { - if (conflictingCollapsedRange(doc, from.line, from, to, marker) || - from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) - throw new Error("Inserting collapsed marker partially overlapping an existing one"); - sawCollapsedSpans = true; - } - - if (marker.addToHistory) - addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN); - - var curLine = from.line, cm = doc.cm, updateMaxLine; - doc.iter(curLine, to.line + 1, function(line) { - if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) - updateMaxLine = true; - if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0); - addMarkedSpan(line, new MarkedSpan(marker, - curLine == from.line ? from.ch : null, - curLine == to.line ? to.ch : null)); - ++curLine; - }); - // lineIsHidden depends on the presence of the spans, so needs a second pass - if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) { - if (lineIsHidden(doc, line)) updateLineHeight(line, 0); - }); - - if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); }); - - if (marker.readOnly) { - sawReadOnlySpans = true; - if (doc.history.done.length || doc.history.undone.length) - doc.clearHistory(); - } - if (marker.collapsed) { - marker.id = ++nextMarkerId; - marker.atomic = true; - } - if (cm) { - // Sync editor state - if (updateMaxLine) cm.curOp.updateMaxLine = true; - if (marker.collapsed) - regChange(cm, from.line, to.line + 1); - else if (marker.className || marker.title || marker.startStyle || marker.endStyle) - for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text"); - if (marker.atomic) reCheckSelection(cm.doc); - signalLater(cm, "markerAdded", cm, marker); - } - return marker; - } - - // SHARED TEXTMARKERS - - // A shared marker spans multiple linked documents. It is - // implemented as a meta-marker-object controlling multiple normal - // markers. - var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) { - this.markers = markers; - this.primary = primary; - for (var i = 0; i < markers.length; ++i) - markers[i].parent = this; - }; - eventMixin(SharedTextMarker); - - SharedTextMarker.prototype.clear = function() { - if (this.explicitlyCleared) return; - this.explicitlyCleared = true; - for (var i = 0; i < this.markers.length; ++i) - this.markers[i].clear(); - signalLater(this, "clear"); - }; - SharedTextMarker.prototype.find = function(side, lineObj) { - return this.primary.find(side, lineObj); - }; - - function markTextShared(doc, from, to, options, type) { - options = copyObj(options); - options.shared = false; - var markers = [markText(doc, from, to, options, type)], primary = markers[0]; - var widget = options.widgetNode; - linkedDocs(doc, function(doc) { - if (widget) options.widgetNode = widget.cloneNode(true); - markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type)); - for (var i = 0; i < doc.linked.length; ++i) - if (doc.linked[i].isParent) return; - primary = lst(markers); - }); - return new SharedTextMarker(markers, primary); - } - - function findSharedMarkers(doc) { - return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), - function(m) { return m.parent; }); - } - - function copySharedMarkers(doc, markers) { - for (var i = 0; i < markers.length; i++) { - var marker = markers[i], pos = marker.find(); - var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to); - if (cmp(mFrom, mTo)) { - var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type); - marker.markers.push(subMark); - subMark.parent = marker; - } - } - } - - function detachSharedMarkers(markers) { - for (var i = 0; i < markers.length; i++) { - var marker = markers[i], linked = [marker.primary.doc];; - linkedDocs(marker.primary.doc, function(d) { linked.push(d); }); - for (var j = 0; j < marker.markers.length; j++) { - var subMarker = marker.markers[j]; - if (indexOf(linked, subMarker.doc) == -1) { - subMarker.parent = null; - marker.markers.splice(j--, 1); - } - } - } - } - - // TEXTMARKER SPANS - - function MarkedSpan(marker, from, to) { - this.marker = marker; - this.from = from; this.to = to; - } - - // Search an array of spans for a span matching the given marker. - function getMarkedSpanFor(spans, marker) { - if (spans) for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if (span.marker == marker) return span; - } - } - // Remove a span from an array, returning undefined if no spans are - // left (we don't store arrays for lines without spans). - function removeMarkedSpan(spans, span) { - for (var r, i = 0; i < spans.length; ++i) - if (spans[i] != span) (r || (r = [])).push(spans[i]); - return r; - } - // Add a span to a line. - function addMarkedSpan(line, span) { - line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span]; - span.marker.attachLine(line); - } - - // Used for the algorithm that adjusts markers for a change in the - // document. These functions cut an array of spans at a given - // character position, returning an array of remaining chunks (or - // undefined if nothing remains). - function markedSpansBefore(old, startCh, isInsert) { - if (old) for (var i = 0, nw; i < old.length; ++i) { - var span = old[i], marker = span.marker; - var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh); - if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) { - var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh); - (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to)); - } - } - return nw; - } - function markedSpansAfter(old, endCh, isInsert) { - if (old) for (var i = 0, nw; i < old.length; ++i) { - var span = old[i], marker = span.marker; - var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh); - if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) { - var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh); - (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh, - span.to == null ? null : span.to - endCh)); - } - } - return nw; - } - - // Given a change object, compute the new set of marker spans that - // cover the line in which the change took place. Removes spans - // entirely within the change, reconnects spans belonging to the - // same marker that appear on both sides of the change, and cuts off - // spans partially within the change. Returns an array of span - // arrays with one element for each line in (after) the change. - function stretchSpansOverChange(doc, change) { - var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans; - var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans; - if (!oldFirst && !oldLast) return null; - - var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0; - // Get the spans that 'stick out' on both sides - var first = markedSpansBefore(oldFirst, startCh, isInsert); - var last = markedSpansAfter(oldLast, endCh, isInsert); - - // Next, merge those two ends - var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0); - if (first) { - // Fix up .to properties of first - for (var i = 0; i < first.length; ++i) { - var span = first[i]; - if (span.to == null) { - var found = getMarkedSpanFor(last, span.marker); - if (!found) span.to = startCh; - else if (sameLine) span.to = found.to == null ? null : found.to + offset; - } - } - } - if (last) { - // Fix up .from in last (or move them into first in case of sameLine) - for (var i = 0; i < last.length; ++i) { - var span = last[i]; - if (span.to != null) span.to += offset; - if (span.from == null) { - var found = getMarkedSpanFor(first, span.marker); - if (!found) { - span.from = offset; - if (sameLine) (first || (first = [])).push(span); - } - } else { - span.from += offset; - if (sameLine) (first || (first = [])).push(span); - } - } - } - // Make sure we didn't create any zero-length spans - if (first) first = clearEmptySpans(first); - if (last && last != first) last = clearEmptySpans(last); - - var newMarkers = [first]; - if (!sameLine) { - // Fill gap with whole-line-spans - var gap = change.text.length - 2, gapMarkers; - if (gap > 0 && first) - for (var i = 0; i < first.length; ++i) - if (first[i].to == null) - (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null)); - for (var i = 0; i < gap; ++i) - newMarkers.push(gapMarkers); - newMarkers.push(last); - } - return newMarkers; - } - - // Remove spans that are empty and don't have a clearWhenEmpty - // option of false. - function clearEmptySpans(spans) { - for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false) - spans.splice(i--, 1); - } - if (!spans.length) return null; - return spans; - } - - // Used for un/re-doing changes from the history. Combines the - // result of computing the existing spans with the set of spans that - // existed in the history (so that deleting around a span and then - // undoing brings back the span). - function mergeOldSpans(doc, change) { - var old = getOldSpans(doc, change); - var stretched = stretchSpansOverChange(doc, change); - if (!old) return stretched; - if (!stretched) return old; - - for (var i = 0; i < old.length; ++i) { - var oldCur = old[i], stretchCur = stretched[i]; - if (oldCur && stretchCur) { - spans: for (var j = 0; j < stretchCur.length; ++j) { - var span = stretchCur[j]; - for (var k = 0; k < oldCur.length; ++k) - if (oldCur[k].marker == span.marker) continue spans; - oldCur.push(span); - } - } else if (stretchCur) { - old[i] = stretchCur; - } - } - return old; - } - - // Used to 'clip' out readOnly ranges when making a change. - function removeReadOnlyRanges(doc, from, to) { - var markers = null; - doc.iter(from.line, to.line + 1, function(line) { - if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) { - var mark = line.markedSpans[i].marker; - if (mark.readOnly && (!markers || indexOf(markers, mark) == -1)) - (markers || (markers = [])).push(mark); - } - }); - if (!markers) return null; - var parts = [{from: from, to: to}]; - for (var i = 0; i < markers.length; ++i) { - var mk = markers[i], m = mk.find(0); - for (var j = 0; j < parts.length; ++j) { - var p = parts[j]; - if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue; - var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to); - if (dfrom < 0 || !mk.inclusiveLeft && !dfrom) - newParts.push({from: p.from, to: m.from}); - if (dto > 0 || !mk.inclusiveRight && !dto) - newParts.push({from: m.to, to: p.to}); - parts.splice.apply(parts, newParts); - j += newParts.length - 1; - } - } - return parts; - } - - // Connect or disconnect spans from a line. - function detachMarkedSpans(line) { - var spans = line.markedSpans; - if (!spans) return; - for (var i = 0; i < spans.length; ++i) - spans[i].marker.detachLine(line); - line.markedSpans = null; - } - function attachMarkedSpans(line, spans) { - if (!spans) return; - for (var i = 0; i < spans.length; ++i) - spans[i].marker.attachLine(line); - line.markedSpans = spans; - } - - // Helpers used when computing which overlapping collapsed span - // counts as the larger one. - function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; } - function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; } - - // Returns a number indicating which of two overlapping collapsed - // spans is larger (and thus includes the other). Falls back to - // comparing ids when the spans cover exactly the same range. - function compareCollapsedMarkers(a, b) { - var lenDiff = a.lines.length - b.lines.length; - if (lenDiff != 0) return lenDiff; - var aPos = a.find(), bPos = b.find(); - var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b); - if (fromCmp) return -fromCmp; - var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b); - if (toCmp) return toCmp; - return b.id - a.id; - } - - // Find out whether a line ends or starts in a collapsed span. If - // so, return the marker for that span. - function collapsedSpanAtSide(line, start) { - var sps = sawCollapsedSpans && line.markedSpans, found; - if (sps) for (var sp, i = 0; i < sps.length; ++i) { - sp = sps[i]; - if (sp.marker.collapsed && (start ? sp.from : sp.to) == null && - (!found || compareCollapsedMarkers(found, sp.marker) < 0)) - found = sp.marker; - } - return found; - } - function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); } - function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); } - - // Test whether there exists a collapsed span that partially - // overlaps (covers the start or end, but not both) of a new span. - // Such overlap is not allowed. - function conflictingCollapsedRange(doc, lineNo, from, to, marker) { - var line = getLine(doc, lineNo); - var sps = sawCollapsedSpans && line.markedSpans; - if (sps) for (var i = 0; i < sps.length; ++i) { - var sp = sps[i]; - if (!sp.marker.collapsed) continue; - var found = sp.marker.find(0); - var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker); - var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker); - if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue; - if (fromCmp <= 0 && (cmp(found.to, from) > 0 || (sp.marker.inclusiveRight && marker.inclusiveLeft)) || - fromCmp >= 0 && (cmp(found.from, to) < 0 || (sp.marker.inclusiveLeft && marker.inclusiveRight))) - return true; - } - } - - // A visual line is a line as drawn on the screen. Folding, for - // example, can cause multiple logical lines to appear on the same - // visual line. This finds the start of the visual line that the - // given line is part of (usually that is the line itself). - function visualLine(line) { - var merged; - while (merged = collapsedSpanAtStart(line)) - line = merged.find(-1, true).line; - return line; - } - - // Returns an array of logical lines that continue the visual line - // started by the argument, or undefined if there are no such lines. - function visualLineContinued(line) { - var merged, lines; - while (merged = collapsedSpanAtEnd(line)) { - line = merged.find(1, true).line; - (lines || (lines = [])).push(line); - } - return lines; - } - - // Get the line number of the start of the visual line that the - // given line number is part of. - function visualLineNo(doc, lineN) { - var line = getLine(doc, lineN), vis = visualLine(line); - if (line == vis) return lineN; - return lineNo(vis); - } - // Get the line number of the start of the next visual line after - // the given line. - function visualLineEndNo(doc, lineN) { - if (lineN > doc.lastLine()) return lineN; - var line = getLine(doc, lineN), merged; - if (!lineIsHidden(doc, line)) return lineN; - while (merged = collapsedSpanAtEnd(line)) - line = merged.find(1, true).line; - return lineNo(line) + 1; - } - - // Compute whether a line is hidden. Lines count as hidden when they - // are part of a visual line that starts with another line, or when - // they are entirely covered by collapsed, non-widget span. - function lineIsHidden(doc, line) { - var sps = sawCollapsedSpans && line.markedSpans; - if (sps) for (var sp, i = 0; i < sps.length; ++i) { - sp = sps[i]; - if (!sp.marker.collapsed) continue; - if (sp.from == null) return true; - if (sp.marker.widgetNode) continue; - if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp)) - return true; - } - } - function lineIsHiddenInner(doc, line, span) { - if (span.to == null) { - var end = span.marker.find(1, true); - return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker)); - } - if (span.marker.inclusiveRight && span.to == line.text.length) - return true; - for (var sp, i = 0; i < line.markedSpans.length; ++i) { - sp = line.markedSpans[i]; - if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to && - (sp.to == null || sp.to != span.from) && - (sp.marker.inclusiveLeft || span.marker.inclusiveRight) && - lineIsHiddenInner(doc, line, sp)) return true; - } - } - - // LINE WIDGETS - - // Line widgets are block elements displayed above or below a line. - - var LineWidget = CodeMirror.LineWidget = function(cm, node, options) { - if (options) for (var opt in options) if (options.hasOwnProperty(opt)) - this[opt] = options[opt]; - this.cm = cm; - this.node = node; - }; - eventMixin(LineWidget); - - function adjustScrollWhenAboveVisible(cm, line, diff) { - if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop)) - addToScrollPos(cm, null, diff); - } - - LineWidget.prototype.clear = function() { - var cm = this.cm, ws = this.line.widgets, line = this.line, no = lineNo(line); - if (no == null || !ws) return; - for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1); - if (!ws.length) line.widgets = null; - var height = widgetHeight(this); - runInOp(cm, function() { - adjustScrollWhenAboveVisible(cm, line, -height); - regLineChange(cm, no, "widget"); - updateLineHeight(line, Math.max(0, line.height - height)); - }); - }; - LineWidget.prototype.changed = function() { - var oldH = this.height, cm = this.cm, line = this.line; - this.height = null; - var diff = widgetHeight(this) - oldH; - if (!diff) return; - runInOp(cm, function() { - cm.curOp.forceUpdate = true; - adjustScrollWhenAboveVisible(cm, line, diff); - updateLineHeight(line, line.height + diff); - }); - }; - - function widgetHeight(widget) { - if (widget.height != null) return widget.height; - if (!contains(document.body, widget.node)) { - var parentStyle = "position: relative;"; - if (widget.coverGutter) - parentStyle += "margin-left: -" + widget.cm.getGutterElement().offsetWidth + "px;"; - removeChildrenAndAdd(widget.cm.display.measure, elt("div", [widget.node], null, parentStyle)); - } - return widget.height = widget.node.offsetHeight; - } - - function addLineWidget(cm, handle, node, options) { - var widget = new LineWidget(cm, node, options); - if (widget.noHScroll) cm.display.alignWidgets = true; - changeLine(cm.doc, handle, "widget", function(line) { - var widgets = line.widgets || (line.widgets = []); - if (widget.insertAt == null) widgets.push(widget); - else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget); - widget.line = line; - if (!lineIsHidden(cm.doc, line)) { - var aboveVisible = heightAtLine(line) < cm.doc.scrollTop; - updateLineHeight(line, line.height + widgetHeight(widget)); - if (aboveVisible) addToScrollPos(cm, null, widget.height); - cm.curOp.forceUpdate = true; - } - return true; - }); - return widget; - } - - // LINE DATA STRUCTURE - - // Line objects. These hold state related to a line, including - // highlighting info (the styles array). - var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) { - this.text = text; - attachMarkedSpans(this, markedSpans); - this.height = estimateHeight ? estimateHeight(this) : 1; - }; - eventMixin(Line); - Line.prototype.lineNo = function() { return lineNo(this); }; - - // Change the content (text, markers) of a line. Automatically - // invalidates cached information and tries to re-estimate the - // line's height. - function updateLine(line, text, markedSpans, estimateHeight) { - line.text = text; - if (line.stateAfter) line.stateAfter = null; - if (line.styles) line.styles = null; - if (line.order != null) line.order = null; - detachMarkedSpans(line); - attachMarkedSpans(line, markedSpans); - var estHeight = estimateHeight ? estimateHeight(line) : 1; - if (estHeight != line.height) updateLineHeight(line, estHeight); - } - - // Detach a line from the document tree and its markers. - function cleanUpLine(line) { - line.parent = null; - detachMarkedSpans(line); - } - - function extractLineClasses(type, output) { - if (type) for (;;) { - var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/); - if (!lineClass) break; - type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length); - var prop = lineClass[1] ? "bgClass" : "textClass"; - if (output[prop] == null) - output[prop] = lineClass[2]; - else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop])) - output[prop] += " " + lineClass[2]; - } - return type; - } - - function callBlankLine(mode, state) { - if (mode.blankLine) return mode.blankLine(state); - if (!mode.innerMode) return; - var inner = CodeMirror.innerMode(mode, state); - if (inner.mode.blankLine) return inner.mode.blankLine(inner.state); - } - - function readToken(mode, stream, state) { - for (var i = 0; i < 10; i++) { - var style = mode.token(stream, state); - if (stream.pos > stream.start) return style; - } - throw new Error("Mode " + mode.name + " failed to advance stream."); - } - - // Run the given mode's parser over a line, calling f for each token. - function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) { - var flattenSpans = mode.flattenSpans; - if (flattenSpans == null) flattenSpans = cm.options.flattenSpans; - var curStart = 0, curStyle = null; - var stream = new StringStream(text, cm.options.tabSize), style; - if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses); - while (!stream.eol()) { - if (stream.pos > cm.options.maxHighlightLength) { - flattenSpans = false; - if (forceToEnd) processLine(cm, text, state, stream.pos); - stream.pos = text.length; - style = null; - } else { - style = extractLineClasses(readToken(mode, stream, state), lineClasses); - } - if (cm.options.addModeClass) { - var mName = CodeMirror.innerMode(mode, state).mode.name; - if (mName) style = "m-" + (style ? mName + " " + style : mName); - } - if (!flattenSpans || curStyle != style) { - if (curStart < stream.start) f(stream.start, curStyle); - curStart = stream.start; curStyle = style; - } - stream.start = stream.pos; - } - while (curStart < stream.pos) { - // Webkit seems to refuse to render text nodes longer than 57444 characters - var pos = Math.min(stream.pos, curStart + 50000); - f(pos, curStyle); - curStart = pos; - } - } - - // Compute a style array (an array starting with a mode generation - // -- for invalidation -- followed by pairs of end positions and - // style strings), which is used to highlight the tokens on the - // line. - function highlightLine(cm, line, state, forceToEnd) { - // A styles array always starts with a number identifying the - // mode/overlays that it is based on (for easy invalidation). - var st = [cm.state.modeGen], lineClasses = {}; - // Compute the base array of styles - runMode(cm, line.text, cm.doc.mode, state, function(end, style) { - st.push(end, style); - }, lineClasses, forceToEnd); - - // Run overlays, adjust style array. - for (var o = 0; o < cm.state.overlays.length; ++o) { - var overlay = cm.state.overlays[o], i = 1, at = 0; - runMode(cm, line.text, overlay.mode, true, function(end, style) { - var start = i; - // Ensure there's a token end at the current position, and that i points at it - while (at < end) { - var i_end = st[i]; - if (i_end > end) - st.splice(i, 1, end, st[i+1], i_end); - i += 2; - at = Math.min(end, i_end); - } - if (!style) return; - if (overlay.opaque) { - st.splice(start, i - start, end, "cm-overlay " + style); - i = start + 2; - } else { - for (; start < i; start += 2) { - var cur = st[start+1]; - st[start+1] = (cur ? cur + " " : "") + "cm-overlay " + style; - } - } - }, lineClasses); - } - - return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null}; - } - - function getLineStyles(cm, line) { - if (!line.styles || line.styles[0] != cm.state.modeGen) { - var result = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line))); - line.styles = result.styles; - if (result.classes) line.styleClasses = result.classes; - else if (line.styleClasses) line.styleClasses = null; - } - return line.styles; - } - - // Lightweight form of highlight -- proceed over this line and - // update state, but don't save a style array. Used for lines that - // aren't currently visible. - function processLine(cm, text, state, startAt) { - var mode = cm.doc.mode; - var stream = new StringStream(text, cm.options.tabSize); - stream.start = stream.pos = startAt || 0; - if (text == "") callBlankLine(mode, state); - while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) { - readToken(mode, stream, state); - stream.start = stream.pos; - } - } - - // Convert a style as returned by a mode (either null, or a string - // containing one or more styles) to a CSS style. This is cached, - // and also looks for line-wide styles. - var styleToClassCache = {}, styleToClassCacheWithMode = {}; - function interpretTokenStyle(style, options) { - if (!style || /^\s*$/.test(style)) return null; - var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache; - return cache[style] || - (cache[style] = style.replace(/\S+/g, "cm-$&")); - } - - // Render the DOM representation of the text of a line. Also builds - // up a 'line map', which points at the DOM nodes that represent - // specific stretches of text, and is used by the measuring code. - // The returned object contains the DOM node, this map, and - // information about line-wide styles that were set by the mode. - function buildLineContent(cm, lineView) { - // The padding-right forces the element to have a 'border', which - // is needed on Webkit to be able to get line-level bounding - // rectangles for it (in measureChar). - var content = elt("span", null, null, webkit ? "padding-right: .1px" : null); - var builder = {pre: elt("pre", [content]), content: content, col: 0, pos: 0, cm: cm}; - lineView.measure = {}; - - // Iterate over the logical lines that make up this visual line. - for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) { - var line = i ? lineView.rest[i - 1] : lineView.line, order; - builder.pos = 0; - builder.addToken = buildToken; - // Optionally wire in some hacks into the token-rendering - // algorithm, to deal with browser quirks. - if ((ie || webkit) && cm.getOption("lineWrapping")) - builder.addToken = buildTokenSplitSpaces(builder.addToken); - if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line))) - builder.addToken = buildTokenBadBidi(builder.addToken, order); - builder.map = []; - insertLineContent(line, builder, getLineStyles(cm, line)); - if (line.styleClasses) { - if (line.styleClasses.bgClass) - builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || ""); - if (line.styleClasses.textClass) - builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || ""); - } - - // Ensure at least a single node is present, for measuring. - if (builder.map.length == 0) - builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure))); - - // Store the map and a cache object for the current logical line - if (i == 0) { - lineView.measure.map = builder.map; - lineView.measure.cache = {}; - } else { - (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map); - (lineView.measure.caches || (lineView.measure.caches = [])).push({}); - } - } - - signal(cm, "renderLine", cm, lineView.line, builder.pre); - if (builder.pre.className) - builder.textClass = joinClasses(builder.pre.className, builder.textClass || ""); - return builder; - } - - function defaultSpecialCharPlaceholder(ch) { - var token = elt("span", "\u2022", "cm-invalidchar"); - token.title = "\\u" + ch.charCodeAt(0).toString(16); - return token; - } - - // Build up the DOM representation for a single token, and add it to - // the line map. Takes care to render special characters separately. - function buildToken(builder, text, style, startStyle, endStyle, title) { - if (!text) return; - var special = builder.cm.options.specialChars, mustWrap = false; - if (!special.test(text)) { - builder.col += text.length; - var content = document.createTextNode(text); - builder.map.push(builder.pos, builder.pos + text.length, content); - if (ie && ie_version < 9) mustWrap = true; - builder.pos += text.length; - } else { - var content = document.createDocumentFragment(), pos = 0; - while (true) { - special.lastIndex = pos; - var m = special.exec(text); - var skipped = m ? m.index - pos : text.length - pos; - if (skipped) { - var txt = document.createTextNode(text.slice(pos, pos + skipped)); - if (ie && ie_version < 9) content.appendChild(elt("span", [txt])); - else content.appendChild(txt); - builder.map.push(builder.pos, builder.pos + skipped, txt); - builder.col += skipped; - builder.pos += skipped; - } - if (!m) break; - pos += skipped + 1; - if (m[0] == "\t") { - var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize; - var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab")); - builder.col += tabWidth; - } else { - var txt = builder.cm.options.specialCharPlaceholder(m[0]); - if (ie && ie_version < 9) content.appendChild(elt("span", [txt])); - else content.appendChild(txt); - builder.col += 1; - } - builder.map.push(builder.pos, builder.pos + 1, txt); - builder.pos++; - } - } - if (style || startStyle || endStyle || mustWrap) { - var fullStyle = style || ""; - if (startStyle) fullStyle += startStyle; - if (endStyle) fullStyle += endStyle; - var token = elt("span", [content], fullStyle); - if (title) token.title = title; - return builder.content.appendChild(token); - } - builder.content.appendChild(content); - } - - function buildTokenSplitSpaces(inner) { - function split(old) { - var out = " "; - for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0"; - out += " "; - return out; - } - return function(builder, text, style, startStyle, endStyle, title) { - inner(builder, text.replace(/ {3,}/g, split), style, startStyle, endStyle, title); - }; - } - - // Work around nonsense dimensions being reported for stretches of - // right-to-left text. - function buildTokenBadBidi(inner, order) { - return function(builder, text, style, startStyle, endStyle, title) { - style = style ? style + " cm-force-border" : "cm-force-border"; - var start = builder.pos, end = start + text.length; - for (;;) { - // Find the part that overlaps with the start of this text - for (var i = 0; i < order.length; i++) { - var part = order[i]; - if (part.to > start && part.from <= start) break; - } - if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title); - inner(builder, text.slice(0, part.to - start), style, startStyle, null, title); - startStyle = null; - text = text.slice(part.to - start); - start = part.to; - } - }; - } - - function buildCollapsedSpan(builder, size, marker, ignoreWidget) { - var widget = !ignoreWidget && marker.widgetNode; - if (widget) { - builder.map.push(builder.pos, builder.pos + size, widget); - builder.content.appendChild(widget); - } - builder.pos += size; - } - - // Outputs a number of spans to make up a line, taking highlighting - // and marked text into account. - function insertLineContent(line, builder, styles) { - var spans = line.markedSpans, allText = line.text, at = 0; - if (!spans) { - for (var i = 1; i < styles.length; i+=2) - builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder.cm.options)); - return; - } - - var len = allText.length, pos = 0, i = 1, text = "", style; - var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed; - for (;;) { - if (nextChange == pos) { // Update current marker set - spanStyle = spanEndStyle = spanStartStyle = title = ""; - collapsed = null; nextChange = Infinity; - var foundBookmarks = []; - for (var j = 0; j < spans.length; ++j) { - var sp = spans[j], m = sp.marker; - if (sp.from <= pos && (sp.to == null || sp.to > pos)) { - if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = ""; } - if (m.className) spanStyle += " " + m.className; - if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle; - if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle; - if (m.title && !title) title = m.title; - if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0)) - collapsed = sp; - } else if (sp.from > pos && nextChange > sp.from) { - nextChange = sp.from; - } - if (m.type == "bookmark" && sp.from == pos && m.widgetNode) foundBookmarks.push(m); - } - if (collapsed && (collapsed.from || 0) == pos) { - buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos, - collapsed.marker, collapsed.from == null); - if (collapsed.to == null) return; - } - if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j) - buildCollapsedSpan(builder, 0, foundBookmarks[j]); - } - if (pos >= len) break; - - var upto = Math.min(len, nextChange); - while (true) { - if (text) { - var end = pos + text.length; - if (!collapsed) { - var tokenText = end > upto ? text.slice(0, upto - pos) : text; - builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle, - spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title); - } - if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;} - pos = end; - spanStartStyle = ""; - } - text = allText.slice(at, at = styles[i++]); - style = interpretTokenStyle(styles[i++], builder.cm.options); - } - } - } - - // DOCUMENT DATA STRUCTURE - - // By default, updates that start and end at the beginning of a line - // are treated specially, in order to make the association of line - // widgets and marker elements with the text behave more intuitive. - function isWholeLineUpdate(doc, change) { - return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" && - (!doc.cm || doc.cm.options.wholeLineUpdateBefore); - } - - // Perform a change on the document data structure. - function updateDoc(doc, change, markedSpans, estimateHeight) { - function spansFor(n) {return markedSpans ? markedSpans[n] : null;} - function update(line, text, spans) { - updateLine(line, text, spans, estimateHeight); - signalLater(line, "change", line, change); - } - - var from = change.from, to = change.to, text = change.text; - var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line); - var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line; - - // Adjust the line structure - if (isWholeLineUpdate(doc, change)) { - // This is a whole-line replace. Treated specially to make - // sure line objects move the way they are supposed to. - for (var i = 0, added = []; i < text.length - 1; ++i) - added.push(new Line(text[i], spansFor(i), estimateHeight)); - update(lastLine, lastLine.text, lastSpans); - if (nlines) doc.remove(from.line, nlines); - if (added.length) doc.insert(from.line, added); - } else if (firstLine == lastLine) { - if (text.length == 1) { - update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans); - } else { - for (var added = [], i = 1; i < text.length - 1; ++i) - added.push(new Line(text[i], spansFor(i), estimateHeight)); - added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)); - update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); - doc.insert(from.line + 1, added); - } - } else if (text.length == 1) { - update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)); - doc.remove(from.line + 1, nlines); - } else { - update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)); - update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans); - for (var i = 1, added = []; i < text.length - 1; ++i) - added.push(new Line(text[i], spansFor(i), estimateHeight)); - if (nlines > 1) doc.remove(from.line + 1, nlines - 1); - doc.insert(from.line + 1, added); - } - - signalLater(doc, "change", doc, change); - } - - // The document is represented as a BTree consisting of leaves, with - // chunk of lines in them, and branches, with up to ten leaves or - // other branch nodes below them. The top node is always a branch - // node, and is the document object itself (meaning it has - // additional methods and properties). - // - // All nodes have parent links. The tree is used both to go from - // line numbers to line objects, and to go from objects to numbers. - // It also indexes by height, and is used to convert between height - // and line object, and to find the total height of the document. - // - // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html - - function LeafChunk(lines) { - this.lines = lines; - this.parent = null; - for (var i = 0, height = 0; i < lines.length; ++i) { - lines[i].parent = this; - height += lines[i].height; - } - this.height = height; - } - - LeafChunk.prototype = { - chunkSize: function() { return this.lines.length; }, - // Remove the n lines at offset 'at'. - removeInner: function(at, n) { - for (var i = at, e = at + n; i < e; ++i) { - var line = this.lines[i]; - this.height -= line.height; - cleanUpLine(line); - signalLater(line, "delete"); - } - this.lines.splice(at, n); - }, - // Helper used to collapse a small branch into a single leaf. - collapse: function(lines) { - lines.push.apply(lines, this.lines); - }, - // Insert the given array of lines at offset 'at', count them as - // having the given height. - insertInner: function(at, lines, height) { - this.height += height; - this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at)); - for (var i = 0; i < lines.length; ++i) lines[i].parent = this; - }, - // Used to iterate over a part of the tree. - iterN: function(at, n, op) { - for (var e = at + n; at < e; ++at) - if (op(this.lines[at])) return true; - } - }; - - function BranchChunk(children) { - this.children = children; - var size = 0, height = 0; - for (var i = 0; i < children.length; ++i) { - var ch = children[i]; - size += ch.chunkSize(); height += ch.height; - ch.parent = this; - } - this.size = size; - this.height = height; - this.parent = null; - } - - BranchChunk.prototype = { - chunkSize: function() { return this.size; }, - removeInner: function(at, n) { - this.size -= n; - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at < sz) { - var rm = Math.min(n, sz - at), oldHeight = child.height; - child.removeInner(at, rm); - this.height -= oldHeight - child.height; - if (sz == rm) { this.children.splice(i--, 1); child.parent = null; } - if ((n -= rm) == 0) break; - at = 0; - } else at -= sz; - } - // If the result is smaller than 25 lines, ensure that it is a - // single leaf node. - if (this.size - n < 25 && - (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) { - var lines = []; - this.collapse(lines); - this.children = [new LeafChunk(lines)]; - this.children[0].parent = this; - } - }, - collapse: function(lines) { - for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines); - }, - insertInner: function(at, lines, height) { - this.size += lines.length; - this.height += height; - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at <= sz) { - child.insertInner(at, lines, height); - if (child.lines && child.lines.length > 50) { - while (child.lines.length > 50) { - var spilled = child.lines.splice(child.lines.length - 25, 25); - var newleaf = new LeafChunk(spilled); - child.height -= newleaf.height; - this.children.splice(i + 1, 0, newleaf); - newleaf.parent = this; - } - this.maybeSpill(); - } - break; - } - at -= sz; - } - }, - // When a node has grown, check whether it should be split. - maybeSpill: function() { - if (this.children.length <= 10) return; - var me = this; - do { - var spilled = me.children.splice(me.children.length - 5, 5); - var sibling = new BranchChunk(spilled); - if (!me.parent) { // Become the parent node - var copy = new BranchChunk(me.children); - copy.parent = me; - me.children = [copy, sibling]; - me = copy; - } else { - me.size -= sibling.size; - me.height -= sibling.height; - var myIndex = indexOf(me.parent.children, me); - me.parent.children.splice(myIndex + 1, 0, sibling); - } - sibling.parent = me.parent; - } while (me.children.length > 10); - me.parent.maybeSpill(); - }, - iterN: function(at, n, op) { - for (var i = 0; i < this.children.length; ++i) { - var child = this.children[i], sz = child.chunkSize(); - if (at < sz) { - var used = Math.min(n, sz - at); - if (child.iterN(at, used, op)) return true; - if ((n -= used) == 0) break; - at = 0; - } else at -= sz; - } - } - }; - - var nextDocId = 0; - var Doc = CodeMirror.Doc = function(text, mode, firstLine) { - if (!(this instanceof Doc)) return new Doc(text, mode, firstLine); - if (firstLine == null) firstLine = 0; - - BranchChunk.call(this, [new LeafChunk([new Line("", null)])]); - this.first = firstLine; - this.scrollTop = this.scrollLeft = 0; - this.cantEdit = false; - this.cleanGeneration = 1; - this.frontier = firstLine; - var start = Pos(firstLine, 0); - this.sel = simpleSelection(start); - this.history = new History(null); - this.id = ++nextDocId; - this.modeOption = mode; - - if (typeof text == "string") text = splitLines(text); - updateDoc(this, {from: start, to: start, text: text}); - setSelection(this, simpleSelection(start), sel_dontScroll); - }; - - Doc.prototype = createObj(BranchChunk.prototype, { - constructor: Doc, - // Iterate over the document. Supports two forms -- with only one - // argument, it calls that for each line in the document. With - // three, it iterates over the range given by the first two (with - // the second being non-inclusive). - iter: function(from, to, op) { - if (op) this.iterN(from - this.first, to - from, op); - else this.iterN(this.first, this.first + this.size, from); - }, - - // Non-public interface for adding and removing lines. - insert: function(at, lines) { - var height = 0; - for (var i = 0; i < lines.length; ++i) height += lines[i].height; - this.insertInner(at - this.first, lines, height); - }, - remove: function(at, n) { this.removeInner(at - this.first, n); }, - - // From here, the methods are part of the public interface. Most - // are also available from CodeMirror (editor) instances. - - getValue: function(lineSep) { - var lines = getLines(this, this.first, this.first + this.size); - if (lineSep === false) return lines; - return lines.join(lineSep || "\n"); - }, - setValue: docMethodOp(function(code) { - var top = Pos(this.first, 0), last = this.first + this.size - 1; - makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length), - text: splitLines(code), origin: "setValue"}, true); - setSelection(this, simpleSelection(top)); - }), - replaceRange: function(code, from, to, origin) { - from = clipPos(this, from); - to = to ? clipPos(this, to) : from; - replaceRange(this, code, from, to, origin); - }, - getRange: function(from, to, lineSep) { - var lines = getBetween(this, clipPos(this, from), clipPos(this, to)); - if (lineSep === false) return lines; - return lines.join(lineSep || "\n"); - }, - - getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;}, - - getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);}, - getLineNumber: function(line) {return lineNo(line);}, - - getLineHandleVisualStart: function(line) { - if (typeof line == "number") line = getLine(this, line); - return visualLine(line); - }, - - lineCount: function() {return this.size;}, - firstLine: function() {return this.first;}, - lastLine: function() {return this.first + this.size - 1;}, - - clipPos: function(pos) {return clipPos(this, pos);}, - - getCursor: function(start) { - var range = this.sel.primary(), pos; - if (start == null || start == "head") pos = range.head; - else if (start == "anchor") pos = range.anchor; - else if (start == "end" || start == "to" || start === false) pos = range.to(); - else pos = range.from(); - return pos; - }, - listSelections: function() { return this.sel.ranges; }, - somethingSelected: function() {return this.sel.somethingSelected();}, - - setCursor: docMethodOp(function(line, ch, options) { - setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options); - }), - setSelection: docMethodOp(function(anchor, head, options) { - setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options); - }), - extendSelection: docMethodOp(function(head, other, options) { - extendSelection(this, clipPos(this, head), other && clipPos(this, other), options); - }), - extendSelections: docMethodOp(function(heads, options) { - extendSelections(this, clipPosArray(this, heads, options)); - }), - extendSelectionsBy: docMethodOp(function(f, options) { - extendSelections(this, map(this.sel.ranges, f), options); - }), - setSelections: docMethodOp(function(ranges, primary, options) { - if (!ranges.length) return; - for (var i = 0, out = []; i < ranges.length; i++) - out[i] = new Range(clipPos(this, ranges[i].anchor), - clipPos(this, ranges[i].head)); - if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex); - setSelection(this, normalizeSelection(out, primary), options); - }), - addSelection: docMethodOp(function(anchor, head, options) { - var ranges = this.sel.ranges.slice(0); - ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor))); - setSelection(this, normalizeSelection(ranges, ranges.length - 1), options); - }), - - getSelection: function(lineSep) { - var ranges = this.sel.ranges, lines; - for (var i = 0; i < ranges.length; i++) { - var sel = getBetween(this, ranges[i].from(), ranges[i].to()); - lines = lines ? lines.concat(sel) : sel; - } - if (lineSep === false) return lines; - else return lines.join(lineSep || "\n"); - }, - getSelections: function(lineSep) { - var parts = [], ranges = this.sel.ranges; - for (var i = 0; i < ranges.length; i++) { - var sel = getBetween(this, ranges[i].from(), ranges[i].to()); - if (lineSep !== false) sel = sel.join(lineSep || "\n"); - parts[i] = sel; - } - return parts; - }, - replaceSelection: function(code, collapse, origin) { - var dup = []; - for (var i = 0; i < this.sel.ranges.length; i++) - dup[i] = code; - this.replaceSelections(dup, collapse, origin || "+input"); - }, - replaceSelections: docMethodOp(function(code, collapse, origin) { - var changes = [], sel = this.sel; - for (var i = 0; i < sel.ranges.length; i++) { - var range = sel.ranges[i]; - changes[i] = {from: range.from(), to: range.to(), text: splitLines(code[i]), origin: origin}; - } - var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse); - for (var i = changes.length - 1; i >= 0; i--) - makeChange(this, changes[i]); - if (newSel) setSelectionReplaceHistory(this, newSel); - else if (this.cm) ensureCursorVisible(this.cm); - }), - undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}), - redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}), - undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}), - redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}), - - setExtending: function(val) {this.extend = val;}, - getExtending: function() {return this.extend;}, - - historySize: function() { - var hist = this.history, done = 0, undone = 0; - for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done; - for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone; - return {undo: done, redo: undone}; - }, - clearHistory: function() {this.history = new History(this.history.maxGeneration);}, - - markClean: function() { - this.cleanGeneration = this.changeGeneration(true); - }, - changeGeneration: function(forceSplit) { - if (forceSplit) - this.history.lastOp = this.history.lastOrigin = null; - return this.history.generation; - }, - isClean: function (gen) { - return this.history.generation == (gen || this.cleanGeneration); - }, - - getHistory: function() { - return {done: copyHistoryArray(this.history.done), - undone: copyHistoryArray(this.history.undone)}; - }, - setHistory: function(histData) { - var hist = this.history = new History(this.history.maxGeneration); - hist.done = copyHistoryArray(histData.done.slice(0), null, true); - hist.undone = copyHistoryArray(histData.undone.slice(0), null, true); - }, - - addLineClass: docMethodOp(function(handle, where, cls) { - return changeLine(this, handle, "class", function(line) { - var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass"; - if (!line[prop]) line[prop] = cls; - else if (new RegExp("(?:^|\\s)" + cls + "(?:$|\\s)").test(line[prop])) return false; - else line[prop] += " " + cls; - return true; - }); - }), - removeLineClass: docMethodOp(function(handle, where, cls) { - return changeLine(this, handle, "class", function(line) { - var prop = where == "text" ? "textClass" : where == "background" ? "bgClass" : "wrapClass"; - var cur = line[prop]; - if (!cur) return false; - else if (cls == null) line[prop] = null; - else { - var found = cur.match(new RegExp("(?:^|\\s+)" + cls + "(?:$|\\s+)")); - if (!found) return false; - var end = found.index + found[0].length; - line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null; - } - return true; - }); - }), - - markText: function(from, to, options) { - return markText(this, clipPos(this, from), clipPos(this, to), options, "range"); - }, - setBookmark: function(pos, options) { - var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options), - insertLeft: options && options.insertLeft, - clearWhenEmpty: false, shared: options && options.shared}; - pos = clipPos(this, pos); - return markText(this, pos, pos, realOpts, "bookmark"); - }, - findMarksAt: function(pos) { - pos = clipPos(this, pos); - var markers = [], spans = getLine(this, pos.line).markedSpans; - if (spans) for (var i = 0; i < spans.length; ++i) { - var span = spans[i]; - if ((span.from == null || span.from <= pos.ch) && - (span.to == null || span.to >= pos.ch)) - markers.push(span.marker.parent || span.marker); - } - return markers; - }, - findMarks: function(from, to, filter) { - from = clipPos(this, from); to = clipPos(this, to); - var found = [], lineNo = from.line; - this.iter(from.line, to.line + 1, function(line) { - var spans = line.markedSpans; - if (spans) for (var i = 0; i < spans.length; i++) { - var span = spans[i]; - if (!(lineNo == from.line && from.ch > span.to || - span.from == null && lineNo != from.line|| - lineNo == to.line && span.from > to.ch) && - (!filter || filter(span.marker))) - found.push(span.marker.parent || span.marker); - } - ++lineNo; - }); - return found; - }, - getAllMarks: function() { - var markers = []; - this.iter(function(line) { - var sps = line.markedSpans; - if (sps) for (var i = 0; i < sps.length; ++i) - if (sps[i].from != null) markers.push(sps[i].marker); - }); - return markers; - }, - - posFromIndex: function(off) { - var ch, lineNo = this.first; - this.iter(function(line) { - var sz = line.text.length + 1; - if (sz > off) { ch = off; return true; } - off -= sz; - ++lineNo; - }); - return clipPos(this, Pos(lineNo, ch)); - }, - indexFromPos: function (coords) { - coords = clipPos(this, coords); - var index = coords.ch; - if (coords.line < this.first || coords.ch < 0) return 0; - this.iter(this.first, coords.line, function (line) { - index += line.text.length + 1; - }); - return index; - }, - - copy: function(copyHistory) { - var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first); - doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft; - doc.sel = this.sel; - doc.extend = false; - if (copyHistory) { - doc.history.undoDepth = this.history.undoDepth; - doc.setHistory(this.getHistory()); - } - return doc; - }, - - linkedDoc: function(options) { - if (!options) options = {}; - var from = this.first, to = this.first + this.size; - if (options.from != null && options.from > from) from = options.from; - if (options.to != null && options.to < to) to = options.to; - var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from); - if (options.sharedHist) copy.history = this.history; - (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist}); - copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}]; - copySharedMarkers(copy, findSharedMarkers(this)); - return copy; - }, - unlinkDoc: function(other) { - if (other instanceof CodeMirror) other = other.doc; - if (this.linked) for (var i = 0; i < this.linked.length; ++i) { - var link = this.linked[i]; - if (link.doc != other) continue; - this.linked.splice(i, 1); - other.unlinkDoc(this); - detachSharedMarkers(findSharedMarkers(this)); - break; - } - // If the histories were shared, split them again - if (other.history == this.history) { - var splitIds = [other.id]; - linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true); - other.history = new History(null); - other.history.done = copyHistoryArray(this.history.done, splitIds); - other.history.undone = copyHistoryArray(this.history.undone, splitIds); - } - }, - iterLinkedDocs: function(f) {linkedDocs(this, f);}, - - getMode: function() {return this.mode;}, - getEditor: function() {return this.cm;} - }); - - // Public alias. - Doc.prototype.eachLine = Doc.prototype.iter; - - // Set up methods on CodeMirror's prototype to redirect to the editor's document. - var dontDelegate = "iter insert remove copy getEditor".split(" "); - for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0) - CodeMirror.prototype[prop] = (function(method) { - return function() {return method.apply(this.doc, arguments);}; - })(Doc.prototype[prop]); - - eventMixin(Doc); - - // Call f for all linked documents. - function linkedDocs(doc, f, sharedHistOnly) { - function propagate(doc, skip, sharedHist) { - if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) { - var rel = doc.linked[i]; - if (rel.doc == skip) continue; - var shared = sharedHist && rel.sharedHist; - if (sharedHistOnly && !shared) continue; - f(rel.doc, shared); - propagate(rel.doc, doc, shared); - } - } - propagate(doc, null, true); - } - - // Attach a document to an editor. - function attachDoc(cm, doc) { - if (doc.cm) throw new Error("This document is already in use."); - cm.doc = doc; - doc.cm = cm; - estimateLineHeights(cm); - loadMode(cm); - if (!cm.options.lineWrapping) findMaxLine(cm); - cm.options.mode = doc.modeOption; - regChange(cm); - } - - // LINE UTILITIES - - // Find the line object corresponding to the given line number. - function getLine(doc, n) { - n -= doc.first; - if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document."); - for (var chunk = doc; !chunk.lines;) { - for (var i = 0;; ++i) { - var child = chunk.children[i], sz = child.chunkSize(); - if (n < sz) { chunk = child; break; } - n -= sz; - } - } - return chunk.lines[n]; - } - - // Get the part of a document between two positions, as an array of - // strings. - function getBetween(doc, start, end) { - var out = [], n = start.line; - doc.iter(start.line, end.line + 1, function(line) { - var text = line.text; - if (n == end.line) text = text.slice(0, end.ch); - if (n == start.line) text = text.slice(start.ch); - out.push(text); - ++n; - }); - return out; - } - // Get the lines between from and to, as array of strings. - function getLines(doc, from, to) { - var out = []; - doc.iter(from, to, function(line) { out.push(line.text); }); - return out; - } - - // Update the height of a line, propagating the height change - // upwards to parent nodes. - function updateLineHeight(line, height) { - var diff = height - line.height; - if (diff) for (var n = line; n; n = n.parent) n.height += diff; - } - - // Given a line object, find its line number by walking up through - // its parent links. - function lineNo(line) { - if (line.parent == null) return null; - var cur = line.parent, no = indexOf(cur.lines, line); - for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) { - for (var i = 0;; ++i) { - if (chunk.children[i] == cur) break; - no += chunk.children[i].chunkSize(); - } - } - return no + cur.first; - } - - // Find the line at the given vertical position, using the height - // information in the document tree. - function lineAtHeight(chunk, h) { - var n = chunk.first; - outer: do { - for (var i = 0; i < chunk.children.length; ++i) { - var child = chunk.children[i], ch = child.height; - if (h < ch) { chunk = child; continue outer; } - h -= ch; - n += child.chunkSize(); - } - return n; - } while (!chunk.lines); - for (var i = 0; i < chunk.lines.length; ++i) { - var line = chunk.lines[i], lh = line.height; - if (h < lh) break; - h -= lh; - } - return n + i; - } - - - // Find the height above the given line. - function heightAtLine(lineObj) { - lineObj = visualLine(lineObj); - - var h = 0, chunk = lineObj.parent; - for (var i = 0; i < chunk.lines.length; ++i) { - var line = chunk.lines[i]; - if (line == lineObj) break; - else h += line.height; - } - for (var p = chunk.parent; p; chunk = p, p = chunk.parent) { - for (var i = 0; i < p.children.length; ++i) { - var cur = p.children[i]; - if (cur == chunk) break; - else h += cur.height; - } - } - return h; - } - - // Get the bidi ordering for the given line (and cache it). Returns - // false for lines that are fully left-to-right, and an array of - // BidiSpan objects otherwise. - function getOrder(line) { - var order = line.order; - if (order == null) order = line.order = bidiOrdering(line.text); - return order; - } - - // HISTORY - - function History(startGen) { - // Arrays of change events and selections. Doing something adds an - // event to done and clears undo. Undoing moves events from done - // to undone, redoing moves them in the other direction. - this.done = []; this.undone = []; - this.undoDepth = Infinity; - // Used to track when changes can be merged into a single undo - // event - this.lastModTime = this.lastSelTime = 0; - this.lastOp = null; - this.lastOrigin = this.lastSelOrigin = null; - // Used by the isClean() method - this.generation = this.maxGeneration = startGen || 1; - } - - // Create a history change event from an updateDoc-style change - // object. - function historyChangeFromChange(doc, change) { - var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)}; - attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1); - linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true); - return histChange; - } - - // Pop all selection events off the end of a history array. Stop at - // a change event. - function clearSelectionEvents(array) { - while (array.length) { - var last = lst(array); - if (last.ranges) array.pop(); - else break; - } - } - - // Find the top change event in the history. Pop off selection - // events that are in the way. - function lastChangeEvent(hist, force) { - if (force) { - clearSelectionEvents(hist.done); - return lst(hist.done); - } else if (hist.done.length && !lst(hist.done).ranges) { - return lst(hist.done); - } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) { - hist.done.pop(); - return lst(hist.done); - } - } - - // Register a change in the history. Merges changes that are within - // a single operation, ore are close together with an origin that - // allows merging (starting with "+") into a single event. - function addChangeToHistory(doc, change, selAfter, opId) { - var hist = doc.history; - hist.undone.length = 0; - var time = +new Date, cur; - - if ((hist.lastOp == opId || - hist.lastOrigin == change.origin && change.origin && - ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) || - change.origin.charAt(0) == "*")) && - (cur = lastChangeEvent(hist, hist.lastOp == opId))) { - // Merge this change into the last event - var last = lst(cur.changes); - if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) { - // Optimized case for simple insertion -- don't want to add - // new changesets for every character typed - last.to = changeEnd(change); - } else { - // Add new sub-event - cur.changes.push(historyChangeFromChange(doc, change)); - } - } else { - // Can not be merged, start a new event. - var before = lst(hist.done); - if (!before || !before.ranges) - pushSelectionToHistory(doc.sel, hist.done); - cur = {changes: [historyChangeFromChange(doc, change)], - generation: hist.generation}; - hist.done.push(cur); - while (hist.done.length > hist.undoDepth) { - hist.done.shift(); - if (!hist.done[0].ranges) hist.done.shift(); - } - } - hist.done.push(selAfter); - hist.generation = ++hist.maxGeneration; - hist.lastModTime = hist.lastSelTime = time; - hist.lastOp = opId; - hist.lastOrigin = hist.lastSelOrigin = change.origin; - - if (!last) signal(doc, "historyAdded"); - } - - function selectionEventCanBeMerged(doc, origin, prev, sel) { - var ch = origin.charAt(0); - return ch == "*" || - ch == "+" && - prev.ranges.length == sel.ranges.length && - prev.somethingSelected() == sel.somethingSelected() && - new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500); - } - - // Called whenever the selection changes, sets the new selection as - // the pending selection in the history, and pushes the old pending - // selection into the 'done' array when it was significantly - // different (in number of selected ranges, emptiness, or time). - function addSelectionToHistory(doc, sel, opId, options) { - var hist = doc.history, origin = options && options.origin; - - // A new event is started when the previous origin does not match - // the current, or the origins don't allow matching. Origins - // starting with * are always merged, those starting with + are - // merged when similar and close together in time. - if (opId == hist.lastOp || - (origin && hist.lastSelOrigin == origin && - (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin || - selectionEventCanBeMerged(doc, origin, lst(hist.done), sel)))) - hist.done[hist.done.length - 1] = sel; - else - pushSelectionToHistory(sel, hist.done); - - hist.lastSelTime = +new Date; - hist.lastSelOrigin = origin; - hist.lastOp = opId; - if (options && options.clearRedo !== false) - clearSelectionEvents(hist.undone); - } - - function pushSelectionToHistory(sel, dest) { - var top = lst(dest); - if (!(top && top.ranges && top.equals(sel))) - dest.push(sel); - } - - // Used to store marked span information in the history. - function attachLocalSpans(doc, change, from, to) { - var existing = change["spans_" + doc.id], n = 0; - doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) { - if (line.markedSpans) - (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans; - ++n; - }); - } - - // When un/re-doing restores text containing marked spans, those - // that have been explicitly cleared should not be restored. - function removeClearedSpans(spans) { - if (!spans) return null; - for (var i = 0, out; i < spans.length; ++i) { - if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); } - else if (out) out.push(spans[i]); - } - return !out ? spans : out.length ? out : null; - } - - // Retrieve and filter the old marked spans stored in a change event. - function getOldSpans(doc, change) { - var found = change["spans_" + doc.id]; - if (!found) return null; - for (var i = 0, nw = []; i < change.text.length; ++i) - nw.push(removeClearedSpans(found[i])); - return nw; - } - - // Used both to provide a JSON-safe object in .getHistory, and, when - // detaching a document, to split the history in two - function copyHistoryArray(events, newGroup, instantiateSel) { - for (var i = 0, copy = []; i < events.length; ++i) { - var event = events[i]; - if (event.ranges) { - copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event); - continue; - } - var changes = event.changes, newChanges = []; - copy.push({changes: newChanges}); - for (var j = 0; j < changes.length; ++j) { - var change = changes[j], m; - newChanges.push({from: change.from, to: change.to, text: change.text}); - if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) { - if (indexOf(newGroup, Number(m[1])) > -1) { - lst(newChanges)[prop] = change[prop]; - delete change[prop]; - } - } - } - } - return copy; - } - - // Rebasing/resetting history to deal with externally-sourced changes - - function rebaseHistSelSingle(pos, from, to, diff) { - if (to < pos.line) { - pos.line += diff; - } else if (from < pos.line) { - pos.line = from; - pos.ch = 0; - } - } - - // Tries to rebase an array of history events given a change in the - // document. If the change touches the same lines as the event, the - // event, and everything 'behind' it, is discarded. If the change is - // before the event, the event's positions are updated. Uses a - // copy-on-write scheme for the positions, to avoid having to - // reallocate them all on every rebase, but also avoid problems with - // shared position objects being unsafely updated. - function rebaseHistArray(array, from, to, diff) { - for (var i = 0; i < array.length; ++i) { - var sub = array[i], ok = true; - if (sub.ranges) { - if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; } - for (var j = 0; j < sub.ranges.length; j++) { - rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff); - rebaseHistSelSingle(sub.ranges[j].head, from, to, diff); - } - continue; - } - for (var j = 0; j < sub.changes.length; ++j) { - var cur = sub.changes[j]; - if (to < cur.from.line) { - cur.from = Pos(cur.from.line + diff, cur.from.ch); - cur.to = Pos(cur.to.line + diff, cur.to.ch); - } else if (from <= cur.to.line) { - ok = false; - break; - } - } - if (!ok) { - array.splice(0, i + 1); - i = 0; - } - } - } - - function rebaseHist(hist, change) { - var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1; - rebaseHistArray(hist.done, from, to, diff); - rebaseHistArray(hist.undone, from, to, diff); - } - - // EVENT UTILITIES - - // Due to the fact that we still support jurassic IE versions, some - // compatibility wrappers are needed. - - var e_preventDefault = CodeMirror.e_preventDefault = function(e) { - if (e.preventDefault) e.preventDefault(); - else e.returnValue = false; - }; - var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) { - if (e.stopPropagation) e.stopPropagation(); - else e.cancelBubble = true; - }; - function e_defaultPrevented(e) { - return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false; - } - var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);}; - - function e_target(e) {return e.target || e.srcElement;} - function e_button(e) { - var b = e.which; - if (b == null) { - if (e.button & 1) b = 1; - else if (e.button & 2) b = 3; - else if (e.button & 4) b = 2; - } - if (mac && e.ctrlKey && b == 1) b = 3; - return b; - } - - // EVENT HANDLING - - // Lightweight event framework. on/off also work on DOM nodes, - // registering native DOM handlers. - - var on = CodeMirror.on = function(emitter, type, f) { - if (emitter.addEventListener) - emitter.addEventListener(type, f, false); - else if (emitter.attachEvent) - emitter.attachEvent("on" + type, f); - else { - var map = emitter._handlers || (emitter._handlers = {}); - var arr = map[type] || (map[type] = []); - arr.push(f); - } - }; - - var off = CodeMirror.off = function(emitter, type, f) { - if (emitter.removeEventListener) - emitter.removeEventListener(type, f, false); - else if (emitter.detachEvent) - emitter.detachEvent("on" + type, f); - else { - var arr = emitter._handlers && emitter._handlers[type]; - if (!arr) return; - for (var i = 0; i < arr.length; ++i) - if (arr[i] == f) { arr.splice(i, 1); break; } - } - }; - - var signal = CodeMirror.signal = function(emitter, type /*, values...*/) { - var arr = emitter._handlers && emitter._handlers[type]; - if (!arr) return; - var args = Array.prototype.slice.call(arguments, 2); - for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args); - }; - - // Often, we want to signal events at a point where we are in the - // middle of some work, but don't want the handler to start calling - // other methods on the editor, which might be in an inconsistent - // state or simply not expect any other events to happen. - // signalLater looks whether there are any handlers, and schedules - // them to be executed when the last operation ends, or, if no - // operation is active, when a timeout fires. - var delayedCallbacks, delayedCallbackDepth = 0; - function signalLater(emitter, type /*, values...*/) { - var arr = emitter._handlers && emitter._handlers[type]; - if (!arr) return; - var args = Array.prototype.slice.call(arguments, 2); - if (!delayedCallbacks) { - ++delayedCallbackDepth; - delayedCallbacks = []; - setTimeout(fireDelayed, 0); - } - function bnd(f) {return function(){f.apply(null, args);};}; - for (var i = 0; i < arr.length; ++i) - delayedCallbacks.push(bnd(arr[i])); - } - - function fireDelayed() { - --delayedCallbackDepth; - var delayed = delayedCallbacks; - delayedCallbacks = null; - for (var i = 0; i < delayed.length; ++i) delayed[i](); - } - - // The DOM events that CodeMirror handles can be overridden by - // registering a (non-DOM) handler on the editor for the event name, - // and preventDefault-ing the event in that handler. - function signalDOMEvent(cm, e, override) { - signal(cm, override || e.type, cm, e); - return e_defaultPrevented(e) || e.codemirrorIgnore; - } - - function signalCursorActivity(cm) { - var arr = cm._handlers && cm._handlers.cursorActivity; - if (!arr) return; - var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []); - for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1) - set.push(arr[i]); - } - - function hasHandler(emitter, type) { - var arr = emitter._handlers && emitter._handlers[type]; - return arr && arr.length > 0; - } - - // Add on and off methods to a constructor's prototype, to make - // registering events on such objects more convenient. - function eventMixin(ctor) { - ctor.prototype.on = function(type, f) {on(this, type, f);}; - ctor.prototype.off = function(type, f) {off(this, type, f);}; - } - - // MISC UTILITIES - - // Number of pixels added to scroller and sizer to hide scrollbar - var scrollerCutOff = 30; - - // Returned or thrown by various protocols to signal 'I'm not - // handling this'. - var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}}; - - // Reused option objects for setSelection & friends - var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"}; - - function Delayed() {this.id = null;} - Delayed.prototype.set = function(ms, f) { - clearTimeout(this.id); - this.id = setTimeout(f, ms); - }; - - // Counts the column offset in a string, taking tabs into account. - // Used mostly to find indentation. - var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) { - if (end == null) { - end = string.search(/[^\s\u00a0]/); - if (end == -1) end = string.length; - } - for (var i = startIndex || 0, n = startValue || 0;;) { - var nextTab = string.indexOf("\t", i); - if (nextTab < 0 || nextTab >= end) - return n + (end - i); - n += nextTab - i; - n += tabSize - (n % tabSize); - i = nextTab + 1; - } - }; - - // The inverse of countColumn -- find the offset that corresponds to - // a particular column. - function findColumn(string, goal, tabSize) { - for (var pos = 0, col = 0;;) { - var nextTab = string.indexOf("\t", pos); - if (nextTab == -1) nextTab = string.length; - var skipped = nextTab - pos; - if (nextTab == string.length || col + skipped >= goal) - return pos + Math.min(skipped, goal - col); - col += nextTab - pos; - col += tabSize - (col % tabSize); - pos = nextTab + 1; - if (col >= goal) return pos; - } - } - - var spaceStrs = [""]; - function spaceStr(n) { - while (spaceStrs.length <= n) - spaceStrs.push(lst(spaceStrs) + " "); - return spaceStrs[n]; - } - - function lst(arr) { return arr[arr.length-1]; } - - var selectInput = function(node) { node.select(); }; - if (ios) // Mobile Safari apparently has a bug where select() is broken. - selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; }; - else if (ie) // Suppress mysterious IE10 errors - selectInput = function(node) { try { node.select(); } catch(_e) {} }; - - function indexOf(array, elt) { - for (var i = 0; i < array.length; ++i) - if (array[i] == elt) return i; - return -1; - } - if ([].indexOf) indexOf = function(array, elt) { return array.indexOf(elt); }; - function map(array, f) { - var out = []; - for (var i = 0; i < array.length; i++) out[i] = f(array[i], i); - return out; - } - if ([].map) map = function(array, f) { return array.map(f); }; - - function createObj(base, props) { - var inst; - if (Object.create) { - inst = Object.create(base); - } else { - var ctor = function() {}; - ctor.prototype = base; - inst = new ctor(); - } - if (props) copyObj(props, inst); - return inst; - }; - - function copyObj(obj, target, overwrite) { - if (!target) target = {}; - for (var prop in obj) - if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop))) - target[prop] = obj[prop]; - return target; - } - - function bind(f) { - var args = Array.prototype.slice.call(arguments, 1); - return function(){return f.apply(null, args);}; - } - - var nonASCIISingleCaseWordChar = /[\u00df\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; - var isWordCharBasic = CodeMirror.isWordChar = function(ch) { - return /\w/.test(ch) || ch > "\x80" && - (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)); - }; - function isWordChar(ch, helper) { - if (!helper) return isWordCharBasic(ch); - if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true; - return helper.test(ch); - } - - function isEmpty(obj) { - for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false; - return true; - } - - // Extending unicode characters. A series of a non-extending char + - // any number of extending chars is treated as a single unit as far - // as editing and measuring is concerned. This is not fully correct, - // since some scripts/fonts/browsers also treat other configurations - // of code points as a group. - var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/; - function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); } - - // DOM UTILITIES - - function elt(tag, content, className, style) { - var e = document.createElement(tag); - if (className) e.className = className; - if (style) e.style.cssText = style; - if (typeof content == "string") e.appendChild(document.createTextNode(content)); - else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]); - return e; - } - - var range; - if (document.createRange) range = function(node, start, end) { - var r = document.createRange(); - r.setEnd(node, end); - r.setStart(node, start); - return r; - }; - else range = function(node, start, end) { - var r = document.body.createTextRange(); - r.moveToElementText(node.parentNode); - r.collapse(true); - r.moveEnd("character", end); - r.moveStart("character", start); - return r; - }; - - function removeChildren(e) { - for (var count = e.childNodes.length; count > 0; --count) - e.removeChild(e.firstChild); - return e; - } - - function removeChildrenAndAdd(parent, e) { - return removeChildren(parent).appendChild(e); - } - - function contains(parent, child) { - if (parent.contains) - return parent.contains(child); - while (child = child.parentNode) - if (child == parent) return true; - } - - function activeElt() { return document.activeElement; } - // Older versions of IE throws unspecified error when touching - // document.activeElement in some cases (during loading, in iframe) - if (ie && ie_version < 11) activeElt = function() { - try { return document.activeElement; } - catch(e) { return document.body; } - }; - - function classTest(cls) { return new RegExp("\\b" + cls + "\\b\\s*"); } - function rmClass(node, cls) { - var test = classTest(cls); - if (test.test(node.className)) node.className = node.className.replace(test, ""); - } - function addClass(node, cls) { - if (!classTest(cls).test(node.className)) node.className += " " + cls; - } - function joinClasses(a, b) { - var as = a.split(" "); - for (var i = 0; i < as.length; i++) - if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i]; - return b; - } - - // WINDOW-WIDE EVENTS - - // These must be handled carefully, because naively registering a - // handler for each editor will cause the editors to never be - // garbage collected. - - function forEachCodeMirror(f) { - if (!document.body.getElementsByClassName) return; - var byClass = document.body.getElementsByClassName("CodeMirror"); - for (var i = 0; i < byClass.length; i++) { - var cm = byClass[i].CodeMirror; - if (cm) f(cm); - } - } - - var globalsRegistered = false; - function ensureGlobalHandlers() { - if (globalsRegistered) return; - registerGlobalHandlers(); - globalsRegistered = true; - } - function registerGlobalHandlers() { - // When the window resizes, we need to refresh active editors. - var resizeTimer; - on(window, "resize", function() { - if (resizeTimer == null) resizeTimer = setTimeout(function() { - resizeTimer = null; - knownScrollbarWidth = null; - forEachCodeMirror(onResize); - }, 100); - }); - // When the window loses focus, we want to show the editor as blurred - on(window, "blur", function() { - forEachCodeMirror(onBlur); - }); - } - - // FEATURE DETECTION - - // Detect drag-and-drop - var dragAndDrop = function() { - // There is *some* kind of drag-and-drop support in IE6-8, but I - // couldn't get it to work yet. - if (ie && ie_version < 9) return false; - var div = elt('div'); - return "draggable" in div || "dragDrop" in div; - }(); - - var knownScrollbarWidth; - function scrollbarWidth(measure) { - if (knownScrollbarWidth != null) return knownScrollbarWidth; - var test = elt("div", null, null, "width: 50px; height: 50px; overflow-x: scroll"); - removeChildrenAndAdd(measure, test); - if (test.offsetWidth) - knownScrollbarWidth = test.offsetHeight - test.clientHeight; - return knownScrollbarWidth || 0; - } - - var zwspSupported; - function zeroWidthElement(measure) { - if (zwspSupported == null) { - var test = elt("span", "\u200b"); - removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")])); - if (measure.firstChild.offsetHeight != 0) - zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8); - } - if (zwspSupported) return elt("span", "\u200b"); - else return elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px"); - } - - // Feature-detect IE's crummy client rect reporting for bidi text - var badBidiRects; - function hasBadBidiRects(measure) { - if (badBidiRects != null) return badBidiRects; - var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA")); - var r0 = range(txt, 0, 1).getBoundingClientRect(); - if (r0.left == r0.right) return false; - var r1 = range(txt, 1, 2).getBoundingClientRect(); - return badBidiRects = (r1.right - r0.right < 3); - } - - // See if "".split is the broken IE version, if so, provide an - // alternative way to split lines. - var splitLines = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) { - var pos = 0, result = [], l = string.length; - while (pos <= l) { - var nl = string.indexOf("\n", pos); - if (nl == -1) nl = string.length; - var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl); - var rt = line.indexOf("\r"); - if (rt != -1) { - result.push(line.slice(0, rt)); - pos += rt + 1; - } else { - result.push(line); - pos = nl + 1; - } - } - return result; - } : function(string){return string.split(/\r\n?|\n/);}; - - var hasSelection = window.getSelection ? function(te) { - try { return te.selectionStart != te.selectionEnd; } - catch(e) { return false; } - } : function(te) { - try {var range = te.ownerDocument.selection.createRange();} - catch(e) {} - if (!range || range.parentElement() != te) return false; - return range.compareEndPoints("StartToEnd", range) != 0; - }; - - var hasCopyEvent = (function() { - var e = elt("div"); - if ("oncopy" in e) return true; - e.setAttribute("oncopy", "return;"); - return typeof e.oncopy == "function"; - })(); - - // KEY NAMES - - var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt", - 19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", - 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert", - 46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", 107: "=", 109: "-", 127: "Delete", - 173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\", - 221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete", - 63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"}; - CodeMirror.keyNames = keyNames; - (function() { - // Number keys - for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i); - // Alphabetic keys - for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i); - // Function keys - for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i; - })(); - - // BIDI HELPERS - - function iterateBidiSections(order, from, to, f) { - if (!order) return f(from, to, "ltr"); - var found = false; - for (var i = 0; i < order.length; ++i) { - var part = order[i]; - if (part.from < to && part.to > from || from == to && part.to == from) { - f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr"); - found = true; - } - } - if (!found) f(from, to, "ltr"); - } - - function bidiLeft(part) { return part.level % 2 ? part.to : part.from; } - function bidiRight(part) { return part.level % 2 ? part.from : part.to; } - - function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; } - function lineRight(line) { - var order = getOrder(line); - if (!order) return line.text.length; - return bidiRight(lst(order)); - } - - function lineStart(cm, lineN) { - var line = getLine(cm.doc, lineN); - var visual = visualLine(line); - if (visual != line) lineN = lineNo(visual); - var order = getOrder(visual); - var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual); - return Pos(lineN, ch); - } - function lineEnd(cm, lineN) { - var merged, line = getLine(cm.doc, lineN); - while (merged = collapsedSpanAtEnd(line)) { - line = merged.find(1, true).line; - lineN = null; - } - var order = getOrder(line); - var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line); - return Pos(lineN == null ? lineNo(line) : lineN, ch); - } - - function compareBidiLevel(order, a, b) { - var linedir = order[0].level; - if (a == linedir) return true; - if (b == linedir) return false; - return a < b; - } - var bidiOther; - function getBidiPartAt(order, pos) { - bidiOther = null; - for (var i = 0, found; i < order.length; ++i) { - var cur = order[i]; - if (cur.from < pos && cur.to > pos) return i; - if ((cur.from == pos || cur.to == pos)) { - if (found == null) { - found = i; - } else if (compareBidiLevel(order, cur.level, order[found].level)) { - if (cur.from != cur.to) bidiOther = found; - return i; - } else { - if (cur.from != cur.to) bidiOther = i; - return found; - } - } - } - return found; - } - - function moveInLine(line, pos, dir, byUnit) { - if (!byUnit) return pos + dir; - do pos += dir; - while (pos > 0 && isExtendingChar(line.text.charAt(pos))); - return pos; - } - - // This is needed in order to move 'visually' through bi-directional - // text -- i.e., pressing left should make the cursor go left, even - // when in RTL text. The tricky part is the 'jumps', where RTL and - // LTR text touch each other. This often requires the cursor offset - // to move more than one unit, in order to visually move one unit. - function moveVisually(line, start, dir, byUnit) { - var bidi = getOrder(line); - if (!bidi) return moveLogically(line, start, dir, byUnit); - var pos = getBidiPartAt(bidi, start), part = bidi[pos]; - var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit); - - for (;;) { - if (target > part.from && target < part.to) return target; - if (target == part.from || target == part.to) { - if (getBidiPartAt(bidi, target) == pos) return target; - part = bidi[pos += dir]; - return (dir > 0) == part.level % 2 ? part.to : part.from; - } else { - part = bidi[pos += dir]; - if (!part) return null; - if ((dir > 0) == part.level % 2) - target = moveInLine(line, part.to, -1, byUnit); - else - target = moveInLine(line, part.from, 1, byUnit); - } - } - } - - function moveLogically(line, start, dir, byUnit) { - var target = start + dir; - if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir; - return target < 0 || target > line.text.length ? null : target; - } - - // Bidirectional ordering algorithm - // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm - // that this (partially) implements. - - // One-char codes used for character types: - // L (L): Left-to-Right - // R (R): Right-to-Left - // r (AL): Right-to-Left Arabic - // 1 (EN): European Number - // + (ES): European Number Separator - // % (ET): European Number Terminator - // n (AN): Arabic Number - // , (CS): Common Number Separator - // m (NSM): Non-Spacing Mark - // b (BN): Boundary Neutral - // s (B): Paragraph Separator - // t (S): Segment Separator - // w (WS): Whitespace - // N (ON): Other Neutrals - - // Returns null if characters are ordered as they appear - // (left-to-right), or an array of sections ({from, to, level} - // objects) in the order in which they occur visually. - var bidiOrdering = (function() { - // Character types for codepoints 0 to 0xff - var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN"; - // Character types for codepoints 0x600 to 0x6ff - var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm"; - function charType(code) { - if (code <= 0xf7) return lowTypes.charAt(code); - else if (0x590 <= code && code <= 0x5f4) return "R"; - else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600); - else if (0x6ee <= code && code <= 0x8ac) return "r"; - else if (0x2000 <= code && code <= 0x200b) return "w"; - else if (code == 0x200c) return "b"; - else return "L"; - } - - var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/; - var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/; - // Browsers seem to always treat the boundaries of block elements as being L. - var outerType = "L"; - - function BidiSpan(level, from, to) { - this.level = level; - this.from = from; this.to = to; - } - - return function(str) { - if (!bidiRE.test(str)) return false; - var len = str.length, types = []; - for (var i = 0, type; i < len; ++i) - types.push(type = charType(str.charCodeAt(i))); - - // W1. Examine each non-spacing mark (NSM) in the level run, and - // change the type of the NSM to the type of the previous - // character. If the NSM is at the start of the level run, it will - // get the type of sor. - for (var i = 0, prev = outerType; i < len; ++i) { - var type = types[i]; - if (type == "m") types[i] = prev; - else prev = type; - } - - // W2. Search backwards from each instance of a European number - // until the first strong type (R, L, AL, or sor) is found. If an - // AL is found, change the type of the European number to Arabic - // number. - // W3. Change all ALs to R. - for (var i = 0, cur = outerType; i < len; ++i) { - var type = types[i]; - if (type == "1" && cur == "r") types[i] = "n"; - else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; } - } - - // W4. A single European separator between two European numbers - // changes to a European number. A single common separator between - // two numbers of the same type changes to that type. - for (var i = 1, prev = types[0]; i < len - 1; ++i) { - var type = types[i]; - if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1"; - else if (type == "," && prev == types[i+1] && - (prev == "1" || prev == "n")) types[i] = prev; - prev = type; - } - - // W5. A sequence of European terminators adjacent to European - // numbers changes to all European numbers. - // W6. Otherwise, separators and terminators change to Other - // Neutral. - for (var i = 0; i < len; ++i) { - var type = types[i]; - if (type == ",") types[i] = "N"; - else if (type == "%") { - for (var end = i + 1; end < len && types[end] == "%"; ++end) {} - var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N"; - for (var j = i; j < end; ++j) types[j] = replace; - i = end - 1; - } - } - - // W7. Search backwards from each instance of a European number - // until the first strong type (R, L, or sor) is found. If an L is - // found, then change the type of the European number to L. - for (var i = 0, cur = outerType; i < len; ++i) { - var type = types[i]; - if (cur == "L" && type == "1") types[i] = "L"; - else if (isStrong.test(type)) cur = type; - } - - // N1. A sequence of neutrals takes the direction of the - // surrounding strong text if the text on both sides has the same - // direction. European and Arabic numbers act as if they were R in - // terms of their influence on neutrals. Start-of-level-run (sor) - // and end-of-level-run (eor) are used at level run boundaries. - // N2. Any remaining neutrals take the embedding direction. - for (var i = 0; i < len; ++i) { - if (isNeutral.test(types[i])) { - for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {} - var before = (i ? types[i-1] : outerType) == "L"; - var after = (end < len ? types[end] : outerType) == "L"; - var replace = before || after ? "L" : "R"; - for (var j = i; j < end; ++j) types[j] = replace; - i = end - 1; - } - } - - // Here we depart from the documented algorithm, in order to avoid - // building up an actual levels array. Since there are only three - // levels (0, 1, 2) in an implementation that doesn't take - // explicit embedding into account, we can build up the order on - // the fly, without following the level-based algorithm. - var order = [], m; - for (var i = 0; i < len;) { - if (countsAsLeft.test(types[i])) { - var start = i; - for (++i; i < len && countsAsLeft.test(types[i]); ++i) {} - order.push(new BidiSpan(0, start, i)); - } else { - var pos = i, at = order.length; - for (++i; i < len && types[i] != "L"; ++i) {} - for (var j = pos; j < i;) { - if (countsAsNum.test(types[j])) { - if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j)); - var nstart = j; - for (++j; j < i && countsAsNum.test(types[j]); ++j) {} - order.splice(at, 0, new BidiSpan(2, nstart, j)); - pos = j; - } else ++j; - } - if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i)); - } - } - if (order[0].level == 1 && (m = str.match(/^\s+/))) { - order[0].from = m[0].length; - order.unshift(new BidiSpan(0, 0, m[0].length)); - } - if (lst(order).level == 1 && (m = str.match(/\s+$/))) { - lst(order).to -= m[0].length; - order.push(new BidiSpan(0, len - m[0].length, len)); - } - if (order[0].level != lst(order).level) - order.push(new BidiSpan(order[0].level, len, len)); - - return order; - }; - })(); - - // THE END - - CodeMirror.version = "4.3.0"; - - return CodeMirror; -}); diff --git a/triplestores/fuseki/webapp/js/lib/mode/javascript/javascript.js b/triplestores/fuseki/webapp/js/lib/mode/javascript/javascript.js deleted file mode 100644 index 315674be74..0000000000 --- a/triplestores/fuseki/webapp/js/lib/mode/javascript/javascript.js +++ /dev/null @@ -1,683 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -// TODO actually recognize syntax of TypeScript constructs - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.defineMode("javascript", function(config, parserConfig) { - var indentUnit = config.indentUnit; - var statementIndent = parserConfig.statementIndent; - var jsonldMode = parserConfig.jsonld; - var jsonMode = parserConfig.json || jsonldMode; - var isTS = parserConfig.typescript; - - // Tokenizer - - var keywords = function(){ - function kw(type) {return {type: type, style: "keyword"};} - var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c"); - var operator = kw("operator"), atom = {type: "atom", style: "atom"}; - - var jsKeywords = { - "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B, - "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C, - "var": kw("var"), "const": kw("var"), "let": kw("var"), - "function": kw("function"), "catch": kw("catch"), - "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"), - "in": operator, "typeof": operator, "instanceof": operator, - "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom, - "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"), - "yield": C, "export": kw("export"), "import": kw("import"), "extends": C - }; - - // Extend the 'normal' keywords with the TypeScript language extensions - if (isTS) { - var type = {type: "variable", style: "variable-3"}; - var tsKeywords = { - // object-like things - "interface": kw("interface"), - "extends": kw("extends"), - "constructor": kw("constructor"), - - // scope modifiers - "public": kw("public"), - "private": kw("private"), - "protected": kw("protected"), - "static": kw("static"), - - // types - "string": type, "number": type, "bool": type, "any": type - }; - - for (var attr in tsKeywords) { - jsKeywords[attr] = tsKeywords[attr]; - } - } - - return jsKeywords; - }(); - - var isOperatorChar = /[+\-*&%=<>!?|~^]/; - var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/; - - function readRegexp(stream) { - var escaped = false, next, inSet = false; - while ((next = stream.next()) != null) { - if (!escaped) { - if (next == "/" && !inSet) return; - if (next == "[") inSet = true; - else if (inSet && next == "]") inSet = false; - } - escaped = !escaped && next == "\\"; - } - } - - // Used as scratch variables to communicate multiple values without - // consing up tons of objects. - var type, content; - function ret(tp, style, cont) { - type = tp; content = cont; - return style; - } - function tokenBase(stream, state) { - var ch = stream.next(); - if (ch == '"' || ch == "'") { - state.tokenize = tokenString(ch); - return state.tokenize(stream, state); - } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) { - return ret("number", "number"); - } else if (ch == "." && stream.match("..")) { - return ret("spread", "meta"); - } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) { - return ret(ch); - } else if (ch == "=" && stream.eat(">")) { - return ret("=>", "operator"); - } else if (ch == "0" && stream.eat(/x/i)) { - stream.eatWhile(/[\da-f]/i); - return ret("number", "number"); - } else if (/\d/.test(ch)) { - stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/); - return ret("number", "number"); - } else if (ch == "/") { - if (stream.eat("*")) { - state.tokenize = tokenComment; - return tokenComment(stream, state); - } else if (stream.eat("/")) { - stream.skipToEnd(); - return ret("comment", "comment"); - } else if (state.lastType == "operator" || state.lastType == "keyword c" || - state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) { - readRegexp(stream); - stream.eatWhile(/[gimy]/); // 'y' is "sticky" option in Mozilla - return ret("regexp", "string-2"); - } else { - stream.eatWhile(isOperatorChar); - return ret("operator", "operator", stream.current()); - } - } else if (ch == "`") { - state.tokenize = tokenQuasi; - return tokenQuasi(stream, state); - } else if (ch == "#") { - stream.skipToEnd(); - return ret("error", "error"); - } else if (isOperatorChar.test(ch)) { - stream.eatWhile(isOperatorChar); - return ret("operator", "operator", stream.current()); - } else { - stream.eatWhile(/[\w\$_]/); - var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word]; - return (known && state.lastType != ".") ? ret(known.type, known.style, word) : - ret("variable", "variable", word); - } - } - - function tokenString(quote) { - return function(stream, state) { - var escaped = false, next; - if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){ - state.tokenize = tokenBase; - return ret("jsonld-keyword", "meta"); - } - while ((next = stream.next()) != null) { - if (next == quote && !escaped) break; - escaped = !escaped && next == "\\"; - } - if (!escaped) state.tokenize = tokenBase; - return ret("string", "string"); - }; - } - - function tokenComment(stream, state) { - var maybeEnd = false, ch; - while (ch = stream.next()) { - if (ch == "/" && maybeEnd) { - state.tokenize = tokenBase; - break; - } - maybeEnd = (ch == "*"); - } - return ret("comment", "comment"); - } - - function tokenQuasi(stream, state) { - var escaped = false, next; - while ((next = stream.next()) != null) { - if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) { - state.tokenize = tokenBase; - break; - } - escaped = !escaped && next == "\\"; - } - return ret("quasi", "string-2", stream.current()); - } - - var brackets = "([{}])"; - // This is a crude lookahead trick to try and notice that we're - // parsing the argument patterns for a fat-arrow function before we - // actually hit the arrow token. It only works if the arrow is on - // the same line as the arguments and there's no strange noise - // (comments) in between. Fallback is to only notice when we hit the - // arrow, and not declare the arguments as locals for the arrow - // body. - function findFatArrow(stream, state) { - if (state.fatArrowAt) state.fatArrowAt = null; - var arrow = stream.string.indexOf("=>", stream.start); - if (arrow < 0) return; - - var depth = 0, sawSomething = false; - for (var pos = arrow - 1; pos >= 0; --pos) { - var ch = stream.string.charAt(pos); - var bracket = brackets.indexOf(ch); - if (bracket >= 0 && bracket < 3) { - if (!depth) { ++pos; break; } - if (--depth == 0) break; - } else if (bracket >= 3 && bracket < 6) { - ++depth; - } else if (/[$\w]/.test(ch)) { - sawSomething = true; - } else if (sawSomething && !depth) { - ++pos; - break; - } - } - if (sawSomething && !depth) state.fatArrowAt = pos; - } - - // Parser - - var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true}; - - function JSLexical(indented, column, type, align, prev, info) { - this.indented = indented; - this.column = column; - this.type = type; - this.prev = prev; - this.info = info; - if (align != null) this.align = align; - } - - function inScope(state, varname) { - for (var v = state.localVars; v; v = v.next) - if (v.name == varname) return true; - for (var cx = state.context; cx; cx = cx.prev) { - for (var v = cx.vars; v; v = v.next) - if (v.name == varname) return true; - } - } - - function parseJS(state, style, type, content, stream) { - var cc = state.cc; - // Communicate our context to the combinators. - // (Less wasteful than consing up a hundred closures on every call.) - cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style; - - if (!state.lexical.hasOwnProperty("align")) - state.lexical.align = true; - - while(true) { - var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement; - if (combinator(type, content)) { - while(cc.length && cc[cc.length - 1].lex) - cc.pop()(); - if (cx.marked) return cx.marked; - if (type == "variable" && inScope(state, content)) return "variable-2"; - return style; - } - } - } - - // Combinator utils - - var cx = {state: null, column: null, marked: null, cc: null}; - function pass() { - for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]); - } - function cont() { - pass.apply(null, arguments); - return true; - } - function register(varname) { - function inList(list) { - for (var v = list; v; v = v.next) - if (v.name == varname) return true; - return false; - } - var state = cx.state; - if (state.context) { - cx.marked = "def"; - if (inList(state.localVars)) return; - state.localVars = {name: varname, next: state.localVars}; - } else { - if (inList(state.globalVars)) return; - if (parserConfig.globalVars) - state.globalVars = {name: varname, next: state.globalVars}; - } - } - - // Combinators - - var defaultVars = {name: "this", next: {name: "arguments"}}; - function pushcontext() { - cx.state.context = {prev: cx.state.context, vars: cx.state.localVars}; - cx.state.localVars = defaultVars; - } - function popcontext() { - cx.state.localVars = cx.state.context.vars; - cx.state.context = cx.state.context.prev; - } - function pushlex(type, info) { - var result = function() { - var state = cx.state, indent = state.indented; - if (state.lexical.type == "stat") indent = state.lexical.indented; - state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info); - }; - result.lex = true; - return result; - } - function poplex() { - var state = cx.state; - if (state.lexical.prev) { - if (state.lexical.type == ")") - state.indented = state.lexical.indented; - state.lexical = state.lexical.prev; - } - } - poplex.lex = true; - - function expect(wanted) { - function exp(type) { - if (type == wanted) return cont(); - else if (wanted == ";") return pass(); - else return cont(exp); - }; - return exp; - } - - function statement(type, value) { - if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex); - if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex); - if (type == "keyword b") return cont(pushlex("form"), statement, poplex); - if (type == "{") return cont(pushlex("}"), block, poplex); - if (type == ";") return cont(); - if (type == "if") { - if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex) - cx.state.cc.pop()(); - return cont(pushlex("form"), expression, statement, poplex, maybeelse); - } - if (type == "function") return cont(functiondef); - if (type == "for") return cont(pushlex("form"), forspec, statement, poplex); - if (type == "variable") return cont(pushlex("stat"), maybelabel); - if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"), - block, poplex, poplex); - if (type == "case") return cont(expression, expect(":")); - if (type == "default") return cont(expect(":")); - if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"), - statement, poplex, popcontext); - if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex); - if (type == "class") return cont(pushlex("form"), className, poplex); - if (type == "export") return cont(pushlex("form"), afterExport, poplex); - if (type == "import") return cont(pushlex("form"), afterImport, poplex); - return pass(pushlex("stat"), expression, expect(";"), poplex); - } - function expression(type) { - return expressionInner(type, false); - } - function expressionNoComma(type) { - return expressionInner(type, true); - } - function expressionInner(type, noComma) { - if (cx.state.fatArrowAt == cx.stream.start) { - var body = noComma ? arrowBodyNoComma : arrowBody; - if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext); - else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext); - } - - var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma; - if (atomicTypes.hasOwnProperty(type)) return cont(maybeop); - if (type == "function") return cont(functiondef, maybeop); - if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression); - if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop); - if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression); - if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop); - if (type == "{") return contCommasep(objprop, "}", null, maybeop); - if (type == "quasi") { return pass(quasi, maybeop); } - return cont(); - } - function maybeexpression(type) { - if (type.match(/[;\}\)\],]/)) return pass(); - return pass(expression); - } - function maybeexpressionNoComma(type) { - if (type.match(/[;\}\)\],]/)) return pass(); - return pass(expressionNoComma); - } - - function maybeoperatorComma(type, value) { - if (type == ",") return cont(expression); - return maybeoperatorNoComma(type, value, false); - } - function maybeoperatorNoComma(type, value, noComma) { - var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma; - var expr = noComma == false ? expression : expressionNoComma; - if (value == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext); - if (type == "operator") { - if (/\+\+|--/.test(value)) return cont(me); - if (value == "?") return cont(expression, expect(":"), expr); - return cont(expr); - } - if (type == "quasi") { return pass(quasi, me); } - if (type == ";") return; - if (type == "(") return contCommasep(expressionNoComma, ")", "call", me); - if (type == ".") return cont(property, me); - if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me); - } - function quasi(type, value) { - if (type != "quasi") return pass(); - if (value.slice(value.length - 2) != "${") return cont(quasi); - return cont(expression, continueQuasi); - } - function continueQuasi(type) { - if (type == "}") { - cx.marked = "string-2"; - cx.state.tokenize = tokenQuasi; - return cont(quasi); - } - } - function arrowBody(type) { - findFatArrow(cx.stream, cx.state); - if (type == "{") return pass(statement); - return pass(expression); - } - function arrowBodyNoComma(type) { - findFatArrow(cx.stream, cx.state); - if (type == "{") return pass(statement); - return pass(expressionNoComma); - } - function maybelabel(type) { - if (type == ":") return cont(poplex, statement); - return pass(maybeoperatorComma, expect(";"), poplex); - } - function property(type) { - if (type == "variable") {cx.marked = "property"; return cont();} - } - function objprop(type, value) { - if (type == "variable" || cx.style == "keyword") { - cx.marked = "property"; - if (value == "get" || value == "set") return cont(getterSetter); - return cont(afterprop); - } else if (type == "number" || type == "string") { - cx.marked = jsonldMode ? "property" : (cx.style + " property"); - return cont(afterprop); - } else if (type == "jsonld-keyword") { - return cont(afterprop); - } else if (type == "[") { - return cont(expression, expect("]"), afterprop); - } - } - function getterSetter(type) { - if (type != "variable") return pass(afterprop); - cx.marked = "property"; - return cont(functiondef); - } - function afterprop(type) { - if (type == ":") return cont(expressionNoComma); - if (type == "(") return pass(functiondef); - } - function commasep(what, end) { - function proceed(type) { - if (type == ",") { - var lex = cx.state.lexical; - if (lex.info == "call") lex.pos = (lex.pos || 0) + 1; - return cont(what, proceed); - } - if (type == end) return cont(); - return cont(expect(end)); - } - return function(type) { - if (type == end) return cont(); - return pass(what, proceed); - }; - } - function contCommasep(what, end, info) { - for (var i = 3; i < arguments.length; i++) - cx.cc.push(arguments[i]); - return cont(pushlex(end, info), commasep(what, end), poplex); - } - function block(type) { - if (type == "}") return cont(); - return pass(statement, block); - } - function maybetype(type) { - if (isTS && type == ":") return cont(typedef); - } - function typedef(type) { - if (type == "variable"){cx.marked = "variable-3"; return cont();} - } - function vardef() { - return pass(pattern, maybetype, maybeAssign, vardefCont); - } - function pattern(type, value) { - if (type == "variable") { register(value); return cont(); } - if (type == "[") return contCommasep(pattern, "]"); - if (type == "{") return contCommasep(proppattern, "}"); - } - function proppattern(type, value) { - if (type == "variable" && !cx.stream.match(/^\s*:/, false)) { - register(value); - return cont(maybeAssign); - } - if (type == "variable") cx.marked = "property"; - return cont(expect(":"), pattern, maybeAssign); - } - function maybeAssign(_type, value) { - if (value == "=") return cont(expressionNoComma); - } - function vardefCont(type) { - if (type == ",") return cont(vardef); - } - function maybeelse(type, value) { - if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex); - } - function forspec(type) { - if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex); - } - function forspec1(type) { - if (type == "var") return cont(vardef, expect(";"), forspec2); - if (type == ";") return cont(forspec2); - if (type == "variable") return cont(formaybeinof); - return pass(expression, expect(";"), forspec2); - } - function formaybeinof(_type, value) { - if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } - return cont(maybeoperatorComma, forspec2); - } - function forspec2(type, value) { - if (type == ";") return cont(forspec3); - if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); } - return pass(expression, expect(";"), forspec3); - } - function forspec3(type) { - if (type != ")") cont(expression); - } - function functiondef(type, value) { - if (value == "*") {cx.marked = "keyword"; return cont(functiondef);} - if (type == "variable") {register(value); return cont(functiondef);} - if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext); - } - function funarg(type) { - if (type == "spread") return cont(funarg); - return pass(pattern, maybetype); - } - function className(type, value) { - if (type == "variable") {register(value); return cont(classNameAfter);} - } - function classNameAfter(type, value) { - if (value == "extends") return cont(expression, classNameAfter); - if (type == "{") return cont(pushlex("}"), classBody, poplex); - } - function classBody(type, value) { - if (type == "variable" || cx.style == "keyword") { - cx.marked = "property"; - if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody); - return cont(functiondef, classBody); - } - if (value == "*") { - cx.marked = "keyword"; - return cont(classBody); - } - if (type == ";") return cont(classBody); - if (type == "}") return cont(); - } - function classGetterSetter(type) { - if (type != "variable") return pass(); - cx.marked = "property"; - return cont(); - } - function afterModule(type, value) { - if (type == "string") return cont(statement); - if (type == "variable") { register(value); return cont(maybeFrom); } - } - function afterExport(_type, value) { - if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); } - if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); } - return pass(statement); - } - function afterImport(type) { - if (type == "string") return cont(); - return pass(importSpec, maybeFrom); - } - function importSpec(type, value) { - if (type == "{") return contCommasep(importSpec, "}"); - if (type == "variable") register(value); - return cont(); - } - function maybeFrom(_type, value) { - if (value == "from") { cx.marked = "keyword"; return cont(expression); } - } - function arrayLiteral(type) { - if (type == "]") return cont(); - return pass(expressionNoComma, maybeArrayComprehension); - } - function maybeArrayComprehension(type) { - if (type == "for") return pass(comprehension, expect("]")); - if (type == ",") return cont(commasep(expressionNoComma, "]")); - return pass(commasep(expressionNoComma, "]")); - } - function comprehension(type) { - if (type == "for") return cont(forspec, comprehension); - if (type == "if") return cont(expression, comprehension); - } - - // Interface - - return { - startState: function(basecolumn) { - var state = { - tokenize: tokenBase, - lastType: "sof", - cc: [], - lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false), - localVars: parserConfig.localVars, - context: parserConfig.localVars && {vars: parserConfig.localVars}, - indented: 0 - }; - if (parserConfig.globalVars && typeof parserConfig.globalVars == "object") - state.globalVars = parserConfig.globalVars; - return state; - }, - - token: function(stream, state) { - if (stream.sol()) { - if (!state.lexical.hasOwnProperty("align")) - state.lexical.align = false; - state.indented = stream.indentation(); - findFatArrow(stream, state); - } - if (state.tokenize != tokenComment && stream.eatSpace()) return null; - var style = state.tokenize(stream, state); - if (type == "comment") return style; - state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type; - return parseJS(state, style, type, content, stream); - }, - - indent: function(state, textAfter) { - if (state.tokenize == tokenComment) return CodeMirror.Pass; - if (state.tokenize != tokenBase) return 0; - var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical; - // Kludge to prevent 'maybelse' from blocking lexical scope pops - if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) { - var c = state.cc[i]; - if (c == poplex) lexical = lexical.prev; - else if (c != maybeelse) break; - } - if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev; - if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat") - lexical = lexical.prev; - var type = lexical.type, closing = firstChar == type; - - if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0); - else if (type == "form" && firstChar == "{") return lexical.indented; - else if (type == "form") return lexical.indented + indentUnit; - else if (type == "stat") - return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? statementIndent || indentUnit : 0); - else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false) - return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit); - else if (lexical.align) return lexical.column + (closing ? 0 : 1); - else return lexical.indented + (closing ? 0 : indentUnit); - }, - - electricChars: ":{}", - blockCommentStart: jsonMode ? null : "/*", - blockCommentEnd: jsonMode ? null : "*/", - lineComment: jsonMode ? null : "//", - fold: "brace", - - helperType: jsonMode ? "json" : "javascript", - jsonldMode: jsonldMode, - jsonMode: jsonMode - }; -}); - -CodeMirror.registerHelper("wordChars", "javascript", /[\\w$]/); - -CodeMirror.defineMIME("text/javascript", "javascript"); -CodeMirror.defineMIME("text/ecmascript", "javascript"); -CodeMirror.defineMIME("application/javascript", "javascript"); -CodeMirror.defineMIME("application/x-javascript", "javascript"); -CodeMirror.defineMIME("application/ecmascript", "javascript"); -CodeMirror.defineMIME("application/json", {name: "javascript", json: true}); -CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true}); -CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true}); -CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true }); -CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true }); - -}); diff --git a/triplestores/fuseki/webapp/js/lib/mode/sparql/sparql.js b/triplestores/fuseki/webapp/js/lib/mode/sparql/sparql.js deleted file mode 100644 index 64dbb612c2..0000000000 --- a/triplestores/fuseki/webapp/js/lib/mode/sparql/sparql.js +++ /dev/null @@ -1,160 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.defineMode("sparql", function(config) { - var indentUnit = config.indentUnit; - var curPunc; - - function wordRegexp(words) { - return new RegExp("^(?:" + words.join("|") + ")$", "i"); - } - var ops = wordRegexp(["str", "lang", "langmatches", "datatype", "bound", "sameterm", "isiri", "isuri", - "isblank", "isliteral", "a"]); - var keywords = wordRegexp(["base", "prefix", "select", "distinct", "reduced", "construct", "describe", - "ask", "from", "named", "where", "order", "limit", "offset", "filter", "optional", - "graph", "by", "asc", "desc", "as", "having", "undef", "values", "group", - "minus", "in", "not", "service", "silent", "using", "insert", "delete", "union", - "data", "copy", "to", "move", "add", "create", "drop", "clear", "load"]); - var operatorChars = /[*+\-<>=&|]/; - - function tokenBase(stream, state) { - var ch = stream.next(); - curPunc = null; - if (ch == "$" || ch == "?") { - stream.match(/^[\w\d]*/); - return "variable-2"; - } - else if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) { - stream.match(/^[^\s\u00a0>]*>?/); - return "atom"; - } - else if (ch == "\"" || ch == "'") { - state.tokenize = tokenLiteral(ch); - return state.tokenize(stream, state); - } - else if (/[{}\(\),\.;\[\]]/.test(ch)) { - curPunc = ch; - return null; - } - else if (ch == "#") { - stream.skipToEnd(); - return "comment"; - } - else if (operatorChars.test(ch)) { - stream.eatWhile(operatorChars); - return null; - } - else if (ch == ":") { - stream.eatWhile(/[\w\d\._\-]/); - return "atom"; - } - else { - stream.eatWhile(/[_\w\d]/); - if (stream.eat(":")) { - stream.eatWhile(/[\w\d_\-]/); - return "atom"; - } - var word = stream.current(); - if (ops.test(word)) - return null; - else if (keywords.test(word)) - return "keyword"; - else - return "variable"; - } - } - - function tokenLiteral(quote) { - return function(stream, state) { - var escaped = false, ch; - while ((ch = stream.next()) != null) { - if (ch == quote && !escaped) { - state.tokenize = tokenBase; - break; - } - escaped = !escaped && ch == "\\"; - } - return "string"; - }; - } - - function pushContext(state, type, col) { - state.context = {prev: state.context, indent: state.indent, col: col, type: type}; - } - function popContext(state) { - state.indent = state.context.indent; - state.context = state.context.prev; - } - - return { - startState: function() { - return {tokenize: tokenBase, - context: null, - indent: 0, - col: 0}; - }, - - token: function(stream, state) { - if (stream.sol()) { - if (state.context && state.context.align == null) state.context.align = false; - state.indent = stream.indentation(); - } - if (stream.eatSpace()) return null; - var style = state.tokenize(stream, state); - - if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") { - state.context.align = true; - } - - if (curPunc == "(") pushContext(state, ")", stream.column()); - else if (curPunc == "[") pushContext(state, "]", stream.column()); - else if (curPunc == "{") pushContext(state, "}", stream.column()); - else if (/[\]\}\)]/.test(curPunc)) { - while (state.context && state.context.type == "pattern") popContext(state); - if (state.context && curPunc == state.context.type) popContext(state); - } - else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state); - else if (/atom|string|variable/.test(style) && state.context) { - if (/[\}\]]/.test(state.context.type)) - pushContext(state, "pattern", stream.column()); - else if (state.context.type == "pattern" && !state.context.align) { - state.context.align = true; - state.context.col = stream.column(); - } - } - - return style; - }, - - indent: function(state, textAfter) { - var firstChar = textAfter && textAfter.charAt(0); - var context = state.context; - if (/[\]\}]/.test(firstChar)) - while (context && context.type == "pattern") context = context.prev; - - var closing = context && firstChar == context.type; - if (!context) - return 0; - else if (context.type == "pattern") - return context.col; - else if (context.align) - return context.col + (closing ? 0 : 1); - else - return context.indent + (closing ? 0 : indentUnit); - } - }; -}); - -CodeMirror.defineMIME("application/x-sparql-query", "sparql"); - -}); diff --git a/triplestores/fuseki/webapp/js/lib/mode/turtle/turtle.js b/triplestores/fuseki/webapp/js/lib/mode/turtle/turtle.js deleted file mode 100644 index a4727ed572..0000000000 --- a/triplestores/fuseki/webapp/js/lib/mode/turtle/turtle.js +++ /dev/null @@ -1,160 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.defineMode("turtle", function(config) { - var indentUnit = config.indentUnit; - var curPunc; - - function wordRegexp(words) { - return new RegExp("^(?:" + words.join("|") + ")$", "i"); - } - var ops = wordRegexp([]); - var keywords = wordRegexp(["@prefix", "@base", "a"]); - var operatorChars = /[*+\-<>=&|]/; - - function tokenBase(stream, state) { - var ch = stream.next(); - curPunc = null; - if (ch == "<" && !stream.match(/^[\s\u00a0=]/, false)) { - stream.match(/^[^\s\u00a0>]*>?/); - return "atom"; - } - else if (ch == "\"" || ch == "'") { - state.tokenize = tokenLiteral(ch); - return state.tokenize(stream, state); - } - else if (/[{}\(\),\.;\[\]]/.test(ch)) { - curPunc = ch; - return null; - } - else if (ch == "#") { - stream.skipToEnd(); - return "comment"; - } - else if (operatorChars.test(ch)) { - stream.eatWhile(operatorChars); - return null; - } - else if (ch == ":") { - return "operator"; - } else { - stream.eatWhile(/[_\w\d]/); - if(stream.peek() == ":") { - return "variable-3"; - } else { - var word = stream.current(); - - if(keywords.test(word)) { - return "meta"; - } - - if(ch >= "A" && ch <= "Z") { - return "comment"; - } else { - return "keyword"; - } - } - var word = stream.current(); - if (ops.test(word)) - return null; - else if (keywords.test(word)) - return "meta"; - else - return "variable"; - } - } - - function tokenLiteral(quote) { - return function(stream, state) { - var escaped = false, ch; - while ((ch = stream.next()) != null) { - if (ch == quote && !escaped) { - state.tokenize = tokenBase; - break; - } - escaped = !escaped && ch == "\\"; - } - return "string"; - }; - } - - function pushContext(state, type, col) { - state.context = {prev: state.context, indent: state.indent, col: col, type: type}; - } - function popContext(state) { - state.indent = state.context.indent; - state.context = state.context.prev; - } - - return { - startState: function() { - return {tokenize: tokenBase, - context: null, - indent: 0, - col: 0}; - }, - - token: function(stream, state) { - if (stream.sol()) { - if (state.context && state.context.align == null) state.context.align = false; - state.indent = stream.indentation(); - } - if (stream.eatSpace()) return null; - var style = state.tokenize(stream, state); - - if (style != "comment" && state.context && state.context.align == null && state.context.type != "pattern") { - state.context.align = true; - } - - if (curPunc == "(") pushContext(state, ")", stream.column()); - else if (curPunc == "[") pushContext(state, "]", stream.column()); - else if (curPunc == "{") pushContext(state, "}", stream.column()); - else if (/[\]\}\)]/.test(curPunc)) { - while (state.context && state.context.type == "pattern") popContext(state); - if (state.context && curPunc == state.context.type) popContext(state); - } - else if (curPunc == "." && state.context && state.context.type == "pattern") popContext(state); - else if (/atom|string|variable/.test(style) && state.context) { - if (/[\}\]]/.test(state.context.type)) - pushContext(state, "pattern", stream.column()); - else if (state.context.type == "pattern" && !state.context.align) { - state.context.align = true; - state.context.col = stream.column(); - } - } - - return style; - }, - - indent: function(state, textAfter) { - var firstChar = textAfter && textAfter.charAt(0); - var context = state.context; - if (/[\]\}]/.test(firstChar)) - while (context && context.type == "pattern") context = context.prev; - - var closing = context && firstChar == context.type; - if (!context) - return 0; - else if (context.type == "pattern") - return context.col; - else if (context.align) - return context.col + (closing ? 0 : 1); - else - return context.indent + (closing ? 0 : indentUnit); - } - }; -}); - -CodeMirror.defineMIME("text/turtle", "turtle"); - -}); diff --git a/triplestores/fuseki/webapp/js/lib/mode/xml/xml.js b/triplestores/fuseki/webapp/js/lib/mode/xml/xml.js deleted file mode 100644 index 786507d2e4..0000000000 --- a/triplestores/fuseki/webapp/js/lib/mode/xml/xml.js +++ /dev/null @@ -1,384 +0,0 @@ -// CodeMirror, copyright (c) by Marijn Haverbeke and others -// Distributed under an MIT license: http://codemirror.net/LICENSE - -(function(mod) { - if (typeof exports == "object" && typeof module == "object") // CommonJS - mod(require("../../lib/codemirror")); - else if (typeof define == "function" && define.amd) // AMD - define(["../../lib/codemirror"], mod); - else // Plain browser env - mod(CodeMirror); -})(function(CodeMirror) { -"use strict"; - -CodeMirror.defineMode("xml", function(config, parserConfig) { - var indentUnit = config.indentUnit; - var multilineTagIndentFactor = parserConfig.multilineTagIndentFactor || 1; - var multilineTagIndentPastTag = parserConfig.multilineTagIndentPastTag; - if (multilineTagIndentPastTag == null) multilineTagIndentPastTag = true; - - var Kludges = parserConfig.htmlMode ? { - autoSelfClosers: {'area': true, 'base': true, 'br': true, 'col': true, 'command': true, - 'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true, - 'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true, - 'track': true, 'wbr': true}, - implicitlyClosed: {'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true, - 'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true, - 'th': true, 'tr': true}, - contextGrabbers: { - 'dd': {'dd': true, 'dt': true}, - 'dt': {'dd': true, 'dt': true}, - 'li': {'li': true}, - 'option': {'option': true, 'optgroup': true}, - 'optgroup': {'optgroup': true}, - 'p': {'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true, - 'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true, - 'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true, - 'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true, - 'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true}, - 'rp': {'rp': true, 'rt': true}, - 'rt': {'rp': true, 'rt': true}, - 'tbody': {'tbody': true, 'tfoot': true}, - 'td': {'td': true, 'th': true}, - 'tfoot': {'tbody': true}, - 'th': {'td': true, 'th': true}, - 'thead': {'tbody': true, 'tfoot': true}, - 'tr': {'tr': true} - }, - doNotIndent: {"pre": true}, - allowUnquoted: true, - allowMissing: true, - caseFold: true - } : { - autoSelfClosers: {}, - implicitlyClosed: {}, - contextGrabbers: {}, - doNotIndent: {}, - allowUnquoted: false, - allowMissing: false, - caseFold: false - }; - var alignCDATA = parserConfig.alignCDATA; - - // Return variables for tokenizers - var type, setStyle; - - function inText(stream, state) { - function chain(parser) { - state.tokenize = parser; - return parser(stream, state); - } - - var ch = stream.next(); - if (ch == "<") { - if (stream.eat("!")) { - if (stream.eat("[")) { - if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>")); - else return null; - } else if (stream.match("--")) { - return chain(inBlock("comment", "-->")); - } else if (stream.match("DOCTYPE", true, true)) { - stream.eatWhile(/[\w\._\-]/); - return chain(doctype(1)); - } else { - return null; - } - } else if (stream.eat("?")) { - stream.eatWhile(/[\w\._\-]/); - state.tokenize = inBlock("meta", "?>"); - return "meta"; - } else { - type = stream.eat("/") ? "closeTag" : "openTag"; - state.tokenize = inTag; - return "tag bracket"; - } - } else if (ch == "&") { - var ok; - if (stream.eat("#")) { - if (stream.eat("x")) { - ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";"); - } else { - ok = stream.eatWhile(/[\d]/) && stream.eat(";"); - } - } else { - ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";"); - } - return ok ? "atom" : "error"; - } else { - stream.eatWhile(/[^&<]/); - return null; - } - } - - function inTag(stream, state) { - var ch = stream.next(); - if (ch == ">" || (ch == "/" && stream.eat(">"))) { - state.tokenize = inText; - type = ch == ">" ? "endTag" : "selfcloseTag"; - return "tag bracket"; - } else if (ch == "=") { - type = "equals"; - return null; - } else if (ch == "<") { - state.tokenize = inText; - state.state = baseState; - state.tagName = state.tagStart = null; - var next = state.tokenize(stream, state); - return next ? next + " tag error" : "tag error"; - } else if (/[\'\"]/.test(ch)) { - state.tokenize = inAttribute(ch); - state.stringStartCol = stream.column(); - return state.tokenize(stream, state); - } else { - stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/); - return "word"; - } - } - - function inAttribute(quote) { - var closure = function(stream, state) { - while (!stream.eol()) { - if (stream.next() == quote) { - state.tokenize = inTag; - break; - } - } - return "string"; - }; - closure.isInAttribute = true; - return closure; - } - - function inBlock(style, terminator) { - return function(stream, state) { - while (!stream.eol()) { - if (stream.match(terminator)) { - state.tokenize = inText; - break; - } - stream.next(); - } - return style; - }; - } - function doctype(depth) { - return function(stream, state) { - var ch; - while ((ch = stream.next()) != null) { - if (ch == "<") { - state.tokenize = doctype(depth + 1); - return state.tokenize(stream, state); - } else if (ch == ">") { - if (depth == 1) { - state.tokenize = inText; - break; - } else { - state.tokenize = doctype(depth - 1); - return state.tokenize(stream, state); - } - } - } - return "meta"; - }; - } - - function Context(state, tagName, startOfLine) { - this.prev = state.context; - this.tagName = tagName; - this.indent = state.indented; - this.startOfLine = startOfLine; - if (Kludges.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent)) - this.noIndent = true; - } - function popContext(state) { - if (state.context) state.context = state.context.prev; - } - function maybePopContext(state, nextTagName) { - var parentTagName; - while (true) { - if (!state.context) { - return; - } - parentTagName = state.context.tagName; - if (!Kludges.contextGrabbers.hasOwnProperty(parentTagName) || - !Kludges.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) { - return; - } - popContext(state); - } - } - - function baseState(type, stream, state) { - if (type == "openTag") { - state.tagStart = stream.column(); - return tagNameState; - } else if (type == "closeTag") { - return closeTagNameState; - } else { - return baseState; - } - } - function tagNameState(type, stream, state) { - if (type == "word") { - state.tagName = stream.current(); - setStyle = "tag"; - return attrState; - } else { - setStyle = "error"; - return tagNameState; - } - } - function closeTagNameState(type, stream, state) { - if (type == "word") { - var tagName = stream.current(); - if (state.context && state.context.tagName != tagName && - Kludges.implicitlyClosed.hasOwnProperty(state.context.tagName)) - popContext(state); - if (state.context && state.context.tagName == tagName) { - setStyle = "tag"; - return closeState; - } else { - setStyle = "tag error"; - return closeStateErr; - } - } else { - setStyle = "error"; - return closeStateErr; - } - } - - function closeState(type, _stream, state) { - if (type != "endTag") { - setStyle = "error"; - return closeState; - } - popContext(state); - return baseState; - } - function closeStateErr(type, stream, state) { - setStyle = "error"; - return closeState(type, stream, state); - } - - function attrState(type, _stream, state) { - if (type == "word") { - setStyle = "attribute"; - return attrEqState; - } else if (type == "endTag" || type == "selfcloseTag") { - var tagName = state.tagName, tagStart = state.tagStart; - state.tagName = state.tagStart = null; - if (type == "selfcloseTag" || - Kludges.autoSelfClosers.hasOwnProperty(tagName)) { - maybePopContext(state, tagName); - } else { - maybePopContext(state, tagName); - state.context = new Context(state, tagName, tagStart == state.indented); - } - return baseState; - } - setStyle = "error"; - return attrState; - } - function attrEqState(type, stream, state) { - if (type == "equals") return attrValueState; - if (!Kludges.allowMissing) setStyle = "error"; - return attrState(type, stream, state); - } - function attrValueState(type, stream, state) { - if (type == "string") return attrContinuedState; - if (type == "word" && Kludges.allowUnquoted) {setStyle = "string"; return attrState;} - setStyle = "error"; - return attrState(type, stream, state); - } - function attrContinuedState(type, stream, state) { - if (type == "string") return attrContinuedState; - return attrState(type, stream, state); - } - - return { - startState: function() { - return {tokenize: inText, - state: baseState, - indented: 0, - tagName: null, tagStart: null, - context: null}; - }, - - token: function(stream, state) { - if (!state.tagName && stream.sol()) - state.indented = stream.indentation(); - - if (stream.eatSpace()) return null; - type = null; - var style = state.tokenize(stream, state); - if ((style || type) && style != "comment") { - setStyle = null; - state.state = state.state(type || style, stream, state); - if (setStyle) - style = setStyle == "error" ? style + " error" : setStyle; - } - return style; - }, - - indent: function(state, textAfter, fullLine) { - var context = state.context; - // Indent multi-line strings (e.g. css). - if (state.tokenize.isInAttribute) { - if (state.tagStart == state.indented) - return state.stringStartCol + 1; - else - return state.indented + indentUnit; - } - if (context && context.noIndent) return CodeMirror.Pass; - if (state.tokenize != inTag && state.tokenize != inText) - return fullLine ? fullLine.match(/^(\s*)/)[0].length : 0; - // Indent the starts of attribute names. - if (state.tagName) { - if (multilineTagIndentPastTag) - return state.tagStart + state.tagName.length + 2; - else - return state.tagStart + indentUnit * multilineTagIndentFactor; - } - if (alignCDATA && /$/, - blockCommentStart: "", - - configuration: parserConfig.htmlMode ? "html" : "xml", - helperType: parserConfig.htmlMode ? "html" : "xml" - }; -}); - -CodeMirror.defineMIME("text/xml", "xml"); -CodeMirror.defineMIME("application/xml", "xml"); -if (!CodeMirror.mimeModes.hasOwnProperty("text/html")) - CodeMirror.defineMIME("text/html", {name: "xml", htmlMode: true}); - -}); diff --git a/triplestores/fuseki/webapp/js/lib/pivot.js b/triplestores/fuseki/webapp/js/lib/pivot.js deleted file mode 100644 index c4f7eabf4f..0000000000 --- a/triplestores/fuseki/webapp/js/lib/pivot.js +++ /dev/null @@ -1,1363 +0,0 @@ -(function() { - var callWithJQuery, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - __slice = [].slice, - __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, - __hasProp = {}.hasOwnProperty; - - callWithJQuery = function(pivotModule) { - if (typeof exports === "object" && typeof module === "object") { - return pivotModule(require("jquery")); - } else if (typeof define === "function" && define.amd) { - return define(["jquery"], pivotModule); - } else { - return pivotModule(jQuery); - } - }; - - callWithJQuery(function($) { - - /* - Utilities - */ - var PivotData, addSeparators, aggregatorTemplates, aggregators, dayNamesEn, derivers, locales, mthNamesEn, naturalSort, numberFormat, pivotTableRenderer, renderers, usFmt, usFmtInt, usFmtPct, zeroPad; - addSeparators = function(nStr, thousandsSep, decimalSep) { - var rgx, x, x1, x2; - nStr += ''; - x = nStr.split('.'); - x1 = x[0]; - x2 = x.length > 1 ? decimalSep + x[1] : ''; - rgx = /(\d+)(\d{3})/; - while (rgx.test(x1)) { - x1 = x1.replace(rgx, '$1' + thousandsSep + '$2'); - } - return x1 + x2; - }; - numberFormat = function(opts) { - var defaults; - defaults = { - digitsAfterDecimal: 2, - scaler: 1, - thousandsSep: ",", - decimalSep: ".", - prefix: "", - suffix: "", - showZero: false - }; - opts = $.extend(defaults, opts); - return function(x) { - var result; - if (isNaN(x) || !isFinite(x)) { - return ""; - } - if (x === 0 && !opts.showZero) { - return ""; - } - result = addSeparators((opts.scaler * x).toFixed(opts.digitsAfterDecimal), opts.thousandsSep, opts.decimalSep); - return "" + opts.prefix + result + opts.suffix; - }; - }; - usFmt = numberFormat(); - usFmtInt = numberFormat({ - digitsAfterDecimal: 0 - }); - usFmtPct = numberFormat({ - digitsAfterDecimal: 1, - scaler: 100, - suffix: "%" - }); - aggregatorTemplates = { - count: function(formatter) { - if (formatter == null) { - formatter = usFmtInt; - } - return function() { - return function(data, rowKey, colKey) { - return { - count: 0, - push: function() { - return this.count++; - }, - value: function() { - return this.count; - }, - format: formatter - }; - }; - }; - }, - countUnique: function(formatter) { - if (formatter == null) { - formatter = usFmtInt; - } - return function(_arg) { - var attr; - attr = _arg[0]; - return function(data, rowKey, colKey) { - return { - uniq: [], - push: function(record) { - var _ref; - if (_ref = record[attr], __indexOf.call(this.uniq, _ref) < 0) { - return this.uniq.push(record[attr]); - } - }, - value: function() { - return this.uniq.length; - }, - format: formatter, - numInputs: attr != null ? 0 : 1 - }; - }; - }; - }, - listUnique: function(sep) { - return function(_arg) { - var attr; - attr = _arg[0]; - return function(data, rowKey, colKey) { - return { - uniq: [], - push: function(record) { - var _ref; - if (_ref = record[attr], __indexOf.call(this.uniq, _ref) < 0) { - return this.uniq.push(record[attr]); - } - }, - value: function() { - return this.uniq.join(sep); - }, - format: function(x) { - return x; - }, - numInputs: attr != null ? 0 : 1 - }; - }; - }; - }, - sum: function(formatter) { - if (formatter == null) { - formatter = usFmt; - } - return function(_arg) { - var attr; - attr = _arg[0]; - return function(data, rowKey, colKey) { - return { - sum: 0, - push: function(record) { - if (!isNaN(parseFloat(record[attr]))) { - return this.sum += parseFloat(record[attr]); - } - }, - value: function() { - return this.sum; - }, - format: formatter, - numInputs: attr != null ? 0 : 1 - }; - }; - }; - }, - average: function(formatter) { - if (formatter == null) { - formatter = usFmt; - } - return function(_arg) { - var attr; - attr = _arg[0]; - return function(data, rowKey, colKey) { - return { - sum: 0, - len: 0, - push: function(record) { - if (!isNaN(parseFloat(record[attr]))) { - this.sum += parseFloat(record[attr]); - return this.len++; - } - }, - value: function() { - return this.sum / this.len; - }, - format: formatter, - numInputs: attr != null ? 0 : 1 - }; - }; - }; - }, - sumOverSum: function(formatter) { - if (formatter == null) { - formatter = usFmt; - } - return function(_arg) { - var denom, num; - num = _arg[0], denom = _arg[1]; - return function(data, rowKey, colKey) { - return { - sumNum: 0, - sumDenom: 0, - push: function(record) { - if (!isNaN(parseFloat(record[num]))) { - this.sumNum += parseFloat(record[num]); - } - if (!isNaN(parseFloat(record[denom]))) { - return this.sumDenom += parseFloat(record[denom]); - } - }, - value: function() { - return this.sumNum / this.sumDenom; - }, - format: formatter, - numInputs: (num != null) && (denom != null) ? 0 : 2 - }; - }; - }; - }, - sumOverSumBound80: function(upper, formatter) { - if (upper == null) { - upper = true; - } - if (formatter == null) { - formatter = usFmt; - } - return function(_arg) { - var denom, num; - num = _arg[0], denom = _arg[1]; - return function(data, rowKey, colKey) { - return { - sumNum: 0, - sumDenom: 0, - push: function(record) { - if (!isNaN(parseFloat(record[num]))) { - this.sumNum += parseFloat(record[num]); - } - if (!isNaN(parseFloat(record[denom]))) { - return this.sumDenom += parseFloat(record[denom]); - } - }, - value: function() { - var sign; - sign = upper ? 1 : -1; - return (0.821187207574908 / this.sumDenom + this.sumNum / this.sumDenom + 1.2815515655446004 * sign * Math.sqrt(0.410593603787454 / (this.sumDenom * this.sumDenom) + (this.sumNum * (1 - this.sumNum / this.sumDenom)) / (this.sumDenom * this.sumDenom))) / (1 + 1.642374415149816 / this.sumDenom); - }, - format: formatter, - numInputs: (num != null) && (denom != null) ? 0 : 2 - }; - }; - }; - }, - fractionOf: function(wrapped, type, formatter) { - if (type == null) { - type = "total"; - } - if (formatter == null) { - formatter = usFmtPct; - } - return function() { - var x; - x = 1 <= arguments.length ? __slice.call(arguments, 0) : []; - return function(data, rowKey, colKey) { - return { - selector: { - total: [[], []], - row: [rowKey, []], - col: [[], colKey] - }[type], - inner: wrapped.apply(null, x)(data, rowKey, colKey), - push: function(record) { - return this.inner.push(record); - }, - format: formatter, - value: function() { - return this.inner.value() / data.getAggregator.apply(data, this.selector).inner.value(); - }, - numInputs: wrapped.apply(null, x)().numInputs - }; - }; - }; - } - }; - aggregators = (function(tpl) { - return { - "Count": tpl.count(usFmtInt), - "Count Unique Values": tpl.countUnique(usFmtInt), - "List Unique Values": tpl.listUnique(", "), - "Sum": tpl.sum(usFmt), - "Integer Sum": tpl.sum(usFmtInt), - "Average": tpl.average(usFmt), - "Sum over Sum": tpl.sumOverSum(usFmt), - "80% Upper Bound": tpl.sumOverSumBound80(true, usFmt), - "80% Lower Bound": tpl.sumOverSumBound80(false, usFmt), - "Sum as Fraction of Total": tpl.fractionOf(tpl.sum(), "total", usFmtPct), - "Sum as Fraction of Rows": tpl.fractionOf(tpl.sum(), "row", usFmtPct), - "Sum as Fraction of Columns": tpl.fractionOf(tpl.sum(), "col", usFmtPct), - "Count as Fraction of Total": tpl.fractionOf(tpl.count(), "total", usFmtPct), - "Count as Fraction of Rows": tpl.fractionOf(tpl.count(), "row", usFmtPct), - "Count as Fraction of Columns": tpl.fractionOf(tpl.count(), "col", usFmtPct) - }; - })(aggregatorTemplates); - renderers = { - "Table": function(pvtData, opts) { - return pivotTableRenderer(pvtData, opts); - }, - "Table Barchart": function(pvtData, opts) { - return $(pivotTableRenderer(pvtData, opts)).barchart(); - }, - "Heatmap": function(pvtData, opts) { - return $(pivotTableRenderer(pvtData, opts)).heatmap(); - }, - "Row Heatmap": function(pvtData, opts) { - return $(pivotTableRenderer(pvtData, opts)).heatmap("rowheatmap"); - }, - "Col Heatmap": function(pvtData, opts) { - return $(pivotTableRenderer(pvtData, opts)).heatmap("colheatmap"); - } - }; - locales = { - en: { - aggregators: aggregators, - renderers: renderers, - localeStrings: { - renderError: "An error occurred rendering the PivotTable results.", - computeError: "An error occurred computing the PivotTable results.", - uiRenderError: "An error occurred rendering the PivotTable UI.", - selectAll: "Select All", - selectNone: "Select None", - tooMany: "(too many to list)", - filterResults: "Filter results", - totals: "Totals", - vs: "vs", - by: "by" - } - } - }; - mthNamesEn = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; - dayNamesEn = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; - zeroPad = function(number) { - return ("0" + number).substr(-2, 2); - }; - derivers = { - bin: function(col, binWidth) { - return function(record) { - return record[col] - record[col] % binWidth; - }; - }, - dateFormat: function(col, formatString, mthNames, dayNames) { - if (mthNames == null) { - mthNames = mthNamesEn; - } - if (dayNames == null) { - dayNames = dayNamesEn; - } - return function(record) { - var date; - date = new Date(Date.parse(record[col])); - if (isNaN(date)) { - return ""; - } - return formatString.replace(/%(.)/g, function(m, p) { - switch (p) { - case "y": - return date.getFullYear(); - case "m": - return zeroPad(date.getMonth() + 1); - case "n": - return mthNames[date.getMonth()]; - case "d": - return zeroPad(date.getDate()); - case "w": - return dayNames[date.getDay()]; - case "x": - return date.getDay(); - case "H": - return zeroPad(date.getHours()); - case "M": - return zeroPad(date.getMinutes()); - case "S": - return zeroPad(date.getSeconds()); - default: - return "%" + p; - } - }); - }; - } - }; - naturalSort = (function(_this) { - return function(as, bs) { - var a, a1, b, b1, rd, rx, rz; - rx = /(\d+)|(\D+)/g; - rd = /\d/; - rz = /^0/; - if (typeof as === "number" || typeof bs === "number") { - if (isNaN(as)) { - return 1; - } - if (isNaN(bs)) { - return -1; - } - return as - bs; - } - a = String(as).toLowerCase(); - b = String(bs).toLowerCase(); - if (a === b) { - return 0; - } - if (!(rd.test(a) && rd.test(b))) { - return (a > b ? 1 : -1); - } - a = a.match(rx); - b = b.match(rx); - while (a.length && b.length) { - a1 = a.shift(); - b1 = b.shift(); - if (a1 !== b1) { - if (rd.test(a1) && rd.test(b1)) { - return a1.replace(rz, ".0") - b1.replace(rz, ".0"); - } else { - return (a1 > b1 ? 1 : -1); - } - } - } - return a.length - b.length; - }; - })(this); - $.pivotUtilities = { - aggregatorTemplates: aggregatorTemplates, - aggregators: aggregators, - renderers: renderers, - derivers: derivers, - locales: locales, - naturalSort: naturalSort, - numberFormat: numberFormat - }; - - /* - Data Model class - */ - PivotData = (function() { - function PivotData(input, opts) { - this.getAggregator = __bind(this.getAggregator, this); - this.getRowKeys = __bind(this.getRowKeys, this); - this.getColKeys = __bind(this.getColKeys, this); - this.sortKeys = __bind(this.sortKeys, this); - this.arrSort = __bind(this.arrSort, this); - this.natSort = __bind(this.natSort, this); - this.aggregator = opts.aggregator; - this.aggregatorName = opts.aggregatorName; - this.colAttrs = opts.cols; - this.rowAttrs = opts.rows; - this.valAttrs = opts.vals; - this.tree = {}; - this.rowKeys = []; - this.colKeys = []; - this.rowTotals = {}; - this.colTotals = {}; - this.allTotal = this.aggregator(this, [], []); - this.sorted = false; - PivotData.forEachRecord(input, opts.derivedAttributes, (function(_this) { - return function(record) { - if (opts.filter(record)) { - return _this.processRecord(record); - } - }; - })(this)); - } - - PivotData.forEachRecord = function(input, derivedAttributes, f) { - var addRecord, compactRecord, i, j, k, record, tblCols, _i, _len, _ref, _results, _results1; - if ($.isEmptyObject(derivedAttributes)) { - addRecord = f; - } else { - addRecord = function(record) { - var k, v, _ref; - for (k in derivedAttributes) { - v = derivedAttributes[k]; - record[k] = (_ref = v(record)) != null ? _ref : record[k]; - } - return f(record); - }; - } - if ($.isFunction(input)) { - return input(addRecord); - } else if ($.isArray(input)) { - if ($.isArray(input[0])) { - _results = []; - for (i in input) { - if (!__hasProp.call(input, i)) continue; - compactRecord = input[i]; - if (!(i > 0)) { - continue; - } - record = {}; - _ref = input[0]; - for (j in _ref) { - if (!__hasProp.call(_ref, j)) continue; - k = _ref[j]; - record[k] = compactRecord[j]; - } - _results.push(addRecord(record)); - } - return _results; - } else { - _results1 = []; - for (_i = 0, _len = input.length; _i < _len; _i++) { - record = input[_i]; - _results1.push(addRecord(record)); - } - return _results1; - } - } else if (input instanceof jQuery) { - tblCols = []; - $("thead > tr > th", input).each(function(i) { - return tblCols.push($(this).text()); - }); - return $("tbody > tr", input).each(function(i) { - record = {}; - $("td", this).each(function(j) { - return record[tblCols[j]] = $(this).text(); - }); - return addRecord(record); - }); - } else { - throw new Error("unknown input format"); - } - }; - - PivotData.convertToArray = function(input) { - var result; - result = []; - PivotData.forEachRecord(input, {}, function(record) { - return result.push(record); - }); - return result; - }; - - PivotData.prototype.natSort = function(as, bs) { - return naturalSort(as, bs); - }; - - PivotData.prototype.arrSort = function(a, b) { - return this.natSort(a.join(), b.join()); - }; - - PivotData.prototype.sortKeys = function() { - if (!this.sorted) { - this.rowKeys.sort(this.arrSort); - this.colKeys.sort(this.arrSort); - } - return this.sorted = true; - }; - - PivotData.prototype.getColKeys = function() { - this.sortKeys(); - return this.colKeys; - }; - - PivotData.prototype.getRowKeys = function() { - this.sortKeys(); - return this.rowKeys; - }; - - PivotData.prototype.processRecord = function(record) { - var colKey, flatColKey, flatRowKey, rowKey, x, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3; - colKey = []; - rowKey = []; - _ref = this.colAttrs; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - x = _ref[_i]; - colKey.push((_ref1 = record[x]) != null ? _ref1 : "null"); - } - _ref2 = this.rowAttrs; - for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) { - x = _ref2[_j]; - rowKey.push((_ref3 = record[x]) != null ? _ref3 : "null"); - } - flatRowKey = rowKey.join(String.fromCharCode(0)); - flatColKey = colKey.join(String.fromCharCode(0)); - this.allTotal.push(record); - if (rowKey.length !== 0) { - if (!this.rowTotals[flatRowKey]) { - this.rowKeys.push(rowKey); - this.rowTotals[flatRowKey] = this.aggregator(this, rowKey, []); - } - this.rowTotals[flatRowKey].push(record); - } - if (colKey.length !== 0) { - if (!this.colTotals[flatColKey]) { - this.colKeys.push(colKey); - this.colTotals[flatColKey] = this.aggregator(this, [], colKey); - } - this.colTotals[flatColKey].push(record); - } - if (colKey.length !== 0 && rowKey.length !== 0) { - if (!this.tree[flatRowKey]) { - this.tree[flatRowKey] = {}; - } - if (!this.tree[flatRowKey][flatColKey]) { - this.tree[flatRowKey][flatColKey] = this.aggregator(this, rowKey, colKey); - } - return this.tree[flatRowKey][flatColKey].push(record); - } - }; - - PivotData.prototype.getAggregator = function(rowKey, colKey) { - var agg, flatColKey, flatRowKey; - flatRowKey = rowKey.join(String.fromCharCode(0)); - flatColKey = colKey.join(String.fromCharCode(0)); - if (rowKey.length === 0 && colKey.length === 0) { - agg = this.allTotal; - } else if (rowKey.length === 0) { - agg = this.colTotals[flatColKey]; - } else if (colKey.length === 0) { - agg = this.rowTotals[flatRowKey]; - } else { - agg = this.tree[flatRowKey][flatColKey]; - } - return agg != null ? agg : { - value: (function() { - return null; - }), - format: function() { - return ""; - } - }; - }; - - return PivotData; - - })(); - - /* - Default Renderer for hierarchical table layout - */ - pivotTableRenderer = function(pivotData, opts) { - var aggregator, c, colAttrs, colKey, colKeys, defaults, i, j, r, result, rowAttrs, rowKey, rowKeys, spanSize, td, th, totalAggregator, tr, txt, val, x; - defaults = { - localeStrings: { - totals: "Totals" - } - }; - opts = $.extend(defaults, opts); - colAttrs = pivotData.colAttrs; - rowAttrs = pivotData.rowAttrs; - rowKeys = pivotData.getRowKeys(); - colKeys = pivotData.getColKeys(); - result = document.createElement("table"); - result.className = "pvtTable"; - spanSize = function(arr, i, j) { - var len, noDraw, stop, x, _i, _j; - if (i !== 0) { - noDraw = true; - for (x = _i = 0; 0 <= j ? _i <= j : _i >= j; x = 0 <= j ? ++_i : --_i) { - if (arr[i - 1][x] !== arr[i][x]) { - noDraw = false; - } - } - if (noDraw) { - return -1; - } - } - len = 0; - while (i + len < arr.length) { - stop = false; - for (x = _j = 0; 0 <= j ? _j <= j : _j >= j; x = 0 <= j ? ++_j : --_j) { - if (arr[i][x] !== arr[i + len][x]) { - stop = true; - } - } - if (stop) { - break; - } - len++; - } - return len; - }; - for (j in colAttrs) { - if (!__hasProp.call(colAttrs, j)) continue; - c = colAttrs[j]; - tr = document.createElement("tr"); - if (parseInt(j) === 0 && rowAttrs.length !== 0) { - th = document.createElement("th"); - th.setAttribute("colspan", rowAttrs.length); - th.setAttribute("rowspan", colAttrs.length); - tr.appendChild(th); - } - th = document.createElement("th"); - th.className = "pvtAxisLabel"; - th.textContent = c; - tr.appendChild(th); - for (i in colKeys) { - if (!__hasProp.call(colKeys, i)) continue; - colKey = colKeys[i]; - x = spanSize(colKeys, parseInt(i), parseInt(j)); - if (x !== -1) { - th = document.createElement("th"); - th.className = "pvtColLabel"; - th.textContent = colKey[j]; - th.setAttribute("colspan", x); - if (parseInt(j) === colAttrs.length - 1 && rowAttrs.length !== 0) { - th.setAttribute("rowspan", 2); - } - tr.appendChild(th); - } - } - if (parseInt(j) === 0) { - th = document.createElement("th"); - th.className = "pvtTotalLabel"; - th.innerHTML = opts.localeStrings.totals; - th.setAttribute("rowspan", colAttrs.length + (rowAttrs.length === 0 ? 0 : 1)); - tr.appendChild(th); - } - result.appendChild(tr); - } - if (rowAttrs.length !== 0) { - tr = document.createElement("tr"); - for (i in rowAttrs) { - if (!__hasProp.call(rowAttrs, i)) continue; - r = rowAttrs[i]; - th = document.createElement("th"); - th.className = "pvtAxisLabel"; - th.textContent = r; - tr.appendChild(th); - } - th = document.createElement("th"); - if (colAttrs.length === 0) { - th.className = "pvtTotalLabel"; - th.innerHTML = opts.localeStrings.totals; - } - tr.appendChild(th); - result.appendChild(tr); - } - for (i in rowKeys) { - if (!__hasProp.call(rowKeys, i)) continue; - rowKey = rowKeys[i]; - tr = document.createElement("tr"); - for (j in rowKey) { - if (!__hasProp.call(rowKey, j)) continue; - txt = rowKey[j]; - x = spanSize(rowKeys, parseInt(i), parseInt(j)); - if (x !== -1) { - th = document.createElement("th"); - th.className = "pvtRowLabel"; - th.textContent = txt; - th.setAttribute("rowspan", x); - if (parseInt(j) === rowAttrs.length - 1 && colAttrs.length !== 0) { - th.setAttribute("colspan", 2); - } - tr.appendChild(th); - } - } - for (j in colKeys) { - if (!__hasProp.call(colKeys, j)) continue; - colKey = colKeys[j]; - aggregator = pivotData.getAggregator(rowKey, colKey); - val = aggregator.value(); - td = document.createElement("td"); - td.className = "pvtVal row" + i + " col" + j; - td.innerHTML = aggregator.format(val); - td.setAttribute("data-value", val); - tr.appendChild(td); - } - totalAggregator = pivotData.getAggregator(rowKey, []); - val = totalAggregator.value(); - td = document.createElement("td"); - td.className = "pvtTotal rowTotal"; - td.innerHTML = totalAggregator.format(val); - td.setAttribute("data-value", val); - td.setAttribute("data-for", "row" + i); - tr.appendChild(td); - result.appendChild(tr); - } - tr = document.createElement("tr"); - th = document.createElement("th"); - th.className = "pvtTotalLabel"; - th.innerHTML = opts.localeStrings.totals; - th.setAttribute("colspan", rowAttrs.length + (colAttrs.length === 0 ? 0 : 1)); - tr.appendChild(th); - for (j in colKeys) { - if (!__hasProp.call(colKeys, j)) continue; - colKey = colKeys[j]; - totalAggregator = pivotData.getAggregator([], colKey); - val = totalAggregator.value(); - td = document.createElement("td"); - td.className = "pvtTotal colTotal"; - td.innerHTML = totalAggregator.format(val); - td.setAttribute("data-value", val); - td.setAttribute("data-for", "col" + j); - tr.appendChild(td); - } - totalAggregator = pivotData.getAggregator([], []); - val = totalAggregator.value(); - td = document.createElement("td"); - td.className = "pvtGrandTotal"; - td.innerHTML = totalAggregator.format(val); - td.setAttribute("data-value", val); - tr.appendChild(td); - result.appendChild(tr); - result.setAttribute("data-numrows", rowKeys.length); - result.setAttribute("data-numcols", colKeys.length); - return result; - }; - - /* - Pivot Table core: create PivotData object and call Renderer on it - */ - $.fn.pivot = function(input, opts) { - var defaults, e, pivotData, result, x; - defaults = { - cols: [], - rows: [], - filter: function() { - return true; - }, - aggregator: aggregatorTemplates.count()(), - aggregatorName: "Count", - derivedAttributes: {}, - renderer: pivotTableRenderer, - rendererOptions: null, - localeStrings: locales.en.localeStrings - }; - opts = $.extend(defaults, opts); - result = null; - try { - pivotData = new PivotData(input, opts); - try { - result = opts.renderer(pivotData, opts.rendererOptions); - } catch (_error) { - e = _error; - if (typeof console !== "undefined" && console !== null) { - console.error(e.stack); - } - result = $("").html(opts.localeStrings.renderError); - } - } catch (_error) { - e = _error; - if (typeof console !== "undefined" && console !== null) { - console.error(e.stack); - } - result = $("").html(opts.localeStrings.computeError); - } - x = this[0]; - while (x.hasChildNodes()) { - x.removeChild(x.lastChild); - } - return this.append(result); - }; - - /* - Pivot Table UI: calls Pivot Table core above with options set by user - */ - $.fn.pivotUI = function(input, inputOpts, overwrite, locale) { - var a, aggregator, attrLength, axisValues, c, colList, defaults, e, existingOpts, i, initialRender, k, opts, pivotTable, refresh, refreshDelayed, renderer, rendererControl, shownAttributes, tblCols, tr1, tr2, uiTable, unusedAttrsVerticalAutoOverride, x, _fn, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, _ref4; - if (overwrite == null) { - overwrite = false; - } - if (locale == null) { - locale = "en"; - } - defaults = { - derivedAttributes: {}, - aggregators: locales[locale].aggregators, - renderers: locales[locale].renderers, - hiddenAttributes: [], - menuLimit: 200, - cols: [], - rows: [], - vals: [], - exclusions: {}, - unusedAttrsVertical: "auto", - autoSortUnusedAttrs: false, - rendererOptions: { - localeStrings: locales[locale].localeStrings - }, - onRefresh: null, - filter: function() { - return true; - }, - localeStrings: locales[locale].localeStrings - }; - existingOpts = this.data("pivotUIOptions"); - if ((existingOpts == null) || overwrite) { - opts = $.extend(defaults, inputOpts); - } else { - opts = existingOpts; - } - try { - input = PivotData.convertToArray(input); - tblCols = (function() { - var _ref, _results; - _ref = input[0]; - _results = []; - for (k in _ref) { - if (!__hasProp.call(_ref, k)) continue; - _results.push(k); - } - return _results; - })(); - _ref = opts.derivedAttributes; - for (c in _ref) { - if (!__hasProp.call(_ref, c)) continue; - if ((__indexOf.call(tblCols, c) < 0)) { - tblCols.push(c); - } - } - axisValues = {}; - for (_i = 0, _len = tblCols.length; _i < _len; _i++) { - x = tblCols[_i]; - axisValues[x] = {}; - } - PivotData.forEachRecord(input, opts.derivedAttributes, function(record) { - var v, _base, _results; - _results = []; - for (k in record) { - if (!__hasProp.call(record, k)) continue; - v = record[k]; - if (!(opts.filter(record))) { - continue; - } - if (v == null) { - v = "null"; - } - if ((_base = axisValues[k])[v] == null) { - _base[v] = 0; - } - _results.push(axisValues[k][v]++); - } - return _results; - }); - uiTable = $(""); - rendererControl = $("").appendTo(uiTable); - aggregator = $("").appendTo(uiTable); - tr2.append($("").append(rendererControl).append(colList)); - } - this.html(uiTable); - _ref3 = opts.cols; - for (_k = 0, _len2 = _ref3.length; _k < _len2; _k++) { - x = _ref3[_k]; - this.find(".pvtCols").append(this.find(".axis_" + (shownAttributes.indexOf(x)))); - } - _ref4 = opts.rows; - for (_l = 0, _len3 = _ref4.length; _l < _len3; _l++) { - x = _ref4[_l]; - this.find(".pvtRows").append(this.find(".axis_" + (shownAttributes.indexOf(x)))); - } - if (opts.aggregatorName != null) { - this.find(".pvtAggregator").val(opts.aggregatorName); - } - if (opts.rendererName != null) { - this.find(".pvtRenderer").val(opts.rendererName); - } - initialRender = true; - refreshDelayed = (function(_this) { - return function() { - var attr, exclusions, natSort, newDropdown, numInputsToProcess, pivotUIOptions, pvtVals, subopts, unusedAttrsContainer, vals, _len4, _m, _n, _ref5; - subopts = { - derivedAttributes: opts.derivedAttributes, - localeStrings: opts.localeStrings, - rendererOptions: opts.rendererOptions, - cols: [], - rows: [] - }; - numInputsToProcess = (_ref5 = opts.aggregators[aggregator.val()]([])().numInputs) != null ? _ref5 : 0; - vals = []; - _this.find(".pvtRows li span.pvtAttr").each(function() { - return subopts.rows.push($(this).data("attrName")); - }); - _this.find(".pvtCols li span.pvtAttr").each(function() { - return subopts.cols.push($(this).data("attrName")); - }); - _this.find(".pvtVals select.pvtAttrDropdown").each(function() { - if (numInputsToProcess === 0) { - return $(this).remove(); - } else { - numInputsToProcess--; - if ($(this).val() !== "") { - return vals.push($(this).val()); - } - } - }); - if (numInputsToProcess !== 0) { - pvtVals = _this.find(".pvtVals"); - for (x = _m = 0; 0 <= numInputsToProcess ? _m < numInputsToProcess : _m > numInputsToProcess; x = 0 <= numInputsToProcess ? ++_m : --_m) { - newDropdown = $("
      "); - renderer = $(""); - shownAttributes = (function() { - var _j, _len1, _results; - _results = []; - for (_j = 0, _len1 = tblCols.length; _j < _len1; _j++) { - c = tblCols[_j]; - if (__indexOf.call(opts.hiddenAttributes, c) < 0) { - _results.push(c); - } - } - return _results; - })(); - unusedAttrsVerticalAutoOverride = false; - if (opts.unusedAttrsVertical === "auto") { - attrLength = 0; - for (_j = 0, _len1 = shownAttributes.length; _j < _len1; _j++) { - a = shownAttributes[_j]; - attrLength += a.length; - } - unusedAttrsVerticalAutoOverride = attrLength > 120; - } - if (opts.unusedAttrsVertical === true || unusedAttrsVerticalAutoOverride) { - colList.addClass('pvtVertList'); - } else { - colList.addClass('pvtHorizList'); - } - _fn = function(c) { - var attrElem, btns, checkContainer, filterItem, filterItemExcluded, hasExcludedItem, keys, showFilterList, triangleLink, updateFilter, v, valueList, _k, _len2, _ref2; - keys = (function() { - var _results; - _results = []; - for (k in axisValues[c]) { - _results.push(k); - } - return _results; - })(); - hasExcludedItem = false; - valueList = $("
      ").addClass('pvtFilterBox').hide(); - valueList.append($("

      ").text("" + c + " (" + keys.length + ")")); - if (keys.length > opts.menuLimit) { - valueList.append($("

      ").html(opts.localeStrings.tooMany)); - } else { - btns = $("

      ").appendTo(valueList); - btns.append($("

      ").appendTo(tr1).append(aggregator).append($("
      ")); - $("
      ").appendTo(tr1); - tr2 = $("
      ")); - pivotTable = $("").appendTo(tr2); - if (opts.unusedAttrsVertical === true || unusedAttrsVerticalAutoOverride) { - uiTable.find('tr:nth-child(1)').prepend(rendererControl); - uiTable.find('tr:nth-child(2)').prepend(colList); - } else { - uiTable.prepend($("
      "),F=t("").appendTo(L),l=t("").appendTo(L),R.append(t("").append(F).append(g)),this.html(L),Q=C.cols,U=0,B=Q.length;B>U;U++)M=Q[U],this.find(".pvtCols").append(this.find(".axis_"+E.indexOf(M)));for(W=C.rows,V=0,P=W.length;P>V;V++)M=W[V],this.find(".pvtRows").append(this.find(".axis_"+E.indexOf(M)));null!=C.aggregatorName&&this.find(".pvtAggregator").val(C.aggregatorName),null!=C.rendererName&&this.find(".pvtRenderer").val(C.rendererName),y=!0,x=function(r){return function(){var o,a,i,s,u,c,p,h,d,f,g,m,v,b;if(h={derivedAttributes:C.derivedAttributes,localeStrings:C.localeStrings,rendererOptions:C.rendererOptions,cols:[],rows:[]},u=null!=(b=C.aggregators[l.val()]([])().numInputs)?b:0,f=[],r.find(".pvtRows li span.pvtAttr").each(function(){return h.rows.push(t(this).data("attrName"))}),r.find(".pvtCols li span.pvtAttr").each(function(){return h.cols.push(t(this).data("attrName"))}),r.find(".pvtVals select.pvtAttrDropdown").each(function(){return 0===u?t(this).remove():(u--,""!==t(this).val()?f.push(t(this).val()):void 0)}),0!==u)for(p=r.find(".pvtVals"),M=m=0;u>=0?u>m:m>u;M=u>=0?++m:--m){for(s=t("
      "),N=t(""),E=function(){var t,n,r;for(r=[],t=0,n=D.length;n>t;t++)f=D[t],e.call(C.hiddenAttributes,f)<0&&r.push(f);return r}(),k=!1,"auto"===C.unusedAttrsVertical){for(c=0,q=0,H=E.length;H>q;q++)u=E[q],c+=u.length;k=c>120}g.addClass(C.unusedAttrsVertical===!0||k?"pvtVertList":"pvtHorizList"),I=function(n){var r,o,a,i,s,u,l,c,p,f,m,v,b,y,S;if(l=function(){var t;t=[];for(w in h[n])t.push(w);return t}(),u=!1,v=t("
      ").addClass("pvtFilterBox").hide(),v.append(t("

      ").text(""+n+" ("+l.length+")")),l.length>C.menuLimit)v.append(t("

      ").html(C.localeStrings.tooMany));else for(o=t("

      ").appendTo(v),o.append(t("

      ").appendTo(O).append(l).append(t("
      ")),t("
      ").appendTo(O),R=t("
      ")),S=t("").appendTo(R),C.unusedAttrsVertical===!0||k?(L.find("tr:nth-child(1)").prepend(F),L.find("tr:nth-child(2)").prepend(g)):L.prepend(t("
      \")\n\n #renderer control\n rendererControl = $(\"\").appendTo(uiTable)\n\n #aggregator menu and value area\n\n aggregator = $(\"\").appendTo(uiTable)\n\n #row axes\n tr2.append $(\"\").append(rendererControl).append(colList)\n\n #render the UI in its default state\n @html uiTable\n\n #set up the UI initial state as requested by moving elements around\n\n for x in opts.cols\n @find(\".pvtCols\").append @find(\".axis_#{shownAttributes.indexOf(x)}\")\n for x in opts.rows\n @find(\".pvtRows\").append @find(\".axis_#{shownAttributes.indexOf(x)}\")\n if opts.aggregatorName?\n @find(\".pvtAggregator\").val opts.aggregatorName\n if opts.rendererName?\n @find(\".pvtRenderer\").val opts.rendererName\n\n initialRender = true\n\n #set up for refreshing\n refreshDelayed = =>\n subopts =\n derivedAttributes: opts.derivedAttributes\n localeStrings: opts.localeStrings\n rendererOptions: opts.rendererOptions\n cols: [], rows: []\n\n numInputsToProcess = opts.aggregators[aggregator.val()]([])().numInputs ? 0\n vals = []\n @find(\".pvtRows li span.pvtAttr\").each -> subopts.rows.push $(this).data(\"attrName\")\n @find(\".pvtCols li span.pvtAttr\").each -> subopts.cols.push $(this).data(\"attrName\")\n @find(\".pvtVals select.pvtAttrDropdown\").each ->\n if numInputsToProcess == 0\n $(this).remove()\n else\n numInputsToProcess--\n vals.push $(this).val() if $(this).val() != \"\"\n\n if numInputsToProcess != 0\n pvtVals = @find(\".pvtVals\")\n for x in [0...numInputsToProcess]\n newDropdown = $(\"").val(location.protocol+"//"+location.host+location.pathname+location.search+"#"+n.param(e.options.createShareLink(e)));t.focus(function(){var e=n(this);e.select();e.mouseup(function(){e.unbind("mouseup");return!1})});o.empty().append(n("
      ",{"class":"inputWrapper"}).append(t));if(e.options.createShortLink){o.addClass("enableShort");n("").addClass("yasqe_btn yasqe_btn-sm yasqe_btn-primary").click(function(){n(this).parent().find("button").attr("disabled","disabled");e.options.createShortLink(t.val(),function(e,i){if(e){t.remove();o.find(".inputWrapper").append(n("",{"class":"shortlinkErr"}).text(e))}else t.val(i).focus()})}).appendTo(o)}n("").addClass("yasqe_btn yasqe_btn-sm yasqe_btn-primary").click(function(){n(this).parent().find("button").attr("disabled","disabled");t.val(p.getAsCurl(e)).focus()}).appendTo(o);var s=i.position();o.css("top",s.top+i.outerHeight()+parseInt(o.css("padding-top"))+"px").css("left",s.left+i.outerWidth()-o.outerWidth()+"px");t.focus()}).addClass("yasqe_share").attr("title","Share your query").appendTo(e.buttons)}var r=n("
      ",{"class":"fullscreenToggleBtns"}).append(n(s.svg.getElement(a.fullscreen)).addClass("yasqe_fullscreenBtn").attr("title","Set editor full screen").click(function(){e.setOption("fullScreen",!0)})).append(n(s.svg.getElement(a.smallscreen)).addClass("yasqe_smallscreenBtn").attr("title","Set editor to normale size").click(function(){e.setOption("fullScreen",!1)}));e.buttons.append(r);if(e.options.sparql.showQueryButton){n("
      ",{"class":"yasqe_queryButton"}).click(function(){if(n(this).hasClass("query_busy")){e.xhr&&e.xhr.abort();p.updateQueryButton(e)}else e.query()}).appendTo(e.buttons);p.updateQueryButton(e)}};var m={busy:"loader",valid:"query",error:"queryInvalid"};p.updateQueryButton=function(e,i){var r=n(e.getWrapperElement()).find(".yasqe_queryButton");if(0!=r.length){if(!i){i="valid";e.queryValid===!1&&(i="error")}if(i!=e.queryStatus){r.empty().removeClass(function(e,i){return i.split(" ").filter(function(e){return 0==e.indexOf("query_")}).join(" ")});if("busy"==i){r.append(n("
      ",{"class":"loader"}));e.queryStatus=i}else if("valid"==i||"error"==i){r.addClass("query_"+i);s.svg.draw(r,a[m[i]]);e.queryStatus=i}}}};p.fromTextArea=function(e,i){i=l(i);var r=(n("
      ",{"class":"yasqe"}).insertBefore(n(e)).append(n(e)),E(o.fromTextArea(e,i)));d(r);return r};p.storeQuery=function(e){var i=t.getPersistencyId(e,e.options.persistent);i&&s.storage.set(i,e.getValue(),"month")};p.commentLines=function(e){for(var i=e.getCursor(!0).line,r=e.getCursor(!1).line,n=Math.min(i,r),o=Math.max(i,r),t=!0,s=n;o>=s;s++){var a=e.getLine(s);if(0==a.length||"#"!=a.substring(0,1)){t=!1;break}}for(var s=n;o>=s;s++)t?e.replaceRange("",{line:s,ch:0},{line:s,ch:1}):e.replaceRange("#",{line:s,ch:0})};p.copyLineUp=function(e){var i=e.getCursor(),r=e.lineCount();e.replaceRange("\n",{line:r-1,ch:e.getLine(r-1).length});for(var n=r;n>i.line;n--){var o=e.getLine(n-1);e.replaceRange(o,{line:n,ch:0},{line:n,ch:e.getLine(n).length})}};p.copyLineDown=function(e){p.copyLineUp(e);var i=e.getCursor();i.line++;e.setCursor(i)};p.doAutoFormat=function(e){if(e.somethingSelected()){var i={line:e.getCursor(!1).line,ch:e.getSelection().length};L(e,e.getCursor(!0),i)}else{var r=e.lineCount(),n=e.getTextArea().value.length;L(e,{line:0,ch:0},{line:r,ch:n})}};var L=function(e,i,r){var n=e.indexFromPos(i),o=e.indexFromPos(r),t=T(e.getValue(),n,o);e.operation(function(){e.replaceRange(t,i,r);for(var o=e.posFromIndex(n).line,s=e.posFromIndex(n+t.length).line,a=o;s>=a;a++)e.indentLine(a,"smart")})},T=function(e,i,r){e=e.substring(i,r);var t=[["keyword","ws","prefixed","ws","uri"],["keyword","ws","uri"]],s=["{",".",";"],a=["}"],p=function(e,i){for(var r=0;rp)break;tokenType=e.getTokenTypeAt(o.Pos(i,p+1));if(!/^(comment|string)/.test(tokenType))return p+1;t=p-1}else{if(1==a)break;a=1;t=n.length}}}var o=function(){try{return e("codemirror")}catch(i){return window.CodeMirror}}(),t=e("./tokenUtils.js"),s="PREFIX";i.exports={findFirstPrefixLine:function(e){for(var i=e.lastLine(),r=0;i>=r;++r)if(n(e,r)>=0)return r}};o.registerHelper("fold","prefix",function(e,i){function r(){for(var i=!1,r=a-1;r>=0;r--)if(e.getLine(r).toUpperCase().indexOf(s)>=0){i=!0;break}return i}var a=i.line,p=e.getLine(a),l=function(i,r){var n=e.getTokenAt(o.Pos(i,r+1));if(!n||"keyword"!=n.type)return-1;var s=t.getNextNonWsToken(e,i,n.end+1);if(!s||"string-2"!=s.type)return-1;var a=t.getNextNonWsToken(e,i,s.end+1);return a&&"variable-3"==a.type?a.end:-1};if(!r()){var E=n(e,a,i.ch,p);if(null!=E){for(var u,c="{",d=!1,N=e.lastLine(),x=l(a,E),I=a,m=a;N>=m&&!d;++m)for(var L=e.getLine(m),T=m==a?E+1:0;;){!d&&L.indexOf(c)>=0&&(d=!0);var A=L.toUpperCase().indexOf(s,T);if(!(A>=0))break;if((u=l(m,A))>0){x=u;I=m;T=x}T++}return{from:o.Pos(a,E+s.length),to:o.Pos(I,x)}}}})},{"./tokenUtils.js":34,codemirror:void 0}],32:[function(e,i,r){"use strict";var n=function(e,i){var r=e.getPrefixesFromQuery();if("string"==typeof i)o(e,i);else for(var n in i)n in r||o(e,n+": <"+i[n]+">");e.collapsePrefixes(!1)},o=function(e,i){for(var r=null,n=0,o=e.lineCount(),t=0;o>t;t++){var s=e.getNextNonWsToken(t);if(null!=s&&("PREFIX"==s.string||"BASE"==s.string)){r=s;n=t}}if(null==r)e.replaceRange("PREFIX "+i+"\n",{line:0,ch:0});else{var p=a(e,n);e.replaceRange("\n"+p+"PREFIX "+i,{line:n})}e.collapsePrefixes(!1)},t=function(e,i){var r=function(e){return e.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")};for(var n in i)e.setValue(e.getValue().replace(new RegExp("PREFIX\\s*"+n+":\\s*"+r("<"+i[n]+">")+"\\s*","ig"),""));e.collapsePrefixes(!1)},s=function(e){for(var i={},r=!0,n=function(o,s){if(r){s||(s=1);var a=e.getNextNonWsToken(t,s);if(a){-1==a.state.possibleCurrent.indexOf("PREFIX")&&-1==a.state.possibleNext.indexOf("PREFIX")&&(r=!1);if("PREFIX"==a.string.toUpperCase()){var p=e.getNextNonWsToken(t,a.end+1);if(p){var l=e.getNextNonWsToken(t,p.end+1);if(l){var E=l.string;0==E.indexOf("<")&&(E=E.substring(1));">"==E.slice(-1)&&(E=E.substring(0,E.length-1));i[p.string.slice(0,-1)]=E;n(o,l.end+1)}else n(o,p.end+1)}else n(o,a.end+1)}else n(o,a.end+1)}}},o=e.lineCount(),t=0;o>t&&r;t++)n(t);return i},a=function(e,i,r){void 0==r&&(r=1);var n=e.getTokenAt({line:i,ch:r});return null==n||void 0==n||"ws"!=n.type?"":n.string+a(e,i,n.end+1)};i.exports={addPrefixes:n,getPrefixesFromQuery:s,removePrefixes:t}},{}],33:[function(e,i,r){"use strict";var n=function(){try{return e("jquery")}catch(i){return window.jQuery}}(),o=e("./utils.js"),t=e("./main.js");t.getAjaxConfig=function(i,r){var o="function"==typeof r?r:null,a="object"==typeof r?r:{};i.options.sparql&&(a=n.extend({},i.options.sparql,a));a.handlers&&n.extend(!0,a.callbacks,a.handlers);if(a.endpoint&&0!=a.endpoint.length){var p={url:"function"==typeof a.endpoint?a.endpoint(i):a.endpoint,type:"function"==typeof a.requestMethod?a.requestMethod(i):a.requestMethod,headers:{Accept:s(i,a)}};a.xhrFields&&(p.xhrFields=a.xhrFields);var l=!1;if(a.callbacks)for(var E in a.callbacks)if(a.callbacks[E]){l=!0;p[E]=a.callbacks[E]}p.data=i.getUrlArguments(a);if(l||o){o&&(p.complete=o);a.headers&&!n.isEmptyObject(a.headers)&&n.extend(p.headers,a.headers);var u=new Date,c=function(){i.lastQueryDuration=new Date-u;t.updateQueryButton(i);i.setBackdrop(!1)},d=[function(){e("./main.js").signal(i,"queryFinish",arguments)},c];p.complete&&d.push(p.complete);p.complete=d;return p}}};t.executeQuery=function(e,i){t.signal(e,"query",e,i);t.updateQueryButton(e,"busy");e.setBackdrop(!0);e.xhr=n.ajax(t.getAjaxConfig(e,i))};t.getUrlArguments=function(e,i){var r=e.getQueryMode(),t=[{name:o.getString(e,e.options.sparql.queryName),value:i.getQueryForAjax?i.getQueryForAjax(e):e.getValue()}];if(i.namedGraphs&&i.namedGraphs.length>0)for(var s="query"==r?"named-graph-uri":"using-named-graph-uri ",a=0;a0)for(var s="query"==r?"default-graph-uri":"using-graph-uri ",a=0;a0&&n.merge(t,i.args);return t};var s=function(e,i){var r=null;if(!i.acceptHeader||i.acceptHeaderGraph||i.acceptHeaderSelect||i.acceptHeaderUpdate)if("update"==e.getQueryMode())r="function"==typeof i.acceptHeader?i.acceptHeaderUpdate(e):i.acceptHeaderUpdate;else{var n=e.getQueryType();r="DESCRIBE"==n||"CONSTRUCT"==n?"function"==typeof i.acceptHeaderGraph?i.acceptHeaderGraph(e):i.acceptHeaderGraph:"function"==typeof i.acceptHeaderSelect?i.acceptHeaderSelect(e):i.acceptHeaderSelect}else r="function"==typeof i.acceptHeader?i.acceptHeader(e):i.acceptHeader;return r};i.exports={getAjaxConfig:t.getAjaxConfig}},{"./main.js":30,"./utils.js":36,jquery:void 0}],34:[function(e,i,r){"use strict";var n=function(e,i,r){r||(r=e.getCursor());i||(i=e.getTokenAt(r));var o=e.getTokenAt({line:r.line,ch:i.start});if(null!=o.type&&"ws"!=o.type&&null!=i.type&&"ws"!=i.type){i.start=o.start;i.string=o.string+i.string;return n(e,i,{line:r.line,ch:o.start})}if(null!=i.type&&"ws"==i.type){i.start=i.start+1;i.string=i.string.substring(1);return i}return i},o=function(e,i,r){var n=e.getTokenAt({line:i,ch:r.start});null!=n&&"ws"==n.type&&(n=o(e,i,n));return n},t=function(e,i,r){void 0==r&&(r=1);var n=e.getTokenAt({line:i,ch:r});return null==n||void 0==n||n.end").addClass("yasqe_tooltip").html(r).appendTo(i);t()},function(){n(".yasqe_tooltip").remove()});var t=function(){if(n(e.getWrapperElement()).offset().top>=o.offset().top){o.css("bottom","auto");o.css("top","26px")}}}},{"./utils.js":36,jquery:void 0}],36:[function(e,i,r){"use strict";var n=function(){try{return e("jquery")}catch(i){return window.jQuery}}(),o=function(e,i){var r=!1;try{void 0!==e[i]&&(r=!0)}catch(n){}return r},t=function(e,i){var r=null;i&&(r="string"==typeof i?i:i(e));return r},s=function(){function e(e){var i,r,o;i=n(e).offset();r=n(e).width();o=n(e).height();return[[i.left,i.left+r],[i.top,i.top+o]]}function i(e,i){var r,n;r=e[0]n[0]||r[0]===n[0]}return function(r,n){var o=e(r),t=e(n);return i(o[0],t[0])&&i(o[1],t[1])}}(),a=function(e,i){return"function"==typeof i?i(e):i};i.exports={keyExists:o,getPersistencyId:t,elementsOverlap:s,getString:a}},{jquery:void 0}]},{},[1])(1)}); -//# sourceMappingURL=yasqe.min.js.map diff --git a/triplestores/fuseki/webapp/js/lib/yasqe.min.js.map b/triplestores/fuseki/webapp/js/lib/yasqe.min.js.map deleted file mode 100644 index 6e8a15a388..0000000000 --- a/triplestores/fuseki/webapp/js/lib/yasqe.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["yasqe.min.js","node_modules/store/store.js"],"names":["e","exports","module","define","amd","f","window","global","self","YASQE","t","n","r","s","o","u","a","require","i","Error","code","l","call","length",1,"./main.js",2,"$","jQuery","deparam","params","coerce","obj","coerce_types","true","false","null","each","replace","split","j","v","val","param","key","decodeURIComponent","cur","keys","keys_last","test","shift","concat","isNaN","undefined","isArray","push","jquery",3,"table","*[&&,valueLogical]","&&","AS",")",",","||",";","*[,,expression]","*[,,objectPath]",".","]","{","OPTIONAL","MINUS","GRAPH","SERVICE","FILTER","BIND","VALUES","}","*[,,object]","*[/,pathEltOrInverse]","/","|","(","[","VAR1","VAR2","NIL","IRI_REF","TRUE","FALSE","BLANK_NODE_LABEL","ANON","PNAME_LN","PNAME_NS","STRING_LITERAL1","STRING_LITERAL2","STRING_LITERAL_LONG1","STRING_LITERAL_LONG2","INTEGER","DECIMAL","DOUBLE","INTEGER_POSITIVE","DECIMAL_POSITIVE","DOUBLE_POSITIVE","INTEGER_NEGATIVE","DECIMAL_NEGATIVE","DOUBLE_NEGATIVE","*[;,?[or([verbPath,verbSimple]),objectList]]","*[;,?[verb,objectList]]","*[UNION,groupGraphPattern]","UNION","*[graphPatternNotTriples,?.,?triplesBlock]","*[quadsNotTriples,?.,?triplesTemplate]","*[|,pathOneInPropertySet]","*[|,pathSequence]","*[||,conditionalAndExpression]","*dataBlockValue","UNDEF","*datasetClause","FROM","WHERE","*describeDatasetClause","ORDER","HAVING","GROUP","LIMIT","OFFSET","*graphNode","*graphNodePath","*groupCondition","STR","LANG","LANGMATCHES","DATATYPE","BOUND","IRI","URI","BNODE","RAND","ABS","CEIL","FLOOR","ROUND","CONCAT","STRLEN","UCASE","LCASE","ENCODE_FOR_URI","CONTAINS","STRSTARTS","STRENDS","STRBEFORE","STRAFTER","YEAR","MONTH","DAY","HOURS","MINUTES","SECONDS","TIMEZONE","TZ","NOW","UUID","STRUUID","MD5","SHA1","SHA256","SHA384","SHA512","COALESCE","IF","STRLANG","STRDT","SAMETERM","ISIRI","ISURI","ISBLANK","ISLITERAL","ISNUMERIC","SUBSTR","REPLACE","REGEX","EXISTS","NOT","*havingCondition","*or([[ (,*dataBlockValue,)],NIL])","*or([[*,unaryExpression],[/,unaryExpression]])","*","=","!=","<",">","<=",">=","IN","+","-","*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])","*or([baseDecl,prefixDecl])","BASE","PREFIX","CONSTRUCT","DESCRIBE","ASK","INSERT","DELETE","SELECT","LOAD","CLEAR","DROP","ADD","MOVE","COPY","CREATE","WITH","*or([var,[ (,expression,AS,var,)]])","*orderCondition","ASC","DESC","*usingClause","USING","*var","*varOrIRIref","+graphNode","+graphNodePath","+groupCondition","+havingCondition","+or([var,[ (,expression,AS,var,)]])","+orderCondition","+varOrIRIref","?.","?DISTINCT","DISTINCT","!","COUNT","SUM","MIN","MAX","AVG","SAMPLE","GROUP_CONCAT","?GRAPH","?SILENT","SILENT","?SILENT_1","?SILENT_2","DEFAULT","NAMED","ALL","?SILENT_3","?SILENT_4","?WHERE","?[,,expression]","?[.,?constructTriples]","?[.,?triplesBlock]","?[.,?triplesTemplate]","?[;,SEPARATOR,=,string]","?[;,update]","?[AS,var]","?[INTO,graphRef]","INTO","?[or([verbPath,verbSimple]),objectList]","^","?[pathOneInPropertySet,*[|,pathOneInPropertySet]]","?[update1,?[;,update]]","?[verb,objectList]","?argList","?constructTriples","?groupClause","?havingClause","?insertClause","?limitClause","?limitOffsetClauses","?offsetClause","?or([DISTINCT,REDUCED])","REDUCED","?or([LANGTAG,[^^,iriRef]])","LANGTAG","^^","?or([[*,unaryExpression],[/,unaryExpression]])","?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])","?orderClause","?pathMod","?","?triplesBlock","?triplesTemplate","?whereClause","[ (,*dataBlockValue,)]","[ (,*var,)]","[ (,expression,)]","[ (,expression,AS,var,)]","[!=,numericExpression]","[&&,valueLogical]","[*,unaryExpression]","[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]","[+,multiplicativeExpression]","[,,expression]","[,,integer,}]","[,,objectPath]","[,,object]","[,,or([},[integer,}]])]","[-,multiplicativeExpression]","[.,?constructTriples]","[.,?triplesBlock]","[.,?triplesTemplate]","[/,pathEltOrInverse]","[/,unaryExpression]","[;,?[or([verbPath,verbSimple]),objectList]]","[;,?[verb,objectList]]","[;,SEPARATOR,=,string]","[;,update]","[<,numericExpression]","[<=,numericExpression]","[=,numericExpression]","[>,numericExpression]","[>=,numericExpression]","[AS,var]","[IN,expressionList]","[INTO,graphRef]","[NAMED,iriRef]","[NOT,IN,expressionList]","[UNION,groupGraphPattern]","[^^,iriRef]","[constructTemplate,*datasetClause,whereClause,solutionModifier]","[deleteClause,?insertClause]","[graphPatternNotTriples,?.,?triplesBlock]","[integer,or([[,,or([},[integer,}]])],}])]","[integer,}]","[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]","[or([verbPath,verbSimple]),objectList]","[pathOneInPropertySet,*[|,pathOneInPropertySet]]","[quadsNotTriples,?.,?triplesTemplate]","[update1,?[;,update]]","[verb,objectList]","[|,pathOneInPropertySet]","[|,pathSequence]","[||,conditionalAndExpression]","add","additiveExpression","aggregate","allowBnodes","allowVars","argList","askQuery","baseDecl","bind","blankNode","blankNodePropertyList","blankNodePropertyListPath","booleanLiteral","brackettedExpression","builtInCall","clear","collection","collectionPath","conditionalAndExpression","conditionalOrExpression","constraint","constructQuery","constructTemplate","constructTriples","copy","create","dataBlock","dataBlockValue","datasetClause","defaultGraphClause","delete1","DATA","deleteClause","describeDatasetClause","describeQuery","disallowBnodes","disallowVars","drop","existsFunc","expression","expressionList","filter","functionCall","graphGraphPattern","graphNode","graphNodePath","graphOrDefault","graphPatternNotTriples","graphRef","graphRefAll","graphTerm","groupClause","groupCondition","groupGraphPattern","groupGraphPatternSub","groupOrUnionGraphPattern","havingClause","havingCondition","inlineData","inlineDataFull","inlineDataOneVar","insert1","insertClause","integer","iriRef","iriRefOrFunction","limitClause","limitOffsetClauses","load","minusGraphPattern","modify","move","multiplicativeExpression","namedGraphClause","notExistsFunc","numericExpression","numericLiteral","numericLiteralNegative","numericLiteralPositive","numericLiteralUnsigned","object","objectList","objectListPath","objectPath","offsetClause","optionalGraphPattern","or([*,expression])","or([+or([var,[ (,expression,AS,var,)]]),*])","or([+varOrIRIref,*])","or([ASC,DESC])","or([DISTINCT,REDUCED])","or([LANGTAG,[^^,iriRef]])","or([NIL,[ (,*var,)]])","or([[ (,*dataBlockValue,)],NIL])","or([[ (,expression,)],NIL])","or([[*,unaryExpression],[/,unaryExpression]])","or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])","or([[,,or([},[integer,}]])],}])","or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])","or([[constructTemplate,*datasetClause,whereClause,solutionModifier],[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]])","or([[deleteClause,?insertClause],insertClause])","or([[integer,or([[,,or([},[integer,}]])],}])],[,,integer,}]])","or([baseDecl,prefixDecl])","or([defaultGraphClause,namedGraphClause])","or([inlineDataOneVar,inlineDataFull])","or([iriRef,[NAMED,iriRef]])","or([iriRef,a])","or([numericLiteralPositive,numericLiteralNegative])","or([queryAll,updateAll])","or([selectQuery,constructQuery,describeQuery,askQuery])","or([subSelect,groupGraphPatternSub])","or([var,[ (,expression,AS,var,)]])","or([verbPath,verbSimple])","or([},[integer,}]])","orderClause","orderCondition","path","pathAlternative","pathElt","pathEltOrInverse","pathMod","pathNegatedPropertySet","pathOneInPropertySet","pathPrimary","pathSequence","prefixDecl","prefixedName","primaryExpression","prologue","propertyList","propertyListNotEmpty","propertyListPath","propertyListPathNotEmpty","quadData","quadDataNoBnodes","quadPattern","quadPatternNoBnodes","quads","quadsNotTriples","queryAll","rdfLiteral","regexExpression","relationalExpression","selectClause","selectQuery","serviceGraphPattern","solutionModifier","sourceSelector","sparql11","storeProperty","strReplaceExpression","string","subSelect","substringExpression","triplesBlock","triplesNode","triplesNodePath","triplesSameSubject","triplesSameSubjectPath","triplesTemplate","unaryExpression","update","update1","updateAll","usingClause","valueLogical","valuesClause","var","varOrIRIref","varOrTerm","verb","verbPath","verbSimple","whereClause","keywords","punct","startSymbol","acceptEmpty",4,"CodeMirror","defineMode","config","parserConfig","getPossibles","symbol","possibles","possiblesOb","ll1_table","property","toString","tokenBase","stream","state","nextToken","consumed","inLiteral","closingQuotes","match","stringLiteralLongRegex","contents","regex","closing","returnObj","quotePos","cat","STRING_LITERAL_LONG","CAT","style","complete","text","start","quoteType","quotes","terminals","name","grammar","current","toUpperCase","recordFailurePos","col","column","errorStartPos","errorEndPos","tokenOb","setQueryType","queryType","setSideConditions","topSymbol","checkSideConditions","pos","possibleCurrent","possibleNext","OK","finished","token","stack","pop","nextSymbols","allNillable","sp","item","lastProperty","indexOf","lastPredicateOffset","indent","textAfter","closeBracket","substr","dn","indentTop","indentTable","indentUnit","PN_CHARS_BASE","PN_CHARS_U","PN_CHARS","VARNAME","PN_PREFIX","HEX","PERCENT","PN_LOCAL_ESC","PLX","PN_LOCAL","EXPONENT","ECHAR","hex4","unicode","SINGLE","QUOTES","CONTENTS","COMPLETE","RegExp","WS","COMMENT","WS_OR_COMMENT_STAR","*[,, object]","*[(,),object]","*[(,),objectPath]","startState","base","tokenize","electricChars","defineMIME","./_tokenizer-table.js","codemirror",5,"Trie","this","words","prefixes","children","prototype","insert","str","k","child","T","remove","strOld","strNew","countWord","ret","countPrefix","find","getAllWords","autoComplete",6,"mod","setFullscreen","cm","wrap","getWrapperElement","fullScreenRestore","scrollTop","pageYOffset","scrollLeft","pageXOffset","width","height","className","document","documentElement","overflow","refresh","setNormal","info","scrollTo","defineOption","old","Init",7,"findMatchingBracket","where","strict","line","getLineHandle","ch","matching","charAt","dir","getTokenTypeAt","Pos","found","scanForBracket","from","to","forward","maxScanLen","maxScanLineLength","maxScanLines","re","bracketRegex","lineEnd","Math","min","lastLine","max","firstLine","lineNo","getLine","end","matchBrackets","autoclear","maxHighlightLen","maxHighlightLineLength","marks","ranges","listSelections","empty","head","markText","ie_lt8","focused","focus","operation","setTimeout","doMatchBrackets","currentlyHighlighted","navigator","userAgent","documentMode","off","on","defineExtension",8,"registerHelper","findOpening","openCh","at","pass","lineText","lastIndexOf","tokenType","startCh","startToken","endToken","endCh","count","outer","nextOpen","nextClose","hasImport","getTokenAt","type","semi","prev","has","next","clipPos","hasInclude","slice",9,"doFold","options","force","getRange","allowFolded","range","finder","minSize","findMarksAt","__isFold","cleared","getOption","myWidget","makeWidget","myRange","e_preventDefault","replacedWith","clearOnEnter","signal","widget","createTextNode","createElement","appendChild","editorOptions","foldOptions","defaultOptions","newFoldFunction","rangeFinder","commands","toggleFold","foldCode","getCursor","fold","unfold","foldAll","unfoldAll","funcs","Array","arguments","helpers","getHelpers","auto","minFoldSize","scanUp",10,"State","parseOptions","opts","gutter","indicatorOpen","indicatorFolded","isFolded","marker","spec","elt","cloneNode","updateFoldInfo","foldGutter","foldOption","func","eachLine","mark","setGutterMarker","updateInViewport","vp","getViewport","onGutterClick","folded","onChange","clearTimeout","changeUpdate","foldOnChangeTimeSpan","onViewportChange","updateViewportTimeSpan","onFold","clearGutter","./foldcode",11,"cmp","b","Iter","tagAt","iter","nextLine","prevLine","toTagEnd","gt","lastSlash","selfClose","toTagStart","lt","xmlTagStart","lastIndex","exec","index","toNextTag","toPrevTag","findMatchingClose","tag","startLine","findMatchingOpen","endLine","nameStartChar","nameChar","openTag","close","findMatchingTag","here","open","findEnclosingTag","scanForClosingTag",12,"Completion","debounce","tick","startPos","startLen","getSelection","activityFunc","cursorActivity","editor","hintOptions","out","prop","hint","resolve","getText","completion","buildKeyMap","handle","addBinding","bound","baseMap","hasOwnProperty","ourMap","Up","moveFocus","Down","PageUp","menuSize","PageDown","Home","setFocus","End","Enter","pick","Tab","Esc","custom","customKeys","extra","extraKeys","getHintElement","hintsElement","el","nodeName","parentNode","Widget","data","picked","hints","selectedHint","completions","list","HINT_ELEMENT_CLASS","ACTIVE_HINT_ELEMENT_CLASS","render","displayText","hintId","cursorCoords","alignWithWord","left","top","bottom","below","winW","innerWidth","body","offsetWidth","winH","innerHeight","offsetHeight","container","box","getBoundingClientRect","overlapY","curTop","cursor","overlapX","right","addKeyMap","keyMap","avoidWrap","changeActive","screenAmount","closeOnUnfocus","closingOnBlur","onBlur","onFocus","startScroll","getScrollInfo","onScroll","curScroll","newTop","point","target","srcElement","completeOnSingleClick","firstChild","applicableHelpers","somethingSelected","result","supportsSelection","resolveAutoHints","resolved","async","callback","run","app","helper","getHelper","fromList","anyword","showHint","getHints","newOpts","selections","anchor","completionActive","requestAnimationFrame","fn","cancelAnimationFrame","active","replaceRange","closeCharacters","disable","first","myTick","finishUpdate","cmpPos","completeSingle","removeChild","removeKeyMap","node","childNodes","offsetTop","clientHeight","floor","term","word","autocomplete",13,"runMode","modespec","mode","getMode","defaults","ie","ie_lt9","tabSize","innerHTML","content","idx","size","lines","splitLines","StringStream","blankLine","eol",14,"SearchCursor","doc","query","caseFold","atOccurrence","source","ignoreCase","matches","reverse","cutOff","newMatch","matchLen","origQuery","toLowerCase","orig","adjustPos","origTarget","last","ln","cut","pos1","len1","findNext","findPrevious","savePosAndFail","maxLine","lineCount","newText","origin","defineDocExtension","getSearchCursor","setSelections",15,"root","factory","store","isLocalStorageNameSupported","localStorageName","win","err","storage","scriptTag","disabled","version","set","value","get","defaultVal","transact","transactionFn","getAll","forEach","serialize","JSON","stringify","deserialize","parse","setItem","getItem","removeItem","addBehavior","storageOwner","storageContainer","ActiveXObject","write","w","frames","withIEStorage","storeFunction","args","unshift","apply","forbiddenCharsRegex","ieKeyFix","setAttribute","save","getAttribute","removeAttribute","attributes","XMLDocument","attr","testKey","enabled",16,"_args","_from","_id","_inCache","_installable","_location","_npmUser","email","_npmVersion","_phantomChildren","_requested","raw","rawSpec","scope","_requiredBy","_shrinkwrap","_spec","_where","author","bugs","url","dependencies","description","devDependencies","directories","dist","shasum","tarball","homepage","licenses","main","maintainers","optionalDependencies","readme","repository",17,"console","log","svg","yasgui-utils","nestedExists","../package.json","./storage.js","./svg.js",18,"times","day","month","year","exp","XMLSerializer","serializeToString","time","Date","getTime","removeAll",19,"draw","parent","svgString","getElement","append","parser","DOMParser","dom","parseFromString","svgContainer",20,"license","bootstrap-sass","browserify","browserify-transform-tools","exorcist","gulp","gulp-autoprefixer","gulp-bump","gulp-concat","gulp-connect","gulp-cssimport","gulp-cssnano","gulp-embedlr","gulp-filter","gulp-git","gulp-jsvalidate","gulp-livereload","gulp-minify-css","gulp-notify","gulp-rename","gulp-sass","gulp-sourcemaps","gulp-streamify","gulp-tag-version","gulp-uglify","node-sass","require-dir","run-sequence","vinyl-buffer","vinyl-source-stream","vinyl-transform","watchify","web","optionalShim","../../lib/codemirror",21,"utils","yutils","yasqe","completionNotifications","completers","tries","eventInfo","needPossibleAdjustment","notificationName","is","scrollBar","offset","outerWidth","notification","css","storeBulkCompletions","completer","storageId","getPersistencyId","persistent","initCompleter","completionInit","bulk","storeArrayAsBulk","suggestions","completionsFromStorage","persistencyIdentifier","Function","fromAutoShow","tryHintType","autoShow","hintConfig","wrappedHintCallback","getCompletionHintsObject","completerName","inArray","autocompleters","isValidCompletionPosition","callbacks","validPosition","success","invalidPosition","getSuggestionsFromToken","partialToken","stringToAutocomplete","autocompletionString","partialTokenLength","getSuggestionsAsHintObject","getCompleteToken","preProcessToken","wrappedCallback","hintList","suggestedString","postProcessToken","selectHint","completionToken","callbackName","init","notifications","getEl","show","autoshow","appendTo","hide","getTrie","../../lib/trie.js","../main.js","../utils.js",22,"fetchFromLov","previousToken","getPreviousNonWsToken","preprocessResourceTokenForCompletion","postprocessResourceTokenForCompletion","./utils","./utils.js",23,"tokenTypes","string-2","atom","appendPrefixIfNeeded","prefixArray","prefix","completeString","sort","preprocessPrefixTokenForCompletion","collapsePrefixes","colonIndex","lastNonWsTokenString","currentPrefix","substring","queryPrefixes","getPrefixesFromQuery","addPrefixes",24,25,"tokenPrefix","tokenPrefixUri","trim","maxResults","q","page","results","updateUrl","increasePage","doRequests","uri","total_results","fail","jqXHR","textStatus","errorThrown","loader","addClass","../imgs.js",26,"distinctVars","variable","nextEl","nextElClass","variables",27,"sparql","quote","createCurlString","ajaxConfig","getAjaxConfig","endpoint","requestMethod","cmds","header","headers","join","./sparql.js",28,"extend","highlightSelectionMatches","showToken","tabMode","lineNumbers","lineWrapping","backdrop","combine","brace","collapsePrefixesOnLoad","gutters","fixedGutter","syntaxErrorCheck","Ctrl-Space","Cmd-Space","Ctrl-D","deleteLine","Ctrl-K","Cmd-D","Cmd-K","Ctrl-/","commentLines","Cmd-/","Ctrl-Alt-Down","copyLineDown","Ctrl-Alt-Up","copyLineUp","Cmd-Alt-Down","Cmd-Alt-Up","Shift-Ctrl-F","doAutoFormat","Shift-Cmd-F","Ctrl-]","indentMore","Cmd-]","Ctrl-[","indentLess","Cmd-[","Ctrl-S","storeQuery","Cmd-S","Ctrl-Enter","executeQuery","Cmd-Enter","F11","setOption","cursorHeight","createShareLink","createShortLink","consumeShareLink","closest","queryName","getQueryMode","showQueryButton","acceptHeaderGraph","acceptHeaderSelect","acceptHeaderUpdate","namedGraphs","defaultGraphs","getQueryForAjax","beforeSend","error","handlers",29,"queryInvalid","download","share","warning","fullscreen","smallscreen",30,"imgs","rootEl","class","extendConfig","extendCmInstance","postProcessCmElement","extendedConfig","Autocompleters","lastQueryDuration","getNextNonWsToken","lineNumber","charNumber","collapse","findFirstPrefixLine","animateSpeed","setBackdrop","click","insertAfter","callbackOrConfig","getUrlArguments","removePrefixes","getValueWithoutComments","cleanedQuery","getValue","stringVal","getQueryType","setCheckSyntaxErrors","isEnabled","checkSyntax","enableCompleter","addCompleterToSettings","disableCompleter","removeCompleterFromSettings","settings","splice","valueFromStorage","setValue","drawButtons","updateQueryButton","positionButtons","updateButtonsTransparency","prevQueryValid","matchText","removeClass","getUrlParams","addEventListener","urlParams","location","hash","href","search","buttons","elementsOverlap","deepcheck","queryValid","precise","warningEl","expectedEncoded","expected","html","marginTop","marginLeft","len","registerAutocompleter","constructor","getAsCurl","curl","svgShare","event","stopPropagation","popup","$input","protocol","host","pathname","$this","select","mouseup","unbind","errString","shortLink","positions","position","outerHeight","parseInt","toggleFullscreen","hasClass","xhr","abort","queryButtonIds","busy","valid","status","queryButton","queryStatus","classNames","c","fromTextArea","textAreaEl","insertBefore","linesAreCommented","setCursor","autoFormatRange","totalLines","totalChars","getTextArea","absStart","indexFromPos","absEnd","res","autoFormatLineBreaks","posFromIndex","indentLine","breakAfterArray","breakAfterCharacters","breakBeforeCharacters","getBreakType","stackTrace","valueOf","currentLine","formattedQuery","breakType","../lib/deparam.js","../lib/grammar/tokenizer.js","./autocompleters/autocompleterBase.js","./autocompleters/classes.js","./autocompleters/prefixes.js","./autocompleters/properties.js","./autocompleters/variables.js","./curl.js","./defaults.js","./imgs.js","./prefixFold.js","./prefixUtils.js","./tokenUtils.js","./tooltip","codemirror/addon/display/fullscreen.js","codemirror/addon/edit/matchbrackets.js","codemirror/addon/fold/brace-fold.js","codemirror/addon/fold/foldcode.js","codemirror/addon/fold/foldgutter.js","codemirror/addon/fold/xml-fold.js","codemirror/addon/hint/show-hint.js","codemirror/addon/runmode/runmode.js","codemirror/addon/search/searchcursor.js",31,"findFirstPrefix","lookFor","tokenUtils","hasPreviousPrefix","getLastPrefixPos","prefixKeywordToken","prefixShortname","prefixUri","prefixStart","stopAt","stopAtNextLine","prefixEndChar","prefixEndLine","nextPrefixDeclaration",32,"existingPrefixes","addPrefixAsString","pref","prefixString","lastPrefix","lastPrefixLine","numLines","firstToken","previousIndent","getIndentFromLine","escapeRegex","shouldContinue","getPrefixesFromLine","lineOffset","colOffset","uriString",33,"Accept","getAcceptHeader","xhrFields","handlerDefined","handler","isEmptyObject","queryStart","updateYasqe","completeCallbacks","ajax","queryMode","getString","argName","merge","acceptHeader","qType",34,"prevToken",35,"tooltip","hover","repositionTooltip",36,"keyExists","objectToTest","exists","persistentIdCreator","persistencyId","getPositions","elem","comparePositions","p1","p2","r1","r2","pos2"],"mappings":"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BACAC,WACAC,WACAC,UACAC,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,oBACAC,gDACA3C,KAAA,8CAAA,gDACAG,OACAC,OACAC,OACAC,YACAC,SACAC,SACAC,WACAC,UACAC,QACAC,UACAC,QACA+B,2BACA5C,KAAA,yBAAA,2BACAG,OACAC,OACAS,OACAL,SDEKH,OACAC,YACAC,SACAE,WACAC,UACAC,QACAC,WACHiC,8BACGC,OAAU,4BAA4B,8BACtC1B,QACAC,QACAC,OACAJ,OACAC,OACAI,WACAC,QACAC,SACAC,oBACAC,QACAC,YACAC,YACAC,mBACAC,mBACAC,wBACAC,wBACAC,WACAC,WACAC,UACAC,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,mBACAvC,OACAE,OACAC,YACAC,SACAC,SACAC,WACAC,UACAC,QACAC,UACAC,QACHkC,8CACG1C,KAAM,4CAA4C,8CAClDC,UAAa,4CAA4C,8CACzDC,OAAU,4CAA4C,8CACtDC,OAAU,4CAA4C,8CACtDC,SAAY,4CAA4C,8CACxDC,QAAW,4CAA4C,8CACvDC,MAAS,4CAA4C,8CACrDC,QAAW,4CAA4C,8CACvDC,QACHmC,0CACGxC,OAAU,wCAAwC,0CAClDK,QACHoC,6BACGhC,KAAM,2BAA2B,6BACjCpB,QACHqD,qBACGjC,KAAM,mBAAmB,qBACzBpB,OACAqB,OACAC,OACAC,QACAC,QACAC,OACAC,WACAC,QACAC,SACAC,oBACAC,QACAC,YACAC,YACAC,mBACAC,mBACAC,wBACAC,wBACAC,WACAC,WACAC,UACAC,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,oBACHS,kCACGpD,MAAO,gCAAgC,kCACvCH,MACAC,OACAC,OACAE,QACHoD,mBACGC,OAAU,iBAAiB,mBAC3B9B,SAAY,iBAAiB,mBAC7BC,MAAS,iBAAiB,mBAC1BC,OAAU,iBAAiB,mBAC3BG,UAAa,iBAAiB,mBAC9BC,UAAa,iBAAiB,mBAC9BC,iBAAoB,iBAAiB,mBACrCC,iBAAoB,iBAAiB,mBACrCC,sBAAyB,iBAAiB,mBAC1CC,sBAAyB,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CGjJ,MAAS,cAAc;AACvBC,MAAS,cAAc,gBACvBE,SAAY,cAAc,gBAC1BK,UAAa,cAAc,gBAC3BC,UAAa,cAAc,iBAC9ByI,MACGnK,KAAM,KACNiB,QACAC,QACAC,OACAJ,OACAC,OACAI,WACAC,QACAC,SACAC,oBACAC,QACAC,YACAC,YACAC,mBACAC,mBACAC,wBACAC,wBACAC,WACAC,WACAC,UACAC,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,mBACAlC,SACAH,OACAC,YACAC,SACAE,WACAC,UACAC,QACAC,UACAC,QACH0J,aACGC,UAAa,YACbC,OACAtC,OACAC,OACAhH,QACAC,QACAH,OACAgD,OACAC,QACAC,eACAC,YACAC,SACAC,OACAC,OACAC,SACAC,QACAC,OACAC,QACAC,SACAC,SACAC,UACAC,UACAC,SACAC,SACAC,kBACAC,YACAC,aACAC,WACAC,aACAC,YACAC,QACAC,SACAC,OACAC,SACAC,WACAC,WACAC,YACAC,MACAC,OACAC,QACAC,WACAC,OACAC,QACAC,UACAC,UACAC,UACAC,YACAC,MACAC,WACAC,SACAC,YACAC,SACAC,SACAC,WACAC,aACAC,aACA1F,QACAC,SACAiJ,SACAC,OACAC,OACAC,OACAC,OACAC,UACAC,gBACA7D,UACAC,WACAC,SACAC,UACAC,OACAhG,WACAO,mBACAC,mBACAC,wBACAC,wBACAC,WACAC,WACAC,UACAC,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,mBACAd,YACAC,YACA8F,QACHsD,UACGzK,OAAU,SACVe,WACAK,YACAC,aACHqJ,WACGC,QAAW,UACX/J,QACAC,QACAE,WACAK,YACAC,aACHuJ,aACGD,QAAW,UACX5J,WACAK,YACAC,aACHwJ,aACGF,QAAW,UACX3K,SACA8K,WACAC,SACAC,QACHC,aACGN,QAAW,UACX3K,UACHkL,aACGP,QAAW,UACXG,WACA9K,SACAe,WACAK,YACAC,aACH8J,UACGnI,OAAU,SACVnD,QACHuL,mBACG9L,KAAM,kBACND,QACHgM,0BACG1L,KAAM,yBACNU,QACHiL,sBACG3L,KAAM,qBACNE,OACAC,YACAC,SACAC,SACAC,WACAC,UACAC,QACAC,UACAC,QACHkL,yBACG5L,KAAM,wBACNU,OACAL,UACHwL,2BACGhM,KAAM,0BACNH,QACHoM,eACGjM,KAAM,cACNtC,MACHwO,aACGtM,IAAO,YACPC,QACHsM,oBACGC,MAAS,mBACTpM,OACAtC,MACH2O,2CACGjL,MAAS,0CACTC,MAAS,0CACTiL,KAAM,0CACNvP,GAAM,0CACN0N,KAAM,0CACNvJ,KAAM,0CACNK,SAAY,0CACZK,UAAa,0CACbC,UAAa,0CACb7B,OACAG,OACAC,OACAC,OACAC,YACAC,SACAC,SACAC,WACAC,UACAC,QACAC,UACAC,QACH0L,qDACGxP,GAAM,oDACNuP,KAAM,oDACN/K,SAAY,oDACZK,UAAa,oDACbC,UAAa,oDACbhC,QACH2M,0BACG5D,QAAW,yBACXC,QAAW,yBACXE,MAAS,yBACTC,OAAU,yBACVC,MAAS,yBACTC,KAAQ,yBACRC,MAAS,yBACTC,MAAS,yBACTC,QAAW,yBACXC,MAAS,yBACT5L,MACH+O,sBACG1P,GAAM,qBACNqE,MAAS,qBACTC,MAAS,qBACTE,SAAY,qBACZK,UAAa,qBACbC,UAAa,qBACb7B,OACAG,OACAC,OACAS,OACAL,SACAH,OACAC,YACAC,SACAE,WACAC,UACAC,QACAC,WACH8L,YACGpL,KAAQ,WACRJ,KAAM,WACNtB,MACAC,OACAC,OACAC,QACAJ,QACAiI,OACAC,QACAC,OACAC,OACAC,QACAC,QACAC,MACAX,OACAY,OACAC,OACA/F,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,mBACAiF,OACA3G,OACAhB,QACH2M,qBACGvL,MAAS,oBACTC,MAAS,oBACTC,KAAQ,oBACRJ,KAAM,oBACNC,KAAM,oBACNI,SAAY,oBACZC,MAAS,oBACTC,OAAU,oBACVC,kBAAqB,oBACrBC,MAAS,oBACTC,UAAa,oBACbC,UAAa,oBACbC,iBAAoB,oBACpBC,iBAAoB,oBACpBC,sBAAyB,oBACzBC,sBAAyB,oBACzBC,SAAY,oBACZC,SAAY,oBACZC,QAAW,oBACXC,kBAAqB,oBACrBC,kBAAqB,oBACrBC,iBAAoB,oBACpBC,kBAAqB,oBACrBC,kBAAqB,oBACrBC,iBAAoB,oBACpB7B,QACH+L,gBACGhJ,OAAU,eACVhD,UACAiD,SACAC,UACAJ,SACAC,UACAjG,KACAmD,QACHgM,iBACGlJ,QAAW,gBACX/C,UACAiD,SACAC,UACAJ,SACAhG,KACAmD,QACHiM,iBACGlE,QAAW,gBACXpF,SACAoG,UACHmD,gBACGlJ,OAAU,eACVjD,UACAlD,KACAmD,QACHmM,uBACGnJ,OAAU,sBACVC,QAAW,sBACXlD,UACAlD,KACAmD,QACHoM,iBACGnJ,QAAW,gBACXlD,UACAlD,KACAmD,QACHqM,2BACG1C,UAAa,0BACb2C,SAAY,0BACZxF,OACAzG,OACAE,QACAC,SACH+L,8BACGC,SAAY,6BACZC,MAAO,6BACPjK,SACA9B,WACAC,QACAC,SACAG,YACAC,YACAC,mBACAC,mBACAC,wBACAC,wBACAC,WACAC,WACAC,UACAC,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,mBACA3F,KACAqE,QACAC,QACAiL,OACA7B,OACAvJ,OACAf,OACAH,OACAF,OACAF,MACAC,OACAE,QACAJ,QACAiI,OACAC,QACAC,OACAC,OACAC,QACAC,QACAC,MACAX,OACAY,OACAC,OACAT,OACA3G,OACAH,OACAM,OACAG,OACAI,oBACAC,QACAvB,OACAI,SACAH,OACAC,YACAC,SACAE,WACAC,UACAC,QACAC,WACH2M,kDACG5F,KAAM,iDACN3G,KAAM,iDACNmH,OACAC,OACA/F,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,mBACA9C,MACAC,OACAC,OACAC,QACAJ,QACAiI,OACAC,QACAC,OACAC,OACAC,QACAC,QACAC,MACAX,OACAvH,QACHwN,6LACG5F,KAAM,4LACNC,MAAO,4LACPC,KAAM,4LACNC,KAAM,4LACNC,MAAO,4LACPC,MAAO,4LACPC,IAAO,4LACPX,KAAQ,4LACR3H,MACAC,OACAC,OACAC,QACAJ,QACAK,QACHyN,gBACG/J,OAAU,eACV9C,UACAiD,SACAC,UACApG,KACAmD,QACH6M,YACG/F,KAAM,WACNgG,KAAM,WACNxF,KAAM,WACN9H,KAAM,WACNY,OACAD,OACAnB,OACAqB,OACAC,OACAC,QACAC,QACAC,OACAC,WACAC,QACAC,SACAC,oBACAC,QACAC,YACAC,YACAC,mBACAC,mBACAC,wBACAC,wBACAC,WACAC,WACAC,UACAC,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,oBACHkL,iBACGxM,MAAS,gBACTC,MAAS,gBACTC,KAAQ,gBACRJ,KAAM,gBACNC,KAAM,gBACNI,SAAY,gBACZC,MAAS,gBACTC,OAAU,gBACVC,kBAAqB,gBACrBC,MAAS,gBACTC,UAAa,gBACbC,UAAa,gBACbC,iBAAoB,gBACpBC,iBAAoB,gBACpBC,sBAAyB,gBACzBC,sBAAyB,gBACzBC,SAAY,gBACZC,SAAY,gBACZC,QAAW,gBACXC,kBAAqB,gBACrBC,kBAAqB,gBACrBC,iBAAoB,gBACpBC,kBAAqB,gBACrBC,kBAAqB,gBACrBC,iBAAoB,gBACpBrC,OACAC,YACAC,SACAC,SACAC,WACAC,UACAC,QACAC,UACAC,QACHgN,oBACGzM,MAAS,mBACTC,MAAS,mBACTC,KAAQ,mBACRJ,KAAM,mBACNC,KAAM,mBACNI,SAAY,mBACZC,MAAS,mBACTC,OAAU,mBACVC,kBAAqB,mBACrBC,MAAS,mBACTC,UAAa,mBACbC,UAAa,mBACbC,iBAAoB,mBACpBC,iBAAoB,mBACpBC,sBAAyB,mBACzBC,sBAAyB,mBACzBC,SAAY,mBACZC,SAAY,mBACZC,QAAW,mBACXC,kBAAqB,mBACrBC,kBAAqB,mBACrBC,iBAAoB,mBACpBC,kBAAqB,mBACrBC,kBAAqB,mBACrBC,iBAAoB,mBACpB7B,OACAL,UACHsN,gBACGtK,OAAU,eACVnD,KAAM,eACNqD,SACAC,UACAC,SACAC,SACAC,UACAlD,UACAlD,MACHqQ,0BACG7M,KAAM,IAAI,kBAAkB,MAC/B8M,eACG9M,KAAM,IAAI,OAAO,MACpB+M,qBACG/M,KAAM,IAA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","file":"yasqe.min.js","sourcesContent":["!function(e){if(\"object\"==typeof exports&&\"undefined\"!=typeof module)module.exports=e();else if(\"function\"==typeof define&&define.amd)define([],e);else{var f;\"undefined\"!=typeof window?f=window:\"undefined\"!=typeof global?f=global:\"undefined\"!=typeof self&&(f=self),f.YASQE=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o\": [], \n \"<=\": [], \n \">=\": [], \n \"IN\": [], \n \"NOT\": [], \n \"+\": [], \n \"-\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \";\": []}, \n \"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\" : {\n \"+\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"-\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"INTEGER_POSITIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DECIMAL_POSITIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DOUBLE_POSITIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"INTEGER_NEGATIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DECIMAL_NEGATIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DOUBLE_NEGATIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"AS\": [], \n \")\": [], \n \",\": [], \n \"||\": [], \n \"&&\": [], \n \"=\": [], \n \"!=\": [], \n \"<\": [], \n \">\": [], \n \"<=\": [], \n \">=\": [], \n \"IN\": [], \n \"NOT\": [], \n \";\": []}, \n \"*or([baseDecl,prefixDecl])\" : {\n \"BASE\": [\"or([baseDecl,prefixDecl])\",\"*or([baseDecl,prefixDecl])\"], \n \"PREFIX\": [\"or([baseDecl,prefixDecl])\",\"*or([baseDecl,prefixDecl])\"], \n \"$\": [], \n \"CONSTRUCT\": [], \n \"DESCRIBE\": [], \n \"ASK\": [], \n \"INSERT\": [], \n \"DELETE\": [], \n \"SELECT\": [], \n \"LOAD\": [], \n \"CLEAR\": [], \n \"DROP\": [], \n \"ADD\": [], \n \"MOVE\": [], \n \"COPY\": [], \n \"CREATE\": [], \n \"WITH\": []}, \n \"*or([var,[ (,expression,AS,var,)]])\" : {\n \"(\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"], \n \"VAR1\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"], \n \"VAR2\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"], \n \"WHERE\": [], \n \"{\": [], \n \"FROM\": []}, \n \"*orderCondition\" : {\n \"ASC\": [\"orderCondition\",\"*orderCondition\"], \n \"DESC\": [\"orderCondition\",\"*orderCondition\"], \n \"VAR1\": [\"orderCondition\",\"*orderCondition\"], \n \"VAR2\": [\"orderCondition\",\"*orderCondition\"], \n \"(\": [\"orderCondition\",\"*orderCondition\"], \n \"STR\": [\"orderCondition\",\"*orderCondition\"], \n \"LANG\": [\"orderCondition\",\"*orderCondition\"], \n \"LANGMATCHES\": [\"orderCondition\",\"*orderCondition\"], \n \"DATATYPE\": [\"orderCondition\",\"*orderCondition\"], \n \"BOUND\": [\"orderCondition\",\"*orderCondition\"], \n \"IRI\": [\"orderCondition\",\"*orderCondition\"], \n \"URI\": [\"orderCondition\",\"*orderCondition\"], \n \"BNODE\": [\"orderCondition\",\"*orderCondition\"], \n \"RAND\": [\"orderCondition\",\"*orderCondition\"], \n \"ABS\": [\"orderCondition\",\"*orderCondition\"], \n \"CEIL\": [\"orderCondition\",\"*orderCondition\"], \n \"FLOOR\": [\"orderCondition\",\"*orderCondition\"], \n \"ROUND\": [\"orderCondition\",\"*orderCondition\"], \n \"CONCAT\": [\"orderCondition\",\"*orderCondition\"], \n \"STRLEN\": [\"orderCondition\",\"*orderCondition\"], \n \"UCASE\": [\"orderCondition\",\"*orderCondition\"], \n \"LCASE\": [\"orderCondition\",\"*orderCondition\"], \n \"ENCODE_FOR_URI\": [\"orderCondition\",\"*orderCondition\"], \n \"CONTAINS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRSTARTS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRENDS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRBEFORE\": [\"orderCondition\",\"*orderCondition\"], \n \"STRAFTER\": [\"orderCondition\",\"*orderCondition\"], \n \"YEAR\": [\"orderCondition\",\"*orderCondition\"], \n \"MONTH\": [\"orderCondition\",\"*orderCondition\"], \n \"DAY\": [\"orderCondition\",\"*orderCondition\"], \n \"HOURS\": [\"orderCondition\",\"*orderCondition\"], \n \"MINUTES\": [\"orderCondition\",\"*orderCondition\"], \n \"SECONDS\": [\"orderCondition\",\"*orderCondition\"], \n \"TIMEZONE\": [\"orderCondition\",\"*orderCondition\"], \n \"TZ\": [\"orderCondition\",\"*orderCondition\"], \n \"NOW\": [\"orderCondition\",\"*orderCondition\"], \n \"UUID\": [\"orderCondition\",\"*orderCondition\"], \n \"STRUUID\": [\"orderCondition\",\"*orderCondition\"], \n \"MD5\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA1\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA256\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA384\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA512\": [\"orderCondition\",\"*orderCondition\"], \n \"COALESCE\": [\"orderCondition\",\"*orderCondition\"], \n \"IF\": [\"orderCondition\",\"*orderCondition\"], \n \"STRLANG\": [\"orderCondition\",\"*orderCondition\"], \n \"STRDT\": [\"orderCondition\",\"*orderCondition\"], \n \"SAMETERM\": [\"orderCondition\",\"*orderCondition\"], \n \"ISIRI\": [\"orderCondition\",\"*orderCondition\"], \n \"ISURI\": [\"orderCondition\",\"*orderCondition\"], \n \"ISBLANK\": [\"orderCondition\",\"*orderCondition\"], \n \"ISLITERAL\": [\"orderCondition\",\"*orderCondition\"], \n \"ISNUMERIC\": [\"orderCondition\",\"*orderCondition\"], \n \"SUBSTR\": [\"orderCondition\",\"*orderCondition\"], \n \"REPLACE\": [\"orderCondition\",\"*orderCondition\"], \n \"REGEX\": [\"orderCondition\",\"*orderCondition\"], \n \"EXISTS\": [\"orderCondition\",\"*orderCondition\"], \n \"NOT\": [\"orderCondition\",\"*orderCondition\"], \n \"IRI_REF\": [\"orderCondition\",\"*orderCondition\"], \n \"PNAME_LN\": [\"orderCondition\",\"*orderCondition\"], \n \"PNAME_NS\": [\"orderCondition\",\"*orderCondition\"], \n \"VALUES\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"$\": [], \n \"}\": []}, \n \"*usingClause\" : {\n \"USING\": [\"usingClause\",\"*usingClause\"], \n \"WHERE\": []}, \n \"*var\" : {\n \"VAR1\": [\"var\",\"*var\"], \n \"VAR2\": [\"var\",\"*var\"], \n \")\": []}, \n \"*varOrIRIref\" : {\n \"VAR1\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"VAR2\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"IRI_REF\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"PNAME_LN\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"PNAME_NS\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"ORDER\": [], \n \"HAVING\": [], \n \"GROUP\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"WHERE\": [], \n \"{\": [], \n \"FROM\": [], \n \"VALUES\": [], \n \"$\": []}, \n \"+graphNode\" : {\n \"(\": [\"graphNode\",\"*graphNode\"], \n \"[\": [\"graphNode\",\"*graphNode\"], \n \"VAR1\": [\"graphNode\",\"*graphNode\"], \n \"VAR2\": [\"graphNode\",\"*graphNode\"], \n \"NIL\": [\"graphNode\",\"*graphNode\"], \n \"IRI_REF\": [\"graphNode\",\"*graphNode\"], \n \"TRUE\": [\"graphNode\",\"*graphNode\"], \n \"FALSE\": [\"graphNode\",\"*graphNode\"], \n \"BLANK_NODE_LABEL\": [\"graphNode\",\"*graphNode\"], \n \"ANON\": [\"graphNode\",\"*graphNode\"], \n \"PNAME_LN\": [\"graphNode\",\"*graphNode\"], \n \"PNAME_NS\": [\"graphNode\",\"*graphNode\"], \n \"STRING_LITERAL1\": [\"graphNode\",\"*graphNode\"], \n \"STRING_LITERAL2\": [\"graphNode\",\"*graphNode\"], \n \"STRING_LITERAL_LONG1\": [\"graphNode\",\"*graphNode\"], \n \"STRING_LITERAL_LONG2\": [\"graphNode\",\"*graphNode\"], \n \"INTEGER\": [\"graphNode\",\"*graphNode\"], \n \"DECIMAL\": [\"graphNode\",\"*graphNode\"], \n \"DOUBLE\": [\"graphNode\",\"*graphNode\"], \n \"INTEGER_POSITIVE\": [\"graphNode\",\"*graphNode\"], \n \"DECIMAL_POSITIVE\": [\"graphNode\",\"*graphNode\"], \n \"DOUBLE_POSITIVE\": [\"graphNode\",\"*graphNode\"], \n \"INTEGER_NEGATIVE\": [\"graphNode\",\"*graphNode\"], \n \"DECIMAL_NEGATIVE\": [\"graphNode\",\"*graphNode\"], \n \"DOUBLE_NEGATIVE\": [\"graphNode\",\"*graphNode\"]}, \n \"+graphNodePath\" : {\n \"(\": [\"graphNodePath\",\"*graphNodePath\"], \n \"[\": [\"graphNodePath\",\"*graphNodePath\"], \n \"VAR1\": [\"graphNodePath\",\"*graphNodePath\"], \n \"VAR2\": [\"graphNodePath\",\"*graphNodePath\"], \n \"NIL\": [\"graphNodePath\",\"*graphNodePath\"], \n \"IRI_REF\": [\"graphNodePath\",\"*graphNodePath\"], \n \"TRUE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"FALSE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"BLANK_NODE_LABEL\": [\"graphNodePath\",\"*graphNodePath\"], \n \"ANON\": [\"graphNodePath\",\"*graphNodePath\"], \n \"PNAME_LN\": [\"graphNodePath\",\"*graphNodePath\"], \n \"PNAME_NS\": [\"graphNodePath\",\"*graphNodePath\"], \n \"STRING_LITERAL1\": [\"graphNodePath\",\"*graphNodePath\"], \n \"STRING_LITERAL2\": [\"graphNodePath\",\"*graphNodePath\"], \n \"STRING_LITERAL_LONG1\": [\"graphNodePath\",\"*graphNodePath\"], \n \"STRING_LITERAL_LONG2\": [\"graphNodePath\",\"*graphNodePath\"], \n \"INTEGER\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DECIMAL\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DOUBLE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"INTEGER_POSITIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DECIMAL_POSITIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DOUBLE_POSITIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"INTEGER_NEGATIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DECIMAL_NEGATIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DOUBLE_NEGATIVE\": [\"graphNodePath\",\"*graphNodePath\"]}, \n \"+groupCondition\" : {\n \"(\": [\"groupCondition\",\"*groupCondition\"], \n \"STR\": [\"groupCondition\",\"*groupCondition\"], \n \"LANG\": [\"groupCondition\",\"*groupCondition\"], \n \"LANGMATCHES\": [\"groupCondition\",\"*groupCondition\"], \n \"DATATYPE\": [\"groupCondition\",\"*groupCondition\"], \n \"BOUND\": [\"groupCondition\",\"*groupCondition\"], \n \"IRI\": [\"groupCondition\",\"*groupCondition\"], \n \"URI\": [\"groupCondition\",\"*groupCondition\"], \n \"BNODE\": [\"groupCondition\",\"*groupCondition\"], \n \"RAND\": [\"groupCondition\",\"*groupCondition\"], \n \"ABS\": [\"groupCondition\",\"*groupCondition\"], \n \"CEIL\": [\"groupCondition\",\"*groupCondition\"], \n \"FLOOR\": [\"groupCondition\",\"*groupCondition\"], \n \"ROUND\": [\"groupCondition\",\"*groupCondition\"], \n \"CONCAT\": [\"groupCondition\",\"*groupCondition\"], \n \"STRLEN\": [\"groupCondition\",\"*groupCondition\"], \n \"UCASE\": [\"groupCondition\",\"*groupCondition\"], \n \"LCASE\": [\"groupCondition\",\"*groupCondition\"], \n \"ENCODE_FOR_URI\": [\"groupCondition\",\"*groupCondition\"], \n \"CONTAINS\": [\"groupCondition\",\"*groupCondition\"], \n \"STRSTARTS\": [\"groupCondition\",\"*groupCondition\"], \n \"STRENDS\": [\"groupCondition\",\"*groupCondition\"], \n \"STRBEFORE\": [\"groupCondition\",\"*groupCondition\"], \n \"STRAFTER\": [\"groupCondition\",\"*groupCondition\"], \n \"YEAR\": [\"groupCondition\",\"*groupCondition\"], \n \"MONTH\": [\"groupCondition\",\"*groupCondition\"], \n \"DAY\": [\"groupCondition\",\"*groupCondition\"], \n \"HOURS\": [\"groupCondition\",\"*groupCondition\"], \n \"MINUTES\": [\"groupCondition\",\"*groupCondition\"], \n \"SECONDS\": [\"groupCondition\",\"*groupCondition\"], \n \"TIMEZONE\": [\"groupCondition\",\"*groupCondition\"], \n \"TZ\": [\"groupCondition\",\"*groupCondition\"], \n \"NOW\": [\"groupCondition\",\"*groupCondition\"], \n \"UUID\": [\"groupCondition\",\"*groupCondition\"], \n \"STRUUID\": [\"groupCondition\",\"*groupCondition\"], \n \"MD5\": [\"groupCondition\",\"*groupCondition\"], \n \"SHA1\": [\"groupCondition\",\"*groupCondition\"], \n \"SHA256\": [\"groupCondition\",\"*groupCondition\"], \n \"SHA384\": [\"groupCondition\",\"*groupCondition\"], \n \"SHA512\": [\"groupCondition\",\"*groupCondition\"], \n \"COALESCE\": [\"groupCondition\",\"*groupCondition\"], \n \"IF\": [\"groupCondition\",\"*groupCondition\"], \n \"STRLANG\": [\"groupCondition\",\"*groupCondition\"], \n \"STRDT\": [\"groupCondition\",\"*groupCondition\"], \n \"SAMETERM\": [\"groupCondition\",\"*groupCondition\"], \n \"ISIRI\": [\"groupCondition\",\"*groupCondition\"], \n \"ISURI\": [\"groupCondition\",\"*groupCondition\"], \n \"ISBLANK\": [\"groupCondition\",\"*groupCondition\"], \n \"ISLITERAL\": [\"groupCondition\",\"*groupCondition\"], \n \"ISNUMERIC\": [\"groupCondition\",\"*groupCondition\"], \n \"VAR1\": [\"groupCondition\",\"*groupCondition\"], \n \"VAR2\": [\"groupCondition\",\"*groupCondition\"], \n \"SUBSTR\": [\"groupCondition\",\"*groupCondition\"], \n \"REPLACE\": [\"groupCondition\",\"*groupCondition\"], \n \"REGEX\": [\"groupCondition\",\"*groupCondition\"], \n \"EXISTS\": [\"groupCondition\",\"*groupCondition\"], \n \"NOT\": [\"groupCondition\",\"*groupCondition\"], \n \"IRI_REF\": [\"groupCondition\",\"*groupCondition\"], \n \"PNAME_LN\": [\"groupCondition\",\"*groupCondition\"], \n \"PNAME_NS\": [\"groupCondition\",\"*groupCondition\"]}, \n \"+havingCondition\" : {\n \"(\": [\"havingCondition\",\"*havingCondition\"], \n \"STR\": [\"havingCondition\",\"*havingCondition\"], \n \"LANG\": [\"havingCondition\",\"*havingCondition\"], \n \"LANGMATCHES\": [\"havingCondition\",\"*havingCondition\"], \n \"DATATYPE\": [\"havingCondition\",\"*havingCondition\"], \n \"BOUND\": [\"havingCondition\",\"*havingCondition\"], \n \"IRI\": [\"havingCondition\",\"*havingCondition\"], \n \"URI\": [\"havingCondition\",\"*havingCondition\"], \n \"BNODE\": [\"havingCondition\",\"*havingCondition\"], \n \"RAND\": [\"havingCondition\",\"*havingCondition\"], \n \"ABS\": [\"havingCondition\",\"*havingCondition\"], \n \"CEIL\": [\"havingCondition\",\"*havingCondition\"], \n \"FLOOR\": [\"havingCondition\",\"*havingCondition\"], \n \"ROUND\": [\"havingCondition\",\"*havingCondition\"], \n \"CONCAT\": [\"havingCondition\",\"*havingCondition\"], \n \"STRLEN\": [\"havingCondition\",\"*havingCondition\"], \n \"UCASE\": [\"havingCondition\",\"*havingCondition\"], \n \"LCASE\": [\"havingCondition\",\"*havingCondition\"], \n \"ENCODE_FOR_URI\": [\"havingCondition\",\"*havingCondition\"], \n \"CONTAINS\": [\"havingCondition\",\"*havingCondition\"], \n \"STRSTARTS\": [\"havingCondition\",\"*havingCondition\"], \n \"STRENDS\": [\"havingCondition\",\"*havingCondition\"], \n \"STRBEFORE\": [\"havingCondition\",\"*havingCondition\"], \n \"STRAFTER\": [\"havingCondition\",\"*havingCondition\"], \n \"YEAR\": [\"havingCondition\",\"*havingCondition\"], \n \"MONTH\": [\"havingCondition\",\"*havingCondition\"], \n \"DAY\": [\"havingCondition\",\"*havingCondition\"], \n \"HOURS\": [\"havingCondition\",\"*havingCondition\"], \n \"MINUTES\": [\"havingCondition\",\"*havingCondition\"], \n \"SECONDS\": [\"havingCondition\",\"*havingCondition\"], \n \"TIMEZONE\": [\"havingCondition\",\"*havingCondition\"], \n \"TZ\": [\"havingCondition\",\"*havingCondition\"], \n \"NOW\": [\"havingCondition\",\"*havingCondition\"], \n \"UUID\": [\"havingCondition\",\"*havingCondition\"], \n \"STRUUID\": [\"havingCondition\",\"*havingCondition\"], \n \"MD5\": [\"havingCondition\",\"*havingCondition\"], \n \"SHA1\": [\"havingCondition\",\"*havingCondition\"], \n \"SHA256\": [\"havingCondition\",\"*havingCondition\"], \n \"SHA384\": [\"havingCondition\",\"*havingCondition\"], \n \"SHA512\": [\"havingCondition\",\"*havingCondition\"], \n \"COALESCE\": [\"havingCondition\",\"*havingCondition\"], \n \"IF\": [\"havingCondition\",\"*havingCondition\"], \n \"STRLANG\": [\"havingCondition\",\"*havingCondition\"], \n \"STRDT\": [\"havingCondition\",\"*havingCondition\"], \n \"SAMETERM\": [\"havingCondition\",\"*havingCondition\"], \n \"ISIRI\": [\"havingCondition\",\"*havingCondition\"], \n \"ISURI\": [\"havingCondition\",\"*havingCondition\"], \n \"ISBLANK\": [\"havingCondition\",\"*havingCondition\"], \n \"ISLITERAL\": [\"havingCondition\",\"*havingCondition\"], \n \"ISNUMERIC\": [\"havingCondition\",\"*havingCondition\"], \n \"SUBSTR\": [\"havingCondition\",\"*havingCondition\"], \n \"REPLACE\": [\"havingCondition\",\"*havingCondition\"], \n \"REGEX\": [\"havingCondition\",\"*havingCondition\"], \n \"EXISTS\": [\"havingCondition\",\"*havingCondition\"], \n \"NOT\": [\"havingCondition\",\"*havingCondition\"], \n \"IRI_REF\": [\"havingCondition\",\"*havingCondition\"], \n \"PNAME_LN\": [\"havingCondition\",\"*havingCondition\"], \n \"PNAME_NS\": [\"havingCondition\",\"*havingCondition\"]}, \n \"+or([var,[ (,expression,AS,var,)]])\" : {\n \"(\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"], \n \"VAR1\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"], \n \"VAR2\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"]}, \n \"+orderCondition\" : {\n \"ASC\": [\"orderCondition\",\"*orderCondition\"], \n \"DESC\": [\"orderCondition\",\"*orderCondition\"], \n \"VAR1\": [\"orderCondition\",\"*orderCondition\"], \n \"VAR2\": [\"orderCondition\",\"*orderCondition\"], \n \"(\": [\"orderCondition\",\"*orderCondition\"], \n \"STR\": [\"orderCondition\",\"*orderCondition\"], \n \"LANG\": [\"orderCondition\",\"*orderCondition\"], \n \"LANGMATCHES\": [\"orderCondition\",\"*orderCondition\"], \n \"DATATYPE\": [\"orderCondition\",\"*orderCondition\"], \n \"BOUND\": [\"orderCondition\",\"*orderCondition\"], \n \"IRI\": [\"orderCondition\",\"*orderCondition\"], \n \"URI\": [\"orderCondition\",\"*orderCondition\"], \n \"BNODE\": [\"orderCondition\",\"*orderCondition\"], \n \"RAND\": [\"orderCondition\",\"*orderCondition\"], \n \"ABS\": [\"orderCondition\",\"*orderCondition\"], \n \"CEIL\": [\"orderCondition\",\"*orderCondition\"], \n \"FLOOR\": [\"orderCondition\",\"*orderCondition\"], \n \"ROUND\": [\"orderCondition\",\"*orderCondition\"], \n \"CONCAT\": [\"orderCondition\",\"*orderCondition\"], \n \"STRLEN\": [\"orderCondition\",\"*orderCondition\"], \n \"UCASE\": [\"orderCondition\",\"*orderCondition\"], \n \"LCASE\": [\"orderCondition\",\"*orderCondition\"], \n \"ENCODE_FOR_URI\": [\"orderCondition\",\"*orderCondition\"], \n \"CONTAINS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRSTARTS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRENDS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRBEFORE\": [\"orderCondition\",\"*orderCondition\"], \n \"STRAFTER\": [\"orderCondition\",\"*orderCondition\"], \n \"YEAR\": [\"orderCondition\",\"*orderCondition\"], \n \"MONTH\": [\"orderCondition\",\"*orderCondition\"], \n \"DAY\": [\"orderCondition\",\"*orderCondition\"], \n \"HOURS\": [\"orderCondition\",\"*orderCondition\"], \n \"MINUTES\": [\"orderCondition\",\"*orderCondition\"], \n \"SECONDS\": [\"orderCondition\",\"*orderCondition\"], \n \"TIMEZONE\": [\"orderCondition\",\"*orderCondition\"], \n \"TZ\": [\"orderCondition\",\"*orderCondition\"], \n \"NOW\": [\"orderCondition\",\"*orderCondition\"], \n \"UUID\": [\"orderCondition\",\"*orderCondition\"], \n \"STRUUID\": [\"orderCondition\",\"*orderCondition\"], \n \"MD5\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA1\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA256\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA384\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA512\": [\"orderCondition\",\"*orderCondition\"], \n \"COALESCE\": [\"orderCondition\",\"*orderCondition\"], \n \"IF\": [\"orderCondition\",\"*orderCondition\"], \n \"STRLANG\": [\"orderCondition\",\"*orderCondition\"], \n \"STRDT\": [\"orderCondition\",\"*orderCondition\"], \n \"SAMETERM\": [\"orderCondition\",\"*orderCondition\"], \n \"ISIRI\": [\"orderCondition\",\"*orderCondition\"], \n \"ISURI\": [\"orderCondition\",\"*orderCondition\"], \n \"ISBLANK\": [\"orderCondition\",\"*orderCondition\"], \n \"ISLITERAL\": [\"orderCondition\",\"*orderCondition\"], \n \"ISNUMERIC\": [\"orderCondition\",\"*orderCondition\"], \n \"SUBSTR\": [\"orderCondition\",\"*orderCondition\"], \n \"REPLACE\": [\"orderCondition\",\"*orderCondition\"], \n \"REGEX\": [\"orderCondition\",\"*orderCondition\"], \n \"EXISTS\": [\"orderCondition\",\"*orderCondition\"], \n \"NOT\": [\"orderCondition\",\"*orderCondition\"], \n \"IRI_REF\": [\"orderCondition\",\"*orderCondition\"], \n \"PNAME_LN\": [\"orderCondition\",\"*orderCondition\"], \n \"PNAME_NS\": [\"orderCondition\",\"*orderCondition\"]}, \n \"+varOrIRIref\" : {\n \"VAR1\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"VAR2\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"IRI_REF\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"PNAME_LN\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"PNAME_NS\": [\"varOrIRIref\",\"*varOrIRIref\"]}, \n \"?.\" : {\n \".\": [\".\"], \n \"VAR1\": [], \n \"VAR2\": [], \n \"NIL\": [], \n \"(\": [], \n \"[\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \"GRAPH\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"?DISTINCT\" : {\n \"DISTINCT\": [\"DISTINCT\"], \n \"!\": [], \n \"+\": [], \n \"-\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"(\": [], \n \"STR\": [], \n \"LANG\": [], \n \"LANGMATCHES\": [], \n \"DATATYPE\": [], \n \"BOUND\": [], \n \"IRI\": [], \n \"URI\": [], \n \"BNODE\": [], \n \"RAND\": [], \n \"ABS\": [], \n \"CEIL\": [], \n \"FLOOR\": [], \n \"ROUND\": [], \n \"CONCAT\": [], \n \"STRLEN\": [], \n \"UCASE\": [], \n \"LCASE\": [], \n \"ENCODE_FOR_URI\": [], \n \"CONTAINS\": [], \n \"STRSTARTS\": [], \n \"STRENDS\": [], \n \"STRBEFORE\": [], \n \"STRAFTER\": [], \n \"YEAR\": [], \n \"MONTH\": [], \n \"DAY\": [], \n \"HOURS\": [], \n \"MINUTES\": [], \n \"SECONDS\": [], \n \"TIMEZONE\": [], \n \"TZ\": [], \n \"NOW\": [], \n \"UUID\": [], \n \"STRUUID\": [], \n \"MD5\": [], \n \"SHA1\": [], \n \"SHA256\": [], \n \"SHA384\": [], \n \"SHA512\": [], \n \"COALESCE\": [], \n \"IF\": [], \n \"STRLANG\": [], \n \"STRDT\": [], \n \"SAMETERM\": [], \n \"ISIRI\": [], \n \"ISURI\": [], \n \"ISBLANK\": [], \n \"ISLITERAL\": [], \n \"ISNUMERIC\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"COUNT\": [], \n \"SUM\": [], \n \"MIN\": [], \n \"MAX\": [], \n \"AVG\": [], \n \"SAMPLE\": [], \n \"GROUP_CONCAT\": [], \n \"SUBSTR\": [], \n \"REPLACE\": [], \n \"REGEX\": [], \n \"EXISTS\": [], \n \"NOT\": [], \n \"IRI_REF\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"*\": []}, \n \"?GRAPH\" : {\n \"GRAPH\": [\"GRAPH\"], \n \"IRI_REF\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": []}, \n \"?SILENT\" : {\n \"SILENT\": [\"SILENT\"], \n \"VAR1\": [], \n \"VAR2\": [], \n \"IRI_REF\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": []}, \n \"?SILENT_1\" : {\n \"SILENT\": [\"SILENT\"], \n \"IRI_REF\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": []}, \n \"?SILENT_2\" : {\n \"SILENT\": [\"SILENT\"], \n \"GRAPH\": [], \n \"DEFAULT\": [], \n \"NAMED\": [], \n \"ALL\": []}, \n \"?SILENT_3\" : {\n \"SILENT\": [\"SILENT\"], \n \"GRAPH\": []}, \n \"?SILENT_4\" : {\n \"SILENT\": [\"SILENT\"], \n \"DEFAULT\": [], \n \"GRAPH\": [], \n \"IRI_REF\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": []}, \n \"?WHERE\" : {\n \"WHERE\": [\"WHERE\"], \n \"{\": []}, \n \"?[,,expression]\" : {\n \",\": [\"[,,expression]\"], \n \")\": []}, \n \"?[.,?constructTriples]\" : {\n \".\": [\"[.,?constructTriples]\"], \n \"}\": []}, \n \"?[.,?triplesBlock]\" : {\n \".\": [\"[.,?triplesBlock]\"], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"GRAPH\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"?[.,?triplesTemplate]\" : {\n \".\": [\"[.,?triplesTemplate]\"], \n \"}\": [], \n \"GRAPH\": []}, \n \"?[;,SEPARATOR,=,string]\" : {\n \";\": [\"[;,SEPARATOR,=,string]\"], \n \")\": []}, \n \"?[;,update]\" : {\n \";\": [\"[;,update]\"], \n \"$\": []}, \n \"?[AS,var]\" : {\n \"AS\": [\"[AS,var]\"], \n \")\": []}, \n \"?[INTO,graphRef]\" : {\n \"INTO\": [\"[INTO,graphRef]\"], \n \";\": [], \n \"$\": []}, \n \"?[or([verbPath,verbSimple]),objectList]\" : {\n \"VAR1\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"VAR2\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"^\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"a\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"!\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"(\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"IRI_REF\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"PNAME_LN\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"PNAME_NS\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \";\": [], \n \".\": [], \n \"]\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"GRAPH\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"?[pathOneInPropertySet,*[|,pathOneInPropertySet]]\" : {\n \"a\": [\"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\"], \n \"^\": [\"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\"], \n \"IRI_REF\": [\"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\"], \n \"PNAME_LN\": [\"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\"], \n \"PNAME_NS\": [\"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\"], \n \")\": []}, \n \"?[update1,?[;,update]]\" : {\n \"INSERT\": [\"[update1,?[;,update]]\"], \n \"DELETE\": [\"[update1,?[;,update]]\"], \n \"LOAD\": [\"[update1,?[;,update]]\"], \n \"CLEAR\": [\"[update1,?[;,update]]\"], \n \"DROP\": [\"[update1,?[;,update]]\"], \n \"ADD\": [\"[update1,?[;,update]]\"], \n \"MOVE\": [\"[update1,?[;,update]]\"], \n \"COPY\": [\"[update1,?[;,update]]\"], \n \"CREATE\": [\"[update1,?[;,update]]\"], \n \"WITH\": [\"[update1,?[;,update]]\"], \n \"$\": []}, \n \"?[verb,objectList]\" : {\n \"a\": [\"[verb,objectList]\"], \n \"VAR1\": [\"[verb,objectList]\"], \n \"VAR2\": [\"[verb,objectList]\"], \n \"IRI_REF\": [\"[verb,objectList]\"], \n \"PNAME_LN\": [\"[verb,objectList]\"], \n \"PNAME_NS\": [\"[verb,objectList]\"], \n \";\": [], \n \".\": [], \n \"]\": [], \n \"}\": [], \n \"GRAPH\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": []}, \n \"?argList\" : {\n \"NIL\": [\"argList\"], \n \"(\": [\"argList\"], \n \"AS\": [], \n \")\": [], \n \",\": [], \n \"||\": [], \n \"&&\": [], \n \"=\": [], \n \"!=\": [], \n \"<\": [], \n \">\": [], \n \"<=\": [], \n \">=\": [], \n \"IN\": [], \n \"NOT\": [], \n \"+\": [], \n \"-\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \"*\": [], \n \"/\": [], \n \";\": []}, \n \"?constructTriples\" : {\n \"VAR1\": [\"constructTriples\"], \n \"VAR2\": [\"constructTriples\"], \n \"NIL\": [\"constructTriples\"], \n \"(\": [\"constructTriples\"], \n \"[\": [\"constructTriples\"], \n \"IRI_REF\": [\"constructTriples\"], \n \"TRUE\": [\"constructTriples\"], \n \"FALSE\": [\"constructTriples\"], \n \"BLANK_NODE_LABEL\": [\"constructTriples\"], \n \"ANON\": [\"constructTriples\"], \n \"PNAME_LN\": [\"constructTriples\"], \n \"PNAME_NS\": [\"constructTriples\"], \n \"STRING_LITERAL1\": [\"constructTriples\"], \n \"STRING_LITERAL2\": [\"constructTriples\"], \n \"STRING_LITERAL_LONG1\": [\"constructTriples\"], \n \"STRING_LITERAL_LONG2\": [\"constructTriples\"], \n \"INTEGER\": [\"constructTriples\"], \n \"DECIMAL\": [\"constructTriples\"], \n \"DOUBLE\": [\"constructTriples\"], \n \"INTEGER_POSITIVE\": [\"constructTriples\"], \n \"DECIMAL_POSITIVE\": [\"constructTriples\"], \n \"DOUBLE_POSITIVE\": [\"constructTriples\"], \n \"INTEGER_NEGATIVE\": [\"constructTriples\"], \n \"DECIMAL_NEGATIVE\": [\"constructTriples\"], \n \"DOUBLE_NEGATIVE\": [\"constructTriples\"], \n \"}\": []}, \n \"?groupClause\" : {\n \"GROUP\": [\"groupClause\"], \n \"VALUES\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"ORDER\": [], \n \"HAVING\": [], \n \"$\": [], \n \"}\": []}, \n \"?havingClause\" : {\n \"HAVING\": [\"havingClause\"], \n \"VALUES\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"ORDER\": [], \n \"$\": [], \n \"}\": []}, \n \"?insertClause\" : {\n \"INSERT\": [\"insertClause\"], \n \"WHERE\": [], \n \"USING\": []}, \n \"?limitClause\" : {\n \"LIMIT\": [\"limitClause\"], \n \"VALUES\": [], \n \"$\": [], \n \"}\": []}, \n \"?limitOffsetClauses\" : {\n \"LIMIT\": [\"limitOffsetClauses\"], \n \"OFFSET\": [\"limitOffsetClauses\"], \n \"VALUES\": [], \n \"$\": [], \n \"}\": []}, \n \"?offsetClause\" : {\n \"OFFSET\": [\"offsetClause\"], \n \"VALUES\": [], \n \"$\": [], \n \"}\": []}, \n \"?or([DISTINCT,REDUCED])\" : {\n \"DISTINCT\": [\"or([DISTINCT,REDUCED])\"], \n \"REDUCED\": [\"or([DISTINCT,REDUCED])\"], \n \"*\": [], \n \"(\": [], \n \"VAR1\": [], \n \"VAR2\": []}, \n \"?or([LANGTAG,[^^,iriRef]])\" : {\n \"LANGTAG\": [\"or([LANGTAG,[^^,iriRef]])\"], \n \"^^\": [\"or([LANGTAG,[^^,iriRef]])\"], \n \"UNDEF\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \"a\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"^\": [], \n \"!\": [], \n \"(\": [], \n \".\": [], \n \";\": [], \n \",\": [], \n \"AS\": [], \n \")\": [], \n \"||\": [], \n \"&&\": [], \n \"=\": [], \n \"!=\": [], \n \"<\": [], \n \">\": [], \n \"<=\": [], \n \">=\": [], \n \"IN\": [], \n \"NOT\": [], \n \"+\": [], \n \"-\": [], \n \"*\": [], \n \"/\": [], \n \"}\": [], \n \"[\": [], \n \"NIL\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"]\": [], \n \"GRAPH\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": []}, \n \"?or([[*,unaryExpression],[/,unaryExpression]])\" : {\n \"*\": [\"or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"/\": [\"or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"+\": [], \n \"-\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \"AS\": [], \n \")\": [], \n \",\": [], \n \"||\": [], \n \"&&\": [], \n \"=\": [], \n \"!=\": [], \n \"<\": [], \n \">\": [], \n \"<=\": [], \n \">=\": [], \n \"IN\": [], \n \"NOT\": [], \n \";\": []}, \n \"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\" : {\n \"=\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"!=\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"<\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \">\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"<=\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \">=\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"IN\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"NOT\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"AS\": [], \n \")\": [], \n \",\": [], \n \"||\": [], \n \"&&\": [], \n \";\": []}, \n \"?orderClause\" : {\n \"ORDER\": [\"orderClause\"], \n \"VALUES\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"$\": [], \n \"}\": []}, \n \"?pathMod\" : {\n \"*\": [\"pathMod\"], \n \"?\": [\"pathMod\"], \n \"+\": [\"pathMod\"], \n \"{\": [\"pathMod\"], \n \"|\": [], \n \"/\": [], \n \")\": [], \n \"(\": [], \n \"[\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"NIL\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": []}, \n \"?triplesBlock\" : {\n \"VAR1\": [\"triplesBlock\"], \n \"VAR2\": [\"triplesBlock\"], \n \"NIL\": [\"triplesBlock\"], \n \"(\": [\"triplesBlock\"], \n \"[\": [\"triplesBlock\"], \n \"IRI_REF\": [\"triplesBlock\"], \n \"TRUE\": [\"triplesBlock\"], \n \"FALSE\": [\"triplesBlock\"], \n \"BLANK_NODE_LABEL\": [\"triplesBlock\"], \n \"ANON\": [\"triplesBlock\"], \n \"PNAME_LN\": [\"triplesBlock\"], \n \"PNAME_NS\": [\"triplesBlock\"], \n \"STRING_LITERAL1\": [\"triplesBlock\"], \n \"STRING_LITERAL2\": [\"triplesBlock\"], \n \"STRING_LITERAL_LONG1\": [\"triplesBlock\"], \n \"STRING_LITERAL_LONG2\": [\"triplesBlock\"], \n \"INTEGER\": [\"triplesBlock\"], \n \"DECIMAL\": [\"triplesBlock\"], \n \"DOUBLE\": [\"triplesBlock\"], \n \"INTEGER_POSITIVE\": [\"triplesBlock\"], \n \"DECIMAL_POSITIVE\": [\"triplesBlock\"], \n \"DOUBLE_POSITIVE\": [\"triplesBlock\"], \n \"INTEGER_NEGATIVE\": [\"triplesBlock\"], \n \"DECIMAL_NEGATIVE\": [\"triplesBlock\"], \n \"DOUBLE_NEGATIVE\": [\"triplesBlock\"], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"GRAPH\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"?triplesTemplate\" : {\n \"VAR1\": [\"triplesTemplate\"], \n \"VAR2\": [\"triplesTemplate\"], \n \"NIL\": [\"triplesTemplate\"], \n \"(\": [\"triplesTemplate\"], \n \"[\": [\"triplesTemplate\"], \n \"IRI_REF\": [\"triplesTemplate\"], \n \"TRUE\": [\"triplesTemplate\"], \n \"FALSE\": [\"triplesTemplate\"], \n \"BLANK_NODE_LABEL\": [\"triplesTemplate\"], \n \"ANON\": [\"triplesTemplate\"], \n \"PNAME_LN\": [\"triplesTemplate\"], \n \"PNAME_NS\": [\"triplesTemplate\"], \n \"STRING_LITERAL1\": [\"triplesTemplate\"], \n \"STRING_LITERAL2\": [\"triplesTemplate\"], \n \"STRING_LITERAL_LONG1\": [\"triplesTemplate\"], \n \"STRING_LITERAL_LONG2\": [\"triplesTemplate\"], \n \"INTEGER\": [\"triplesTemplate\"], \n \"DECIMAL\": [\"triplesTemplate\"], \n \"DOUBLE\": [\"triplesTemplate\"], \n \"INTEGER_POSITIVE\": [\"triplesTemplate\"], \n \"DECIMAL_POSITIVE\": [\"triplesTemplate\"], \n \"DOUBLE_POSITIVE\": [\"triplesTemplate\"], \n \"INTEGER_NEGATIVE\": [\"triplesTemplate\"], \n \"DECIMAL_NEGATIVE\": [\"triplesTemplate\"], \n \"DOUBLE_NEGATIVE\": [\"triplesTemplate\"], \n \"}\": [], \n \"GRAPH\": []}, \n \"?whereClause\" : {\n \"WHERE\": [\"whereClause\"], \n \"{\": [\"whereClause\"], \n \"ORDER\": [], \n \"HAVING\": [], \n \"GROUP\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"VALUES\": [], \n \"$\": []}, \n \"[ (,*dataBlockValue,)]\" : {\n \"(\": [\"(\",\"*dataBlockValue\",\")\"]}, \n \"[ (,*var,)]\" : {\n \"(\": [\"(\",\"*var\",\")\"]}, \n \"[ (,expression,)]\" : {\n \"(\": [\"(\",\"expression\",\")\"]}, \n \"[ (,expression,AS,var,)]\" : {\n \"(\": [\"(\",\"expression\",\"AS\",\"var\",\")\"]}, \n \"[!=,numericExpression]\" : {\n \"!=\": [\"!=\",\"numericExpression\"]}, \n \"[&&,valueLogical]\" : {\n \"&&\": [\"&&\",\"valueLogical\"]}, \n \"[*,unaryExpression]\" : {\n \"*\": [\"*\",\"unaryExpression\"]}, \n \"[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]\" : {\n \"WHERE\": [\"*datasetClause\",\"WHERE\",\"{\",\"?triplesTemplate\",\"}\",\"solutionModifier\"], \n \"FROM\": [\"*datasetClause\",\"WHERE\",\"{\",\"?triplesTemplate\",\"}\",\"solutionModifier\"]}, \n \"[+,multiplicativeExpression]\" : {\n \"+\": [\"+\",\"multiplicativeExpression\"]}, \n \"[,,expression]\" : {\n \",\": [\",\",\"expression\"]}, \n \"[,,integer,}]\" : {\n \",\": [\",\",\"integer\",\"}\"]}, \n \"[,,objectPath]\" : {\n \",\": [\",\",\"objectPath\"]}, \n \"[,,object]\" : {\n \",\": [\",\",\"object\"]}, \n \"[,,or([},[integer,}]])]\" : {\n \",\": [\",\",\"or([},[integer,}]])\"]}, \n \"[-,multiplicativeExpression]\" : {\n \"-\": [\"-\",\"multiplicativeExpression\"]}, \n \"[.,?constructTriples]\" : {\n \".\": [\".\",\"?constructTriples\"]}, \n \"[.,?triplesBlock]\" : {\n \".\": [\".\",\"?triplesBlock\"]}, \n \"[.,?triplesTemplate]\" : {\n \".\": [\".\",\"?triplesTemplate\"]}, \n \"[/,pathEltOrInverse]\" : {\n \"/\": [\"/\",\"pathEltOrInverse\"]}, \n \"[/,unaryExpression]\" : {\n \"/\": [\"/\",\"unaryExpression\"]}, \n \"[;,?[or([verbPath,verbSimple]),objectList]]\" : {\n \";\": [\";\",\"?[or([verbPath,verbSimple]),objectList]\"]}, \n \"[;,?[verb,objectList]]\" : {\n \";\": [\";\",\"?[verb,objectList]\"]}, \n \"[;,SEPARATOR,=,string]\" : {\n \";\": [\";\",\"SEPARATOR\",\"=\",\"string\"]}, \n \"[;,update]\" : {\n \";\": [\";\",\"update\"]}, \n \"[<,numericExpression]\" : {\n \"<\": [\"<\",\"numericExpression\"]}, \n \"[<=,numericExpression]\" : {\n \"<=\": [\"<=\",\"numericExpression\"]}, \n \"[=,numericExpression]\" : {\n \"=\": [\"=\",\"numericExpression\"]}, \n \"[>,numericExpression]\" : {\n \">\": [\">\",\"numericExpression\"]}, \n \"[>=,numericExpression]\" : {\n \">=\": [\">=\",\"numericExpression\"]}, \n \"[AS,var]\" : {\n \"AS\": [\"AS\",\"var\"]}, \n \"[IN,expressionList]\" : {\n \"IN\": [\"IN\",\"expressionList\"]}, \n \"[INTO,graphRef]\" : {\n \"INTO\": [\"INTO\",\"graphRef\"]}, \n \"[NAMED,iriRef]\" : {\n \"NAMED\": [\"NAMED\",\"iriRef\"]}, \n \"[NOT,IN,expressionList]\" : {\n \"NOT\": [\"NOT\",\"IN\",\"expressionList\"]}, \n \"[UNION,groupGraphPattern]\" : {\n \"UNION\": [\"UNION\",\"groupGraphPattern\"]}, \n \"[^^,iriRef]\" : {\n \"^^\": [\"^^\",\"iriRef\"]}, \n \"[constructTemplate,*datasetClause,whereClause,solutionModifier]\" : {\n \"{\": [\"constructTemplate\",\"*datasetClause\",\"whereClause\",\"solutionModifier\"]}, \n \"[deleteClause,?insertClause]\" : {\n \"DELETE\": [\"deleteClause\",\"?insertClause\"]}, \n \"[graphPatternNotTriples,?.,?triplesBlock]\" : {\n \"{\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"OPTIONAL\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"MINUS\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"GRAPH\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"SERVICE\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"FILTER\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"BIND\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"VALUES\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"]}, \n \"[integer,or([[,,or([},[integer,}]])],}])]\" : {\n \"INTEGER\": [\"integer\",\"or([[,,or([},[integer,}]])],}])\"]}, \n \"[integer,}]\" : {\n \"INTEGER\": [\"integer\",\"}\"]}, \n \"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\" : {\n \"INTEGER_POSITIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DECIMAL_POSITIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DOUBLE_POSITIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"INTEGER_NEGATIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DECIMAL_NEGATIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DOUBLE_NEGATIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"]}, \n \"[or([verbPath,verbSimple]),objectList]\" : {\n \"VAR1\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"VAR2\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"^\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"a\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"!\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"(\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"IRI_REF\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"PNAME_LN\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"PNAME_NS\": [\"or([verbPath,verbSimple])\",\"objectList\"]}, \n \"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\" : {\n \"a\": [\"pathOneInPropertySet\",\"*[|,pathOneInPropertySet]\"], \n \"^\": [\"pathOneInPropertySet\",\"*[|,pathOneInPropertySet]\"], \n \"IRI_REF\": [\"pathOneInPropertySet\",\"*[|,pathOneInPropertySet]\"], \n \"PNAME_LN\": [\"pathOneInPropertySet\",\"*[|,pathOneInPropertySet]\"], \n \"PNAME_NS\": [\"pathOneInPropertySet\",\"*[|,pathOneInPropertySet]\"]}, \n \"[quadsNotTriples,?.,?triplesTemplate]\" : {\n \"GRAPH\": [\"quadsNotTriples\",\"?.\",\"?triplesTemplate\"]}, \n \"[update1,?[;,update]]\" : {\n \"INSERT\": [\"update1\",\"?[;,update]\"], \n \"DELETE\": [\"update1\",\"?[;,update]\"], \n \"LOAD\": [\"update1\",\"?[;,update]\"], \n \"CLEAR\": [\"update1\",\"?[;,update]\"], \n \"DROP\": [\"update1\",\"?[;,update]\"], \n \"ADD\": [\"update1\",\"?[;,update]\"], \n \"MOVE\": [\"update1\",\"?[;,update]\"], \n \"COPY\": [\"update1\",\"?[;,update]\"], \n \"CREATE\": [\"update1\",\"?[;,update]\"], \n \"WITH\": [\"update1\",\"?[;,update]\"]}, \n \"[verb,objectList]\" : {\n \"a\": [\"verb\",\"objectList\"], \n \"VAR1\": [\"verb\",\"objectList\"], \n \"VAR2\": [\"verb\",\"objectList\"], \n \"IRI_REF\": [\"verb\",\"objectList\"], \n \"PNAME_LN\": [\"verb\",\"objectList\"], \n \"PNAME_NS\": [\"verb\",\"objectList\"]}, \n \"[|,pathOneInPropertySet]\" : {\n \"|\": [\"|\",\"pathOneInPropertySet\"]}, \n \"[|,pathSequence]\" : {\n \"|\": [\"|\",\"pathSequence\"]}, \n \"[||,conditionalAndExpression]\" : {\n \"||\": [\"||\",\"conditionalAndExpression\"]}, \n \"add\" : {\n \"ADD\": [\"ADD\",\"?SILENT_4\",\"graphOrDefault\",\"TO\",\"graphOrDefault\"]}, \n \"additiveExpression\" : {\n \"!\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"+\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"-\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"VAR1\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"VAR2\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"(\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STR\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"LANG\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"LANGMATCHES\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DATATYPE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"BOUND\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"IRI\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"URI\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"BNODE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"RAND\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ABS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"CEIL\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"FLOOR\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ROUND\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"CONCAT\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRLEN\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"UCASE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"LCASE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ENCODE_FOR_URI\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"CONTAINS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRSTARTS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRENDS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRBEFORE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRAFTER\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"YEAR\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"MONTH\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DAY\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"HOURS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"MINUTES\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SECONDS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"TIMEZONE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"TZ\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"NOW\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"UUID\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRUUID\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"MD5\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SHA1\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SHA256\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SHA384\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SHA512\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"COALESCE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"IF\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRLANG\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRDT\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SAMETERM\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ISIRI\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ISURI\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ISBLANK\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ISLITERAL\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ISNUMERIC\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"TRUE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"FALSE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"COUNT\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SUM\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"MIN\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"MAX\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"AVG\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SAMPLE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"GROUP_CONCAT\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SUBSTR\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"REPLACE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"REGEX\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"EXISTS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"NOT\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"IRI_REF\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRING_LITERAL1\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRING_LITERAL2\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRING_LITERAL_LONG1\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRING_LITERAL_LONG2\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"INTEGER\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DECIMAL\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DOUBLE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"INTEGER_POSITIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DECIMAL_POSITIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DOUBLE_POSITIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"INTEGER_NEGATIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DECIMAL_NEGATIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DOUBLE_NEGATIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"PNAME_LN\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"PNAME_NS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"]}, \n \"aggregate\" : {\n \"COUNT\": [\"COUNT\",\"(\",\"?DISTINCT\",\"or([*,expression])\",\")\"], \n \"SUM\": [\"SUM\",\"(\",\"?DISTINCT\",\"expression\",\")\"], \n \"MIN\": [\"MIN\",\"(\",\"?DISTINCT\",\"expression\",\")\"], \n \"MAX\": [\"MAX\",\"(\",\"?DISTINCT\",\"expression\",\")\"], \n \"AVG\": [\"AVG\",\"(\",\"?DISTINCT\",\"expression\",\")\"], \n \"SAMPLE\": [\"SAMPLE\",\"(\",\"?DISTINCT\",\"expression\",\")\"], \n \"GROUP_CONCAT\": [\"GROUP_CONCAT\",\"(\",\"?DISTINCT\",\"expression\",\"?[;,SEPARATOR,=,string]\",\")\"]}, \n \"allowBnodes\" : {\n \"}\": []}, \n \"allowVars\" : {\n \"}\": []}, \n \"argList\" : {\n \"NIL\": [\"NIL\"], \n \"(\": [\"(\",\"?DISTINCT\",\"expression\",\"*[,,expression]\",\")\"]}, \n \"askQuery\" : {\n \"ASK\": [\"ASK\",\"*datasetClause\",\"whereClause\",\"solutionModifier\"]}, \n \"baseDecl\" : {\n \"BASE\": [\"BASE\",\"IRI_REF\"]}, \n \"bind\" : {\n \"BIND\": [\"BIND\",\"(\",\"expression\",\"AS\",\"var\",\")\"]}, \n \"blankNode\" : {\n \"BLANK_NODE_LABEL\": [\"BLANK_NODE_LABEL\"], \n \"ANON\": [\"ANON\"]}, \n \"blankNodePropertyList\" : {\n \"[\": [\"[\",\"propertyListNotEmpty\",\"]\"]}, \n \"blankNodePropertyListPath\" : {\n \"[\": [\"[\",\"propertyListPathNotEmpty\",\"]\"]}, \n \"booleanLiteral\" : {\n \"TRUE\": [\"TRUE\"], \n \"FALSE\": [\"FALSE\"]}, \n \"brackettedExpression\" : {\n \"(\": [\"(\",\"expression\",\")\"]}, \n \"builtInCall\" : {\n \"STR\": [\"STR\",\"(\",\"expression\",\")\"], \n \"LANG\": [\"LANG\",\"(\",\"expression\",\")\"], \n \"LANGMATCHES\": [\"LANGMATCHES\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"DATATYPE\": [\"DATATYPE\",\"(\",\"expression\",\")\"], \n \"BOUND\": [\"BOUND\",\"(\",\"var\",\")\"], \n \"IRI\": [\"IRI\",\"(\",\"expression\",\")\"], \n \"URI\": [\"URI\",\"(\",\"expression\",\")\"], \n \"BNODE\": [\"BNODE\",\"or([[ (,expression,)],NIL])\"], \n \"RAND\": [\"RAND\",\"NIL\"], \n \"ABS\": [\"ABS\",\"(\",\"expression\",\")\"], \n \"CEIL\": [\"CEIL\",\"(\",\"expression\",\")\"], \n \"FLOOR\": [\"FLOOR\",\"(\",\"expression\",\")\"], \n \"ROUND\": [\"ROUND\",\"(\",\"expression\",\")\"], \n \"CONCAT\": [\"CONCAT\",\"expressionList\"], \n \"SUBSTR\": [\"substringExpression\"], \n \"STRLEN\": [\"STRLEN\",\"(\",\"expression\",\")\"], \n \"REPLACE\": [\"strReplaceExpression\"], \n \"UCASE\": [\"UCASE\",\"(\",\"expression\",\")\"], \n \"LCASE\": [\"LCASE\",\"(\",\"expression\",\")\"], \n \"ENCODE_FOR_URI\": [\"ENCODE_FOR_URI\",\"(\",\"expression\",\")\"], \n \"CONTAINS\": [\"CONTAINS\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"STRSTARTS\": [\"STRSTARTS\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"STRENDS\": [\"STRENDS\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"STRBEFORE\": [\"STRBEFORE\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"STRAFTER\": [\"STRAFTER\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"YEAR\": [\"YEAR\",\"(\",\"expression\",\")\"], \n \"MONTH\": [\"MONTH\",\"(\",\"expression\",\")\"], \n \"DAY\": [\"DAY\",\"(\",\"expression\",\")\"], \n \"HOURS\": [\"HOURS\",\"(\",\"expression\",\")\"], \n \"MINUTES\": [\"MINUTES\",\"(\",\"expression\",\")\"], \n \"SECONDS\": [\"SECONDS\",\"(\",\"expression\",\")\"], \n \"TIMEZONE\": [\"TIMEZONE\",\"(\",\"expression\",\")\"], \n \"TZ\": [\"TZ\",\"(\",\"expression\",\")\"], \n \"NOW\": [\"NOW\",\"NIL\"], \n \"UUID\": [\"UUID\",\"NIL\"], \n \"STRUUID\": [\"STRUUID\",\"NIL\"], \n \"MD5\": [\"MD5\",\"(\",\"expression\",\")\"], \n \"SHA1\": [\"SHA1\",\"(\",\"expression\",\")\"], \n \"SHA256\": [\"SHA256\",\"(\",\"expression\",\")\"], \n \"SHA384\": [\"SHA384\",\"(\",\"expression\",\")\"], \n \"SHA512\": [\"SHA512\",\"(\",\"expression\",\")\"], \n \"COALESCE\": [\"COALESCE\",\"expressionList\"], \n \"IF\": [\"IF\",\"(\",\"expression\",\",\",\"expression\",\",\",\"expression\",\")\"], \n \"STRLANG\": [\"STRLANG\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"STRDT\": [\"STRDT\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"SAMETERM\": [\"SAMETERM\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"ISIRI\": [\"ISIRI\",\"(\",\"expression\",\")\"], \n \"ISURI\": [\"ISURI\",\"(\",\"expression\",\")\"], \n \"ISBLANK\": [\"ISBLANK\",\"(\",\"expression\",\")\"], \n \"ISLITERAL\": [\"ISLITERAL\",\"(\",\"expression\",\")\"], \n \"ISNUMERIC\": [\"ISNUMERIC\",\"(\",\"expression\",\")\"], \n \"REGEX\": [\"regexExpression\"], \n \"EXISTS\": [\"existsFunc\"], \n \"NOT\": [\"notExistsFunc\"]}, \n \"clear\" : {\n \"CLEAR\": [\"CLEAR\",\"?SILENT_2\",\"graphRefAll\"]}, \n \"collection\" : {\n \"(\": [\"(\",\"+graphNode\",\")\"]}, \n \"collectionPath\" : {\n \"(\": [\"(\",\"+graphNodePath\",\")\"]}, \n \"conditionalAndExpression\" : {\n \"!\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"+\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"-\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"VAR1\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"VAR2\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"(\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STR\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"LANG\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"LANGMATCHES\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DATATYPE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"BOUND\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"IRI\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"URI\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"BNODE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"RAND\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ABS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"CEIL\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"FLOOR\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ROUND\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"CONCAT\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRLEN\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"UCASE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"LCASE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ENCODE_FOR_URI\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"CONTAINS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRSTARTS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRENDS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRBEFORE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRAFTER\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"YEAR\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"MONTH\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DAY\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"HOURS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"MINUTES\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SECONDS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"TIMEZONE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"TZ\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"NOW\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"UUID\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRUUID\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"MD5\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SHA1\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SHA256\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SHA384\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SHA512\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"COALESCE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"IF\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRLANG\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRDT\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SAMETERM\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ISIRI\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ISURI\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ISBLANK\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ISLITERAL\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ISNUMERIC\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"TRUE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"FALSE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"COUNT\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SUM\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"MIN\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"MAX\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"AVG\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SAMPLE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"GROUP_CONCAT\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SUBSTR\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"REPLACE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"REGEX\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"EXISTS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"NOT\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"IRI_REF\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRING_LITERAL1\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRING_LITERAL2\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRING_LITERAL_LONG1\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRING_LITERAL_LONG2\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"INTEGER\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DECIMAL\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DOUBLE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"INTEGER_POSITIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DECIMAL_POSITIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DOUBLE_POSITIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"INTEGER_NEGATIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DECIMAL_NEGATIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DOUBLE_NEGATIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"PNAME_LN\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"PNAME_NS\": [\"valueLogical\",\"*[&&,valueLogical]\"]}, \n \"conditionalOrExpression\" : {\n \"!\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"+\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"-\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"VAR1\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"VAR2\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"(\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STR\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"LANG\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"LANGMATCHES\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DATATYPE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"BOUND\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"IRI\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"URI\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"BNODE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"RAND\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ABS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"CEIL\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"FLOOR\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ROUND\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"CONCAT\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRLEN\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"UCASE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"LCASE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ENCODE_FOR_URI\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"CONTAINS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRSTARTS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRENDS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRBEFORE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRAFTER\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"YEAR\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"MONTH\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DAY\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"HOURS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"MINUTES\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SECONDS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"TIMEZONE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"TZ\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"NOW\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"UUID\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRUUID\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"MD5\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SHA1\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SHA256\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SHA384\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SHA512\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"COALESCE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"IF\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRLANG\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRDT\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SAMETERM\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ISIRI\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ISURI\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ISBLANK\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ISLITERAL\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ISNUMERIC\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"TRUE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"FALSE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"COUNT\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SUM\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"MIN\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"MAX\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"AVG\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SAMPLE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"GROUP_CONCAT\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SUBSTR\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"REPLACE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"REGEX\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"EXISTS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"NOT\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"IRI_REF\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRING_LITERAL1\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRING_LITERAL2\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRING_LITERAL_LONG1\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRING_LITERAL_LONG2\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"INTEGER\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DECIMAL\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DOUBLE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"INTEGER_POSITIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DECIMAL_POSITIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DOUBLE_POSITIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"INTEGER_NEGATIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DECIMAL_NEGATIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DOUBLE_NEGATIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"PNAME_LN\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"PNAME_NS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"]}, \n \"constraint\" : {\n \"(\": [\"brackettedExpression\"], \n \"STR\": [\"builtInCall\"], \n \"LANG\": [\"builtInCall\"], \n \"LANGMATCHES\": [\"builtInCall\"], \n \"DATATYPE\": [\"builtInCall\"], \n \"BOUND\": [\"builtInCall\"], \n \"IRI\": [\"builtInCall\"], \n \"URI\": [\"builtInCall\"], \n \"BNODE\": [\"builtInCall\"], \n \"RAND\": [\"builtInCall\"], \n \"ABS\": [\"builtInCall\"], \n \"CEIL\": [\"builtInCall\"], \n \"FLOOR\": [\"builtInCall\"], \n \"ROUND\": [\"builtInCall\"], \n \"CONCAT\": [\"builtInCall\"], \n \"STRLEN\": [\"builtInCall\"], \n \"UCASE\": [\"builtInCall\"], \n \"LCASE\": [\"builtInCall\"], \n \"ENCODE_FOR_URI\": [\"builtInCall\"], \n \"CONTAINS\": [\"builtInCall\"], \n \"STRSTARTS\": [\"builtInCall\"], \n \"STRENDS\": [\"builtInCall\"], \n \"STRBEFORE\": [\"builtInCall\"], \n \"STRAFTER\": [\"builtInCall\"], \n \"YEAR\": [\"builtInCall\"], \n \"MONTH\": [\"builtInCall\"], \n \"DAY\": [\"builtInCall\"], \n \"HOURS\": [\"builtInCall\"], \n \"MINUTES\": [\"builtInCall\"], \n \"SECONDS\": [\"builtInCall\"], \n \"TIMEZONE\": [\"builtInCall\"], \n \"TZ\": [\"builtInCall\"], \n \"NOW\": [\"builtInCall\"], \n \"UUID\": [\"builtInCall\"], \n \"STRUUID\": [\"builtInCall\"], \n \"MD5\": [\"builtInCall\"], \n \"SHA1\": [\"builtInCall\"], \n \"SHA256\": [\"builtInCall\"], \n \"SHA384\": [\"builtInCall\"], \n \"SHA512\": [\"builtInCall\"], \n \"COALESCE\": [\"builtInCall\"], \n \"IF\": [\"builtInCall\"], \n \"STRLANG\": [\"builtInCall\"], \n \"STRDT\": [\"builtInCall\"], \n \"SAMETERM\": [\"builtInCall\"], \n \"ISIRI\": [\"builtInCall\"], \n \"ISURI\": [\"builtInCall\"], \n \"ISBLANK\": [\"builtInCall\"], \n \"ISLITERAL\": [\"builtInCall\"], \n \"ISNUMERIC\": [\"builtInCall\"], \n \"SUBSTR\": [\"builtInCall\"], \n \"REPLACE\": [\"builtInCall\"], \n \"REGEX\": [\"builtInCall\"], \n \"EXISTS\": [\"builtInCall\"], \n \"NOT\": [\"builtInCall\"], \n \"IRI_REF\": [\"functionCall\"], \n \"PNAME_LN\": [\"functionCall\"], \n \"PNAME_NS\": [\"functionCall\"]}, \n \"constructQuery\" : {\n \"CONSTRUCT\": [\"CONSTRUCT\",\"or([[constructTemplate,*datasetClause,whereClause,solutionModifier],[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]])\"]}, \n \"constructTemplate\" : {\n \"{\": [\"{\",\"?constructTriples\",\"}\"]}, \n \"constructTriples\" : {\n \"VAR1\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"VAR2\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"NIL\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"(\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"[\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"IRI_REF\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"TRUE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"FALSE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"BLANK_NODE_LABEL\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"ANON\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"PNAME_LN\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"PNAME_NS\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"STRING_LITERAL1\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"STRING_LITERAL2\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"STRING_LITERAL_LONG1\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"STRING_LITERAL_LONG2\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"INTEGER\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DECIMAL\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DOUBLE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"INTEGER_POSITIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DECIMAL_POSITIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DOUBLE_POSITIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"INTEGER_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DECIMAL_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DOUBLE_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"]}, \n \"copy\" : {\n \"COPY\": [\"COPY\",\"?SILENT_4\",\"graphOrDefault\",\"TO\",\"graphOrDefault\"]}, \n \"create\" : {\n \"CREATE\": [\"CREATE\",\"?SILENT_3\",\"graphRef\"]}, \n \"dataBlock\" : {\n \"NIL\": [\"or([inlineDataOneVar,inlineDataFull])\"], \n \"(\": [\"or([inlineDataOneVar,inlineDataFull])\"], \n \"VAR1\": [\"or([inlineDataOneVar,inlineDataFull])\"], \n \"VAR2\": [\"or([inlineDataOneVar,inlineDataFull])\"]}, \n \"dataBlockValue\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"], \n \"STRING_LITERAL1\": [\"rdfLiteral\"], \n \"STRING_LITERAL2\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG1\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG2\": [\"rdfLiteral\"], \n \"INTEGER\": [\"numericLiteral\"], \n \"DECIMAL\": [\"numericLiteral\"], \n \"DOUBLE\": [\"numericLiteral\"], \n \"INTEGER_POSITIVE\": [\"numericLiteral\"], \n \"DECIMAL_POSITIVE\": [\"numericLiteral\"], \n \"DOUBLE_POSITIVE\": [\"numericLiteral\"], \n \"INTEGER_NEGATIVE\": [\"numericLiteral\"], \n \"DECIMAL_NEGATIVE\": [\"numericLiteral\"], \n \"DOUBLE_NEGATIVE\": [\"numericLiteral\"], \n \"TRUE\": [\"booleanLiteral\"], \n \"FALSE\": [\"booleanLiteral\"], \n \"UNDEF\": [\"UNDEF\"]}, \n \"datasetClause\" : {\n \"FROM\": [\"FROM\",\"or([defaultGraphClause,namedGraphClause])\"]}, \n \"defaultGraphClause\" : {\n \"IRI_REF\": [\"sourceSelector\"], \n \"PNAME_LN\": [\"sourceSelector\"], \n \"PNAME_NS\": [\"sourceSelector\"]}, \n \"delete1\" : {\n \"DATA\": [\"DATA\",\"quadDataNoBnodes\"], \n \"WHERE\": [\"WHERE\",\"quadPatternNoBnodes\"], \n \"{\": [\"quadPatternNoBnodes\",\"?insertClause\",\"*usingClause\",\"WHERE\",\"groupGraphPattern\"]}, \n \"deleteClause\" : {\n \"DELETE\": [\"DELETE\",\"quadPattern\"]}, \n \"describeDatasetClause\" : {\n \"FROM\": [\"FROM\",\"or([defaultGraphClause,namedGraphClause])\"]}, \n \"describeQuery\" : {\n \"DESCRIBE\": [\"DESCRIBE\",\"or([+varOrIRIref,*])\",\"*describeDatasetClause\",\"?whereClause\",\"solutionModifier\"]}, \n \"disallowBnodes\" : {\n \"}\": [], \n \"GRAPH\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"NIL\": [], \n \"(\": [], \n \"[\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": []}, \n \"disallowVars\" : {\n \"}\": [], \n \"GRAPH\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"NIL\": [], \n \"(\": [], \n \"[\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": []}, \n \"drop\" : {\n \"DROP\": [\"DROP\",\"?SILENT_2\",\"graphRefAll\"]}, \n \"existsFunc\" : {\n \"EXISTS\": [\"EXISTS\",\"groupGraphPattern\"]}, \n \"expression\" : {\n \"!\": [\"conditionalOrExpression\"], \n \"+\": [\"conditionalOrExpression\"], \n \"-\": [\"conditionalOrExpression\"], \n \"VAR1\": [\"conditionalOrExpression\"], \n \"VAR2\": [\"conditionalOrExpression\"], \n \"(\": [\"conditionalOrExpression\"], \n \"STR\": [\"conditionalOrExpression\"], \n \"LANG\": [\"conditionalOrExpression\"], \n \"LANGMATCHES\": [\"conditionalOrExpression\"], \n \"DATATYPE\": [\"conditionalOrExpression\"], \n \"BOUND\": [\"conditionalOrExpression\"], \n \"IRI\": [\"conditionalOrExpression\"], \n \"URI\": [\"conditionalOrExpression\"], \n \"BNODE\": [\"conditionalOrExpression\"], \n \"RAND\": [\"conditionalOrExpression\"], \n \"ABS\": [\"conditionalOrExpression\"], \n \"CEIL\": [\"conditionalOrExpression\"], \n \"FLOOR\": [\"conditionalOrExpression\"], \n \"ROUND\": [\"conditionalOrExpression\"], \n \"CONCAT\": [\"conditionalOrExpression\"], \n \"STRLEN\": [\"conditionalOrExpression\"], \n \"UCASE\": [\"conditionalOrExpression\"], \n \"LCASE\": [\"conditionalOrExpression\"], \n \"ENCODE_FOR_URI\": [\"conditionalOrExpression\"], \n \"CONTAINS\": [\"conditionalOrExpression\"], \n \"STRSTARTS\": [\"conditionalOrExpression\"], \n \"STRENDS\": [\"conditionalOrExpression\"], \n \"STRBEFORE\": [\"conditionalOrExpression\"], \n \"STRAFTER\": [\"conditionalOrExpression\"], \n \"YEAR\": [\"conditionalOrExpression\"], \n \"MONTH\": [\"conditionalOrExpression\"], \n \"DAY\": [\"conditionalOrExpression\"], \n \"HOURS\": [\"conditionalOrExpression\"], \n \"MINUTES\": [\"conditionalOrExpression\"], \n \"SECONDS\": [\"conditionalOrExpression\"], \n \"TIMEZONE\": [\"conditionalOrExpression\"], \n \"TZ\": [\"conditionalOrExpression\"], \n \"NOW\": [\"conditionalOrExpression\"], \n \"UUID\": [\"conditionalOrExpression\"], \n \"STRUUID\": [\"conditionalOrExpression\"], \n \"MD5\": [\"conditionalOrExpression\"], \n \"SHA1\": [\"conditionalOrExpression\"], \n \"SHA256\": [\"conditionalOrExpression\"], \n \"SHA384\": [\"conditionalOrExpression\"], \n \"SHA512\": [\"conditionalOrExpression\"], \n \"COALESCE\": [\"conditionalOrExpression\"], \n \"IF\": [\"conditionalOrExpression\"], \n \"STRLANG\": [\"conditionalOrExpression\"], \n \"STRDT\": [\"conditionalOrExpression\"], \n \"SAMETERM\": [\"conditionalOrExpression\"], \n \"ISIRI\": [\"conditionalOrExpression\"], \n \"ISURI\": [\"conditionalOrExpression\"], \n \"ISBLANK\": [\"conditionalOrExpression\"], \n \"ISLITERAL\": [\"conditionalOrExpression\"], \n \"ISNUMERIC\": [\"conditionalOrExpression\"], \n \"TRUE\": [\"conditionalOrExpression\"], \n \"FALSE\": [\"conditionalOrExpression\"], \n \"COUNT\": [\"conditionalOrExpression\"], \n \"SUM\": [\"conditionalOrExpression\"], \n \"MIN\": [\"conditionalOrExpression\"], \n \"MAX\": [\"conditionalOrExpression\"], \n \"AVG\": [\"conditionalOrExpression\"], \n \"SAMPLE\": [\"conditionalOrExpression\"], \n \"GROUP_CONCAT\": [\"conditionalOrExpression\"], \n \"SUBSTR\": [\"conditionalOrExpression\"], \n \"REPLACE\": [\"conditionalOrExpression\"], \n \"REGEX\": [\"conditionalOrExpression\"], \n \"EXISTS\": [\"conditionalOrExpression\"], \n \"NOT\": [\"conditionalOrExpression\"], \n \"IRI_REF\": [\"conditionalOrExpression\"], \n \"STRING_LITERAL1\": [\"conditionalOrExpression\"], \n \"STRING_LITERAL2\": [\"conditionalOrExpression\"], \n \"STRING_LITERAL_LONG1\": [\"conditionalOrExpression\"], \n \"STRING_LITERAL_LONG2\": [\"conditionalOrExpression\"], \n \"INTEGER\": [\"conditionalOrExpression\"], \n \"DECIMAL\": [\"conditionalOrExpression\"], \n \"DOUBLE\": [\"conditionalOrExpression\"], \n \"INTEGER_POSITIVE\": [\"conditionalOrExpression\"], \n \"DECIMAL_POSITIVE\": [\"conditionalOrExpression\"], \n \"DOUBLE_POSITIVE\": [\"conditionalOrExpression\"], \n \"INTEGER_NEGATIVE\": [\"conditionalOrExpression\"], \n \"DECIMAL_NEGATIVE\": [\"conditionalOrExpression\"], \n \"DOUBLE_NEGATIVE\": [\"conditionalOrExpression\"], \n \"PNAME_LN\": [\"conditionalOrExpression\"], \n \"PNAME_NS\": [\"conditionalOrExpression\"]}, \n \"expressionList\" : {\n \"NIL\": [\"NIL\"], \n \"(\": [\"(\",\"expression\",\"*[,,expression]\",\")\"]}, \n \"filter\" : {\n \"FILTER\": [\"FILTER\",\"constraint\"]}, \n \"functionCall\" : {\n \"IRI_REF\": [\"iriRef\",\"argList\"], \n \"PNAME_LN\": [\"iriRef\",\"argList\"], \n \"PNAME_NS\": [\"iriRef\",\"argList\"]}, \n \"graphGraphPattern\" : {\n \"GRAPH\": [\"GRAPH\",\"varOrIRIref\",\"groupGraphPattern\"]}, \n \"graphNode\" : {\n \"VAR1\": [\"varOrTerm\"], \n \"VAR2\": [\"varOrTerm\"], \n \"NIL\": [\"varOrTerm\"], \n \"IRI_REF\": [\"varOrTerm\"], \n \"TRUE\": [\"varOrTerm\"], \n \"FALSE\": [\"varOrTerm\"], \n \"BLANK_NODE_LABEL\": [\"varOrTerm\"], \n \"ANON\": [\"varOrTerm\"], \n \"PNAME_LN\": [\"varOrTerm\"], \n \"PNAME_NS\": [\"varOrTerm\"], \n \"STRING_LITERAL1\": [\"varOrTerm\"], \n \"STRING_LITERAL2\": [\"varOrTerm\"], \n \"STRING_LITERAL_LONG1\": [\"varOrTerm\"], \n \"STRING_LITERAL_LONG2\": [\"varOrTerm\"], \n \"INTEGER\": [\"varOrTerm\"], \n \"DECIMAL\": [\"varOrTerm\"], \n \"DOUBLE\": [\"varOrTerm\"], \n \"INTEGER_POSITIVE\": [\"varOrTerm\"], \n \"DECIMAL_POSITIVE\": [\"varOrTerm\"], \n \"DOUBLE_POSITIVE\": [\"varOrTerm\"], \n \"INTEGER_NEGATIVE\": [\"varOrTerm\"], \n \"DECIMAL_NEGATIVE\": [\"varOrTerm\"], \n \"DOUBLE_NEGATIVE\": [\"varOrTerm\"], \n \"(\": [\"triplesNode\"], \n \"[\": [\"triplesNode\"]}, \n \"graphNodePath\" : {\n \"VAR1\": [\"varOrTerm\"], \n \"VAR2\": [\"varOrTerm\"], \n \"NIL\": [\"varOrTerm\"], \n \"IRI_REF\": [\"varOrTerm\"], \n \"TRUE\": [\"varOrTerm\"], \n \"FALSE\": [\"varOrTerm\"], \n \"BLANK_NODE_LABEL\": [\"varOrTerm\"], \n \"ANON\": [\"varOrTerm\"], \n \"PNAME_LN\": [\"varOrTerm\"], \n \"PNAME_NS\": [\"varOrTerm\"], \n \"STRING_LITERAL1\": [\"varOrTerm\"], \n \"STRING_LITERAL2\": [\"varOrTerm\"], \n \"STRING_LITERAL_LONG1\": [\"varOrTerm\"], \n \"STRING_LITERAL_LONG2\": [\"varOrTerm\"], \n \"INTEGER\": [\"varOrTerm\"], \n \"DECIMAL\": [\"varOrTerm\"], \n \"DOUBLE\": [\"varOrTerm\"], \n \"INTEGER_POSITIVE\": [\"varOrTerm\"], \n \"DECIMAL_POSITIVE\": [\"varOrTerm\"], \n \"DOUBLE_POSITIVE\": [\"varOrTerm\"], \n \"INTEGER_NEGATIVE\": [\"varOrTerm\"], \n \"DECIMAL_NEGATIVE\": [\"varOrTerm\"], \n \"DOUBLE_NEGATIVE\": [\"varOrTerm\"], \n \"(\": [\"triplesNodePath\"], \n \"[\": [\"triplesNodePath\"]}, \n \"graphOrDefault\" : {\n \"DEFAULT\": [\"DEFAULT\"], \n \"IRI_REF\": [\"?GRAPH\",\"iriRef\"], \n \"PNAME_LN\": [\"?GRAPH\",\"iriRef\"], \n \"PNAME_NS\": [\"?GRAPH\",\"iriRef\"], \n \"GRAPH\": [\"?GRAPH\",\"iriRef\"]}, \n \"graphPatternNotTriples\" : {\n \"{\": [\"groupOrUnionGraphPattern\"], \n \"OPTIONAL\": [\"optionalGraphPattern\"], \n \"MINUS\": [\"minusGraphPattern\"], \n \"GRAPH\": [\"graphGraphPattern\"], \n \"SERVICE\": [\"serviceGraphPattern\"], \n \"FILTER\": [\"filter\"], \n \"BIND\": [\"bind\"], \n \"VALUES\": [\"inlineData\"]}, \n \"graphRef\" : {\n \"GRAPH\": [\"GRAPH\",\"iriRef\"]}, \n \"graphRefAll\" : {\n \"GRAPH\": [\"graphRef\"], \n \"DEFAULT\": [\"DEFAULT\"], \n \"NAMED\": [\"NAMED\"], \n \"ALL\": [\"ALL\"]}, \n \"graphTerm\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"], \n \"STRING_LITERAL1\": [\"rdfLiteral\"], \n \"STRING_LITERAL2\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG1\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG2\": [\"rdfLiteral\"], \n \"INTEGER\": [\"numericLiteral\"], \n \"DECIMAL\": [\"numericLiteral\"], \n \"DOUBLE\": [\"numericLiteral\"], \n \"INTEGER_POSITIVE\": [\"numericLiteral\"], \n \"DECIMAL_POSITIVE\": [\"numericLiteral\"], \n \"DOUBLE_POSITIVE\": [\"numericLiteral\"], \n \"INTEGER_NEGATIVE\": [\"numericLiteral\"], \n \"DECIMAL_NEGATIVE\": [\"numericLiteral\"], \n \"DOUBLE_NEGATIVE\": [\"numericLiteral\"], \n \"TRUE\": [\"booleanLiteral\"], \n \"FALSE\": [\"booleanLiteral\"], \n \"BLANK_NODE_LABEL\": [\"blankNode\"], \n \"ANON\": [\"blankNode\"], \n \"NIL\": [\"NIL\"]}, \n \"groupClause\" : {\n \"GROUP\": [\"GROUP\",\"BY\",\"+groupCondition\"]}, \n \"groupCondition\" : {\n \"STR\": [\"builtInCall\"], \n \"LANG\": [\"builtInCall\"], \n \"LANGMATCHES\": [\"builtInCall\"], \n \"DATATYPE\": [\"builtInCall\"], \n \"BOUND\": [\"builtInCall\"], \n \"IRI\": [\"builtInCall\"], \n \"URI\": [\"builtInCall\"], \n \"BNODE\": [\"builtInCall\"], \n \"RAND\": [\"builtInCall\"], \n \"ABS\": [\"builtInCall\"], \n \"CEIL\": [\"builtInCall\"], \n \"FLOOR\": [\"builtInCall\"], \n \"ROUND\": [\"builtInCall\"], \n \"CONCAT\": [\"builtInCall\"], \n \"STRLEN\": [\"builtInCall\"], \n \"UCASE\": [\"builtInCall\"], \n \"LCASE\": [\"builtInCall\"], \n \"ENCODE_FOR_URI\": [\"builtInCall\"], \n \"CONTAINS\": [\"builtInCall\"], \n \"STRSTARTS\": [\"builtInCall\"], \n \"STRENDS\": [\"builtInCall\"], \n \"STRBEFORE\": [\"builtInCall\"], \n \"STRAFTER\": [\"builtInCall\"], \n \"YEAR\": [\"builtInCall\"], \n \"MONTH\": [\"builtInCall\"], \n \"DAY\": [\"builtInCall\"], \n \"HOURS\": [\"builtInCall\"], \n \"MINUTES\": [\"builtInCall\"], \n \"SECONDS\": [\"builtInCall\"], \n \"TIMEZONE\": [\"builtInCall\"], \n \"TZ\": [\"builtInCall\"], \n \"NOW\": [\"builtInCall\"], \n \"UUID\": [\"builtInCall\"], \n \"STRUUID\": [\"builtInCall\"], \n \"MD5\": [\"builtInCall\"], \n \"SHA1\": [\"builtInCall\"], \n \"SHA256\": [\"builtInCall\"], \n \"SHA384\": [\"builtInCall\"], \n \"SHA512\": [\"builtInCall\"], \n \"COALESCE\": [\"builtInCall\"], \n \"IF\": [\"builtInCall\"], \n \"STRLANG\": [\"builtInCall\"], \n \"STRDT\": [\"builtInCall\"], \n \"SAMETERM\": [\"builtInCall\"], \n \"ISIRI\": [\"builtInCall\"], \n \"ISURI\": [\"builtInCall\"], \n \"ISBLANK\": [\"builtInCall\"], \n \"ISLITERAL\": [\"builtInCall\"], \n \"ISNUMERIC\": [\"builtInCall\"], \n \"SUBSTR\": [\"builtInCall\"], \n \"REPLACE\": [\"builtInCall\"], \n \"REGEX\": [\"builtInCall\"], \n \"EXISTS\": [\"builtInCall\"], \n \"NOT\": [\"builtInCall\"], \n \"IRI_REF\": [\"functionCall\"], \n \"PNAME_LN\": [\"functionCall\"], \n \"PNAME_NS\": [\"functionCall\"], \n \"(\": [\"(\",\"expression\",\"?[AS,var]\",\")\"], \n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"]}, \n \"groupGraphPattern\" : {\n \"{\": [\"{\",\"or([subSelect,groupGraphPatternSub])\",\"}\"]}, \n \"groupGraphPatternSub\" : {\n \"{\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"OPTIONAL\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"MINUS\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"GRAPH\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"SERVICE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"FILTER\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"BIND\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"VALUES\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"VAR1\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"VAR2\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"NIL\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"(\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"[\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"IRI_REF\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"TRUE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"FALSE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"BLANK_NODE_LABEL\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"ANON\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"PNAME_LN\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"PNAME_NS\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"STRING_LITERAL1\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"STRING_LITERAL2\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"STRING_LITERAL_LONG1\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"STRING_LITERAL_LONG2\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"INTEGER\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DECIMAL\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DOUBLE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"INTEGER_POSITIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DECIMAL_POSITIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DOUBLE_POSITIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"INTEGER_NEGATIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DECIMAL_NEGATIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DOUBLE_NEGATIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"}\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"]}, \n \"groupOrUnionGraphPattern\" : {\n \"{\": [\"groupGraphPattern\",\"*[UNION,groupGraphPattern]\"]}, \n \"havingClause\" : {\n \"HAVING\": [\"HAVING\",\"+havingCondition\"]}, \n \"havingCondition\" : {\n \"(\": [\"constraint\"], \n \"STR\": [\"constraint\"], \n \"LANG\": [\"constraint\"], \n \"LANGMATCHES\": [\"constraint\"], \n \"DATATYPE\": [\"constraint\"], \n \"BOUND\": [\"constraint\"], \n \"IRI\": [\"constraint\"], \n \"URI\": [\"constraint\"], \n \"BNODE\": [\"constraint\"], \n \"RAND\": [\"constraint\"], \n \"ABS\": [\"constraint\"], \n \"CEIL\": [\"constraint\"], \n \"FLOOR\": [\"constraint\"], \n \"ROUND\": [\"constraint\"], \n \"CONCAT\": [\"constraint\"], \n \"STRLEN\": [\"constraint\"], \n \"UCASE\": [\"constraint\"], \n \"LCASE\": [\"constraint\"], \n \"ENCODE_FOR_URI\": [\"constraint\"], \n \"CONTAINS\": [\"constraint\"], \n \"STRSTARTS\": [\"constraint\"], \n \"STRENDS\": [\"constraint\"], \n \"STRBEFORE\": [\"constraint\"], \n \"STRAFTER\": [\"constraint\"], \n \"YEAR\": [\"constraint\"], \n \"MONTH\": [\"constraint\"], \n \"DAY\": [\"constraint\"], \n \"HOURS\": [\"constraint\"], \n \"MINUTES\": [\"constraint\"], \n \"SECONDS\": [\"constraint\"], \n \"TIMEZONE\": [\"constraint\"], \n \"TZ\": [\"constraint\"], \n \"NOW\": [\"constraint\"], \n \"UUID\": [\"constraint\"], \n \"STRUUID\": [\"constraint\"], \n \"MD5\": [\"constraint\"], \n \"SHA1\": [\"constraint\"], \n \"SHA256\": [\"constraint\"], \n \"SHA384\": [\"constraint\"], \n \"SHA512\": [\"constraint\"], \n \"COALESCE\": [\"constraint\"], \n \"IF\": [\"constraint\"], \n \"STRLANG\": [\"constraint\"], \n \"STRDT\": [\"constraint\"], \n \"SAMETERM\": [\"constraint\"], \n \"ISIRI\": [\"constraint\"], \n \"ISURI\": [\"constraint\"], \n \"ISBLANK\": [\"constraint\"], \n \"ISLITERAL\": [\"constraint\"], \n \"ISNUMERIC\": [\"constraint\"], \n \"SUBSTR\": [\"constraint\"], \n \"REPLACE\": [\"constraint\"], \n \"REGEX\": [\"constraint\"], \n \"EXISTS\": [\"constraint\"], \n \"NOT\": [\"constraint\"], \n \"IRI_REF\": [\"constraint\"], \n \"PNAME_LN\": [\"constraint\"], \n \"PNAME_NS\": [\"constraint\"]}, \n \"inlineData\" : {\n \"VALUES\": [\"VALUES\",\"dataBlock\"]}, \n \"inlineDataFull\" : {\n \"NIL\": [\"or([NIL,[ (,*var,)]])\",\"{\",\"*or([[ (,*dataBlockValue,)],NIL])\",\"}\"], \n \"(\": [\"or([NIL,[ (,*var,)]])\",\"{\",\"*or([[ (,*dataBlockValue,)],NIL])\",\"}\"]}, \n \"inlineDataOneVar\" : {\n \"VAR1\": [\"var\",\"{\",\"*dataBlockValue\",\"}\"], \n \"VAR2\": [\"var\",\"{\",\"*dataBlockValue\",\"}\"]}, \n \"insert1\" : {\n \"DATA\": [\"DATA\",\"quadData\"], \n \"{\": [\"quadPattern\",\"*usingClause\",\"WHERE\",\"groupGraphPattern\"]}, \n \"insertClause\" : {\n \"INSERT\": [\"INSERT\",\"quadPattern\"]}, \n \"integer\" : {\n \"INTEGER\": [\"INTEGER\"]}, \n \"iriRef\" : {\n \"IRI_REF\": [\"IRI_REF\"], \n \"PNAME_LN\": [\"prefixedName\"], \n \"PNAME_NS\": [\"prefixedName\"]}, \n \"iriRefOrFunction\" : {\n \"IRI_REF\": [\"iriRef\",\"?argList\"], \n \"PNAME_LN\": [\"iriRef\",\"?argList\"], \n \"PNAME_NS\": [\"iriRef\",\"?argList\"]}, \n \"limitClause\" : {\n \"LIMIT\": [\"LIMIT\",\"INTEGER\"]}, \n \"limitOffsetClauses\" : {\n \"LIMIT\": [\"limitClause\",\"?offsetClause\"], \n \"OFFSET\": [\"offsetClause\",\"?limitClause\"]}, \n \"load\" : {\n \"LOAD\": [\"LOAD\",\"?SILENT_1\",\"iriRef\",\"?[INTO,graphRef]\"]}, \n \"minusGraphPattern\" : {\n \"MINUS\": [\"MINUS\",\"groupGraphPattern\"]}, \n \"modify\" : {\n \"WITH\": [\"WITH\",\"iriRef\",\"or([[deleteClause,?insertClause],insertClause])\",\"*usingClause\",\"WHERE\",\"groupGraphPattern\"]}, \n \"move\" : {\n \"MOVE\": [\"MOVE\",\"?SILENT_4\",\"graphOrDefault\",\"TO\",\"graphOrDefault\"]}, \n \"multiplicativeExpression\" : {\n \"!\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"+\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"-\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"VAR1\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"VAR2\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"(\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STR\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"LANG\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"LANGMATCHES\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DATATYPE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"BOUND\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"IRI\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"URI\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"BNODE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"RAND\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ABS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"CEIL\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"FLOOR\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ROUND\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"CONCAT\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRLEN\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"UCASE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"LCASE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ENCODE_FOR_URI\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"CONTAINS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRSTARTS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRENDS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRBEFORE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRAFTER\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"YEAR\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"MONTH\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DAY\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"HOURS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"MINUTES\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SECONDS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"TIMEZONE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"TZ\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"NOW\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"UUID\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRUUID\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"MD5\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SHA1\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SHA256\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SHA384\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SHA512\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"COALESCE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"IF\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRLANG\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRDT\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SAMETERM\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ISIRI\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ISURI\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ISBLANK\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ISLITERAL\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ISNUMERIC\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"TRUE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"FALSE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"COUNT\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SUM\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"MIN\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"MAX\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"AVG\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SAMPLE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"GROUP_CONCAT\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SUBSTR\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"REPLACE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"REGEX\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"EXISTS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"NOT\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"IRI_REF\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRING_LITERAL1\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRING_LITERAL2\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRING_LITERAL_LONG1\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRING_LITERAL_LONG2\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"INTEGER\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DECIMAL\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DOUBLE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"INTEGER_POSITIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DECIMAL_POSITIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DOUBLE_POSITIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"INTEGER_NEGATIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DECIMAL_NEGATIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DOUBLE_NEGATIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"PNAME_LN\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"PNAME_NS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"]}, \n \"namedGraphClause\" : {\n \"NAMED\": [\"NAMED\",\"sourceSelector\"]}, \n \"notExistsFunc\" : {\n \"NOT\": [\"NOT\",\"EXISTS\",\"groupGraphPattern\"]}, \n \"numericExpression\" : {\n \"!\": [\"additiveExpression\"], \n \"+\": [\"additiveExpression\"], \n \"-\": [\"additiveExpression\"], \n \"VAR1\": [\"additiveExpression\"], \n \"VAR2\": [\"additiveExpression\"], \n \"(\": [\"additiveExpression\"], \n \"STR\": [\"additiveExpression\"], \n \"LANG\": [\"additiveExpression\"], \n \"LANGMATCHES\": [\"additiveExpression\"], \n \"DATATYPE\": [\"additiveExpression\"], \n \"BOUND\": [\"additiveExpression\"], \n \"IRI\": [\"additiveExpression\"], \n \"URI\": [\"additiveExpression\"], \n \"BNODE\": [\"additiveExpression\"], \n \"RAND\": [\"additiveExpression\"], \n \"ABS\": [\"additiveExpression\"], \n \"CEIL\": [\"additiveExpression\"], \n \"FLOOR\": [\"additiveExpression\"], \n \"ROUND\": [\"additiveExpression\"], \n \"CONCAT\": [\"additiveExpression\"], \n \"STRLEN\": [\"additiveExpression\"], \n \"UCASE\": [\"additiveExpression\"], \n \"LCASE\": [\"additiveExpression\"], \n \"ENCODE_FOR_URI\": [\"additiveExpression\"], \n \"CONTAINS\": [\"additiveExpression\"], \n \"STRSTARTS\": [\"additiveExpression\"], \n \"STRENDS\": [\"additiveExpression\"], \n \"STRBEFORE\": [\"additiveExpression\"], \n \"STRAFTER\": [\"additiveExpression\"], \n \"YEAR\": [\"additiveExpression\"], \n \"MONTH\": [\"additiveExpression\"], \n \"DAY\": [\"additiveExpression\"], \n \"HOURS\": [\"additiveExpression\"], \n \"MINUTES\": [\"additiveExpression\"], \n \"SECONDS\": [\"additiveExpression\"], \n \"TIMEZONE\": [\"additiveExpression\"], \n \"TZ\": [\"additiveExpression\"], \n \"NOW\": [\"additiveExpression\"], \n \"UUID\": [\"additiveExpression\"], \n \"STRUUID\": [\"additiveExpression\"], \n \"MD5\": [\"additiveExpression\"], \n \"SHA1\": [\"additiveExpression\"], \n \"SHA256\": [\"additiveExpression\"], \n \"SHA384\": [\"additiveExpression\"], \n \"SHA512\": [\"additiveExpression\"], \n \"COALESCE\": [\"additiveExpression\"], \n \"IF\": [\"additiveExpression\"], \n \"STRLANG\": [\"additiveExpression\"], \n \"STRDT\": [\"additiveExpression\"], \n \"SAMETERM\": [\"additiveExpression\"], \n \"ISIRI\": [\"additiveExpression\"], \n \"ISURI\": [\"additiveExpression\"], \n \"ISBLANK\": [\"additiveExpression\"], \n \"ISLITERAL\": [\"additiveExpression\"], \n \"ISNUMERIC\": [\"additiveExpression\"], \n \"TRUE\": [\"additiveExpression\"], \n \"FALSE\": [\"additiveExpression\"], \n \"COUNT\": [\"additiveExpression\"], \n \"SUM\": [\"additiveExpression\"], \n \"MIN\": [\"additiveExpression\"], \n \"MAX\": [\"additiveExpression\"], \n \"AVG\": [\"additiveExpression\"], \n \"SAMPLE\": [\"additiveExpression\"], \n \"GROUP_CONCAT\": [\"additiveExpression\"], \n \"SUBSTR\": [\"additiveExpression\"], \n \"REPLACE\": [\"additiveExpression\"], \n \"REGEX\": [\"additiveExpression\"], \n \"EXISTS\": [\"additiveExpression\"], \n \"NOT\": [\"additiveExpression\"], \n \"IRI_REF\": [\"additiveExpression\"], \n \"STRING_LITERAL1\": [\"additiveExpression\"], \n \"STRING_LITERAL2\": [\"additiveExpression\"], \n \"STRING_LITERAL_LONG1\": [\"additiveExpression\"], \n \"STRING_LITERAL_LONG2\": [\"additiveExpression\"], \n \"INTEGER\": [\"additiveExpression\"], \n \"DECIMAL\": [\"additiveExpression\"], \n \"DOUBLE\": [\"additiveExpression\"], \n \"INTEGER_POSITIVE\": [\"additiveExpression\"], \n \"DECIMAL_POSITIVE\": [\"additiveExpression\"], \n \"DOUBLE_POSITIVE\": [\"additiveExpression\"], \n \"INTEGER_NEGATIVE\": [\"additiveExpression\"], \n \"DECIMAL_NEGATIVE\": [\"additiveExpression\"], \n \"DOUBLE_NEGATIVE\": [\"additiveExpression\"], \n \"PNAME_LN\": [\"additiveExpression\"], \n \"PNAME_NS\": [\"additiveExpression\"]}, \n \"numericLiteral\" : {\n \"INTEGER\": [\"numericLiteralUnsigned\"], \n \"DECIMAL\": [\"numericLiteralUnsigned\"], \n \"DOUBLE\": [\"numericLiteralUnsigned\"], \n \"INTEGER_POSITIVE\": [\"numericLiteralPositive\"], \n \"DECIMAL_POSITIVE\": [\"numericLiteralPositive\"], \n \"DOUBLE_POSITIVE\": [\"numericLiteralPositive\"], \n \"INTEGER_NEGATIVE\": [\"numericLiteralNegative\"], \n \"DECIMAL_NEGATIVE\": [\"numericLiteralNegative\"], \n \"DOUBLE_NEGATIVE\": [\"numericLiteralNegative\"]}, \n \"numericLiteralNegative\" : {\n \"INTEGER_NEGATIVE\": [\"INTEGER_NEGATIVE\"], \n \"DECIMAL_NEGATIVE\": [\"DECIMAL_NEGATIVE\"], \n \"DOUBLE_NEGATIVE\": [\"DOUBLE_NEGATIVE\"]}, \n \"numericLiteralPositive\" : {\n \"INTEGER_POSITIVE\": [\"INTEGER_POSITIVE\"], \n \"DECIMAL_POSITIVE\": [\"DECIMAL_POSITIVE\"], \n \"DOUBLE_POSITIVE\": [\"DOUBLE_POSITIVE\"]}, \n \"numericLiteralUnsigned\" : {\n \"INTEGER\": [\"INTEGER\"], \n \"DECIMAL\": [\"DECIMAL\"], \n \"DOUBLE\": [\"DOUBLE\"]}, \n \"object\" : {\n \"(\": [\"graphNode\"], \n \"[\": [\"graphNode\"], \n \"VAR1\": [\"graphNode\"], \n \"VAR2\": [\"graphNode\"], \n \"NIL\": [\"graphNode\"], \n \"IRI_REF\": [\"graphNode\"], \n \"TRUE\": [\"graphNode\"], \n \"FALSE\": [\"graphNode\"], \n \"BLANK_NODE_LABEL\": [\"graphNode\"], \n \"ANON\": [\"graphNode\"], \n \"PNAME_LN\": [\"graphNode\"], \n \"PNAME_NS\": [\"graphNode\"], \n \"STRING_LITERAL1\": [\"graphNode\"], \n \"STRING_LITERAL2\": [\"graphNode\"], \n \"STRING_LITERAL_LONG1\": [\"graphNode\"], \n \"STRING_LITERAL_LONG2\": [\"graphNode\"], \n \"INTEGER\": [\"graphNode\"], \n \"DECIMAL\": [\"graphNode\"], \n \"DOUBLE\": [\"graphNode\"], \n \"INTEGER_POSITIVE\": [\"graphNode\"], \n \"DECIMAL_POSITIVE\": [\"graphNode\"], \n \"DOUBLE_POSITIVE\": [\"graphNode\"], \n \"INTEGER_NEGATIVE\": [\"graphNode\"], \n \"DECIMAL_NEGATIVE\": [\"graphNode\"], \n \"DOUBLE_NEGATIVE\": [\"graphNode\"]}, \n \"objectList\" : {\n \"(\": [\"object\",\"*[,,object]\"], \n \"[\": [\"object\",\"*[,,object]\"], \n \"VAR1\": [\"object\",\"*[,,object]\"], \n \"VAR2\": [\"object\",\"*[,,object]\"], \n \"NIL\": [\"object\",\"*[,,object]\"], \n \"IRI_REF\": [\"object\",\"*[,,object]\"], \n \"TRUE\": [\"object\",\"*[,,object]\"], \n \"FALSE\": [\"object\",\"*[,,object]\"], \n \"BLANK_NODE_LABEL\": [\"object\",\"*[,,object]\"], \n \"ANON\": [\"object\",\"*[,,object]\"], \n \"PNAME_LN\": [\"object\",\"*[,,object]\"], \n \"PNAME_NS\": [\"object\",\"*[,,object]\"], \n \"STRING_LITERAL1\": [\"object\",\"*[,,object]\"], \n \"STRING_LITERAL2\": [\"object\",\"*[,,object]\"], \n \"STRING_LITERAL_LONG1\": [\"object\",\"*[,,object]\"], \n \"STRING_LITERAL_LONG2\": [\"object\",\"*[,,object]\"], \n \"INTEGER\": [\"object\",\"*[,,object]\"], \n \"DECIMAL\": [\"object\",\"*[,,object]\"], \n \"DOUBLE\": [\"object\",\"*[,,object]\"], \n \"INTEGER_POSITIVE\": [\"object\",\"*[,,object]\"], \n \"DECIMAL_POSITIVE\": [\"object\",\"*[,,object]\"], \n \"DOUBLE_POSITIVE\": [\"object\",\"*[,,object]\"], \n \"INTEGER_NEGATIVE\": [\"object\",\"*[,,object]\"], \n \"DECIMAL_NEGATIVE\": [\"object\",\"*[,,object]\"], \n \"DOUBLE_NEGATIVE\": [\"object\",\"*[,,object]\"]}, \n \"objectListPath\" : {\n \"(\": [\"objectPath\",\"*[,,objectPath]\"], \n \"[\": [\"objectPath\",\"*[,,objectPath]\"], \n \"VAR1\": [\"objectPath\",\"*[,,objectPath]\"], \n \"VAR2\": [\"objectPath\",\"*[,,objectPath]\"], \n \"NIL\": [\"objectPath\",\"*[,,objectPath]\"], \n \"IRI_REF\": [\"objectPath\",\"*[,,objectPath]\"], \n \"TRUE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"FALSE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"BLANK_NODE_LABEL\": [\"objectPath\",\"*[,,objectPath]\"], \n \"ANON\": [\"objectPath\",\"*[,,objectPath]\"], \n \"PNAME_LN\": [\"objectPath\",\"*[,,objectPath]\"], \n \"PNAME_NS\": [\"objectPath\",\"*[,,objectPath]\"], \n \"STRING_LITERAL1\": [\"objectPath\",\"*[,,objectPath]\"], \n \"STRING_LITERAL2\": [\"objectPath\",\"*[,,objectPath]\"], \n \"STRING_LITERAL_LONG1\": [\"objectPath\",\"*[,,objectPath]\"], \n \"STRING_LITERAL_LONG2\": [\"objectPath\",\"*[,,objectPath]\"], \n \"INTEGER\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DECIMAL\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DOUBLE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"INTEGER_POSITIVE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DECIMAL_POSITIVE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DOUBLE_POSITIVE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"INTEGER_NEGATIVE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DECIMAL_NEGATIVE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DOUBLE_NEGATIVE\": [\"objectPath\",\"*[,,objectPath]\"]}, \n \"objectPath\" : {\n \"(\": [\"graphNodePath\"], \n \"[\": [\"graphNodePath\"], \n \"VAR1\": [\"graphNodePath\"], \n \"VAR2\": [\"graphNodePath\"], \n \"NIL\": [\"graphNodePath\"], \n \"IRI_REF\": [\"graphNodePath\"], \n \"TRUE\": [\"graphNodePath\"], \n \"FALSE\": [\"graphNodePath\"], \n \"BLANK_NODE_LABEL\": [\"graphNodePath\"], \n \"ANON\": [\"graphNodePath\"], \n \"PNAME_LN\": [\"graphNodePath\"], \n \"PNAME_NS\": [\"graphNodePath\"], \n \"STRING_LITERAL1\": [\"graphNodePath\"], \n \"STRING_LITERAL2\": [\"graphNodePath\"], \n \"STRING_LITERAL_LONG1\": [\"graphNodePath\"], \n \"STRING_LITERAL_LONG2\": [\"graphNodePath\"], \n \"INTEGER\": [\"graphNodePath\"], \n \"DECIMAL\": [\"graphNodePath\"], \n \"DOUBLE\": [\"graphNodePath\"], \n \"INTEGER_POSITIVE\": [\"graphNodePath\"], \n \"DECIMAL_POSITIVE\": [\"graphNodePath\"], \n \"DOUBLE_POSITIVE\": [\"graphNodePath\"], \n \"INTEGER_NEGATIVE\": [\"graphNodePath\"], \n \"DECIMAL_NEGATIVE\": [\"graphNodePath\"], \n \"DOUBLE_NEGATIVE\": [\"graphNodePath\"]}, \n \"offsetClause\" : {\n \"OFFSET\": [\"OFFSET\",\"INTEGER\"]}, \n \"optionalGraphPattern\" : {\n \"OPTIONAL\": [\"OPTIONAL\",\"groupGraphPattern\"]}, \n \"or([*,expression])\" : {\n \"*\": [\"*\"], \n \"!\": [\"expression\"], \n \"+\": [\"expression\"], \n \"-\": [\"expression\"], \n \"VAR1\": [\"expression\"], \n \"VAR2\": [\"expression\"], \n \"(\": [\"expression\"], \n \"STR\": [\"expression\"], \n \"LANG\": [\"expression\"], \n \"LANGMATCHES\": [\"expression\"], \n \"DATATYPE\": [\"expression\"], \n \"BOUND\": [\"expression\"], \n \"IRI\": [\"expression\"], \n \"URI\": [\"expression\"], \n \"BNODE\": [\"expression\"], \n \"RAND\": [\"expression\"], \n \"ABS\": [\"expression\"], \n \"CEIL\": [\"expression\"], \n \"FLOOR\": [\"expression\"], \n \"ROUND\": [\"expression\"], \n \"CONCAT\": [\"expression\"], \n \"STRLEN\": [\"expression\"], \n \"UCASE\": [\"expression\"], \n \"LCASE\": [\"expression\"], \n \"ENCODE_FOR_URI\": [\"expression\"], \n \"CONTAINS\": [\"expression\"], \n \"STRSTARTS\": [\"expression\"], \n \"STRENDS\": [\"expression\"], \n \"STRBEFORE\": [\"expression\"], \n \"STRAFTER\": [\"expression\"], \n \"YEAR\": [\"expression\"], \n \"MONTH\": [\"expression\"], \n \"DAY\": [\"expression\"], \n \"HOURS\": [\"expression\"], \n \"MINUTES\": [\"expression\"], \n \"SECONDS\": [\"expression\"], \n \"TIMEZONE\": [\"expression\"], \n \"TZ\": [\"expression\"], \n \"NOW\": [\"expression\"], \n \"UUID\": [\"expression\"], \n \"STRUUID\": [\"expression\"], \n \"MD5\": [\"expression\"], \n \"SHA1\": [\"expression\"], \n \"SHA256\": [\"expression\"], \n \"SHA384\": [\"expression\"], \n \"SHA512\": [\"expression\"], \n \"COALESCE\": [\"expression\"], \n \"IF\": [\"expression\"], \n \"STRLANG\": [\"expression\"], \n \"STRDT\": [\"expression\"], \n \"SAMETERM\": [\"expression\"], \n \"ISIRI\": [\"expression\"], \n \"ISURI\": [\"expression\"], \n \"ISBLANK\": [\"expression\"], \n \"ISLITERAL\": [\"expression\"], \n \"ISNUMERIC\": [\"expression\"], \n \"TRUE\": [\"expression\"], \n \"FALSE\": [\"expression\"], \n \"COUNT\": [\"expression\"], \n \"SUM\": [\"expression\"], \n \"MIN\": [\"expression\"], \n \"MAX\": [\"expression\"], \n \"AVG\": [\"expression\"], \n \"SAMPLE\": [\"expression\"], \n \"GROUP_CONCAT\": [\"expression\"], \n \"SUBSTR\": [\"expression\"], \n \"REPLACE\": [\"expression\"], \n \"REGEX\": [\"expression\"], \n \"EXISTS\": [\"expression\"], \n \"NOT\": [\"expression\"], \n \"IRI_REF\": [\"expression\"], \n \"STRING_LITERAL1\": [\"expression\"], \n \"STRING_LITERAL2\": [\"expression\"], \n \"STRING_LITERAL_LONG1\": [\"expression\"], \n \"STRING_LITERAL_LONG2\": [\"expression\"], \n \"INTEGER\": [\"expression\"], \n \"DECIMAL\": [\"expression\"], \n \"DOUBLE\": [\"expression\"], \n \"INTEGER_POSITIVE\": [\"expression\"], \n \"DECIMAL_POSITIVE\": [\"expression\"], \n \"DOUBLE_POSITIVE\": [\"expression\"], \n \"INTEGER_NEGATIVE\": [\"expression\"], \n \"DECIMAL_NEGATIVE\": [\"expression\"], \n \"DOUBLE_NEGATIVE\": [\"expression\"], \n \"PNAME_LN\": [\"expression\"], \n \"PNAME_NS\": [\"expression\"]}, \n \"or([+or([var,[ (,expression,AS,var,)]]),*])\" : {\n \"(\": [\"+or([var,[ (,expression,AS,var,)]])\"], \n \"VAR1\": [\"+or([var,[ (,expression,AS,var,)]])\"], \n \"VAR2\": [\"+or([var,[ (,expression,AS,var,)]])\"], \n \"*\": [\"*\"]}, \n \"or([+varOrIRIref,*])\" : {\n \"VAR1\": [\"+varOrIRIref\"], \n \"VAR2\": [\"+varOrIRIref\"], \n \"IRI_REF\": [\"+varOrIRIref\"], \n \"PNAME_LN\": [\"+varOrIRIref\"], \n \"PNAME_NS\": [\"+varOrIRIref\"], \n \"*\": [\"*\"]}, \n \"or([ASC,DESC])\" : {\n \"ASC\": [\"ASC\"], \n \"DESC\": [\"DESC\"]}, \n \"or([DISTINCT,REDUCED])\" : {\n \"DISTINCT\": [\"DISTINCT\"], \n \"REDUCED\": [\"REDUCED\"]}, \n \"or([LANGTAG,[^^,iriRef]])\" : {\n \"LANGTAG\": [\"LANGTAG\"], \n \"^^\": [\"[^^,iriRef]\"]}, \n \"or([NIL,[ (,*var,)]])\" : {\n \"NIL\": [\"NIL\"], \n \"(\": [\"[ (,*var,)]\"]}, \n \"or([[ (,*dataBlockValue,)],NIL])\" : {\n \"(\": [\"[ (,*dataBlockValue,)]\"], \n \"NIL\": [\"NIL\"]}, \n \"or([[ (,expression,)],NIL])\" : {\n \"(\": [\"[ (,expression,)]\"], \n \"NIL\": [\"NIL\"]}, \n \"or([[*,unaryExpression],[/,unaryExpression]])\" : {\n \"*\": [\"[*,unaryExpression]\"], \n \"/\": [\"[/,unaryExpression]\"]}, \n \"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\" : {\n \"+\": [\"[+,multiplicativeExpression]\"], \n \"-\": [\"[-,multiplicativeExpression]\"], \n \"INTEGER_POSITIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"], \n \"DECIMAL_POSITIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"], \n \"DOUBLE_POSITIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"], \n \"INTEGER_NEGATIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"], \n \"DECIMAL_NEGATIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"], \n \"DOUBLE_NEGATIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"]}, \n \"or([[,,or([},[integer,}]])],}])\" : {\n \",\": [\"[,,or([},[integer,}]])]\"], \n \"}\": [\"}\"]}, \n \"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\" : {\n \"=\": [\"[=,numericExpression]\"], \n \"!=\": [\"[!=,numericExpression]\"], \n \"<\": [\"[<,numericExpression]\"], \n \">\": [\"[>,numericExpression]\"], \n \"<=\": [\"[<=,numericExpression]\"], \n \">=\": [\"[>=,numericExpression]\"], \n \"IN\": [\"[IN,expressionList]\"], \n \"NOT\": [\"[NOT,IN,expressionList]\"]}, \n \"or([[constructTemplate,*datasetClause,whereClause,solutionModifier],[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]])\" : {\n \"{\": [\"[constructTemplate,*datasetClause,whereClause,solutionModifier]\"], \n \"WHERE\": [\"[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]\"], \n \"FROM\": [\"[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]\"]}, \n \"or([[deleteClause,?insertClause],insertClause])\" : {\n \"DELETE\": [\"[deleteClause,?insertClause]\"], \n \"INSERT\": [\"insertClause\"]}, \n \"or([[integer,or([[,,or([},[integer,}]])],}])],[,,integer,}]])\" : {\n \"INTEGER\": [\"[integer,or([[,,or([},[integer,}]])],}])]\"], \n \",\": [\"[,,integer,}]\"]}, \n \"or([baseDecl,prefixDecl])\" : {\n \"BASE\": [\"baseDecl\"], \n \"PREFIX\": [\"prefixDecl\"]}, \n \"or([defaultGraphClause,namedGraphClause])\" : {\n \"IRI_REF\": [\"defaultGraphClause\"], \n \"PNAME_LN\": [\"defaultGraphClause\"], \n \"PNAME_NS\": [\"defaultGraphClause\"], \n \"NAMED\": [\"namedGraphClause\"]}, \n \"or([inlineDataOneVar,inlineDataFull])\" : {\n \"VAR1\": [\"inlineDataOneVar\"], \n \"VAR2\": [\"inlineDataOneVar\"], \n \"NIL\": [\"inlineDataFull\"], \n \"(\": [\"inlineDataFull\"]}, \n \"or([iriRef,[NAMED,iriRef]])\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"], \n \"NAMED\": [\"[NAMED,iriRef]\"]}, \n \"or([iriRef,a])\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"], \n \"a\": [\"a\"]}, \n \"or([numericLiteralPositive,numericLiteralNegative])\" : {\n \"INTEGER_POSITIVE\": [\"numericLiteralPositive\"], \n \"DECIMAL_POSITIVE\": [\"numericLiteralPositive\"], \n \"DOUBLE_POSITIVE\": [\"numericLiteralPositive\"], \n \"INTEGER_NEGATIVE\": [\"numericLiteralNegative\"], \n \"DECIMAL_NEGATIVE\": [\"numericLiteralNegative\"], \n \"DOUBLE_NEGATIVE\": [\"numericLiteralNegative\"]}, \n \"or([queryAll,updateAll])\" : {\n \"CONSTRUCT\": [\"queryAll\"], \n \"DESCRIBE\": [\"queryAll\"], \n \"ASK\": [\"queryAll\"], \n \"SELECT\": [\"queryAll\"], \n \"INSERT\": [\"updateAll\"], \n \"DELETE\": [\"updateAll\"], \n \"LOAD\": [\"updateAll\"], \n \"CLEAR\": [\"updateAll\"], \n \"DROP\": [\"updateAll\"], \n \"ADD\": [\"updateAll\"], \n \"MOVE\": [\"updateAll\"], \n \"COPY\": [\"updateAll\"], \n \"CREATE\": [\"updateAll\"], \n \"WITH\": [\"updateAll\"], \n \"$\": [\"updateAll\"]}, \n \"or([selectQuery,constructQuery,describeQuery,askQuery])\" : {\n \"SELECT\": [\"selectQuery\"], \n \"CONSTRUCT\": [\"constructQuery\"], \n \"DESCRIBE\": [\"describeQuery\"], \n \"ASK\": [\"askQuery\"]}, \n \"or([subSelect,groupGraphPatternSub])\" : {\n \"SELECT\": [\"subSelect\"], \n \"{\": [\"groupGraphPatternSub\"], \n \"OPTIONAL\": [\"groupGraphPatternSub\"], \n \"MINUS\": [\"groupGraphPatternSub\"], \n \"GRAPH\": [\"groupGraphPatternSub\"], \n \"SERVICE\": [\"groupGraphPatternSub\"], \n \"FILTER\": [\"groupGraphPatternSub\"], \n \"BIND\": [\"groupGraphPatternSub\"], \n \"VALUES\": [\"groupGraphPatternSub\"], \n \"VAR1\": [\"groupGraphPatternSub\"], \n \"VAR2\": [\"groupGraphPatternSub\"], \n \"NIL\": [\"groupGraphPatternSub\"], \n \"(\": [\"groupGraphPatternSub\"], \n \"[\": [\"groupGraphPatternSub\"], \n \"IRI_REF\": [\"groupGraphPatternSub\"], \n \"TRUE\": [\"groupGraphPatternSub\"], \n \"FALSE\": [\"groupGraphPatternSub\"], \n \"BLANK_NODE_LABEL\": [\"groupGraphPatternSub\"], \n \"ANON\": [\"groupGraphPatternSub\"], \n \"PNAME_LN\": [\"groupGraphPatternSub\"], \n \"PNAME_NS\": [\"groupGraphPatternSub\"], \n \"STRING_LITERAL1\": [\"groupGraphPatternSub\"], \n \"STRING_LITERAL2\": [\"groupGraphPatternSub\"], \n \"STRING_LITERAL_LONG1\": [\"groupGraphPatternSub\"], \n \"STRING_LITERAL_LONG2\": [\"groupGraphPatternSub\"], \n \"INTEGER\": [\"groupGraphPatternSub\"], \n \"DECIMAL\": [\"groupGraphPatternSub\"], \n \"DOUBLE\": [\"groupGraphPatternSub\"], \n \"INTEGER_POSITIVE\": [\"groupGraphPatternSub\"], \n \"DECIMAL_POSITIVE\": [\"groupGraphPatternSub\"], \n \"DOUBLE_POSITIVE\": [\"groupGraphPatternSub\"], \n \"INTEGER_NEGATIVE\": [\"groupGraphPatternSub\"], \n \"DECIMAL_NEGATIVE\": [\"groupGraphPatternSub\"], \n \"DOUBLE_NEGATIVE\": [\"groupGraphPatternSub\"], \n \"}\": [\"groupGraphPatternSub\"]}, \n \"or([var,[ (,expression,AS,var,)]])\" : {\n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"], \n \"(\": [\"[ (,expression,AS,var,)]\"]}, \n \"or([verbPath,verbSimple])\" : {\n \"^\": [\"verbPath\"], \n \"a\": [\"verbPath\"], \n \"!\": [\"verbPath\"], \n \"(\": [\"verbPath\"], \n \"IRI_REF\": [\"verbPath\"], \n \"PNAME_LN\": [\"verbPath\"], \n \"PNAME_NS\": [\"verbPath\"], \n \"VAR1\": [\"verbSimple\"], \n \"VAR2\": [\"verbSimple\"]}, \n \"or([},[integer,}]])\" : {\n \"}\": [\"}\"], \n \"INTEGER\": [\"[integer,}]\"]}, \n \"orderClause\" : {\n \"ORDER\": [\"ORDER\",\"BY\",\"+orderCondition\"]}, \n \"orderCondition\" : {\n \"ASC\": [\"or([ASC,DESC])\",\"brackettedExpression\"], \n \"DESC\": [\"or([ASC,DESC])\",\"brackettedExpression\"], \n \"(\": [\"constraint\"], \n \"STR\": [\"constraint\"], \n \"LANG\": [\"constraint\"], \n \"LANGMATCHES\": [\"constraint\"], \n \"DATATYPE\": [\"constraint\"], \n \"BOUND\": [\"constraint\"], \n \"IRI\": [\"constraint\"], \n \"URI\": [\"constraint\"], \n \"BNODE\": [\"constraint\"], \n \"RAND\": [\"constraint\"], \n \"ABS\": [\"constraint\"], \n \"CEIL\": [\"constraint\"], \n \"FLOOR\": [\"constraint\"], \n \"ROUND\": [\"constraint\"], \n \"CONCAT\": [\"constraint\"], \n \"STRLEN\": [\"constraint\"], \n \"UCASE\": [\"constraint\"], \n \"LCASE\": [\"constraint\"], \n \"ENCODE_FOR_URI\": [\"constraint\"], \n \"CONTAINS\": [\"constraint\"], \n \"STRSTARTS\": [\"constraint\"], \n \"STRENDS\": [\"constraint\"], \n \"STRBEFORE\": [\"constraint\"], \n \"STRAFTER\": [\"constraint\"], \n \"YEAR\": [\"constraint\"], \n \"MONTH\": [\"constraint\"], \n \"DAY\": [\"constraint\"], \n \"HOURS\": [\"constraint\"], \n \"MINUTES\": [\"constraint\"], \n \"SECONDS\": [\"constraint\"], \n \"TIMEZONE\": [\"constraint\"], \n \"TZ\": [\"constraint\"], \n \"NOW\": [\"constraint\"], \n \"UUID\": [\"constraint\"], \n \"STRUUID\": [\"constraint\"], \n \"MD5\": [\"constraint\"], \n \"SHA1\": [\"constraint\"], \n \"SHA256\": [\"constraint\"], \n \"SHA384\": [\"constraint\"], \n \"SHA512\": [\"constraint\"], \n \"COALESCE\": [\"constraint\"], \n \"IF\": [\"constraint\"], \n \"STRLANG\": [\"constraint\"], \n \"STRDT\": [\"constraint\"], \n \"SAMETERM\": [\"constraint\"], \n \"ISIRI\": [\"constraint\"], \n \"ISURI\": [\"constraint\"], \n \"ISBLANK\": [\"constraint\"], \n \"ISLITERAL\": [\"constraint\"], \n \"ISNUMERIC\": [\"constraint\"], \n \"SUBSTR\": [\"constraint\"], \n \"REPLACE\": [\"constraint\"], \n \"REGEX\": [\"constraint\"], \n \"EXISTS\": [\"constraint\"], \n \"NOT\": [\"constraint\"], \n \"IRI_REF\": [\"constraint\"], \n \"PNAME_LN\": [\"constraint\"], \n \"PNAME_NS\": [\"constraint\"], \n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"]}, \n \"path\" : {\n \"^\": [\"pathAlternative\"], \n \"a\": [\"pathAlternative\"], \n \"!\": [\"pathAlternative\"], \n \"(\": [\"pathAlternative\"], \n \"IRI_REF\": [\"pathAlternative\"], \n \"PNAME_LN\": [\"pathAlternative\"], \n \"PNAME_NS\": [\"pathAlternative\"]}, \n \"pathAlternative\" : {\n \"^\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"a\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"!\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"(\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"IRI_REF\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"PNAME_LN\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"PNAME_NS\": [\"pathSequence\",\"*[|,pathSequence]\"]}, \n \"pathElt\" : {\n \"a\": [\"pathPrimary\",\"?pathMod\"], \n \"!\": [\"pathPrimary\",\"?pathMod\"], \n \"(\": [\"pathPrimary\",\"?pathMod\"], \n \"IRI_REF\": [\"pathPrimary\",\"?pathMod\"], \n \"PNAME_LN\": [\"pathPrimary\",\"?pathMod\"], \n \"PNAME_NS\": [\"pathPrimary\",\"?pathMod\"]}, \n \"pathEltOrInverse\" : {\n \"a\": [\"pathElt\"], \n \"!\": [\"pathElt\"], \n \"(\": [\"pathElt\"], \n \"IRI_REF\": [\"pathElt\"], \n \"PNAME_LN\": [\"pathElt\"], \n \"PNAME_NS\": [\"pathElt\"], \n \"^\": [\"^\",\"pathElt\"]}, \n \"pathMod\" : {\n \"*\": [\"*\"], \n \"?\": [\"?\"], \n \"+\": [\"+\"], \n \"{\": [\"{\",\"or([[integer,or([[,,or([},[integer,}]])],}])],[,,integer,}]])\"]}, \n \"pathNegatedPropertySet\" : {\n \"a\": [\"pathOneInPropertySet\"], \n \"^\": [\"pathOneInPropertySet\"], \n \"IRI_REF\": [\"pathOneInPropertySet\"], \n \"PNAME_LN\": [\"pathOneInPropertySet\"], \n \"PNAME_NS\": [\"pathOneInPropertySet\"], \n \"(\": [\"(\",\"?[pathOneInPropertySet,*[|,pathOneInPropertySet]]\",\")\"]}, \n \"pathOneInPropertySet\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"], \n \"a\": [\"a\"], \n \"^\": [\"^\",\"or([iriRef,a])\"]}, \n \"pathPrimary\" : {\n \"IRI_REF\": [\"storeProperty\",\"iriRef\"], \n \"PNAME_LN\": [\"storeProperty\",\"iriRef\"], \n \"PNAME_NS\": [\"storeProperty\",\"iriRef\"], \n \"a\": [\"storeProperty\",\"a\"], \n \"!\": [\"!\",\"pathNegatedPropertySet\"], \n \"(\": [\"(\",\"path\",\")\"]}, \n \"pathSequence\" : {\n \"^\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"a\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"!\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"(\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"IRI_REF\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"PNAME_LN\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"PNAME_NS\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"]}, \n \"prefixDecl\" : {\n \"PREFIX\": [\"PREFIX\",\"PNAME_NS\",\"IRI_REF\"]}, \n \"prefixedName\" : {\n \"PNAME_LN\": [\"PNAME_LN\"], \n \"PNAME_NS\": [\"PNAME_NS\"]}, \n \"primaryExpression\" : {\n \"(\": [\"brackettedExpression\"], \n \"STR\": [\"builtInCall\"], \n \"LANG\": [\"builtInCall\"], \n \"LANGMATCHES\": [\"builtInCall\"], \n \"DATATYPE\": [\"builtInCall\"], \n \"BOUND\": [\"builtInCall\"], \n \"IRI\": [\"builtInCall\"], \n \"URI\": [\"builtInCall\"], \n \"BNODE\": [\"builtInCall\"], \n \"RAND\": [\"builtInCall\"], \n \"ABS\": [\"builtInCall\"], \n \"CEIL\": [\"builtInCall\"], \n \"FLOOR\": [\"builtInCall\"], \n \"ROUND\": [\"builtInCall\"], \n \"CONCAT\": [\"builtInCall\"], \n \"STRLEN\": [\"builtInCall\"], \n \"UCASE\": [\"builtInCall\"], \n \"LCASE\": [\"builtInCall\"], \n \"ENCODE_FOR_URI\": [\"builtInCall\"], \n \"CONTAINS\": [\"builtInCall\"], \n \"STRSTARTS\": [\"builtInCall\"], \n \"STRENDS\": [\"builtInCall\"], \n \"STRBEFORE\": [\"builtInCall\"], \n \"STRAFTER\": [\"builtInCall\"], \n \"YEAR\": [\"builtInCall\"], \n \"MONTH\": [\"builtInCall\"], \n \"DAY\": [\"builtInCall\"], \n \"HOURS\": [\"builtInCall\"], \n \"MINUTES\": [\"builtInCall\"], \n \"SECONDS\": [\"builtInCall\"], \n \"TIMEZONE\": [\"builtInCall\"], \n \"TZ\": [\"builtInCall\"], \n \"NOW\": [\"builtInCall\"], \n \"UUID\": [\"builtInCall\"], \n \"STRUUID\": [\"builtInCall\"], \n \"MD5\": [\"builtInCall\"], \n \"SHA1\": [\"builtInCall\"], \n \"SHA256\": [\"builtInCall\"], \n \"SHA384\": [\"builtInCall\"], \n \"SHA512\": [\"builtInCall\"], \n \"COALESCE\": [\"builtInCall\"], \n \"IF\": [\"builtInCall\"], \n \"STRLANG\": [\"builtInCall\"], \n \"STRDT\": [\"builtInCall\"], \n \"SAMETERM\": [\"builtInCall\"], \n \"ISIRI\": [\"builtInCall\"], \n \"ISURI\": [\"builtInCall\"], \n \"ISBLANK\": [\"builtInCall\"], \n \"ISLITERAL\": [\"builtInCall\"], \n \"ISNUMERIC\": [\"builtInCall\"], \n \"SUBSTR\": [\"builtInCall\"], \n \"REPLACE\": [\"builtInCall\"], \n \"REGEX\": [\"builtInCall\"], \n \"EXISTS\": [\"builtInCall\"], \n \"NOT\": [\"builtInCall\"], \n \"IRI_REF\": [\"iriRefOrFunction\"], \n \"PNAME_LN\": [\"iriRefOrFunction\"], \n \"PNAME_NS\": [\"iriRefOrFunction\"], \n \"STRING_LITERAL1\": [\"rdfLiteral\"], \n \"STRING_LITERAL2\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG1\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG2\": [\"rdfLiteral\"], \n \"INTEGER\": [\"numericLiteral\"], \n \"DECIMAL\": [\"numericLiteral\"], \n \"DOUBLE\": [\"numericLiteral\"], \n \"INTEGER_POSITIVE\": [\"numericLiteral\"], \n \"DECIMAL_POSITIVE\": [\"numericLiteral\"], \n \"DOUBLE_POSITIVE\": [\"numericLiteral\"], \n \"INTEGER_NEGATIVE\": [\"numericLiteral\"], \n \"DECIMAL_NEGATIVE\": [\"numericLiteral\"], \n \"DOUBLE_NEGATIVE\": [\"numericLiteral\"], \n \"TRUE\": [\"booleanLiteral\"], \n \"FALSE\": [\"booleanLiteral\"], \n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"], \n \"COUNT\": [\"aggregate\"], \n \"SUM\": [\"aggregate\"], \n \"MIN\": [\"aggregate\"], \n \"MAX\": [\"aggregate\"], \n \"AVG\": [\"aggregate\"], \n \"SAMPLE\": [\"aggregate\"], \n \"GROUP_CONCAT\": [\"aggregate\"]}, \n \"prologue\" : {\n \"BASE\": [\"*or([baseDecl,prefixDecl])\"], \n \"PREFIX\": [\"*or([baseDecl,prefixDecl])\"], \n \"$\": [\"*or([baseDecl,prefixDecl])\"], \n \"CONSTRUCT\": [\"*or([baseDecl,prefixDecl])\"], \n \"DESCRIBE\": [\"*or([baseDecl,prefixDecl])\"], \n \"ASK\": [\"*or([baseDecl,prefixDecl])\"], \n \"INSERT\": [\"*or([baseDecl,prefixDecl])\"], \n \"DELETE\": [\"*or([baseDecl,prefixDecl])\"], \n \"SELECT\": [\"*or([baseDecl,prefixDecl])\"], \n \"LOAD\": [\"*or([baseDecl,prefixDecl])\"], \n \"CLEAR\": [\"*or([baseDecl,prefixDecl])\"], \n \"DROP\": [\"*or([baseDecl,prefixDecl])\"], \n \"ADD\": [\"*or([baseDecl,prefixDecl])\"], \n \"MOVE\": [\"*or([baseDecl,prefixDecl])\"], \n \"COPY\": [\"*or([baseDecl,prefixDecl])\"], \n \"CREATE\": [\"*or([baseDecl,prefixDecl])\"], \n \"WITH\": [\"*or([baseDecl,prefixDecl])\"]}, \n \"propertyList\" : {\n \"a\": [\"propertyListNotEmpty\"], \n \"VAR1\": [\"propertyListNotEmpty\"], \n \"VAR2\": [\"propertyListNotEmpty\"], \n \"IRI_REF\": [\"propertyListNotEmpty\"], \n \"PNAME_LN\": [\"propertyListNotEmpty\"], \n \"PNAME_NS\": [\"propertyListNotEmpty\"], \n \".\": [], \n \"}\": [], \n \"GRAPH\": []}, \n \"propertyListNotEmpty\" : {\n \"a\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"], \n \"VAR1\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"], \n \"VAR2\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"], \n \"IRI_REF\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"], \n \"PNAME_LN\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"], \n \"PNAME_NS\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"]}, \n \"propertyListPath\" : {\n \"a\": [\"propertyListNotEmpty\"], \n \"VAR1\": [\"propertyListNotEmpty\"], \n \"VAR2\": [\"propertyListNotEmpty\"], \n \"IRI_REF\": [\"propertyListNotEmpty\"], \n \"PNAME_LN\": [\"propertyListNotEmpty\"], \n \"PNAME_NS\": [\"propertyListNotEmpty\"], \n \".\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"GRAPH\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"propertyListPathNotEmpty\" : {\n \"VAR1\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"VAR2\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"^\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"a\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"!\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"(\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"IRI_REF\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"PNAME_LN\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"PNAME_NS\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"]}, \n \"quadData\" : {\n \"{\": [\"{\",\"disallowVars\",\"quads\",\"allowVars\",\"}\"]}, \n \"quadDataNoBnodes\" : {\n \"{\": [\"{\",\"disallowBnodes\",\"disallowVars\",\"quads\",\"allowVars\",\"allowBnodes\",\"}\"]}, \n \"quadPattern\" : {\n \"{\": [\"{\",\"quads\",\"}\"]}, \n \"quadPatternNoBnodes\" : {\n \"{\": [\"{\",\"disallowBnodes\",\"quads\",\"allowBnodes\",\"}\"]}, \n \"quads\" : {\n \"GRAPH\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"VAR1\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"VAR2\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"NIL\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"(\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"[\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"IRI_REF\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"TRUE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"FALSE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"BLANK_NODE_LABEL\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"ANON\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"PNAME_LN\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"PNAME_NS\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"STRING_LITERAL1\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"STRING_LITERAL2\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"STRING_LITERAL_LONG1\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"STRING_LITERAL_LONG2\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"INTEGER\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DECIMAL\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DOUBLE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"INTEGER_POSITIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DECIMAL_POSITIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DOUBLE_POSITIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"INTEGER_NEGATIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DECIMAL_NEGATIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DOUBLE_NEGATIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"}\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"]}, \n \"quadsNotTriples\" : {\n \"GRAPH\": [\"GRAPH\",\"varOrIRIref\",\"{\",\"?triplesTemplate\",\"}\"]}, \n \"queryAll\" : {\n \"CONSTRUCT\": [\"or([selectQuery,constructQuery,describeQuery,askQuery])\",\"valuesClause\"], \n \"DESCRIBE\": [\"or([selectQuery,constructQuery,describeQuery,askQuery])\",\"valuesClause\"], \n \"ASK\": [\"or([selectQuery,constructQuery,describeQuery,askQuery])\",\"valuesClause\"], \n \"SELECT\": [\"or([selectQuery,constructQuery,describeQuery,askQuery])\",\"valuesClause\"]}, \n \"rdfLiteral\" : {\n \"STRING_LITERAL1\": [\"string\",\"?or([LANGTAG,[^^,iriRef]])\"], \n \"STRING_LITERAL2\": [\"string\",\"?or([LANGTAG,[^^,iriRef]])\"], \n \"STRING_LITERAL_LONG1\": [\"string\",\"?or([LANGTAG,[^^,iriRef]])\"], \n \"STRING_LITERAL_LONG2\": [\"string\",\"?or([LANGTAG,[^^,iriRef]])\"]}, \n \"regexExpression\" : {\n \"REGEX\": [\"REGEX\",\"(\",\"expression\",\",\",\"expression\",\"?[,,expression]\",\")\"]}, \n \"relationalExpression\" : {\n \"!\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"+\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"-\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"VAR1\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"VAR2\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"(\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STR\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"LANG\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"LANGMATCHES\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DATATYPE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"BOUND\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"IRI\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"URI\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"BNODE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"RAND\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ABS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"CEIL\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"FLOOR\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ROUND\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"CONCAT\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRLEN\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"UCASE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"LCASE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ENCODE_FOR_URI\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"CONTAINS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRSTARTS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRENDS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRBEFORE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRAFTER\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"YEAR\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"MONTH\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DAY\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"HOURS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"MINUTES\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SECONDS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"TIMEZONE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"TZ\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"NOW\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"UUID\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRUUID\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"MD5\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SHA1\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SHA256\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SHA384\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SHA512\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"COALESCE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"IF\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRLANG\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRDT\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SAMETERM\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ISIRI\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ISURI\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ISBLANK\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ISLITERAL\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ISNUMERIC\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"TRUE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"FALSE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"COUNT\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SUM\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"MIN\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"MAX\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"AVG\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SAMPLE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"GROUP_CONCAT\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SUBSTR\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"REPLACE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"REGEX\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"EXISTS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"NOT\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"IRI_REF\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRING_LITERAL1\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRING_LITERAL2\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRING_LITERAL_LONG1\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRING_LITERAL_LONG2\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"INTEGER\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DECIMAL\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DOUBLE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"INTEGER_POSITIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DECIMAL_POSITIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DOUBLE_POSITIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"INTEGER_NEGATIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DECIMAL_NEGATIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DOUBLE_NEGATIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"PNAME_LN\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"PNAME_NS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"]}, \n \"selectClause\" : {\n \"SELECT\": [\"SELECT\",\"?or([DISTINCT,REDUCED])\",\"or([+or([var,[ (,expression,AS,var,)]]),*])\"]}, \n \"selectQuery\" : {\n \"SELECT\": [\"selectClause\",\"*datasetClause\",\"whereClause\",\"solutionModifier\"]}, \n \"serviceGraphPattern\" : {\n \"SERVICE\": [\"SERVICE\",\"?SILENT\",\"varOrIRIref\",\"groupGraphPattern\"]}, \n \"solutionModifier\" : {\n \"LIMIT\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"OFFSET\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"ORDER\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"HAVING\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"GROUP\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"VALUES\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"$\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"}\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"]}, \n \"sourceSelector\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"]}, \n \"sparql11\" : {\n \"$\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"CONSTRUCT\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"DESCRIBE\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"ASK\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"INSERT\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"DELETE\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"SELECT\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"LOAD\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"CLEAR\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"DROP\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"ADD\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"MOVE\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"COPY\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"CREATE\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"WITH\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"BASE\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"PREFIX\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"]}, \n \"storeProperty\" : {\n \"VAR1\": [], \n \"VAR2\": [], \n \"IRI_REF\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"a\": []}, \n \"strReplaceExpression\" : {\n \"REPLACE\": [\"REPLACE\",\"(\",\"expression\",\",\",\"expression\",\",\",\"expression\",\"?[,,expression]\",\")\"]}, \n \"string\" : {\n \"STRING_LITERAL1\": [\"STRING_LITERAL1\"], \n \"STRING_LITERAL2\": [\"STRING_LITERAL2\"], \n \"STRING_LITERAL_LONG1\": [\"STRING_LITERAL_LONG1\"], \n \"STRING_LITERAL_LONG2\": [\"STRING_LITERAL_LONG2\"]}, \n \"subSelect\" : {\n \"SELECT\": [\"selectClause\",\"whereClause\",\"solutionModifier\",\"valuesClause\"]}, \n \"substringExpression\" : {\n \"SUBSTR\": [\"SUBSTR\",\"(\",\"expression\",\",\",\"expression\",\"?[,,expression]\",\")\"]}, \n \"triplesBlock\" : {\n \"VAR1\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"VAR2\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"NIL\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"(\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"[\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"IRI_REF\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"TRUE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"FALSE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"BLANK_NODE_LABEL\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"ANON\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"PNAME_LN\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"PNAME_NS\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"STRING_LITERAL1\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"STRING_LITERAL2\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"STRING_LITERAL_LONG1\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"STRING_LITERAL_LONG2\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"INTEGER\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DECIMAL\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DOUBLE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"INTEGER_POSITIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DECIMAL_POSITIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DOUBLE_POSITIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"INTEGER_NEGATIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DECIMAL_NEGATIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DOUBLE_NEGATIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"]}, \n \"triplesNode\" : {\n \"(\": [\"collection\"], \n \"[\": [\"blankNodePropertyList\"]}, \n \"triplesNodePath\" : {\n \"(\": [\"collectionPath\"], \n \"[\": [\"blankNodePropertyListPath\"]}, \n \"triplesSameSubject\" : {\n \"VAR1\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"VAR2\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"NIL\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"IRI_REF\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"TRUE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"FALSE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"BLANK_NODE_LABEL\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"ANON\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"PNAME_LN\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"PNAME_NS\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"STRING_LITERAL1\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"STRING_LITERAL2\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"STRING_LITERAL_LONG1\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"STRING_LITERAL_LONG2\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"INTEGER\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DECIMAL\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DOUBLE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"INTEGER_POSITIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DECIMAL_POSITIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DOUBLE_POSITIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"INTEGER_NEGATIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DECIMAL_NEGATIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DOUBLE_NEGATIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"(\": [\"triplesNode\",\"propertyList\"], \n \"[\": [\"triplesNode\",\"propertyList\"]}, \n \"triplesSameSubjectPath\" : {\n \"VAR1\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"VAR2\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"NIL\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"IRI_REF\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"TRUE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"FALSE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"BLANK_NODE_LABEL\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"ANON\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"PNAME_LN\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"PNAME_NS\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"STRING_LITERAL1\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"STRING_LITERAL2\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"STRING_LITERAL_LONG1\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"STRING_LITERAL_LONG2\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"INTEGER\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DECIMAL\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DOUBLE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"INTEGER_POSITIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DECIMAL_POSITIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DOUBLE_POSITIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"INTEGER_NEGATIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DECIMAL_NEGATIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DOUBLE_NEGATIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"(\": [\"triplesNodePath\",\"propertyListPath\"], \n \"[\": [\"triplesNodePath\",\"propertyListPath\"]}, \n \"triplesTemplate\" : {\n \"VAR1\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"VAR2\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"NIL\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"(\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"[\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"IRI_REF\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"TRUE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"FALSE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"BLANK_NODE_LABEL\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"ANON\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"PNAME_LN\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"PNAME_NS\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"STRING_LITERAL1\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"STRING_LITERAL2\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"STRING_LITERAL_LONG1\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"STRING_LITERAL_LONG2\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"INTEGER\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DECIMAL\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DOUBLE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"INTEGER_POSITIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DECIMAL_POSITIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DOUBLE_POSITIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"INTEGER_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DECIMAL_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DOUBLE_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"]}, \n \"unaryExpression\" : {\n \"!\": [\"!\",\"primaryExpression\"], \n \"+\": [\"+\",\"primaryExpression\"], \n \"-\": [\"-\",\"primaryExpression\"], \n \"VAR1\": [\"primaryExpression\"], \n \"VAR2\": [\"primaryExpression\"], \n \"(\": [\"primaryExpression\"], \n \"STR\": [\"primaryExpression\"], \n \"LANG\": [\"primaryExpression\"], \n \"LANGMATCHES\": [\"primaryExpression\"], \n \"DATATYPE\": [\"primaryExpression\"], \n \"BOUND\": [\"primaryExpression\"], \n \"IRI\": [\"primaryExpression\"], \n \"URI\": [\"primaryExpression\"], \n \"BNODE\": [\"primaryExpression\"], \n \"RAND\": [\"primaryExpression\"], \n \"ABS\": [\"primaryExpression\"], \n \"CEIL\": [\"primaryExpression\"], \n \"FLOOR\": [\"primaryExpression\"], \n \"ROUND\": [\"primaryExpression\"], \n \"CONCAT\": [\"primaryExpression\"], \n \"STRLEN\": [\"primaryExpression\"], \n \"UCASE\": [\"primaryExpression\"], \n \"LCASE\": [\"primaryExpression\"], \n \"ENCODE_FOR_URI\": [\"primaryExpression\"], \n \"CONTAINS\": [\"primaryExpression\"], \n \"STRSTARTS\": [\"primaryExpression\"], \n \"STRENDS\": [\"primaryExpression\"], \n \"STRBEFORE\": [\"primaryExpression\"], \n \"STRAFTER\": [\"primaryExpression\"], \n \"YEAR\": [\"primaryExpression\"], \n \"MONTH\": [\"primaryExpression\"], \n \"DAY\": [\"primaryExpression\"], \n \"HOURS\": [\"primaryExpression\"], \n \"MINUTES\": [\"primaryExpression\"], \n \"SECONDS\": [\"primaryExpression\"], \n \"TIMEZONE\": [\"primaryExpression\"], \n \"TZ\": [\"primaryExpression\"], \n \"NOW\": [\"primaryExpression\"], \n \"UUID\": [\"primaryExpression\"], \n \"STRUUID\": [\"primaryExpression\"], \n \"MD5\": [\"primaryExpression\"], \n \"SHA1\": [\"primaryExpression\"], \n \"SHA256\": [\"primaryExpression\"], \n \"SHA384\": [\"primaryExpression\"], \n \"SHA512\": [\"primaryExpression\"], \n \"COALESCE\": [\"primaryExpression\"], \n \"IF\": [\"primaryExpression\"], \n \"STRLANG\": [\"primaryExpression\"], \n \"STRDT\": [\"primaryExpression\"], \n \"SAMETERM\": [\"primaryExpression\"], \n \"ISIRI\": [\"primaryExpression\"], \n \"ISURI\": [\"primaryExpression\"], \n \"ISBLANK\": [\"primaryExpression\"], \n \"ISLITERAL\": [\"primaryExpression\"], \n \"ISNUMERIC\": [\"primaryExpression\"], \n \"TRUE\": [\"primaryExpression\"], \n \"FALSE\": [\"primaryExpression\"], \n \"COUNT\": [\"primaryExpression\"], \n \"SUM\": [\"primaryExpression\"], \n \"MIN\": [\"primaryExpression\"], \n \"MAX\": [\"primaryExpression\"], \n \"AVG\": [\"primaryExpression\"], \n \"SAMPLE\": [\"primaryExpression\"], \n \"GROUP_CONCAT\": [\"primaryExpression\"], \n \"SUBSTR\": [\"primaryExpression\"], \n \"REPLACE\": [\"primaryExpression\"], \n \"REGEX\": [\"primaryExpression\"], \n \"EXISTS\": [\"primaryExpression\"], \n \"NOT\": [\"primaryExpression\"], \n \"IRI_REF\": [\"primaryExpression\"], \n \"STRING_LITERAL1\": [\"primaryExpression\"], \n \"STRING_LITERAL2\": [\"primaryExpression\"], \n \"STRING_LITERAL_LONG1\": [\"primaryExpression\"], \n \"STRING_LITERAL_LONG2\": [\"primaryExpression\"], \n \"INTEGER\": [\"primaryExpression\"], \n \"DECIMAL\": [\"primaryExpression\"], \n \"DOUBLE\": [\"primaryExpression\"], \n \"INTEGER_POSITIVE\": [\"primaryExpression\"], \n \"DECIMAL_POSITIVE\": [\"primaryExpression\"], \n \"DOUBLE_POSITIVE\": [\"primaryExpression\"], \n \"INTEGER_NEGATIVE\": [\"primaryExpression\"], \n \"DECIMAL_NEGATIVE\": [\"primaryExpression\"], \n \"DOUBLE_NEGATIVE\": [\"primaryExpression\"], \n \"PNAME_LN\": [\"primaryExpression\"], \n \"PNAME_NS\": [\"primaryExpression\"]}, \n \"update\" : {\n \"INSERT\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"DELETE\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"LOAD\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"CLEAR\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"DROP\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"ADD\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"MOVE\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"COPY\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"CREATE\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"WITH\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"BASE\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"PREFIX\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"$\": [\"prologue\",\"?[update1,?[;,update]]\"]}, \n \"update1\" : {\n \"LOAD\": [\"load\"], \n \"CLEAR\": [\"clear\"], \n \"DROP\": [\"drop\"], \n \"ADD\": [\"add\"], \n \"MOVE\": [\"move\"], \n \"COPY\": [\"copy\"], \n \"CREATE\": [\"create\"], \n \"INSERT\": [\"INSERT\",\"insert1\"], \n \"DELETE\": [\"DELETE\",\"delete1\"], \n \"WITH\": [\"modify\"]}, \n \"updateAll\" : {\n \"INSERT\": [\"?[update1,?[;,update]]\"], \n \"DELETE\": [\"?[update1,?[;,update]]\"], \n \"LOAD\": [\"?[update1,?[;,update]]\"], \n \"CLEAR\": [\"?[update1,?[;,update]]\"], \n \"DROP\": [\"?[update1,?[;,update]]\"], \n \"ADD\": [\"?[update1,?[;,update]]\"], \n \"MOVE\": [\"?[update1,?[;,update]]\"], \n \"COPY\": [\"?[update1,?[;,update]]\"], \n \"CREATE\": [\"?[update1,?[;,update]]\"], \n \"WITH\": [\"?[update1,?[;,update]]\"], \n \"$\": [\"?[update1,?[;,update]]\"]}, \n \"usingClause\" : {\n \"USING\": [\"USING\",\"or([iriRef,[NAMED,iriRef]])\"]}, \n \"valueLogical\" : {\n \"!\": [\"relationalExpression\"], \n \"+\": [\"relationalExpression\"], \n \"-\": [\"relationalExpression\"], \n \"VAR1\": [\"relationalExpression\"], \n \"VAR2\": [\"relationalExpression\"], \n \"(\": [\"relationalExpression\"], \n \"STR\": [\"relationalExpression\"], \n \"LANG\": [\"relationalExpression\"], \n \"LANGMATCHES\": [\"relationalExpression\"], \n \"DATATYPE\": [\"relationalExpression\"], \n \"BOUND\": [\"relationalExpression\"], \n \"IRI\": [\"relationalExpression\"], \n \"URI\": [\"relationalExpression\"], \n \"BNODE\": [\"relationalExpression\"], \n \"RAND\": [\"relationalExpression\"], \n \"ABS\": [\"relationalExpression\"], \n \"CEIL\": [\"relationalExpression\"], \n \"FLOOR\": [\"relationalExpression\"], \n \"ROUND\": [\"relationalExpression\"], \n \"CONCAT\": [\"relationalExpression\"], \n \"STRLEN\": [\"relationalExpression\"], \n \"UCASE\": [\"relationalExpression\"], \n \"LCASE\": [\"relationalExpression\"], \n \"ENCODE_FOR_URI\": [\"relationalExpression\"], \n \"CONTAINS\": [\"relationalExpression\"], \n \"STRSTARTS\": [\"relationalExpression\"], \n \"STRENDS\": [\"relationalExpression\"], \n \"STRBEFORE\": [\"relationalExpression\"], \n \"STRAFTER\": [\"relationalExpression\"], \n \"YEAR\": [\"relationalExpression\"], \n \"MONTH\": [\"relationalExpression\"], \n \"DAY\": [\"relationalExpression\"], \n \"HOURS\": [\"relationalExpression\"], \n \"MINUTES\": [\"relationalExpression\"], \n \"SECONDS\": [\"relationalExpression\"], \n \"TIMEZONE\": [\"relationalExpression\"], \n \"TZ\": [\"relationalExpression\"], \n \"NOW\": [\"relationalExpression\"], \n \"UUID\": [\"relationalExpression\"], \n \"STRUUID\": [\"relationalExpression\"], \n \"MD5\": [\"relationalExpression\"], \n \"SHA1\": [\"relationalExpression\"], \n \"SHA256\": [\"relationalExpression\"], \n \"SHA384\": [\"relationalExpression\"], \n \"SHA512\": [\"relationalExpression\"], \n \"COALESCE\": [\"relationalExpression\"], \n \"IF\": [\"relationalExpression\"], \n \"STRLANG\": [\"relationalExpression\"], \n \"STRDT\": [\"relationalExpression\"], \n \"SAMETERM\": [\"relationalExpression\"], \n \"ISIRI\": [\"relationalExpression\"], \n \"ISURI\": [\"relationalExpression\"], \n \"ISBLANK\": [\"relationalExpression\"], \n \"ISLITERAL\": [\"relationalExpression\"], \n \"ISNUMERIC\": [\"relationalExpression\"], \n \"TRUE\": [\"relationalExpression\"], \n \"FALSE\": [\"relationalExpression\"], \n \"COUNT\": [\"relationalExpression\"], \n \"SUM\": [\"relationalExpression\"], \n \"MIN\": [\"relationalExpression\"], \n \"MAX\": [\"relationalExpression\"], \n \"AVG\": [\"relationalExpression\"], \n \"SAMPLE\": [\"relationalExpression\"], \n \"GROUP_CONCAT\": [\"relationalExpression\"], \n \"SUBSTR\": [\"relationalExpression\"], \n \"REPLACE\": [\"relationalExpression\"], \n \"REGEX\": [\"relationalExpression\"], \n \"EXISTS\": [\"relationalExpression\"], \n \"NOT\": [\"relationalExpression\"], \n \"IRI_REF\": [\"relationalExpression\"], \n \"STRING_LITERAL1\": [\"relationalExpression\"], \n \"STRING_LITERAL2\": [\"relationalExpression\"], \n \"STRING_LITERAL_LONG1\": [\"relationalExpression\"], \n \"STRING_LITERAL_LONG2\": [\"relationalExpression\"], \n \"INTEGER\": [\"relationalExpression\"], \n \"DECIMAL\": [\"relationalExpression\"], \n \"DOUBLE\": [\"relationalExpression\"], \n \"INTEGER_POSITIVE\": [\"relationalExpression\"], \n \"DECIMAL_POSITIVE\": [\"relationalExpression\"], \n \"DOUBLE_POSITIVE\": [\"relationalExpression\"], \n \"INTEGER_NEGATIVE\": [\"relationalExpression\"], \n \"DECIMAL_NEGATIVE\": [\"relationalExpression\"], \n \"DOUBLE_NEGATIVE\": [\"relationalExpression\"], \n \"PNAME_LN\": [\"relationalExpression\"], \n \"PNAME_NS\": [\"relationalExpression\"]}, \n \"valuesClause\" : {\n \"VALUES\": [\"VALUES\",\"dataBlock\"], \n \"$\": [], \n \"}\": []}, \n \"var\" : {\n \"VAR1\": [\"VAR1\"], \n \"VAR2\": [\"VAR2\"]}, \n \"varOrIRIref\" : {\n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"], \n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"]}, \n \"varOrTerm\" : {\n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"], \n \"NIL\": [\"graphTerm\"], \n \"IRI_REF\": [\"graphTerm\"], \n \"TRUE\": [\"graphTerm\"], \n \"FALSE\": [\"graphTerm\"], \n \"BLANK_NODE_LABEL\": [\"graphTerm\"], \n \"ANON\": [\"graphTerm\"], \n \"PNAME_LN\": [\"graphTerm\"], \n \"PNAME_NS\": [\"graphTerm\"], \n \"STRING_LITERAL1\": [\"graphTerm\"], \n \"STRING_LITERAL2\": [\"graphTerm\"], \n \"STRING_LITERAL_LONG1\": [\"graphTerm\"], \n \"STRING_LITERAL_LONG2\": [\"graphTerm\"], \n \"INTEGER\": [\"graphTerm\"], \n \"DECIMAL\": [\"graphTerm\"], \n \"DOUBLE\": [\"graphTerm\"], \n \"INTEGER_POSITIVE\": [\"graphTerm\"], \n \"DECIMAL_POSITIVE\": [\"graphTerm\"], \n \"DOUBLE_POSITIVE\": [\"graphTerm\"], \n \"INTEGER_NEGATIVE\": [\"graphTerm\"], \n \"DECIMAL_NEGATIVE\": [\"graphTerm\"], \n \"DOUBLE_NEGATIVE\": [\"graphTerm\"]}, \n \"verb\" : {\n \"VAR1\": [\"storeProperty\",\"varOrIRIref\"], \n \"VAR2\": [\"storeProperty\",\"varOrIRIref\"], \n \"IRI_REF\": [\"storeProperty\",\"varOrIRIref\"], \n \"PNAME_LN\": [\"storeProperty\",\"varOrIRIref\"], \n \"PNAME_NS\": [\"storeProperty\",\"varOrIRIref\"], \n \"a\": [\"storeProperty\",\"a\"]}, \n \"verbPath\" : {\n \"^\": [\"path\"], \n \"a\": [\"path\"], \n \"!\": [\"path\"], \n \"(\": [\"path\"], \n \"IRI_REF\": [\"path\"], \n \"PNAME_LN\": [\"path\"], \n \"PNAME_NS\": [\"path\"]}, \n \"verbSimple\" : {\n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"]}, \n \"whereClause\" : {\n \"{\": [\"?WHERE\",\"groupGraphPattern\"], \n \"WHERE\": [\"?WHERE\",\"groupGraphPattern\"]}\n},\n\nkeywords:/^(GROUP_CONCAT|DATATYPE|BASE|PREFIX|SELECT|CONSTRUCT|DESCRIBE|ASK|FROM|NAMED|ORDER|BY|LIMIT|ASC|DESC|OFFSET|DISTINCT|REDUCED|WHERE|GRAPH|OPTIONAL|UNION|FILTER|GROUP|HAVING|AS|VALUES|LOAD|CLEAR|DROP|CREATE|MOVE|COPY|SILENT|INSERT|DELETE|DATA|WITH|TO|USING|NAMED|MINUS|BIND|LANGMATCHES|LANG|BOUND|SAMETERM|ISIRI|ISURI|ISBLANK|ISLITERAL|REGEX|TRUE|FALSE|UNDEF|ADD|DEFAULT|ALL|SERVICE|INTO|IN|NOT|IRI|URI|BNODE|RAND|ABS|CEIL|FLOOR|ROUND|CONCAT|STRLEN|UCASE|LCASE|ENCODE_FOR_URI|CONTAINS|STRSTARTS|STRENDS|STRBEFORE|STRAFTER|YEAR|MONTH|DAY|HOURS|MINUTES|SECONDS|TIMEZONE|TZ|NOW|UUID|STRUUID|MD5|SHA1|SHA256|SHA384|SHA512|COALESCE|IF|STRLANG|STRDT|ISNUMERIC|SUBSTR|REPLACE|EXISTS|COUNT|SUM|MIN|MAX|AVG|SAMPLE|SEPARATOR|STR)/i ,\n\npunct:/^(\\*|a|\\.|\\{|\\}|,|\\(|\\)|;|\\[|\\]|\\|\\||&&|=|!=|!|<=|>=|<|>|\\+|-|\\/|\\^\\^|\\?|\\||\\^)/ ,\n\nstartSymbol:\"sparql11\",\nacceptEmpty:true,\n}\n},{}],4:[function(require,module,exports){\n\"use strict\";\nvar CodeMirror = (function(){try{return require('codemirror')}catch(e){return window.CodeMirror}})();\nCodeMirror.defineMode(\"sparql11\", function(config, parserConfig) {\n\n\tvar indentUnit = config.indentUnit;\n\n\tvar grammar = require('./_tokenizer-table.js');\n\tvar ll1_table = grammar.table;\n\n\tvar IRI_REF = '<[^<>\\\"\\'\\|\\{\\}\\^\\\\\\x00-\\x20]*>';\n\t/*\n\t * PN_CHARS_BASE =\n\t * '[A-Z]|[a-z]|[\\\\u00C0-\\\\u00D6]|[\\\\u00D8-\\\\u00F6]|[\\\\u00F8-\\\\u02FF]|[\\\\u0370-\\\\u037D]|[\\\\u037F-\\\\u1FFF]|[\\\\u200C-\\\\u200D]|[\\\\u2070-\\\\u218F]|[\\\\u2C00-\\\\u2FEF]|[\\\\u3001-\\\\uD7FF]|[\\\\uF900-\\\\uFDCF]|[\\\\uFDF0-\\\\uFFFD]|[\\\\u10000-\\\\uEFFFF]';\n\t */\n\n\tvar PN_CHARS_BASE =\n\t\t'[A-Za-z\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD]';\n\tvar PN_CHARS_U = PN_CHARS_BASE+'|_';\n\n\tvar PN_CHARS= '('+PN_CHARS_U+'|-|[0-9\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040])';\n\tvar VARNAME = '('+PN_CHARS_U+'|[0-9])'+\n\t\t'('+PN_CHARS_U+'|[0-9\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040])*';\n\tvar VAR1 = '\\\\?'+VARNAME;\n\tvar VAR2 = '\\\\$'+VARNAME;\n\n\tvar PN_PREFIX= '('+PN_CHARS_BASE+')((('+PN_CHARS+')|\\\\.)*('+PN_CHARS+'))?';\n\n\tvar HEX= '[0-9A-Fa-f]';\n\tvar PERCENT='(%'+HEX+HEX+')';\n\tvar PN_LOCAL_ESC='(\\\\\\\\[_~\\\\.\\\\-!\\\\$&\\'\\\\(\\\\)\\\\*\\\\+,;=/\\\\?#@%])';\n\tvar PLX= '('+PERCENT+'|'+PN_LOCAL_ESC+')';\n\tvar PN_LOCAL= '('+PN_CHARS_U+'|:|[0-9]|'+PLX+')(('+PN_CHARS+'|\\\\.|:|'+PLX+')*('+PN_CHARS+'|:|'+PLX+'))?';\n\tvar BLANK_NODE_LABEL = '_:('+PN_CHARS_U+'|[0-9])(('+PN_CHARS+'|\\\\.)*'+PN_CHARS+')?';\n\tvar PNAME_NS = '('+PN_PREFIX+')?:';\n\tvar PNAME_LN = PNAME_NS+PN_LOCAL;\n\tvar LANGTAG = '@[a-zA-Z]+(-[a-zA-Z0-9]+)*';\n\n\tvar EXPONENT = '[eE][\\\\+-]?[0-9]+';\n\tvar INTEGER = '[0-9]+';\n\tvar DECIMAL = '(([0-9]+\\\\.[0-9]*)|(\\\\.[0-9]+))';\n\tvar DOUBLE =\n\t\t'(([0-9]+\\\\.[0-9]*'+EXPONENT+')|'+\n\t\t'(\\\\.[0-9]+'+EXPONENT+')|'+\n\t\t'([0-9]+'+EXPONENT+'))';\n\n\tvar INTEGER_POSITIVE = '\\\\+' + INTEGER;\n\tvar DECIMAL_POSITIVE = '\\\\+' + DECIMAL;\n\tvar DOUBLE_POSITIVE = '\\\\+' + DOUBLE;\n\tvar INTEGER_NEGATIVE = '-' + INTEGER;\n\tvar DECIMAL_NEGATIVE = '-' + DECIMAL;\n\tvar DOUBLE_NEGATIVE = '-' + DOUBLE;\n\n\tvar ECHAR = '\\\\\\\\[tbnrf\\\\\\\\\"\\']';\n\t\n\t\n\t //IMPORTANT: this unicode rule is not in the official grammar.\n //Reason: https://github.com/YASGUI/YASQE/issues/49\n //unicode escape sequences (which the sparql spec considers part of the pre-processing of sparql queries)\n //are marked as invalid. We have little choice (other than adding a layer of complixity) than to modify the grammar accordingly\n //however, for now only allow these escape sequences in literals (where actually, this should be allows in e.g. prefixes as well)\n\tvar hex4 = HEX + '{4}'\n\tvar unicode = '(\\\\\\\\u' + hex4 +'|\\\\\\\\U00(10|0' + HEX + ')'+ hex4 + ')';\n\tvar LINE_BREAK = \"\\n\";\n\tvar STRING_LITERAL1 = \"'(([^\\\\x27\\\\x5C\\\\x0A\\\\x0D])|\"+ECHAR+\"|\" + unicode + \")*'\";\n\tvar STRING_LITERAL2 = '\"(([^\\\\x22\\\\x5C\\\\x0A\\\\x0D])|'+ECHAR+'|' + unicode + ')*\"';\n\t\n\tvar STRING_LITERAL_LONG = {\n\t\tSINGLE: {\n\t\t\tCAT: \"STRING_LITERAL_LONG1\",\n\t\t\tQUOTES: \"'''\",\n\t\t\tCONTENTS: \"(('|'')?([^'\\\\\\\\]|\"+ECHAR+\"|\"+unicode+\"))*\",\n\t\t\t\n\t\t},\n\t\tDOUBLE: {\n\t\t\tCAT: \"STRING_LITERAL_LONG2\",\n\t\t\tQUOTES: '\"\"\"',\n\t\t\tCONTENTS: '((\"|\"\")?([^\"\\\\\\\\]|'+ECHAR+'|'+unicode+'))*',\n\t\t}\n\t};\n\tfor (var key in STRING_LITERAL_LONG) {\n\t\tSTRING_LITERAL_LONG[key].COMPLETE = STRING_LITERAL_LONG[key].QUOTES + STRING_LITERAL_LONG[key].CONTENTS + STRING_LITERAL_LONG[key].QUOTES;\n\t}\n//\tvar STRING_LITERAL_LONG_QUOTES = {\n//\t\t\"STRING_LITERAL_LONG_QUOTES1\": \"'''\",\n//\t\t\"STRING_LITERAL_LONG_QUOTES2\": '\"\"\"',\n//\t}\n//\tvar STRING_LITERAL_LONG_CONTENTS = {\n//\t\t\"STRING_LITERAL_LONG_QUOTES1\": \"(('|'')?([^'\\\\\\\\]|\"+ECHAR+\"|\"+unicode+\"))*\",\n//\t\t\"STRING_LITERAL_LONG_QUOTES2\": '((\"|\"\")?([^\"\\\\\\\\]|'+ECHAR+'|'+unicode+'))*'\n//\t};\n//\tvar STRING_LITERAL_LONG1 = STRING_LITERAL_LONG['SINGLE'].QUOTES + STRING_LITERAL_LONG['SINGLE'].CONTENTS + STRING_LITERAL_LONG['SINGLE'].QUOTES;\n//\tvar STRING_LITERAL_LONG2 = STRING_LITERAL_LONG['DOUBLE'].QUOTES + STRING_LITERAL_LONG['DOUBLE'].CONTENTS + STRING_LITERAL_LONG['DOUBLE'].QUOTES;\n\t\n//\tvar stringLiteralLongContentTerminals = {};\n//\tfor (var key in STRING_LITERAL_LONG) {\n//\t\tstringLiteralLongContentTerminals[key] = {\n//\t\t\tname: key,\n//\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL_LONG_CONTENTS[key]),\n//\t\t\tstyle:\"string\"\n//\t\t};\n//\t}\n\t//some regular expressions not used in regular terminals, because this is used accross lines\n\tvar stringLiteralLongRegex = {};\n\tfor (var key in STRING_LITERAL_LONG) {\n\t\tstringLiteralLongRegex[key] = {\n\t\t\tcomplete: {\n\t\t\t\tname: \"STRING_LITERAL_LONG_\" + key,\n\t\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL_LONG[key].COMPLETE),\n\t\t\t\tstyle:\"string\"\n\t\t\t},\n\t\t\tcontents: {\n\t\t\t\tname: \"STRING_LITERAL_LONG_\" + key,\n\t\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL_LONG[key].CONTENTS),\n\t\t\t\tstyle:\"string\"\n\t\t\t},\n\t\t\tclosing: {\n\t\t\t\tname: \"STRING_LITERAL_LONG_\" + key,\n\t\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL_LONG[key].CONTENTS + STRING_LITERAL_LONG[key].QUOTES),\n\t\t\t\tstyle:\"string\"\n\t\t\t},\n\t\t\tquotes: {\n\t\t\t\tname: \"STRING_LITERAL_LONG_QUOTES_\" + key,\n\t\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL_LONG[key].QUOTES),\n\t\t\t\tstyle:\"string\"\n\t\t\t},\n\t\t\n\t\t}\n\t}\n\t\n\tvar WS = '[\\\\x20\\\\x09\\\\x0D\\\\x0A]';\n\t// Careful! Code mirror feeds one line at a time with no \\n\n\t// ... but otherwise comment is terminated by \\n\n\tvar COMMENT = '#([^\\\\n\\\\r]*[\\\\n\\\\r]|[^\\\\n\\\\r]*$)';\n\tvar WS_OR_COMMENT_STAR = '('+WS+'|('+COMMENT+'))*';\n\tvar NIL = '\\\\('+WS_OR_COMMENT_STAR+'\\\\)';\n\tvar ANON = '\\\\['+WS_OR_COMMENT_STAR+'\\\\]';\n\tvar terminals= [\n\t\t{ name: \"WS\",\n\t\t\tregex:new RegExp(\"^\"+WS+\"+\"),\n\t\t\tstyle:\"ws\" },\n\n\t\t{ name: \"COMMENT\",\n\t\t\tregex:new RegExp(\"^\"+COMMENT),\n\t\t\tstyle:\"comment\" },\n\n\t\t{ name: \"IRI_REF\",\n\t\t\tregex:new RegExp(\"^\"+IRI_REF),\n\t\t\tstyle:\"variable-3\" },\n\n\t\t{ name: \"VAR1\",\n\t\t\tregex:new RegExp(\"^\"+VAR1),\n\t\t\tstyle:\"atom\"},\n\n\t\t{ name: \"VAR2\",\n\t\t\tregex:new RegExp(\"^\"+VAR2),\n\t\t\tstyle:\"atom\"},\n\n\t\t{ name: \"LANGTAG\",\n\t\t\tregex:new RegExp(\"^\"+LANGTAG),\n\t\t\tstyle:\"meta\"},\n\n\t\t{ name: \"DOUBLE\",\n\t\t\tregex:new RegExp(\"^\"+DOUBLE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"DECIMAL\",\n\t\t\tregex:new RegExp(\"^\"+DECIMAL),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"INTEGER\",\n\t\t\tregex:new RegExp(\"^\"+INTEGER),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"DOUBLE_POSITIVE\",\n\t\t\tregex:new RegExp(\"^\"+DOUBLE_POSITIVE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"DECIMAL_POSITIVE\",\n\t\t\tregex:new RegExp(\"^\"+DECIMAL_POSITIVE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"INTEGER_POSITIVE\",\n\t\t\tregex:new RegExp(\"^\"+INTEGER_POSITIVE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"DOUBLE_NEGATIVE\",\n\t\t\tregex:new RegExp(\"^\"+DOUBLE_NEGATIVE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"DECIMAL_NEGATIVE\",\n\t\t\tregex:new RegExp(\"^\"+DECIMAL_NEGATIVE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"INTEGER_NEGATIVE\",\n\t\t\tregex:new RegExp(\"^\"+INTEGER_NEGATIVE),\n\t\t\tstyle:\"number\" },\n//\t\tstringLiteralLongRegex.SINGLE.complete,\n//\t\tstringLiteralLongRegex.DOUBLE.complete,\n//\t\tstringLiteralLongRegex.SINGLE.quotes,\n//\t\tstringLiteralLongRegex.DOUBLE.quotes,\n\t\t\n\t\t{ name: \"STRING_LITERAL1\",\n\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL1),\n\t\t\tstyle:\"string\" },\n\n\t\t{ name: \"STRING_LITERAL2\",\n\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL2),\n\t\t\tstyle:\"string\" },\n\n\t\t// Enclosed comments won't be highlighted\n\t\t{ name: \"NIL\",\n\t\t\tregex:new RegExp(\"^\"+NIL),\n\t\t\tstyle:\"punc\" },\n\n\t\t// Enclosed comments won't be highlighted\n\t\t{ name: \"ANON\",\n\t\t\tregex:new RegExp(\"^\"+ANON),\n\t\t\tstyle:\"punc\" },\n\n\t\t{ name: \"PNAME_LN\",\n\t\t\tregex:new RegExp(\"^\"+PNAME_LN),\n\t\t\tstyle:\"string-2\" },\n\n\t\t{ name: \"PNAME_NS\",\n\t\t\tregex:new RegExp(\"^\"+PNAME_NS),\n\t\t\tstyle:\"string-2\" },\n\n\t\t{ name: \"BLANK_NODE_LABEL\",\n\t\t\tregex:new RegExp(\"^\"+BLANK_NODE_LABEL),\n\t\t\tstyle:\"string-2\" }\n\t];\n\n\tfunction getPossibles(symbol) {\n\t\tvar possibles=[], possiblesOb=ll1_table[symbol];\n\t\tif (possiblesOb!=undefined) {\n\t\t\tfor (var property in possiblesOb) {\n\t\t\t\tpossibles.push(property.toString());\n\t\t\t}\n\t\t} else {\n\t\t\tpossibles.push(symbol);\n\t\t}\n\t\treturn possibles;\n\t}\n\n\n\tfunction tokenBase(stream, state) {\n\n\t\tfunction nextToken() {\n\t\t\tvar consumed=null;\n\t\t\tif (state.inLiteral) {\n\t\t\t\t\n\t\t\t\tvar closingQuotes = false;\n\t\t\t\t//multi-line literal. try to parse contents.\n\t\t\t\tconsumed = stream.match(stringLiteralLongRegex[state.inLiteral].contents.regex, true, false);\n\t\t\t\tif (consumed && consumed[0].length == 0) {\n\t\t\t\t\t//try seeing whether we can consume closing quotes, to avoid stopping\n\t\t\t\t\tconsumed = stream.match(stringLiteralLongRegex[state.inLiteral].closing.regex, true, false);\n\t\t\t\t\tclosingQuotes = true;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (consumed && consumed[0].length > 0) {\n\t\t\t\t\t//some string content here. \n\t\t\t\t\t var returnObj = {\n\t\t\t\t\t\tquotePos: (closingQuotes? 'end': 'content'),\n\t\t\t\t\t\tcat: STRING_LITERAL_LONG[state.inLiteral].CAT,\n\t\t\t\t\t\tstyle: stringLiteralLongRegex[state.inLiteral].complete.style,\n\t\t\t\t\t\ttext: consumed[0],\n\t\t\t\t\t\tstart: stream.start\n\t\t\t\t\t};\n\t\t\t\t\t if (closingQuotes) state.inLiteral = false;\n\t\t\t\t\t return returnObj;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t//Multiline literals\n\t\t\tfor (var quoteType in stringLiteralLongRegex) {\n\t\t\t\tconsumed= stream.match(stringLiteralLongRegex[quoteType].quotes.regex,true,false);\n\t\t\t\tif (consumed) {\n\t\t\t\t\tvar quotePos;\n\t\t\t\t\tif (state.inLiteral) {\n\t\t\t\t\t\t//end of literal. everything is fine\n\t\t\t\t\t\tstate.inLiteral = false;\n\t\t\t\t\t\tquotePos = 'end';\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate.inLiteral = quoteType;\n\t\t\t\t\t\tquotePos = 'start';\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcat: STRING_LITERAL_LONG[quoteType].CAT,\n\t\t\t\t\t\tstyle: stringLiteralLongRegex[quoteType].quotes.style,\n\t\t\t\t\t\ttext: consumed[0],\n\t\t\t\t\t\tquotePos: quotePos,\n\t\t\t\t\t\tstart: stream.start\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t// Tokens defined by individual regular expressions\n\t\t\tfor (var i=0; i\",\n\t\t\t\t\t\t\t style: \"error\",\n\t\t\t\t\t\t\t text: consumed[0],\n\t\t\t\t\t\t\t start: stream.start\n\t\t\t\t\t\t };\n\t\t}\n\n\t\tfunction recordFailurePos() {\n\t\t\t// tokenOb.style= \"sp-invalid\";\n\t\t\tvar col= stream.column();\n\t\t\tstate.errorStartPos= col;\n\t\t\tstate.errorEndPos= col+tokenOb.text.length;\n\t\t};\n\n\t\tfunction setQueryType(s) {\n\t\t\tif (state.queryType==null) {\n\t\t\t\tif (s ==\"SELECT\" || s==\"CONSTRUCT\" || s==\"ASK\" || s==\"DESCRIBE\" || s==\"INSERT\" || s==\"DELETE\" || s==\"LOAD\" || s==\"CLEAR\" || s==\"CREATE\" || s==\"DROP\" || s==\"COPY\" || s==\"MOVE\" || s==\"ADD\")\n\t\t\t\t\tstate.queryType=s;\n\t\t\t}\n\t\t}\n\n\t\t// Some fake non-terminals are just there to have side-effect on state\n\t\t// - i.e. allow or disallow variables and bnodes in certain non-nesting\n\t\t// contexts\n\t\tfunction setSideConditions(topSymbol) {\n\t\t\tif (topSymbol==\"disallowVars\") state.allowVars=false;\n\t\t\telse if (topSymbol==\"allowVars\") state.allowVars=true;\n\t\t\telse if (topSymbol==\"disallowBnodes\") state.allowBnodes=false;\n\t\t\telse if (topSymbol==\"allowBnodes\") state.allowBnodes=true;\n\t\t\telse if (topSymbol==\"storeProperty\") state.storeProperty=true;\n\t\t}\n\n\t\tfunction checkSideConditions(topSymbol) {\n\t\t\treturn(\n\t\t\t\t(state.allowVars || topSymbol!=\"var\") &&\n\t\t\t\t\t(state.allowBnodes ||\n\t\t\t\t\t (topSymbol!=\"blankNode\" &&\n\t\t\t\t\t\ttopSymbol!=\"blankNodePropertyList\" &&\n\t\t\t\t\t\ttopSymbol!=\"blankNodePropertyListPath\")));\n\t\t}\n\n\t\t// CodeMirror works with one line at a time,\n\t\t// but newline should behave like whitespace\n\t\t// - i.e. a definite break between tokens (for autocompleter)\n\t\tif (stream.pos==0)\n\t\t\tstate.possibleCurrent= state.possibleNext;\n\n\t\tvar tokenOb= nextToken();\n\n\n\t\tif (tokenOb.cat==\"\") {\n\t\t\t// set error state, and\n\t\t\tif (state.OK==true) {\n\t\t\t\tstate.OK=false;\n\t\t\t\trecordFailurePos();\n\t\t\t}\n\t\t\tstate.complete=false;\n\t\t\t// alert(\"Invalid:\"+tokenOb.text);\n\t\t\treturn tokenOb.style;\n\t\t}\n\n\t\tif (tokenOb.cat == \"WS\" || tokenOb.cat == \"COMMENT\" || (tokenOb.quotePos && tokenOb.quotePos != 'end')) {\n\t\t\tstate.possibleCurrent = state.possibleNext;\n\t\t\treturn(tokenOb.style);\n\t\t}\n\t\t// Otherwise, run the parser until the token is digested\n\t\t// or failure\n\t\tvar finished= false;\n\t\tvar topSymbol;\n\t\tvar token= tokenOb.cat;\n\t\t\n\t\tif (!tokenOb.quotePos || tokenOb.quotePos == 'end') {\n\t\t// Incremental LL1 parse\n\t\t\twhile(state.stack.length>0 && token && state.OK && !finished ) {\n\t\t\t\ttopSymbol= state.stack.pop();\n\t\n\t\t\t\tif (!ll1_table[topSymbol]) {\n\t\t\t\t\t// Top symbol is a terminal\n\t\t\t\t\tif (topSymbol == token) {\n\t\t\t\t\t\t// Matching terminals\n\t\t\t\t\t\t// - consume token from input stream\n\t\t\t\t\t\tfinished=true;\n\t\t\t\t\t\tsetQueryType(topSymbol);\n\t\t\t\t\t\t// Check whether $ (end of input token) is poss next\n\t\t\t\t\t\t// for everything on stack\n\t\t\t\t\t\tvar allNillable=true;\n\t\t\t\t\t\tfor(var sp=state.stack.length;sp>0;--sp) {\n\t\t\t\t\t\t\tvar item=ll1_table[state.stack[sp-1]];\n\t\t\t\t\t\t\tif (!item || !item[\"$\"])\n\t\t\t\t\t\t\t\tallNillable=false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstate.complete= allNillable;\n\t\t\t\t\t\tif (state.storeProperty && token.cat != \"punc\") {\n\t\t\t\t\t\t\tstate.lastProperty = tokenOb.text;\n\t\t\t\t\t\t\tstate.storeProperty = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate.OK=false;\n\t\t\t\t\t\tstate.complete=false;\n\t\t\t\t\t\trecordFailurePos();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// topSymbol is nonterminal\n\t\t\t\t\t// - see if there is an entry for topSymbol\n\t\t\t\t\t// and nextToken in table\n\t\t\t\t\tvar nextSymbols= ll1_table[topSymbol][token];\n\t\t\t\t\tif (nextSymbols!=undefined && checkSideConditions(topSymbol)) {\n\t\t\t\t\t\t// Match - copy RHS of rule to stack\n\t\t\t\t\t\tfor (var i=nextSymbols.length-1; i>=0; --i) {\n\t\t\t\t\t\t\tstate.stack.push(nextSymbols[i]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Peform any non-grammatical side-effects\n\t\t\t\t\t\tsetSideConditions(topSymbol);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// No match in table - fail\n\t\t\t\t\t\tstate.OK=false;\n\t\t\t\t\t\tstate.complete=false;\n\t\t\t\t\t\trecordFailurePos();\n\t\t\t\t\t\tstate.stack.push(topSymbol); // Shove topSymbol back on stack\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!finished && state.OK) { \n\t\t\tstate.OK=false; state.complete=false; recordFailurePos(); \n\t\t}\n\t\t\n\t\tif (state.possibleCurrent.indexOf('a') >= 0){\n\t\t\tstate.lastPredicateOffset = tokenOb.start;\n\t\t}\n\t\tstate.possibleCurrent = state.possibleNext;\n\t\t\n\t\tstate.possibleNext = getPossibles(state.stack[state.stack.length-1]);\n\n\t\treturn tokenOb.style;\n\t}\n\n\tvar indentTop={\n\t\t\"*[,, object]\": 3,\n\t\t\"*[(,),object]\": 3,\n\t\t\"*[(,),objectPath]\": 3,\n\t\t\"*[/,pathEltOrInverse]\": 2,\n\t\t\"object\": 2,\n\t\t\"objectPath\": 2,\n\t\t\"objectList\": 2,\n\t\t\"objectListPath\": 2,\n\t\t\"storeProperty\": 2,\n\t\t\"pathMod\": 2,\n\t\t\"?pathMod\": 2,\n\t\t\"propertyListNotEmpty\": 1,\n\t\t\"propertyList\": 1,\n\t\t\"propertyListPath\": 1,\n\t\t\"propertyListPathNotEmpty\": 1,\n\t\t\"?[verb,objectList]\": 1,\n//\t\t\"?[or([verbPath, verbSimple]),objectList]\": 1,\n\t};\n\n\tvar indentTable={\n\t\t\"}\":1,\n\t\t\"]\":0,\n\t\t\")\":1,\n\t\t\"{\":-1,\n\t\t\"(\":-1,\n//\t\t\"*[;,?[or([verbPath,verbSimple]),objectList]]\": 1,\n\t};\n\t\n\n\tfunction indent(state, textAfter) {\n\t\t//just avoid we don't indent multi-line literals\n\t\tif (state.inLiteral) return 0;\n\t\tif (state.stack.length && state.stack[state.stack.length-1] == \"?[or([verbPath,verbSimple]),objectList]\") {\n\t\t\t//we are after a semi-colon. I.e., nicely align this line with predicate position of previous line\n\t\t\treturn state.lastPredicateOffset;\n\t\t} else {\n\t\t\tvar n = 0; // indent level\n\t\t\tvar i = state.stack.length-1;\n\t\t\tif (/^[\\}\\]\\)]/.test(textAfter)) {\n\t\t\t\t// Skip stack items until after matching bracket\n\t\t\t\tvar closeBracket=textAfter.substr(0,1);\n\t\t\t\tfor( ;i>=0;--i)\t{\n\t\t\t\t\tif (state.stack[i]==closeBracket) {\n\t\t\t\t\t\t--i; \n\t\t\t\t\t\tbreak;\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Consider nullable non-terminals if at top of stack\n\t\t\t\tvar dn = indentTop[state.stack[i]];\n\t\t\t\tif (dn) { \n\t\t\t\t\tn += dn; \n\t\t\t\t\t--i;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor( ;i>=0;--i)\t{\n\t\t\t\tvar dn = indentTable[state.stack[i]];\n\t\t\t\tif (dn) {\n\t\t\t\t\tn+=dn;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn n * config.indentUnit;\n\t\t}\n\t};\n\n\treturn {\n\t\ttoken: tokenBase,\n\t\tstartState: function(base) {\n\t\t\treturn {\n\t\t\t\ttokenize: tokenBase,\n\t\t\t\tOK: true,\n\t\t\t\tcomplete: grammar.acceptEmpty,\n\t\t\t\terrorStartPos: null,\n\t\t\t\terrorEndPos: null,\n\t\t\t\tqueryType: null,\n\t\t\t\tpossibleCurrent: getPossibles(grammar.startSymbol),\n\t\t\t\tpossibleNext: getPossibles(grammar.startSymbol),\n\t\t\t\tallowVars : true,\n\t\t\t\tallowBnodes : true,\n\t\t\t\tstoreProperty : false,\n\t\t\t\tlastProperty : \"\",\n\t\t\t\tinLiteral: false,\n\t\t\t\tstack: [grammar.startSymbol],\n\t\t\t\tlastPredicateOffset: config.indentUnit,\n\t\t\t}; \n\t\t},\n\t\tindent: indent,\n\t\telectricChars: \"}])\"\n\t};\n}\n);\nCodeMirror.defineMIME(\"application/x-sparql-query\", \"sparql11\");\n\n},{\"./_tokenizer-table.js\":3,\"codemirror\":undefined}],5:[function(require,module,exports){\n/*\n* TRIE implementation in Javascript\n* Copyright (c) 2010 Saurabh Odhyan | http://odhyan.com\n* \n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n* \n* The above copyright notice and this permission notice shall be included in\n* all copies or substantial portions of the Software.\n* \n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n* THE SOFTWARE.\n*\n* Date: Nov 7, 2010\n*/\n\n/*\n* A trie, or prefix tree, is a multi-way tree structure useful for storing strings over an alphabet. \n* It has been used to store large dictionaries of English (say) words in spell-checking programs \n* and in natural-language \"understanding\" programs. \n* @see http://en.wikipedia.org/wiki/Trie\n* @see http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Tree/Trie/\n/*\n\n* @class Trie\n* @constructor\n*/ \nvar Trie = module.exports = function() {\n this.words = 0;\n this.prefixes = 0;\n this.children = [];\n};\n\nTrie.prototype = {\n \n /*\n * Insert a word into the dictionary. \n * Recursively traverse through the trie nodes, and create new node if does not already exist.\n *\n * @method insert\n * @param {String} str Word to insert in the dictionary\n * @param {Integer} pos Current index of the string to be inserted\n * @return {Void}\n */\n insert: function(str, pos) {\n if(str.length == 0) { //blank string cannot be inserted\n return;\n }\n \n var T = this,\n k,\n child;\n \n if(pos === undefined) {\n pos = 0;\n }\n if(pos === str.length) {\n T.words ++;\n return;\n }\n T.prefixes ++;\n k = str[pos];\n if(T.children[k] === undefined) { //if node for this char doesn't exist, create one\n T.children[k] = new Trie();\n }\n child = T.children[k];\n child.insert(str, pos + 1);\n },\n \n /*\n * Remove a word from the dictionary.\n *\n * @method remove\n * @param {String} str Word to be removed\n * @param {Integer} pos Current index of the string to be removed\n * @return {Void}\n */\n remove: function(str, pos) {\n if(str.length == 0) {\n return;\n }\n \n var T = this,\n k,\n child;\n \n if(pos === undefined) {\n pos = 0;\n } \n if(T === undefined) {\n return;\n }\n if(pos === str.length) {\n T.words --;\n return;\n }\n T.prefixes --;\n k = str[pos];\n child = T.children[k];\n child.remove(str, pos + 1);\n },\n \n /*\n * Update an existing word in the dictionary. \n * This method removes the old word from the dictionary and inserts the new word.\n *\n * @method update\n * @param {String} strOld The old word to be replaced\n * @param {String} strNew The new word to be inserted\n * @return {Void}\n */\n update: function(strOld, strNew) {\n if(strOld.length == 0 || strNew.length == 0) {\n return;\n }\n this.remove(strOld);\n this.insert(strNew);\n },\n \n /*\n * Count the number of times a given word has been inserted into the dictionary\n *\n * @method countWord\n * @param {String} str Word to get count of\n * @param {Integer} pos Current index of the given word\n * @return {Integer} The number of times a given word exists in the dictionary\n */\n countWord: function(str, pos) {\n if(str.length == 0) {\n return 0;\n }\n \n var T = this,\n k,\n child,\n ret = 0;\n \n if(pos === undefined) {\n pos = 0;\n } \n if(pos === str.length) {\n return T.words;\n }\n k = str[pos];\n child = T.children[k];\n if(child !== undefined) { //node exists\n ret = child.countWord(str, pos + 1);\n }\n return ret;\n },\n \n /*\n * Count the number of times a given prefix exists in the dictionary\n *\n * @method countPrefix\n * @param {String} str Prefix to get count of\n * @param {Integer} pos Current index of the given prefix\n * @return {Integer} The number of times a given prefix exists in the dictionary\n */\n countPrefix: function(str, pos) {\n if(str.length == 0) {\n return 0;\n }\n \n var T = this,\n k,\n child,\n ret = 0;\n\n if(pos === undefined) {\n pos = 0;\n }\n if(pos === str.length) {\n return T.prefixes;\n }\n var k = str[pos];\n child = T.children[k];\n if(child !== undefined) { //node exists\n ret = child.countPrefix(str, pos + 1); \n }\n return ret; \n },\n \n /*\n * Find a word in the dictionary\n *\n * @method find\n * @param {String} str The word to find in the dictionary\n * @return {Boolean} True if the word exists in the dictionary, else false\n */\n find: function(str) {\n if(str.length == 0) {\n return false;\n }\n \n if(this.countWord(str) > 0) {\n return true;\n } else {\n return false;\n }\n },\n \n /*\n * Get all words in the dictionary\n *\n * @method getAllWords\n * @param {String} str Prefix of current word\n * @return {Array} Array of words in the dictionary\n */\n getAllWords: function(str) {\n var T = this,\n k,\n child,\n ret = [];\n if(str === undefined) {\n str = \"\";\n }\n if(T === undefined) {\n return [];\n }\n if(T.words > 0) {\n ret.push(str);\n }\n for(k in T.children) {\n child = T.children[k];\n ret = ret.concat(child.getAllWords(str + k));\n }\n return ret;\n },\n \n /*\n * Autocomplete a given prefix\n *\n * @method autoComplete\n * @param {String} str Prefix to be completed based on dictionary entries\n * @param {Integer} pos Current index of the prefix\n * @return {Array} Array of possible suggestions\n */\n autoComplete: function(str, pos) {\n \n \n var T = this,\n k,\n child;\n if(str.length == 0) {\n\t\t\tif (pos === undefined) {\n\t\t\t\treturn T.getAllWords(str);\n\t\t\t} else {\n\t\t\t\treturn [];\n\t\t\t}\n }\n if(pos === undefined) {\n pos = 0;\n } \n k = str[pos];\n child = T.children[k];\n if(child === undefined) { //node doesn't exist\n return [];\n }\n if(pos === str.length - 1) {\n return child.getAllWords(str);\n }\n return child.autoComplete(str, pos + 1);\n }\n};\n\n},{}],6:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod((function(){try{return require('codemirror')}catch(e){return window.CodeMirror}})());\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n CodeMirror.defineOption(\"fullScreen\", false, function(cm, val, old) {\n if (old == CodeMirror.Init) old = false;\n if (!old == !val) return;\n if (val) setFullscreen(cm);\n else setNormal(cm);\n });\n\n function setFullscreen(cm) {\n var wrap = cm.getWrapperElement();\n cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset,\n width: wrap.style.width, height: wrap.style.height};\n wrap.style.width = \"\";\n wrap.style.height = \"auto\";\n wrap.className += \" CodeMirror-fullscreen\";\n document.documentElement.style.overflow = \"hidden\";\n cm.refresh();\n }\n\n function setNormal(cm) {\n var wrap = cm.getWrapperElement();\n wrap.className = wrap.className.replace(/\\s*CodeMirror-fullscreen\\b/, \"\");\n document.documentElement.style.overflow = \"\";\n var info = cm.state.fullScreenRestore;\n wrap.style.width = info.width; wrap.style.height = info.height;\n window.scrollTo(info.scrollLeft, info.scrollTop);\n cm.refresh();\n }\n});\n\n},{\"codemirror\":undefined}],7:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod((function(){try{return require('codemirror')}catch(e){return window.CodeMirror}})());\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n var ie_lt8 = /MSIE \\d/.test(navigator.userAgent) &&\n (document.documentMode == null || document.documentMode < 8);\n\n var Pos = CodeMirror.Pos;\n\n var matching = {\"(\": \")>\", \")\": \"(<\", \"[\": \"]>\", \"]\": \"[<\", \"{\": \"}>\", \"}\": \"{<\"};\n\n function findMatchingBracket(cm, where, strict, config) {\n var line = cm.getLineHandle(where.line), pos = where.ch - 1;\n var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];\n if (!match) return null;\n var dir = match.charAt(1) == \">\" ? 1 : -1;\n if (strict && (dir > 0) != (pos == where.ch)) return null;\n var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));\n\n var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);\n if (found == null) return null;\n return {from: Pos(where.line, pos), to: found && found.pos,\n match: found && found.ch == match.charAt(0), forward: dir > 0};\n }\n\n // bracketRegex is used to specify which type of bracket to scan\n // should be a regexp, e.g. /[[\\]]/\n //\n // Note: If \"where\" is on an open bracket, then this bracket is ignored.\n //\n // Returns false when no bracket was found, null when it reached\n // maxScanLines and gave up\n function scanForBracket(cm, where, dir, style, config) {\n var maxScanLen = (config && config.maxScanLineLength) || 10000;\n var maxScanLines = (config && config.maxScanLines) || 1000;\n\n var stack = [];\n var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\\]]/;\n var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)\n : Math.max(cm.firstLine() - 1, where.line - maxScanLines);\n for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {\n var line = cm.getLine(lineNo);\n if (!line) continue;\n var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;\n if (line.length > maxScanLen) continue;\n if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);\n for (; pos != end; pos += dir) {\n var ch = line.charAt(pos);\n if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {\n var match = matching[ch];\n if ((match.charAt(1) == \">\") == (dir > 0)) stack.push(ch);\n else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};\n else stack.pop();\n }\n }\n }\n return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;\n }\n\n function matchBrackets(cm, autoclear, config) {\n // Disable brace matching in long lines, since it'll cause hugely slow updates\n var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;\n var marks = [], ranges = cm.listSelections();\n for (var i = 0; i < ranges.length; i++) {\n var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config);\n if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {\n var style = match.match ? \"CodeMirror-matchingbracket\" : \"CodeMirror-nonmatchingbracket\";\n marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));\n if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)\n marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));\n }\n }\n\n if (marks.length) {\n // Kludge to work around the IE bug from issue #1193, where text\n // input stops going to the textare whever this fires.\n if (ie_lt8 && cm.state.focused) cm.focus();\n\n var clear = function() {\n cm.operation(function() {\n for (var i = 0; i < marks.length; i++) marks[i].clear();\n });\n };\n if (autoclear) setTimeout(clear, 800);\n else return clear;\n }\n }\n\n var currentlyHighlighted = null;\n function doMatchBrackets(cm) {\n cm.operation(function() {\n if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}\n currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);\n });\n }\n\n CodeMirror.defineOption(\"matchBrackets\", false, function(cm, val, old) {\n if (old && old != CodeMirror.Init)\n cm.off(\"cursorActivity\", doMatchBrackets);\n if (val) {\n cm.state.matchBrackets = typeof val == \"object\" ? val : {};\n cm.on(\"cursorActivity\", doMatchBrackets);\n }\n });\n\n CodeMirror.defineExtension(\"matchBrackets\", function() {matchBrackets(this, true);});\n CodeMirror.defineExtension(\"findMatchingBracket\", function(pos, strict, config){\n return findMatchingBracket(this, pos, strict, config);\n });\n CodeMirror.defineExtension(\"scanForBracket\", function(pos, dir, style, config){\n return scanForBracket(this, pos, dir, style, config);\n });\n});\n\n},{\"codemirror\":undefined}],8:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod((function(){try{return require('codemirror')}catch(e){return window.CodeMirror}})());\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n\"use strict\";\n\nCodeMirror.registerHelper(\"fold\", \"brace\", function(cm, start) {\n var line = start.line, lineText = cm.getLine(line);\n var startCh, tokenType;\n\n function findOpening(openCh) {\n for (var at = start.ch, pass = 0;;) {\n var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1);\n if (found == -1) {\n if (pass == 1) break;\n pass = 1;\n at = lineText.length;\n continue;\n }\n if (pass == 1 && found < start.ch) break;\n tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));\n if (!/^(comment|string)/.test(tokenType)) return found + 1;\n at = found - 1;\n }\n }\n\n var startToken = \"{\", endToken = \"}\", startCh = findOpening(\"{\");\n if (startCh == null) {\n startToken = \"[\", endToken = \"]\";\n startCh = findOpening(\"[\");\n }\n\n if (startCh == null) return;\n var count = 1, lastLine = cm.lastLine(), end, endCh;\n outer: for (var i = line; i <= lastLine; ++i) {\n var text = cm.getLine(i), pos = i == line ? startCh : 0;\n for (;;) {\n var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);\n if (nextOpen < 0) nextOpen = text.length;\n if (nextClose < 0) nextClose = text.length;\n pos = Math.min(nextOpen, nextClose);\n if (pos == text.length) break;\n if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) {\n if (pos == nextOpen) ++count;\n else if (!--count) { end = i; endCh = pos; break outer; }\n }\n ++pos;\n }\n }\n if (end == null || line == end && endCh == startCh) return;\n return {from: CodeMirror.Pos(line, startCh),\n to: CodeMirror.Pos(end, endCh)};\n});\n\nCodeMirror.registerHelper(\"fold\", \"import\", function(cm, start) {\n function hasImport(line) {\n if (line < cm.firstLine() || line > cm.lastLine()) return null;\n var start = cm.getTokenAt(CodeMirror.Pos(line, 1));\n if (!/\\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));\n if (start.type != \"keyword\" || start.string != \"import\") return null;\n // Now find closing semicolon, return its position\n for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) {\n var text = cm.getLine(i), semi = text.indexOf(\";\");\n if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)};\n }\n }\n\n var start = start.line, has = hasImport(start), prev;\n if (!has || hasImport(start - 1) || ((prev = hasImport(start - 2)) && prev.end.line == start - 1))\n return null;\n for (var end = has.end;;) {\n var next = hasImport(end.line + 1);\n if (next == null) break;\n end = next.end;\n }\n return {from: cm.clipPos(CodeMirror.Pos(start, has.startCh + 1)), to: end};\n});\n\nCodeMirror.registerHelper(\"fold\", \"include\", function(cm, start) {\n function hasInclude(line) {\n if (line < cm.firstLine() || line > cm.lastLine()) return null;\n var start = cm.getTokenAt(CodeMirror.Pos(line, 1));\n if (!/\\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));\n if (start.type == \"meta\" && start.string.slice(0, 8) == \"#include\") return start.start + 8;\n }\n\n var start = start.line, has = hasInclude(start);\n if (has == null || hasInclude(start - 1) != null) return null;\n for (var end = start;;) {\n var next = hasInclude(end + 1);\n if (next == null) break;\n ++end;\n }\n return {from: CodeMirror.Pos(start, has + 1),\n to: cm.clipPos(CodeMirror.Pos(end))};\n});\n\n});\n\n},{\"codemirror\":undefined}],9:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod((function(){try{return require('codemirror')}catch(e){return window.CodeMirror}})());\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n function doFold(cm, pos, options, force) {\n if (options && options.call) {\n var finder = options;\n options = null;\n } else {\n var finder = getOption(cm, options, \"rangeFinder\");\n }\n if (typeof pos == \"number\") pos = CodeMirror.Pos(pos, 0);\n var minSize = getOption(cm, options, \"minFoldSize\");\n\n function getRange(allowFolded) {\n var range = finder(cm, pos);\n if (!range || range.to.line - range.from.line < minSize) return null;\n var marks = cm.findMarksAt(range.from);\n for (var i = 0; i < marks.length; ++i) {\n if (marks[i].__isFold && force !== \"fold\") {\n if (!allowFolded) return null;\n range.cleared = true;\n marks[i].clear();\n }\n }\n return range;\n }\n\n var range = getRange(true);\n if (getOption(cm, options, \"scanUp\")) while (!range && pos.line > cm.firstLine()) {\n pos = CodeMirror.Pos(pos.line - 1, 0);\n range = getRange(false);\n }\n if (!range || range.cleared || force === \"unfold\") return;\n\n var myWidget = makeWidget(cm, options);\n CodeMirror.on(myWidget, \"mousedown\", function(e) {\n myRange.clear();\n CodeMirror.e_preventDefault(e);\n });\n var myRange = cm.markText(range.from, range.to, {\n replacedWith: myWidget,\n clearOnEnter: true,\n __isFold: true\n });\n myRange.on(\"clear\", function(from, to) {\n CodeMirror.signal(cm, \"unfold\", cm, from, to);\n });\n CodeMirror.signal(cm, \"fold\", cm, range.from, range.to);\n }\n\n function makeWidget(cm, options) {\n var widget = getOption(cm, options, \"widget\");\n if (typeof widget == \"string\") {\n var text = document.createTextNode(widget);\n widget = document.createElement(\"span\");\n widget.appendChild(text);\n widget.className = \"CodeMirror-foldmarker\";\n }\n return widget;\n }\n\n // Clumsy backwards-compatible interface\n CodeMirror.newFoldFunction = function(rangeFinder, widget) {\n return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); };\n };\n\n // New-style interface\n CodeMirror.defineExtension(\"foldCode\", function(pos, options, force) {\n doFold(this, pos, options, force);\n });\n\n CodeMirror.defineExtension(\"isFolded\", function(pos) {\n var marks = this.findMarksAt(pos);\n for (var i = 0; i < marks.length; ++i)\n if (marks[i].__isFold) return true;\n });\n\n CodeMirror.commands.toggleFold = function(cm) {\n cm.foldCode(cm.getCursor());\n };\n CodeMirror.commands.fold = function(cm) {\n cm.foldCode(cm.getCursor(), null, \"fold\");\n };\n CodeMirror.commands.unfold = function(cm) {\n cm.foldCode(cm.getCursor(), null, \"unfold\");\n };\n CodeMirror.commands.foldAll = function(cm) {\n cm.operation(function() {\n for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)\n cm.foldCode(CodeMirror.Pos(i, 0), null, \"fold\");\n });\n };\n CodeMirror.commands.unfoldAll = function(cm) {\n cm.operation(function() {\n for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)\n cm.foldCode(CodeMirror.Pos(i, 0), null, \"unfold\");\n });\n };\n\n CodeMirror.registerHelper(\"fold\", \"combine\", function() {\n var funcs = Array.prototype.slice.call(arguments, 0);\n return function(cm, start) {\n for (var i = 0; i < funcs.length; ++i) {\n var found = funcs[i](cm, start);\n if (found) return found;\n }\n };\n });\n\n CodeMirror.registerHelper(\"fold\", \"auto\", function(cm, start) {\n var helpers = cm.getHelpers(start, \"fold\");\n for (var i = 0; i < helpers.length; i++) {\n var cur = helpers[i](cm, start);\n if (cur) return cur;\n }\n });\n\n var defaultOptions = {\n rangeFinder: CodeMirror.fold.auto,\n widget: \"\\u2194\",\n minFoldSize: 0,\n scanUp: false\n };\n\n CodeMirror.defineOption(\"foldOptions\", null);\n\n function getOption(cm, options, name) {\n if (options && options[name] !== undefined)\n return options[name];\n var editorOptions = cm.options.foldOptions;\n if (editorOptions && editorOptions[name] !== undefined)\n return editorOptions[name];\n return defaultOptions[name];\n }\n\n CodeMirror.defineExtension(\"foldOption\", function(options, name) {\n return getOption(this, options, name);\n });\n});\n\n},{\"codemirror\":undefined}],10:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod((function(){try{return require('codemirror')}catch(e){return window.CodeMirror}})(), require(\"./foldcode\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\", \"./foldcode\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n CodeMirror.defineOption(\"foldGutter\", false, function(cm, val, old) {\n if (old && old != CodeMirror.Init) {\n cm.clearGutter(cm.state.foldGutter.options.gutter);\n cm.state.foldGutter = null;\n cm.off(\"gutterClick\", onGutterClick);\n cm.off(\"change\", onChange);\n cm.off(\"viewportChange\", onViewportChange);\n cm.off(\"fold\", onFold);\n cm.off(\"unfold\", onFold);\n cm.off(\"swapDoc\", updateInViewport);\n }\n if (val) {\n cm.state.foldGutter = new State(parseOptions(val));\n updateInViewport(cm);\n cm.on(\"gutterClick\", onGutterClick);\n cm.on(\"change\", onChange);\n cm.on(\"viewportChange\", onViewportChange);\n cm.on(\"fold\", onFold);\n cm.on(\"unfold\", onFold);\n cm.on(\"swapDoc\", updateInViewport);\n }\n });\n\n var Pos = CodeMirror.Pos;\n\n function State(options) {\n this.options = options;\n this.from = this.to = 0;\n }\n\n function parseOptions(opts) {\n if (opts === true) opts = {};\n if (opts.gutter == null) opts.gutter = \"CodeMirror-foldgutter\";\n if (opts.indicatorOpen == null) opts.indicatorOpen = \"CodeMirror-foldgutter-open\";\n if (opts.indicatorFolded == null) opts.indicatorFolded = \"CodeMirror-foldgutter-folded\";\n return opts;\n }\n\n function isFolded(cm, line) {\n var marks = cm.findMarksAt(Pos(line));\n for (var i = 0; i < marks.length; ++i)\n if (marks[i].__isFold && marks[i].find().from.line == line) return marks[i];\n }\n\n function marker(spec) {\n if (typeof spec == \"string\") {\n var elt = document.createElement(\"div\");\n elt.className = spec + \" CodeMirror-guttermarker-subtle\";\n return elt;\n } else {\n return spec.cloneNode(true);\n }\n }\n\n function updateFoldInfo(cm, from, to) {\n var opts = cm.state.foldGutter.options, cur = from;\n var minSize = cm.foldOption(opts, \"minFoldSize\");\n var func = cm.foldOption(opts, \"rangeFinder\");\n cm.eachLine(from, to, function(line) {\n var mark = null;\n if (isFolded(cm, cur)) {\n mark = marker(opts.indicatorFolded);\n } else {\n var pos = Pos(cur, 0);\n var range = func && func(cm, pos);\n if (range && range.to.line - range.from.line >= minSize)\n mark = marker(opts.indicatorOpen);\n }\n cm.setGutterMarker(line, opts.gutter, mark);\n ++cur;\n });\n }\n\n function updateInViewport(cm) {\n var vp = cm.getViewport(), state = cm.state.foldGutter;\n if (!state) return;\n cm.operation(function() {\n updateFoldInfo(cm, vp.from, vp.to);\n });\n state.from = vp.from; state.to = vp.to;\n }\n\n function onGutterClick(cm, line, gutter) {\n var state = cm.state.foldGutter;\n if (!state) return;\n var opts = state.options;\n if (gutter != opts.gutter) return;\n var folded = isFolded(cm, line);\n if (folded) folded.clear();\n else cm.foldCode(Pos(line, 0), opts.rangeFinder);\n }\n\n function onChange(cm) {\n var state = cm.state.foldGutter;\n if (!state) return;\n var opts = state.options;\n state.from = state.to = 0;\n clearTimeout(state.changeUpdate);\n state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);\n }\n\n function onViewportChange(cm) {\n var state = cm.state.foldGutter;\n if (!state) return;\n var opts = state.options;\n clearTimeout(state.changeUpdate);\n state.changeUpdate = setTimeout(function() {\n var vp = cm.getViewport();\n if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {\n updateInViewport(cm);\n } else {\n cm.operation(function() {\n if (vp.from < state.from) {\n updateFoldInfo(cm, vp.from, state.from);\n state.from = vp.from;\n }\n if (vp.to > state.to) {\n updateFoldInfo(cm, state.to, vp.to);\n state.to = vp.to;\n }\n });\n }\n }, opts.updateViewportTimeSpan || 400);\n }\n\n function onFold(cm, from) {\n var state = cm.state.foldGutter;\n if (!state) return;\n var line = from.line;\n if (line >= state.from && line < state.to)\n updateFoldInfo(cm, line, line + 1);\n }\n});\n\n},{\"./foldcode\":9,\"codemirror\":undefined}],11:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod((function(){try{return require('codemirror')}catch(e){return window.CodeMirror}})());\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n var Pos = CodeMirror.Pos;\n function cmp(a, b) { return a.line - b.line || a.ch - b.ch; }\n\n var nameStartChar = \"A-Z_a-z\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD\";\n var nameChar = nameStartChar + \"\\-\\:\\.0-9\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040\";\n var xmlTagStart = new RegExp(\"<(/?)([\" + nameStartChar + \"][\" + nameChar + \"]*)\", \"g\");\n\n function Iter(cm, line, ch, range) {\n this.line = line; this.ch = ch;\n this.cm = cm; this.text = cm.getLine(line);\n this.min = range ? range.from : cm.firstLine();\n this.max = range ? range.to - 1 : cm.lastLine();\n }\n\n function tagAt(iter, ch) {\n var type = iter.cm.getTokenTypeAt(Pos(iter.line, ch));\n return type && /\\btag\\b/.test(type);\n }\n\n function nextLine(iter) {\n if (iter.line >= iter.max) return;\n iter.ch = 0;\n iter.text = iter.cm.getLine(++iter.line);\n return true;\n }\n function prevLine(iter) {\n if (iter.line <= iter.min) return;\n iter.text = iter.cm.getLine(--iter.line);\n iter.ch = iter.text.length;\n return true;\n }\n\n function toTagEnd(iter) {\n for (;;) {\n var gt = iter.text.indexOf(\">\", iter.ch);\n if (gt == -1) { if (nextLine(iter)) continue; else return; }\n if (!tagAt(iter, gt + 1)) { iter.ch = gt + 1; continue; }\n var lastSlash = iter.text.lastIndexOf(\"/\", gt);\n var selfClose = lastSlash > -1 && !/\\S/.test(iter.text.slice(lastSlash + 1, gt));\n iter.ch = gt + 1;\n return selfClose ? \"selfClose\" : \"regular\";\n }\n }\n function toTagStart(iter) {\n for (;;) {\n var lt = iter.ch ? iter.text.lastIndexOf(\"<\", iter.ch - 1) : -1;\n if (lt == -1) { if (prevLine(iter)) continue; else return; }\n if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; }\n xmlTagStart.lastIndex = lt;\n iter.ch = lt;\n var match = xmlTagStart.exec(iter.text);\n if (match && match.index == lt) return match;\n }\n }\n\n function toNextTag(iter) {\n for (;;) {\n xmlTagStart.lastIndex = iter.ch;\n var found = xmlTagStart.exec(iter.text);\n if (!found) { if (nextLine(iter)) continue; else return; }\n if (!tagAt(iter, found.index + 1)) { iter.ch = found.index + 1; continue; }\n iter.ch = found.index + found[0].length;\n return found;\n }\n }\n function toPrevTag(iter) {\n for (;;) {\n var gt = iter.ch ? iter.text.lastIndexOf(\">\", iter.ch - 1) : -1;\n if (gt == -1) { if (prevLine(iter)) continue; else return; }\n if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; }\n var lastSlash = iter.text.lastIndexOf(\"/\", gt);\n var selfClose = lastSlash > -1 && !/\\S/.test(iter.text.slice(lastSlash + 1, gt));\n iter.ch = gt + 1;\n return selfClose ? \"selfClose\" : \"regular\";\n }\n }\n\n function findMatchingClose(iter, tag) {\n var stack = [];\n for (;;) {\n var next = toNextTag(iter), end, startLine = iter.line, startCh = iter.ch - (next ? next[0].length : 0);\n if (!next || !(end = toTagEnd(iter))) return;\n if (end == \"selfClose\") continue;\n if (next[1]) { // closing tag\n for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) {\n stack.length = i;\n break;\n }\n if (i < 0 && (!tag || tag == next[2])) return {\n tag: next[2],\n from: Pos(startLine, startCh),\n to: Pos(iter.line, iter.ch)\n };\n } else { // opening tag\n stack.push(next[2]);\n }\n }\n }\n function findMatchingOpen(iter, tag) {\n var stack = [];\n for (;;) {\n var prev = toPrevTag(iter);\n if (!prev) return;\n if (prev == \"selfClose\") { toTagStart(iter); continue; }\n var endLine = iter.line, endCh = iter.ch;\n var start = toTagStart(iter);\n if (!start) return;\n if (start[1]) { // closing tag\n stack.push(start[2]);\n } else { // opening tag\n for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == start[2]) {\n stack.length = i;\n break;\n }\n if (i < 0 && (!tag || tag == start[2])) return {\n tag: start[2],\n from: Pos(iter.line, iter.ch),\n to: Pos(endLine, endCh)\n };\n }\n }\n }\n\n CodeMirror.registerHelper(\"fold\", \"xml\", function(cm, start) {\n var iter = new Iter(cm, start.line, 0);\n for (;;) {\n var openTag = toNextTag(iter), end;\n if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return;\n if (!openTag[1] && end != \"selfClose\") {\n var start = Pos(iter.line, iter.ch);\n var close = findMatchingClose(iter, openTag[2]);\n return close && {from: start, to: close.from};\n }\n }\n });\n CodeMirror.findMatchingTag = function(cm, pos, range) {\n var iter = new Iter(cm, pos.line, pos.ch, range);\n if (iter.text.indexOf(\">\") == -1 && iter.text.indexOf(\"<\") == -1) return;\n var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch);\n var start = end && toTagStart(iter);\n if (!end || !start || cmp(iter, pos) > 0) return;\n var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]};\n if (end == \"selfClose\") return {open: here, close: null, at: \"open\"};\n\n if (start[1]) { // closing tag\n return {open: findMatchingOpen(iter, start[2]), close: here, at: \"close\"};\n } else { // opening tag\n iter = new Iter(cm, to.line, to.ch, range);\n return {open: here, close: findMatchingClose(iter, start[2]), at: \"open\"};\n }\n };\n\n CodeMirror.findEnclosingTag = function(cm, pos, range) {\n var iter = new Iter(cm, pos.line, pos.ch, range);\n for (;;) {\n var open = findMatchingOpen(iter);\n if (!open) break;\n var forward = new Iter(cm, pos.line, pos.ch, range);\n var close = findMatchingClose(forward, open.tag);\n if (close) return {open: open, close: close};\n }\n };\n\n // Used by addon/edit/closetag.js\n CodeMirror.scanForClosingTag = function(cm, pos, name, end) {\n var iter = new Iter(cm, pos.line, pos.ch, end ? {from: 0, to: end} : null);\n return findMatchingClose(iter, name);\n };\n});\n\n},{\"codemirror\":undefined}],12:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod((function(){try{return require('codemirror')}catch(e){return window.CodeMirror}})());\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n var HINT_ELEMENT_CLASS = \"CodeMirror-hint\";\n var ACTIVE_HINT_ELEMENT_CLASS = \"CodeMirror-hint-active\";\n\n // This is the old interface, kept around for now to stay\n // backwards-compatible.\n CodeMirror.showHint = function(cm, getHints, options) {\n if (!getHints) return cm.showHint(options);\n if (options && options.async) getHints.async = true;\n var newOpts = {hint: getHints};\n if (options) for (var prop in options) newOpts[prop] = options[prop];\n return cm.showHint(newOpts);\n };\n\n CodeMirror.defineExtension(\"showHint\", function(options) {\n options = parseOptions(this, this.getCursor(\"start\"), options);\n var selections = this.listSelections()\n if (selections.length > 1) return;\n // By default, don't allow completion when something is selected.\n // A hint function can have a `supportsSelection` property to\n // indicate that it can handle selections.\n if (this.somethingSelected()) {\n if (!options.hint.supportsSelection) return;\n // Don't try with cross-line selections\n for (var i = 0; i < selections.length; i++)\n if (selections[i].head.line != selections[i].anchor.line) return;\n }\n\n if (this.state.completionActive) this.state.completionActive.close();\n var completion = this.state.completionActive = new Completion(this, options);\n if (!completion.options.hint) return;\n\n CodeMirror.signal(this, \"startCompletion\", this);\n completion.update(true);\n });\n\n function Completion(cm, options) {\n this.cm = cm;\n this.options = options;\n this.widget = null;\n this.debounce = 0;\n this.tick = 0;\n this.startPos = this.cm.getCursor(\"start\");\n this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length;\n\n var self = this;\n cm.on(\"cursorActivity\", this.activityFunc = function() { self.cursorActivity(); });\n }\n\n var requestAnimationFrame = window.requestAnimationFrame || function(fn) {\n return setTimeout(fn, 1000/60);\n };\n var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;\n\n Completion.prototype = {\n close: function() {\n if (!this.active()) return;\n this.cm.state.completionActive = null;\n this.tick = null;\n this.cm.off(\"cursorActivity\", this.activityFunc);\n\n if (this.widget && this.data) CodeMirror.signal(this.data, \"close\");\n if (this.widget) this.widget.close();\n CodeMirror.signal(this.cm, \"endCompletion\", this.cm);\n },\n\n active: function() {\n return this.cm.state.completionActive == this;\n },\n\n pick: function(data, i) {\n var completion = data.list[i];\n if (completion.hint) completion.hint(this.cm, data, completion);\n else this.cm.replaceRange(getText(completion), completion.from || data.from,\n completion.to || data.to, \"complete\");\n CodeMirror.signal(data, \"pick\", completion);\n this.close();\n },\n\n cursorActivity: function() {\n if (this.debounce) {\n cancelAnimationFrame(this.debounce);\n this.debounce = 0;\n }\n\n var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);\n if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||\n pos.ch < this.startPos.ch || this.cm.somethingSelected() ||\n (pos.ch && this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {\n this.close();\n } else {\n var self = this;\n this.debounce = requestAnimationFrame(function() {self.update();});\n if (this.widget) this.widget.disable();\n }\n },\n\n update: function(first) {\n if (this.tick == null) return;\n if (!this.options.hint.async) {\n this.finishUpdate(this.options.hint(this.cm, this.options), first);\n } else {\n var myTick = ++this.tick, self = this;\n this.options.hint(this.cm, function(data) {\n if (self.tick == myTick) self.finishUpdate(data, first);\n }, this.options);\n }\n },\n\n finishUpdate: function(data, first) {\n if (this.data) CodeMirror.signal(this.data, \"update\");\n if (data && this.data && CodeMirror.cmpPos(data.from, this.data.from)) data = null;\n this.data = data;\n\n var picked = (this.widget && this.widget.picked) || (first && this.options.completeSingle);\n if (this.widget) this.widget.close();\n if (data && data.list.length) {\n if (picked && data.list.length == 1) {\n this.pick(data, 0);\n } else {\n this.widget = new Widget(this, data);\n CodeMirror.signal(data, \"shown\");\n }\n }\n }\n };\n\n function parseOptions(cm, pos, options) {\n var editor = cm.options.hintOptions;\n var out = {};\n for (var prop in defaultOptions) out[prop] = defaultOptions[prop];\n if (editor) for (var prop in editor)\n if (editor[prop] !== undefined) out[prop] = editor[prop];\n if (options) for (var prop in options)\n if (options[prop] !== undefined) out[prop] = options[prop];\n if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos)\n return out;\n }\n\n function getText(completion) {\n if (typeof completion == \"string\") return completion;\n else return completion.text;\n }\n\n function buildKeyMap(completion, handle) {\n var baseMap = {\n Up: function() {handle.moveFocus(-1);},\n Down: function() {handle.moveFocus(1);},\n PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},\n PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},\n Home: function() {handle.setFocus(0);},\n End: function() {handle.setFocus(handle.length - 1);},\n Enter: handle.pick,\n Tab: handle.pick,\n Esc: handle.close\n };\n var custom = completion.options.customKeys;\n var ourMap = custom ? {} : baseMap;\n function addBinding(key, val) {\n var bound;\n if (typeof val != \"string\")\n bound = function(cm) { return val(cm, handle); };\n // This mechanism is deprecated\n else if (baseMap.hasOwnProperty(val))\n bound = baseMap[val];\n else\n bound = val;\n ourMap[key] = bound;\n }\n if (custom)\n for (var key in custom) if (custom.hasOwnProperty(key))\n addBinding(key, custom[key]);\n var extra = completion.options.extraKeys;\n if (extra)\n for (var key in extra) if (extra.hasOwnProperty(key))\n addBinding(key, extra[key]);\n return ourMap;\n }\n\n function getHintElement(hintsElement, el) {\n while (el && el != hintsElement) {\n if (el.nodeName.toUpperCase() === \"LI\" && el.parentNode == hintsElement) return el;\n el = el.parentNode;\n }\n }\n\n function Widget(completion, data) {\n this.completion = completion;\n this.data = data;\n this.picked = false;\n var widget = this, cm = completion.cm;\n\n var hints = this.hints = document.createElement(\"ul\");\n hints.className = \"CodeMirror-hints\";\n this.selectedHint = data.selectedHint || 0;\n\n var completions = data.list;\n for (var i = 0; i < completions.length; ++i) {\n var elt = hints.appendChild(document.createElement(\"li\")), cur = completions[i];\n var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? \"\" : \" \" + ACTIVE_HINT_ELEMENT_CLASS);\n if (cur.className != null) className = cur.className + \" \" + className;\n elt.className = className;\n if (cur.render) cur.render(elt, data, cur);\n else elt.appendChild(document.createTextNode(cur.displayText || getText(cur)));\n elt.hintId = i;\n }\n\n var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);\n var left = pos.left, top = pos.bottom, below = true;\n hints.style.left = left + \"px\";\n hints.style.top = top + \"px\";\n // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.\n var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);\n var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);\n (completion.options.container || document.body).appendChild(hints);\n var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;\n if (overlapY > 0) {\n var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);\n if (curTop - height > 0) { // Fits above cursor\n hints.style.top = (top = pos.top - height) + \"px\";\n below = false;\n } else if (height > winH) {\n hints.style.height = (winH - 5) + \"px\";\n hints.style.top = (top = pos.bottom - box.top) + \"px\";\n var cursor = cm.getCursor();\n if (data.from.ch != cursor.ch) {\n pos = cm.cursorCoords(cursor);\n hints.style.left = (left = pos.left) + \"px\";\n box = hints.getBoundingClientRect();\n }\n }\n }\n var overlapX = box.right - winW;\n if (overlapX > 0) {\n if (box.right - box.left > winW) {\n hints.style.width = (winW - 5) + \"px\";\n overlapX -= (box.right - box.left) - winW;\n }\n hints.style.left = (left = pos.left - overlapX) + \"px\";\n }\n\n cm.addKeyMap(this.keyMap = buildKeyMap(completion, {\n moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },\n setFocus: function(n) { widget.changeActive(n); },\n menuSize: function() { return widget.screenAmount(); },\n length: completions.length,\n close: function() { completion.close(); },\n pick: function() { widget.pick(); },\n data: data\n }));\n\n if (completion.options.closeOnUnfocus) {\n var closingOnBlur;\n cm.on(\"blur\", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });\n cm.on(\"focus\", this.onFocus = function() { clearTimeout(closingOnBlur); });\n }\n\n var startScroll = cm.getScrollInfo();\n cm.on(\"scroll\", this.onScroll = function() {\n var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();\n var newTop = top + startScroll.top - curScroll.top;\n var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop);\n if (!below) point += hints.offsetHeight;\n if (point <= editor.top || point >= editor.bottom) return completion.close();\n hints.style.top = newTop + \"px\";\n hints.style.left = (left + startScroll.left - curScroll.left) + \"px\";\n });\n\n CodeMirror.on(hints, \"dblclick\", function(e) {\n var t = getHintElement(hints, e.target || e.srcElement);\n if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}\n });\n\n CodeMirror.on(hints, \"click\", function(e) {\n var t = getHintElement(hints, e.target || e.srcElement);\n if (t && t.hintId != null) {\n widget.changeActive(t.hintId);\n if (completion.options.completeOnSingleClick) widget.pick();\n }\n });\n\n CodeMirror.on(hints, \"mousedown\", function() {\n setTimeout(function(){cm.focus();}, 20);\n });\n\n CodeMirror.signal(data, \"select\", completions[0], hints.firstChild);\n return true;\n }\n\n Widget.prototype = {\n close: function() {\n if (this.completion.widget != this) return;\n this.completion.widget = null;\n this.hints.parentNode.removeChild(this.hints);\n this.completion.cm.removeKeyMap(this.keyMap);\n\n var cm = this.completion.cm;\n if (this.completion.options.closeOnUnfocus) {\n cm.off(\"blur\", this.onBlur);\n cm.off(\"focus\", this.onFocus);\n }\n cm.off(\"scroll\", this.onScroll);\n },\n\n disable: function() {\n this.completion.cm.removeKeyMap(this.keyMap);\n var widget = this;\n this.keyMap = {Enter: function() { widget.picked = true; }};\n this.completion.cm.addKeyMap(this.keyMap);\n },\n\n pick: function() {\n this.completion.pick(this.data, this.selectedHint);\n },\n\n changeActive: function(i, avoidWrap) {\n if (i >= this.data.list.length)\n i = avoidWrap ? this.data.list.length - 1 : 0;\n else if (i < 0)\n i = avoidWrap ? 0 : this.data.list.length - 1;\n if (this.selectedHint == i) return;\n var node = this.hints.childNodes[this.selectedHint];\n node.className = node.className.replace(\" \" + ACTIVE_HINT_ELEMENT_CLASS, \"\");\n node = this.hints.childNodes[this.selectedHint = i];\n node.className += \" \" + ACTIVE_HINT_ELEMENT_CLASS;\n if (node.offsetTop < this.hints.scrollTop)\n this.hints.scrollTop = node.offsetTop - 3;\n else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)\n this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;\n CodeMirror.signal(this.data, \"select\", this.data.list[this.selectedHint], node);\n },\n\n screenAmount: function() {\n return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;\n }\n };\n\n function applicableHelpers(cm, helpers) {\n if (!cm.somethingSelected()) return helpers\n var result = []\n for (var i = 0; i < helpers.length; i++)\n if (helpers[i].supportsSelection) result.push(helpers[i])\n return result\n }\n\n function resolveAutoHints(cm, pos) {\n var helpers = cm.getHelpers(pos, \"hint\"), words\n if (helpers.length) {\n var async = false, resolved\n for (var i = 0; i < helpers.length; i++) if (helpers[i].async) async = true\n if (async) {\n resolved = function(cm, callback, options) {\n var app = applicableHelpers(cm, helpers)\n function run(i, result) {\n if (i == app.length) return callback(null)\n var helper = app[i]\n if (helper.async) {\n helper(cm, function(result) {\n if (result) callback(result)\n else run(i + 1)\n }, options)\n } else {\n var result = helper(cm, options)\n if (result) callback(result)\n else run(i + 1)\n }\n }\n run(0)\n }\n resolved.async = true\n } else {\n resolved = function(cm, options) {\n var app = applicableHelpers(cm, helpers)\n for (var i = 0; i < app.length; i++) {\n var cur = app[i](cm, options)\n if (cur && cur.list.length) return cur\n }\n }\n }\n resolved.supportsSelection = true\n return resolved\n } else if (words = cm.getHelper(cm.getCursor(), \"hintWords\")) {\n return function(cm) { return CodeMirror.hint.fromList(cm, {words: words}) }\n } else if (CodeMirror.hint.anyword) {\n return function(cm, options) { return CodeMirror.hint.anyword(cm, options) }\n } else {\n return function() {}\n }\n }\n\n CodeMirror.registerHelper(\"hint\", \"auto\", {\n resolve: resolveAutoHints\n });\n\n CodeMirror.registerHelper(\"hint\", \"fromList\", function(cm, options) {\n var cur = cm.getCursor(), token = cm.getTokenAt(cur);\n var to = CodeMirror.Pos(cur.line, token.end);\n if (token.string && /\\w/.test(token.string[token.string.length - 1])) {\n var term = token.string, from = CodeMirror.Pos(cur.line, token.start);\n } else {\n var term = \"\", from = to;\n }\n var found = [];\n for (var i = 0; i < options.words.length; i++) {\n var word = options.words[i];\n if (word.slice(0, term.length) == term)\n found.push(word);\n }\n\n if (found.length) return {list: found, from: from, to: to};\n });\n\n CodeMirror.commands.autocomplete = CodeMirror.showHint;\n\n var defaultOptions = {\n hint: CodeMirror.hint.auto,\n completeSingle: true,\n alignWithWord: true,\n closeCharacters: /[\\s()\\[\\]{};:>,]/,\n closeOnUnfocus: true,\n completeOnSingleClick: true,\n container: null,\n customKeys: null,\n extraKeys: null\n };\n\n CodeMirror.defineOption(\"hintOptions\", null);\n});\n\n},{\"codemirror\":undefined}],13:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod((function(){try{return require('codemirror')}catch(e){return window.CodeMirror}})());\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n\"use strict\";\n\nCodeMirror.runMode = function(string, modespec, callback, options) {\n var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);\n var ie = /MSIE \\d/.test(navigator.userAgent);\n var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);\n\n if (callback.appendChild) {\n var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;\n var node = callback, col = 0;\n node.innerHTML = \"\";\n callback = function(text, style) {\n if (text == \"\\n\") {\n // Emitting LF or CRLF on IE8 or earlier results in an incorrect display.\n // Emitting a carriage return makes everything ok.\n node.appendChild(document.createTextNode(ie_lt9 ? '\\r' : text));\n col = 0;\n return;\n }\n var content = \"\";\n // replace tabs\n for (var pos = 0;;) {\n var idx = text.indexOf(\"\\t\", pos);\n if (idx == -1) {\n content += text.slice(pos);\n col += text.length - pos;\n break;\n } else {\n col += idx - pos;\n content += text.slice(pos, idx);\n var size = tabSize - col % tabSize;\n col += size;\n for (var i = 0; i < size; ++i) content += \" \";\n pos = idx + 1;\n }\n }\n\n if (style) {\n var sp = node.appendChild(document.createElement(\"span\"));\n sp.className = \"cm-\" + style.replace(/ +/g, \" cm-\");\n sp.appendChild(document.createTextNode(content));\n } else {\n node.appendChild(document.createTextNode(content));\n }\n };\n }\n\n var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);\n for (var i = 0, e = lines.length; i < e; ++i) {\n if (i) callback(\"\\n\");\n var stream = new CodeMirror.StringStream(lines[i]);\n if (!stream.string && mode.blankLine) mode.blankLine(state);\n while (!stream.eol()) {\n var style = mode.token(stream, state);\n callback(stream.current(), style, i, stream.start, state);\n stream.start = stream.pos;\n }\n }\n};\n\n});\n\n},{\"codemirror\":undefined}],14:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod((function(){try{return require('codemirror')}catch(e){return window.CodeMirror}})());\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n var Pos = CodeMirror.Pos;\n\n function SearchCursor(doc, query, pos, caseFold) {\n this.atOccurrence = false; this.doc = doc;\n if (caseFold == null && typeof query == \"string\") caseFold = false;\n\n pos = pos ? doc.clipPos(pos) : Pos(0, 0);\n this.pos = {from: pos, to: pos};\n\n // The matches method is filled in based on the type of query.\n // It takes a position and a direction, and returns an object\n // describing the next occurrence of the query, or null if no\n // more matches were found.\n if (typeof query != \"string\") { // Regexp match\n if (!query.global) query = new RegExp(query.source, query.ignoreCase ? \"ig\" : \"g\");\n this.matches = function(reverse, pos) {\n if (reverse) {\n query.lastIndex = 0;\n var line = doc.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start;\n for (;;) {\n query.lastIndex = cutOff;\n var newMatch = query.exec(line);\n if (!newMatch) break;\n match = newMatch;\n start = match.index;\n cutOff = match.index + (match[0].length || 1);\n if (cutOff == line.length) break;\n }\n var matchLen = (match && match[0].length) || 0;\n if (!matchLen) {\n if (start == 0 && line.length == 0) {match = undefined;}\n else if (start != doc.getLine(pos.line).length) {\n matchLen++;\n }\n }\n } else {\n query.lastIndex = pos.ch;\n var line = doc.getLine(pos.line), match = query.exec(line);\n var matchLen = (match && match[0].length) || 0;\n var start = match && match.index;\n if (start + matchLen != line.length && !matchLen) matchLen = 1;\n }\n if (match && matchLen)\n return {from: Pos(pos.line, start),\n to: Pos(pos.line, start + matchLen),\n match: match};\n };\n } else { // String query\n var origQuery = query;\n if (caseFold) query = query.toLowerCase();\n var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;};\n var target = query.split(\"\\n\");\n // Different methods for single-line and multi-line queries\n if (target.length == 1) {\n if (!query.length) {\n // Empty string would match anything and never progress, so\n // we define it to match nothing instead.\n this.matches = function() {};\n } else {\n this.matches = function(reverse, pos) {\n if (reverse) {\n var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig);\n var match = line.lastIndexOf(query);\n if (match > -1) {\n match = adjustPos(orig, line, match);\n return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};\n }\n } else {\n var orig = doc.getLine(pos.line).slice(pos.ch), line = fold(orig);\n var match = line.indexOf(query);\n if (match > -1) {\n match = adjustPos(orig, line, match) + pos.ch;\n return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};\n }\n }\n };\n }\n } else {\n var origTarget = origQuery.split(\"\\n\");\n this.matches = function(reverse, pos) {\n var last = target.length - 1;\n if (reverse) {\n if (pos.line - (target.length - 1) < doc.firstLine()) return;\n if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return;\n var to = Pos(pos.line, origTarget[last].length);\n for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln)\n if (target[i] != fold(doc.getLine(ln))) return;\n var line = doc.getLine(ln), cut = line.length - origTarget[0].length;\n if (fold(line.slice(cut)) != target[0]) return;\n return {from: Pos(ln, cut), to: to};\n } else {\n if (pos.line + (target.length - 1) > doc.lastLine()) return;\n var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length;\n if (fold(line.slice(cut)) != target[0]) return;\n var from = Pos(pos.line, cut);\n for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln)\n if (target[i] != fold(doc.getLine(ln))) return;\n if (fold(doc.getLine(ln).slice(0, origTarget[last].length)) != target[last]) return;\n return {from: from, to: Pos(ln, origTarget[last].length)};\n }\n };\n }\n }\n }\n\n SearchCursor.prototype = {\n findNext: function() {return this.find(false);},\n findPrevious: function() {return this.find(true);},\n\n find: function(reverse) {\n var self = this, pos = this.doc.clipPos(reverse ? this.pos.from : this.pos.to);\n function savePosAndFail(line) {\n var pos = Pos(line, 0);\n self.pos = {from: pos, to: pos};\n self.atOccurrence = false;\n return false;\n }\n\n for (;;) {\n if (this.pos = this.matches(reverse, pos)) {\n this.atOccurrence = true;\n return this.pos.match || true;\n }\n if (reverse) {\n if (!pos.line) return savePosAndFail(0);\n pos = Pos(pos.line-1, this.doc.getLine(pos.line-1).length);\n }\n else {\n var maxLine = this.doc.lineCount();\n if (pos.line == maxLine - 1) return savePosAndFail(maxLine);\n pos = Pos(pos.line + 1, 0);\n }\n }\n },\n\n from: function() {if (this.atOccurrence) return this.pos.from;},\n to: function() {if (this.atOccurrence) return this.pos.to;},\n\n replace: function(newText, origin) {\n if (!this.atOccurrence) return;\n var lines = CodeMirror.splitLines(newText);\n this.doc.replaceRange(lines, this.pos.from, this.pos.to, origin);\n this.pos.to = Pos(this.pos.from.line + lines.length - 1,\n lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0));\n }\n };\n\n // Maps a position in a case-folded line back to a position in the original line\n // (compensating for codepoints increasing in number during folding)\n function adjustPos(orig, folded, pos) {\n if (orig.length == folded.length) return pos;\n for (var pos1 = Math.min(pos, orig.length);;) {\n var len1 = orig.slice(0, pos1).toLowerCase().length;\n if (len1 < pos) ++pos1;\n else if (len1 > pos) --pos1;\n else return pos1;\n }\n }\n\n CodeMirror.defineExtension(\"getSearchCursor\", function(query, pos, caseFold) {\n return new SearchCursor(this.doc, query, pos, caseFold);\n });\n CodeMirror.defineDocExtension(\"getSearchCursor\", function(query, pos, caseFold) {\n return new SearchCursor(this, query, pos, caseFold);\n });\n\n CodeMirror.defineExtension(\"selectMatches\", function(query, caseFold) {\n var ranges = [];\n var cur = this.getSearchCursor(query, this.getCursor(\"from\"), caseFold);\n while (cur.findNext()) {\n if (CodeMirror.cmpPos(cur.to(), this.getCursor(\"to\")) > 0) break;\n ranges.push({anchor: cur.from(), head: cur.to()});\n }\n if (ranges.length)\n this.setSelections(ranges, 0);\n });\n});\n\n},{\"codemirror\":undefined}],15:[function(require,module,exports){\n(function (global){\n\"use strict\"\n// Module export pattern from\n// https://github.com/umdjs/umd/blob/master/returnExports.js\n;(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module.\n define([], factory);\n } else if (typeof exports === 'object') {\n // Node. Does not work with strict CommonJS, but\n // only CommonJS-like environments that support module.exports,\n // like Node.\n module.exports = factory();\n } else {\n // Browser globals (root is window)\n root.store = factory();\n }\n}(this, function () {\n\t\n\t// Store.js\n\tvar store = {},\n\t\twin = (typeof window != 'undefined' ? window : global),\n\t\tdoc = win.document,\n\t\tlocalStorageName = 'localStorage',\n\t\tscriptTag = 'script',\n\t\tstorage\n\n\tstore.disabled = false\n\tstore.version = '1.3.20'\n\tstore.set = function(key, value) {}\n\tstore.get = function(key, defaultVal) {}\n\tstore.has = function(key) { return store.get(key) !== undefined }\n\tstore.remove = function(key) {}\n\tstore.clear = function() {}\n\tstore.transact = function(key, defaultVal, transactionFn) {\n\t\tif (transactionFn == null) {\n\t\t\ttransactionFn = defaultVal\n\t\t\tdefaultVal = null\n\t\t}\n\t\tif (defaultVal == null) {\n\t\t\tdefaultVal = {}\n\t\t}\n\t\tvar val = store.get(key, defaultVal)\n\t\ttransactionFn(val)\n\t\tstore.set(key, val)\n\t}\n\tstore.getAll = function() {}\n\tstore.forEach = function() {}\n\n\tstore.serialize = function(value) {\n\t\treturn JSON.stringify(value)\n\t}\n\tstore.deserialize = function(value) {\n\t\tif (typeof value != 'string') { return undefined }\n\t\ttry { return JSON.parse(value) }\n\t\tcatch(e) { return value || undefined }\n\t}\n\n\t// Functions to encapsulate questionable FireFox 3.6.13 behavior\n\t// when about.config::dom.storage.enabled === false\n\t// See https://github.com/marcuswestin/store.js/issues#issue/13\n\tfunction isLocalStorageNameSupported() {\n\t\ttry { return (localStorageName in win && win[localStorageName]) }\n\t\tcatch(err) { return false }\n\t}\n\n\tif (isLocalStorageNameSupported()) {\n\t\tstorage = win[localStorageName]\n\t\tstore.set = function(key, val) {\n\t\t\tif (val === undefined) { return store.remove(key) }\n\t\t\tstorage.setItem(key, store.serialize(val))\n\t\t\treturn val\n\t\t}\n\t\tstore.get = function(key, defaultVal) {\n\t\t\tvar val = store.deserialize(storage.getItem(key))\n\t\t\treturn (val === undefined ? defaultVal : val)\n\t\t}\n\t\tstore.remove = function(key) { storage.removeItem(key) }\n\t\tstore.clear = function() { storage.clear() }\n\t\tstore.getAll = function() {\n\t\t\tvar ret = {}\n\t\t\tstore.forEach(function(key, val) {\n\t\t\t\tret[key] = val\n\t\t\t})\n\t\t\treturn ret\n\t\t}\n\t\tstore.forEach = function(callback) {\n\t\t\tfor (var i=0; idocument.w=window')\n\t\t\tstorageContainer.close()\n\t\t\tstorageOwner = storageContainer.w.frames[0].document\n\t\t\tstorage = storageOwner.createElement('div')\n\t\t} catch(e) {\n\t\t\t// somehow ActiveXObject instantiation failed (perhaps some special\n\t\t\t// security settings or otherwse), fall back to per-path storage\n\t\t\tstorage = doc.createElement('div')\n\t\t\tstorageOwner = doc.body\n\t\t}\n\t\tvar withIEStorage = function(storeFunction) {\n\t\t\treturn function() {\n\t\t\t\tvar args = Array.prototype.slice.call(arguments, 0)\n\t\t\t\targs.unshift(storage)\n\t\t\t\t// See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx\n\t\t\t\t// and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx\n\t\t\t\tstorageOwner.appendChild(storage)\n\t\t\t\tstorage.addBehavior('#default#userData')\n\t\t\t\tstorage.load(localStorageName)\n\t\t\t\tvar result = storeFunction.apply(store, args)\n\t\t\t\tstorageOwner.removeChild(storage)\n\t\t\t\treturn result\n\t\t\t}\n\t\t}\n\n\t\t// In IE7, keys cannot start with a digit or contain certain chars.\n\t\t// See https://github.com/marcuswestin/store.js/issues/40\n\t\t// See https://github.com/marcuswestin/store.js/issues/83\n\t\tvar forbiddenCharsRegex = new RegExp(\"[!\\\"#$%&'()*+,/\\\\\\\\:;<=>?@[\\\\]^`{|}~]\", \"g\")\n\t\tvar ieKeyFix = function(key) {\n\t\t\treturn key.replace(/^d/, '___$&').replace(forbiddenCharsRegex, '___')\n\t\t}\n\t\tstore.set = withIEStorage(function(storage, key, val) {\n\t\t\tkey = ieKeyFix(key)\n\t\t\tif (val === undefined) { return store.remove(key) }\n\t\t\tstorage.setAttribute(key, store.serialize(val))\n\t\t\tstorage.save(localStorageName)\n\t\t\treturn val\n\t\t})\n\t\tstore.get = withIEStorage(function(storage, key, defaultVal) {\n\t\t\tkey = ieKeyFix(key)\n\t\t\tvar val = store.deserialize(storage.getAttribute(key))\n\t\t\treturn (val === undefined ? defaultVal : val)\n\t\t})\n\t\tstore.remove = withIEStorage(function(storage, key) {\n\t\t\tkey = ieKeyFix(key)\n\t\t\tstorage.removeAttribute(key)\n\t\t\tstorage.save(localStorageName)\n\t\t})\n\t\tstore.clear = withIEStorage(function(storage) {\n\t\t\tvar attributes = storage.XMLDocument.documentElement.attributes\n\t\t\tstorage.load(localStorageName)\n\t\t\tfor (var i=attributes.length-1; i>=0; i--) {\n\t\t\t\tstorage.removeAttribute(attributes[i].name)\n\t\t\t}\n\t\t\tstorage.save(localStorageName)\n\t\t})\n\t\tstore.getAll = function(storage) {\n\t\t\tvar ret = {}\n\t\t\tstore.forEach(function(key, val) {\n\t\t\t\tret[key] = val\n\t\t\t})\n\t\t\treturn ret\n\t\t}\n\t\tstore.forEach = withIEStorage(function(storage, callback) {\n\t\t\tvar attributes = storage.XMLDocument.documentElement.attributes\n\t\t\tfor (var i=0, attr; attr=attributes[i]; ++i) {\n\t\t\t\tcallback(attr.name, store.deserialize(storage.getAttribute(attr.name)))\n\t\t\t}\n\t\t})\n\t}\n\n\ttry {\n\t\tvar testKey = '__storejs__'\n\t\tstore.set(testKey, testKey)\n\t\tif (store.get(testKey) != testKey) { store.disabled = true }\n\t\tstore.remove(testKey)\n\t} catch(e) {\n\t\tstore.disabled = true\n\t}\n\tstore.enabled = !store.disabled\n\t\n\treturn store\n}));\n\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n\n},{}],16:[function(require,module,exports){\nmodule.exports={\n \"_args\": [\n [\n \"yasgui-utils@^1.4.1\",\n \"/home/lrd900/yasgui/yasqe\"\n ]\n ],\n \"_from\": \"yasgui-utils@>=1.4.1 <2.0.0\",\n \"_id\": \"yasgui-utils@1.6.0\",\n \"_inCache\": true,\n \"_installable\": true,\n \"_location\": \"/yasgui-utils\",\n \"_npmUser\": {\n \"email\": \"laurens.rietveld@gmail.com\",\n \"name\": \"laurens.rietveld\"\n },\n \"_npmVersion\": \"1.4.3\",\n \"_phantomChildren\": {},\n \"_requested\": {\n \"name\": \"yasgui-utils\",\n \"raw\": \"yasgui-utils@^1.4.1\",\n \"rawSpec\": \"^1.4.1\",\n \"scope\": null,\n \"spec\": \">=1.4.1 <2.0.0\",\n \"type\": \"range\"\n },\n \"_requiredBy\": [\n \"/\"\n ],\n \"_shrinkwrap\": null,\n \"_spec\": \"yasgui-utils@^1.4.1\",\n \"_where\": \"/home/lrd900/yasgui/yasqe\",\n \"author\": {\n \"name\": \"Laurens Rietveld\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/YASGUI/Utils/issues\"\n },\n \"dependencies\": {\n \"store\": \"^1.3.14\"\n },\n \"description\": \"Utils for YASGUI libs\",\n \"devDependencies\": {},\n \"directories\": {},\n \"dist\": {\n \"shasum\": \"bcb9091109c233e3e82737c94c202e6512389c47\",\n \"tarball\": \"http://registry.npmjs.org/yasgui-utils/-/yasgui-utils-1.6.0.tgz\"\n },\n \"homepage\": \"https://github.com/YASGUI/Utils\",\n \"licenses\": [\n {\n \"type\": \"MIT\",\n \"url\": \"http://yasgui.github.io/license.txt\"\n }\n ],\n \"main\": \"src/main.js\",\n \"maintainers\": [\n {\n \"name\": \"laurens.rietveld\",\n \"email\": \"laurens.rietveld@gmail.com\"\n }\n ],\n \"name\": \"yasgui-utils\",\n \"optionalDependencies\": {},\n \"readme\": \"ERROR: No README data found!\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git://github.com/YASGUI/Utils.git\"\n },\n \"version\": \"1.6.0\"\n}\n\n},{}],17:[function(require,module,exports){\nwindow.console = window.console || {\"log\":function(){}};//make sure any console statements don't break IE\nmodule.exports = {\n\tstorage: require(\"./storage.js\"),\n\tsvg: require(\"./svg.js\"),\n\tversion: {\n\t\t\"yasgui-utils\" : require(\"../package.json\").version,\n\t},\n\tnestedExists : function(obj) {\n\t\tvar args = Array.prototype.slice.call(arguments, 1);\n\n\t\tfor (var i = 0; i < args.length; i++) {\n\t\t\tif (!obj || !obj.hasOwnProperty(args[i])) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tobj = obj[args[i]];\n\t\t}\n\t\treturn true;\n\t}\n};\n\n},{\"../package.json\":16,\"./storage.js\":18,\"./svg.js\":19}],18:[function(require,module,exports){\nvar store = require(\"store\");\nvar times = {\n\tday: function() {\n\t\treturn 1000 * 3600 * 24;//millis to day\n\t},\n\tmonth: function() {\n\t\ttimes.day() * 30;\n\t},\n\tyear: function() {\n\t\ttimes.month() * 12;\n\t}\n};\n\nvar root = module.exports = {\n\tset : function(key, val, exp) {\n if (!store.enabled) return;//this is probably in private mode. Don't run, as we might get Js errors\n\t\tif (key && val !== undefined) {\n\t\t\tif (typeof exp == \"string\") {\n\t\t\t\texp = times[exp]();\n\t\t\t}\n\t\t\t//try to store string for dom objects (e.g. XML result). Otherwise, we might get a circular reference error when stringifying this\n\t\t\tif (val.documentElement) val = new XMLSerializer().serializeToString(val.documentElement);\n\t\t\tstore.set(key, {\n\t\t\t\tval : val,\n\t\t\t\texp : exp,\n\t\t\t\ttime : new Date().getTime()\n\t\t\t});\n\t\t}\n\t},\n\tremove: function(key) {\n\t\tif (!store.enabled) return;//this is probably in private mode. Don't run, as we might get Js errors\n\t\tif (key) store.remove(key)\n\t},\n\tremoveAll: function(filter) {\n\t\tif (!store.enabled) return;//this is probably in private mode. Don't run, as we might get Js errors\n\t\tif (typeof filter === 'function') {\n\t\t\tfor (var key in store.getAll()) {\n\t\t\t\tif (filter(key, root.get(key))) root.remove(key);\n\t\t\t}\n\t\t}\n\t},\n\tget : function(key) {\n if (!store.enabled) return null;//this is probably in private mode. Don't run, as we might get Js errors\n\t\tif (key) {\n\t\t\tvar info = store.get(key);\n\t\t\tif (!info) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (info.exp && new Date().getTime() - info.time > info.exp) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn info.val;\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n};\n\n},{\"store\":15}],19:[function(require,module,exports){\nmodule.exports = {\n\tdraw: function(parent, svgString) {\n\t\tif (!parent) return;\n\t\tvar el = module.exports.getElement(svgString);\n\t\tif (el) {\n\t\t\tif (parent.append) {\n\t\t\t\tparent.append(el);\n\t\t\t} else {\n\t\t\t\t//regular dom doc\n\t\t\t\tparent.appendChild(el);\n\t\t\t}\n\t\t}\n\t},\n\tgetElement: function(svgString) {\n\t\tif (svgString && svgString.indexOf(\" 0) {\n\t\t\t//position completion notifications\n\t\t\tvar scrollBar = $(yasqe.getWrapperElement()).find(\".CodeMirror-vscrollbar\");\n\t\t\tvar offset = 0;\n\t\t\tif (scrollBar.is(\":visible\")) {\n\t\t\t\toffset = scrollBar.outerWidth();\n\t\t\t}\n\t\t\tneedPossibleAdjustment.forEach(function(notification) {\n\t\t\t\tnotification.css(\"right\", offset)\n\t\t\t});\n\t\t}\n\t});\n\n\n\n\t/**\n\t * Store bulk completions in memory as trie, and store these in localstorage as well (if enabled)\n\t * \n\t * @method doc.storeBulkCompletions\n\t * @param completions {array}\n\t */\n\tvar storeBulkCompletions = function(completer, completions) {\n\t\t// store array as trie\n\t\ttries[completer.name] = new Trie();\n\t\tfor (var i = 0; i < completions.length; i++) {\n\t\t\ttries[completer.name].insert(completions[i]);\n\t\t}\n\t\t// store in localstorage as well\n\t\tvar storageId = utils.getPersistencyId(yasqe, completer.persistent);\n\t\tif (storageId) yutils.storage.set(storageId, completions, \"month\");\n\t};\n\n\tvar initCompleter = function(name, completionInit) {\n\t\tvar completer = completers[name] = new completionInit(yasqe, name);\n\t\tcompleter.name = name;\n\t\tif (completer.bulk) {\n\t\t\tvar storeArrayAsBulk = function(suggestions) {\n\t\t\t\tif (suggestions && suggestions instanceof Array && suggestions.length > 0) {\n\t\t\t\t\tstoreBulkCompletions(completer, suggestions);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (completer.get instanceof Array) {\n\t\t\t\t// we don't care whether the completions are already stored in\n\t\t\t\t// localstorage. just use this one\n\t\t\t\tstoreArrayAsBulk(completer.get);\n\t\t\t} else {\n\t\t\t\t// if completions are defined in localstorage, use those! (calling the\n\t\t\t\t// function may come with overhead (e.g. async calls))\n\t\t\t\tvar completionsFromStorage = null;\n\t\t\t\tvar persistencyIdentifier = utils.getPersistencyId(yasqe, completer.persistent);\n\t\t\t\tif (persistencyIdentifier)\n\t\t\t\t\tcompletionsFromStorage = yutils.storage.get(persistencyIdentifier);\n\t\t\t\tif (completionsFromStorage && completionsFromStorage.length > 0) {\n\t\t\t\t\tstoreArrayAsBulk(completionsFromStorage);\n\t\t\t\t} else {\n\t\t\t\t\t// nothing in storage. check whether we have a function via which we\n\t\t\t\t\t// can get our prefixes\n\t\t\t\t\tif (completer.get instanceof Function) {\n\t\t\t\t\t\tif (completer.async) {\n\t\t\t\t\t\t\tcompleter.get(null, storeArrayAsBulk);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstoreArrayAsBulk(completer.get());\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tvar autoComplete = function(fromAutoShow) {\n\t\tif (yasqe.somethingSelected())\n\t\t\treturn;\n\t\tvar tryHintType = function(completer) {\n\t\t\tif (fromAutoShow // from autoShow, i.e. this gets called each time the editor content changes\n\t\t\t\t&& (!completer.autoShow // autoshow for this particular type of autocompletion is -not- enabled\n\t\t\t\t\t|| (!completer.bulk && completer.async)) // async is enabled (don't want to re-do ajax-like request for every editor change)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar hintConfig = {\n\t\t\t\tcloseCharacters: /(?=a)b/,\n\t\t\t\tcompleteSingle: false\n\t\t\t};\n\t\t\tif (!completer.bulk && completer.async) {\n\t\t\t\thintConfig.async = true;\n\t\t\t}\n\t\t\tvar wrappedHintCallback = function(yasqe, callback) {\n\t\t\t\treturn getCompletionHintsObject(completer, callback);\n\t\t\t};\n\t\t\tvar result = YASQE.showHint(yasqe, wrappedHintCallback, hintConfig);\n\t\t\treturn true;\n\t\t};\n\t\tfor (var completerName in completers) {\n\t\t\tif ($.inArray(completerName, yasqe.options.autocompleters) == -1) continue; //this completer is disabled\n\t\t\tvar completer = completers[completerName];\n\t\t\tif (!completer.isValidCompletionPosition) continue; //no way to check whether we are in a valid position\n\n\t\t\tif (!completer.isValidCompletionPosition()) {\n\t\t\t\t//if needed, fire callbacks for when we are -not- in valid completion position\n\t\t\t\tif (completer.callbacks && completer.callbacks.invalidPosition) {\n\t\t\t\t\tcompleter.callbacks.invalidPosition(yasqe, completer);\n\t\t\t\t}\n\t\t\t\t//not in a valid position, so continue to next completion candidate type\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// run valid position handler, if there is one (if it returns false, stop the autocompletion!)\n\t\t\tif (completer.callbacks && completer.callbacks.validPosition) {\n\t\t\t\tif (completer.callbacks.validPosition(yasqe, completer) === false)\n\t\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvar success = tryHintType(completer);\n\t\t\tif (success)\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\n\n\tvar getCompletionHintsObject = function(completer, callback) {\n\t\tvar getSuggestionsFromToken = function(partialToken) {\n\t\t\tvar stringToAutocomplete = partialToken.autocompletionString || partialToken.string;\n\t\t\tvar suggestions = [];\n\t\t\tif (tries[completer.name]) {\n\t\t\t\tsuggestions = tries[completer.name].autoComplete(stringToAutocomplete);\n\t\t\t} else if (typeof completer.get == \"function\" && completer.async == false) {\n\t\t\t\tsuggestions = completer.get(stringToAutocomplete);\n\t\t\t} else if (typeof completer.get == \"object\") {\n\t\t\t\tvar partialTokenLength = stringToAutocomplete.length;\n\t\t\t\tfor (var i = 0; i < completer.get.length; i++) {\n\t\t\t\t\tvar completion = completer.get[i];\n\t\t\t\t\tif (completion.slice(0, partialTokenLength) == stringToAutocomplete) {\n\t\t\t\t\t\tsuggestions.push(completion);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn getSuggestionsAsHintObject(suggestions, completer, partialToken);\n\n\t\t};\n\n\n\t\tvar token = yasqe.getCompleteToken();\n\t\tif (completer.preProcessToken) {\n\t\t\ttoken = completer.preProcessToken(token);\n\t\t}\n\n\t\tif (token) {\n\t\t\t// use custom completionhint function, to avoid reaching a loop when the\n\t\t\t// completionhint is the same as the current token\n\t\t\t// regular behaviour would keep changing the codemirror dom, hence\n\t\t\t// constantly calling this callback\n\t\t\tif (!completer.bulk && completer.async) {\n\t\t\t\tvar wrappedCallback = function(suggestions) {\n\t\t\t\t\tcallback(getSuggestionsAsHintObject(suggestions, completer, token));\n\t\t\t\t};\n\t\t\t\tcompleter.get(token, wrappedCallback);\n\t\t\t} else {\n\t\t\t\treturn getSuggestionsFromToken(token);\n\n\t\t\t}\n\t\t}\n\t};\n\n\n\t/**\n\t * get our array of suggestions (strings) in the codemirror hint format\n\t */\n\tvar getSuggestionsAsHintObject = function(suggestions, completer, token) {\n\t\tvar hintList = [];\n\t\tfor (var i = 0; i < suggestions.length; i++) {\n\t\t\tvar suggestedString = suggestions[i];\n\t\t\tif (completer.postProcessToken) {\n\t\t\t\tsuggestedString = completer.postProcessToken(token, suggestedString);\n\t\t\t}\n\t\t\thintList.push({\n\t\t\t\ttext: suggestedString,\n\t\t\t\tdisplayText: suggestedString,\n\t\t\t\thint: selectHint,\n\t\t\t});\n\t\t}\n\n\t\tvar cur = yasqe.getCursor();\n\t\tvar returnObj = {\n\t\t\tcompletionToken: token.string,\n\t\t\tlist: hintList,\n\t\t\tfrom: {\n\t\t\t\tline: cur.line,\n\t\t\t\tch: token.start\n\t\t\t},\n\t\t\tto: {\n\t\t\t\tline: cur.line,\n\t\t\t\tch: token.end\n\t\t\t}\n\t\t};\n\t\t//if we have some autocompletion handlers specified, add these these to the object. Codemirror will take care of firing these\n\t\tif (completer.callbacks) {\n\t\t\tfor (var callbackName in completer.callbacks) {\n\t\t\t\tif (completer.callbacks[callbackName]) {\n\t\t\t\t\tYASQE.on(returnObj, callbackName, completer.callbacks[callbackName]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn returnObj;\n\t};\n\n\treturn {\n\t\tinit: initCompleter,\n\t\tcompleters: completers,\n\t\tnotifications: {\n\t\t\tgetEl: function(completer) {\n\t\t\t\treturn $(completionNotifications[completer.name]);\n\t\t\t},\n\t\t\tshow: function(yasqe, completer) {\n\t\t\t\t//only draw when the user needs to use a keypress to summon autocompletions\n\t\t\t\tif (!completer.autoshow) {\n\t\t\t\t\tif (!completionNotifications[completer.name]) completionNotifications[completer.name] = $(\"
      \");\n\t\t\t\t\tcompletionNotifications[completer.name]\n\t\t\t\t\t\t.show()\n\t\t\t\t\t\t.text(\"Press \" + (navigator.userAgent.indexOf('Mac OS X') != -1 ? \"CMD\" : \"CTRL\") + \" - to autocomplete\")\n\t\t\t\t\t\t.appendTo($(yasqe.getWrapperElement()));\n\t\t\t\t}\n\t\t\t},\n\t\t\thide: function(yasqe, completer) {\n\t\t\t\tif (completionNotifications[completer.name]) {\n\t\t\t\t\tcompletionNotifications[completer.name].hide();\n\t\t\t\t}\n\t\t\t}\n\n\t\t},\n\t\tautoComplete: autoComplete,\n\t\tgetTrie: function(completer) {\n\t\t\treturn (typeof completer == \"string\" ? tries[completer] : tries[completer.name]);\n\t\t}\n\t}\n};\n\n\n\n\n\n\n\n\n\n/**\n * function which fires after the user selects a completion. this function checks whether we actually need to store this one (if completion is same as current token, don't do anything)\n */\nvar selectHint = function(yasqe, data, completion) {\n\tif (completion.text != yasqe.getTokenAt(yasqe.getCursor()).string) {\n\t\tyasqe.replaceRange(completion.text, data.from, data.to);\n\t}\n};\n\n\n\n\n\n//\n//module.exports = {\n//\tpreprocessPrefixTokenForCompletion: preprocessPrefixTokenForCompletion,\n//\tpostprocessResourceTokenForCompletion: postprocessResourceTokenForCompletion,\n//\tpreprocessResourceTokenForCompletion: preprocessResourceTokenForCompletion,\n//\tshowCompletionNotification: showCompletionNotification,\n//\thideCompletionNotification: hideCompletionNotification,\n//\tautoComplete: autoComplete,\n//\tautocompleteVariables: autocompleteVariables,\n//\tfetchFromPrefixCc: fetchFromPrefixCc,\n//\tfetchFromLov: fetchFromLov,\n////\tstoreBulkCompletions: storeBulkCompletions,\n//\tloadBulkCompletions: loadBulkCompletions,\n//};\n},{\"../../lib/trie.js\":5,\"../main.js\":30,\"../utils.js\":36,\"jquery\":undefined,\"yasgui-utils\":17}],22:[function(require,module,exports){\n'use strict';\nvar $ = (function(){try{return require('jquery')}catch(e){return window.jQuery}})();\nmodule.exports = function(yasqe, name) {\n\treturn {\n\t\tisValidCompletionPosition: function() {\n\t\t\treturn module.exports.isValidCompletionPosition(yasqe);\n\t\t},\n\t\tget: function(token, callback) {\n\t\t\treturn require('./utils').fetchFromLov(yasqe, this, token, callback);\n\t\t},\n\t\tpreProcessToken: function(token) {\n\t\t\treturn module.exports.preProcessToken(yasqe, token)\n\t\t},\n\t\tpostProcessToken: function(token, suggestedString) {\n\t\t\treturn module.exports.postProcessToken(yasqe, token, suggestedString);\n\t\t},\n\t\tasync: true,\n\t\tbulk: false,\n\t\tautoShow: false,\n\t\tpersistent: name,\n\t\tcallbacks: {\n\t\t\tvalidPosition: yasqe.autocompleters.notifications.show,\n\t\t\tinvalidPosition: yasqe.autocompleters.notifications.hide,\n\t\t}\n\t}\n};\n\nmodule.exports.isValidCompletionPosition = function(yasqe) {\n\tvar token = yasqe.getCompleteToken();\n\tif (token.string.indexOf(\"?\") == 0)\n\t\treturn false;\n\tvar cur = yasqe.getCursor();\n\tvar previousToken = yasqe.getPreviousNonWsToken(cur.line, token);\n\tif (previousToken.string == \"a\")\n\t\treturn true;\n\tif (previousToken.string == \"rdf:type\")\n\t\treturn true;\n\tif (previousToken.string == \"rdfs:domain\")\n\t\treturn true;\n\tif (previousToken.string == \"rdfs:range\")\n\t\treturn true;\n\treturn false;\n};\nmodule.exports.preProcessToken = function(yasqe, token) {\n\treturn require('./utils.js').preprocessResourceTokenForCompletion(yasqe, token);\n};\nmodule.exports.postProcessToken = function(yasqe, token, suggestedString) {\n\treturn require('./utils.js').postprocessResourceTokenForCompletion(yasqe, token, suggestedString)\n};\n},{\"./utils\":25,\"./utils.js\":25,\"jquery\":undefined}],23:[function(require,module,exports){\n'use strict';\nvar $ = (function(){try{return require('jquery')}catch(e){return window.jQuery}})();\n//this is a mapping from the class names (generic ones, for compatability with codemirror themes), to what they -actually- represent\nvar tokenTypes = {\n\t\"string-2\": \"prefixed\",\n\t\"atom\": \"var\"\n};\n\nmodule.exports = function(yasqe, completerName) {\n\t//this autocompleter also fires on-change!\n\tyasqe.on(\"change\", function() {\n\t\tmodule.exports.appendPrefixIfNeeded(yasqe, completerName);\n\t});\n\n\n\treturn {\n\t\tisValidCompletionPosition: function() {\n\t\t\treturn module.exports.isValidCompletionPosition(yasqe);\n\t\t},\n\t\tget: function(token, callback) {\n\t\t\t$.get(\"//prefix.cc/popular/all.file.json\", function(data) {\n\t\t\t\tvar prefixArray = [];\n\t\t\t\tfor (var prefix in data) {\n\t\t\t\t\tif (prefix == \"bif\")\n\t\t\t\t\t\tcontinue; // skip this one! see #231\n\t\t\t\t\tvar completeString = prefix + \": <\" + data[prefix] + \">\";\n\t\t\t\t\tprefixArray.push(completeString); // the array we want to store in localstorage\n\t\t\t\t}\n\n\t\t\t\tprefixArray.sort();\n\t\t\t\tcallback(prefixArray);\n\t\t\t});\n\t\t},\n\t\tpreProcessToken: function(token) {\n\t\t\treturn module.exports.preprocessPrefixTokenForCompletion(yasqe, token)\n\t\t},\n\t\tasync: true,\n\t\tbulk: true,\n\t\tautoShow: true,\n\t\tpersistent: completerName,\n\t\tcallbacks: {\n\t\t\tpick: function() {\n\t\t\t\tyasqe.collapsePrefixes(false);\n\t\t\t}\n\t\t}\n\t};\n};\nmodule.exports.isValidCompletionPosition = function(yasqe) {\n\tvar cur = yasqe.getCursor(),\n\t\ttoken = yasqe.getTokenAt(cur);\n\n\t// not at end of line\n\tif (yasqe.getLine(cur.line).length > cur.ch)\n\t\treturn false;\n\n\tif (token.type != \"ws\") {\n\t\t// we want to complete token, e.g. when the prefix starts with an a\n\t\t// (treated as a token in itself..)\n\t\t// but we to avoid including the PREFIX tag. So when we have just\n\t\t// typed a space after the prefix tag, don't get the complete token\n\t\ttoken = yasqe.getCompleteToken();\n\t}\n\n\t// we shouldnt be at the uri part the prefix declaration\n\t// also check whether current token isnt 'a' (that makes codemirror\n\t// thing a namespace is a possiblecurrent\n\tif (!token.string.indexOf(\"a\") == 0 && $.inArray(\"PNAME_NS\", token.state.possibleCurrent) == -1)\n\t\treturn false;\n\n\t// First token of line needs to be PREFIX,\n\t// there should be no trailing text (otherwise, text is wrongly inserted\n\t// in between)\n\tvar previousToken = yasqe.getPreviousNonWsToken(cur.line, token);\n\tif (!previousToken || previousToken.string.toUpperCase() != \"PREFIX\") return false;\n\treturn true;\n};\nmodule.exports.preprocessPrefixTokenForCompletion = function(yasqe, token) {\n\tvar previousToken = yasqe.getPreviousNonWsToken(yasqe.getCursor().line, token);\n\tif (previousToken && previousToken.string && previousToken.string.slice(-1) == \":\") {\n\t\t//combine both tokens! In this case we have the cursor at the end of line \"PREFIX bla: <\".\n\t\t//we want the token to be \"bla: <\", en not \"<\"\n\t\ttoken = {\n\t\t\tstart: previousToken.start,\n\t\t\tend: token.end,\n\t\t\tstring: previousToken.string + \" \" + token.string,\n\t\t\tstate: token.state\n\t\t};\n\t}\n\treturn token;\n};\n/**\n * Check whether typed prefix is declared. If not, automatically add declaration\n * using list from prefix.cc\n * \n * @param yasqe\n */\nmodule.exports.appendPrefixIfNeeded = function(yasqe, completerName) {\n\tif (!yasqe.autocompleters.getTrie(completerName))\n\t\treturn; // no prefixed defined. just stop\n\tif (!yasqe.options.autocompleters || yasqe.options.autocompleters.indexOf(completerName) == -1) return; //this autocompleter is disabled\n\tvar cur = yasqe.getCursor();\n\n\tvar token = yasqe.getTokenAt(cur);\n\tif (tokenTypes[token.type] == \"prefixed\") {\n\t\tvar colonIndex = token.string.indexOf(\":\");\n\t\tif (colonIndex !== -1) {\n\t\t\t// check previous token isnt PREFIX, or a '<'(which would mean we are in a uri)\n\t\t\t//\t\t\tvar firstTokenString = yasqe.getNextNonWsToken(cur.line).string.toUpperCase();\n\t\t\tvar lastNonWsTokenString = yasqe.getPreviousNonWsToken(cur.line, token).string.toUpperCase();\n\t\t\tvar previousToken = yasqe.getTokenAt({\n\t\t\t\tline: cur.line,\n\t\t\t\tch: token.start\n\t\t\t}); // needs to be null (beginning of line), or whitespace\n\t\t\tif (lastNonWsTokenString != \"PREFIX\" && (previousToken.type == \"ws\" || previousToken.type == null)) {\n\t\t\t\t// check whether it isnt defined already (saves us from looping\n\t\t\t\t// through the array)\n\t\t\t\tvar currentPrefix = token.string.substring(0, colonIndex + 1);\n\t\t\t\tvar queryPrefixes = yasqe.getPrefixesFromQuery();\n\t\t\t\tif (queryPrefixes[currentPrefix.slice(0, -1)] == null) {\n\t\t\t\t\t// ok, so it isnt added yet!\n\t\t\t\t\tvar completions = yasqe.autocompleters.getTrie(completerName).autoComplete(currentPrefix);\n\t\t\t\t\tif (completions.length > 0) {\n\t\t\t\t\t\tyasqe.addPrefixes(completions[0]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\n},{\"jquery\":undefined}],24:[function(require,module,exports){\n'use strict';\nvar $ = (function(){try{return require('jquery')}catch(e){return window.jQuery}})();\nmodule.exports = function(yasqe, name) {\n\treturn {\n\t\tisValidCompletionPosition: function() {\n\t\t\treturn module.exports.isValidCompletionPosition(yasqe);\n\t\t},\n\t\tget: function(token, callback) {\n\t\t\treturn require('./utils').fetchFromLov(yasqe, this, token, callback);\n\t\t},\n\t\tpreProcessToken: function(token) {\n\t\t\treturn module.exports.preProcessToken(yasqe, token)\n\t\t},\n\t\tpostProcessToken: function(token, suggestedString) {\n\t\t\treturn module.exports.postProcessToken(yasqe, token, suggestedString);\n\t\t},\n\t\tasync: true,\n\t\tbulk: false,\n\t\tautoShow: false,\n\t\tpersistent: name,\n\t\tcallbacks: {\n\t\t\tvalidPosition: yasqe.autocompleters.notifications.show,\n\t\t\tinvalidPosition: yasqe.autocompleters.notifications.hide,\n\t\t}\n\t}\n};\n\nmodule.exports.isValidCompletionPosition = function(yasqe) {\n\tvar token = yasqe.getCompleteToken();\n\tif (token.string.length == 0)\n\t\treturn false; //we want -something- to autocomplete\n\tif (token.string.indexOf(\"?\") == 0)\n\t\treturn false; // we are typing a var\n\tif ($.inArray(\"a\", token.state.possibleCurrent) >= 0)\n\t\treturn true; // predicate pos\n\tvar cur = yasqe.getCursor();\n\tvar previousToken = yasqe.getPreviousNonWsToken(cur.line, token);\n\tif (previousToken.string == \"rdfs:subPropertyOf\")\n\t\treturn true;\n\n\t// hmm, we would like -better- checks here, e.g. checking whether we are\n\t// in a subject, and whether next item is a rdfs:subpropertyof.\n\t// difficult though... the grammar we use is unreliable when the query\n\t// is invalid (i.e. during typing), and often the predicate is not typed\n\t// yet, when we are busy writing the subject...\n\treturn false;\n};\nmodule.exports.preProcessToken = function(yasqe, token) {\n\treturn require('./utils.js').preprocessResourceTokenForCompletion(yasqe, token);\n};\nmodule.exports.postProcessToken = function(yasqe, token, suggestedString) {\n\treturn require('./utils.js').postprocessResourceTokenForCompletion(yasqe, token, suggestedString)\n};\n},{\"./utils\":25,\"./utils.js\":25,\"jquery\":undefined}],25:[function(require,module,exports){\n'use strict';\nvar $ = (function(){try{return require('jquery')}catch(e){return window.jQuery}})(),\n\tutils = require('./utils.js'),\n\tyutils = require('yasgui-utils');\n/**\n * Where the base class only contains functionality related to -all- completions, this class contains some utils used here and there in our autocompletions\n */\n\n\n\n/**\n * Converts rdf:type to http://.../type and converts to http://...\n * Stores additional info such as the used namespace and prefix in the token object\n */\nvar preprocessResourceTokenForCompletion = function(yasqe, token) {\n\tvar queryPrefixes = yasqe.getPrefixesFromQuery();\n\tif (!token.string.indexOf(\"<\") == 0) {\n\t\ttoken.tokenPrefix = token.string.substring(0, token.string.indexOf(\":\") + 1);\n\n\t\tif (queryPrefixes[token.tokenPrefix.slice(0, -1)] != null) {\n\t\t\ttoken.tokenPrefixUri = queryPrefixes[token.tokenPrefix.slice(0, -1)];\n\t\t}\n\t}\n\n\ttoken.autocompletionString = token.string.trim();\n\tif (!token.string.indexOf(\"<\") == 0 && token.string.indexOf(\":\") > -1) {\n\t\t// hmm, the token is prefixed. We still need the complete uri for autocompletions. generate this!\n\t\tfor (var prefix in queryPrefixes) {\n\t\t\tif (token.string.indexOf(prefix) == 0) {\n\t\t\t\ttoken.autocompletionString = queryPrefixes[prefix];\n\t\t\t\ttoken.autocompletionString += token.string.substring(prefix.length + 1);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (token.autocompletionString.indexOf(\"<\") == 0) token.autocompletionString = token.autocompletionString.substring(1);\n\tif (token.autocompletionString.indexOf(\">\", token.length - 1) !== -1) token.autocompletionString = token.autocompletionString.substring(0, token.autocompletionString.length - 1);\n\treturn token;\n};\n\nvar postprocessResourceTokenForCompletion = function(yasqe, token, suggestedString) {\n\tif (token.tokenPrefix && token.autocompletionString && token.tokenPrefixUri) {\n\t\t// we need to get the suggested string back to prefixed form\n\t\tsuggestedString = token.tokenPrefix + suggestedString.substring(token.tokenPrefixUri.length);\n\t} else {\n\t\t// it is a regular uri. add '<' and '>' to string\n\t\tsuggestedString = \"<\" + suggestedString + \">\";\n\t}\n\treturn suggestedString;\n};\n\nvar fetchFromLov = function(yasqe, completer, token, callback) {\n\tif (!token || !token.string || token.string.trim().length == 0) {\n\t\tyasqe.autocompleters.notifications.getEl(completer)\n\t\t\t.empty()\n\t\t\t.append(\"Nothing to autocomplete yet!\");\n\t\treturn false;\n\t}\n\tvar maxResults = 50;\n\n\tvar args = {\n\t\tq: token.autocompletionString,\n\t\tpage: 1\n\t};\n\tif (completer.name == \"classes\") {\n\t\targs.type = \"class\";\n\t} else {\n\t\targs.type = \"property\";\n\t}\n\tvar results = [];\n\tvar url = \"\";\n\tvar updateUrl = function() {\n\t\turl = \"http://lov.okfn.org/dataset/lov/api/v2/autocomplete/terms?\" + $.param(args);\n\t};\n\tupdateUrl();\n\tvar increasePage = function() {\n\t\targs.page++;\n\t\tupdateUrl();\n\t};\n\tvar doRequests = function() {\n\t\t$.get(\n\t\t\turl,\n\t\t\tfunction(data) {\n\t\t\t\tfor (var i = 0; i < data.results.length; i++) {\n\t\t\t\t\tif ($.isArray(data.results[i].uri) && data.results[i].uri.length > 0) {\n\t\t\t\t\t\tresults.push(data.results[i].uri[0]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresults.push(data.results[i].uri);\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\tif (results.length < data.total_results && results.length < maxResults) {\n\t\t\t\t\tincreasePage();\n\t\t\t\t\tdoRequests();\n\t\t\t\t} else {\n\t\t\t\t\t//if notification bar is there, show feedback, or close\n\t\t\t\t\tif (results.length > 0) {\n\t\t\t\t\t\tyasqe.autocompleters.notifications.hide(yasqe, completer)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tyasqe.autocompleters.notifications.getEl(completer).text(\"0 matches found...\");\n\t\t\t\t\t}\n\t\t\t\t\tcallback(results);\n\t\t\t\t\t// requests done! Don't call this function again\n\t\t\t\t}\n\t\t\t}).fail(function(jqXHR, textStatus, errorThrown) {\n\t\t\tyasqe.autocompleters.notifications.getEl(completer)\n\t\t\t\t.empty()\n\t\t\t\t.append(\"Failed fetching suggestions..\");\n\n\t\t});\n\t};\n\t//if notification bar is there, show a loader\n\tyasqe.autocompleters.notifications.getEl(completer)\n\t\t.empty()\n\t\t.append($(\"Fetchting autocompletions  \"))\n\t\t.append($(yutils.svg.getElement(require('../imgs.js').loader)).addClass(\"notificationLoader\"));\n\tdoRequests();\n};\n\n\n\nmodule.exports = {\n\tfetchFromLov: fetchFromLov,\n\tpreprocessResourceTokenForCompletion: preprocessResourceTokenForCompletion,\n\tpostprocessResourceTokenForCompletion: postprocessResourceTokenForCompletion,\n};\n},{\"../imgs.js\":29,\"./utils.js\":25,\"jquery\":undefined,\"yasgui-utils\":17}],26:[function(require,module,exports){\n'use strict';\nvar $ = (function(){try{return require('jquery')}catch(e){return window.jQuery}})();\nmodule.exports = function(yasqe) {\n\treturn {\n\t\tisValidCompletionPosition: function() {\n\t\t\tvar token = yasqe.getTokenAt(yasqe.getCursor());\n\t\t\tif (token.type != \"ws\") {\n\t\t\t\ttoken = yasqe.getCompleteToken(token);\n\t\t\t\tif (token && token.string.indexOf(\"?\") == 0) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tget: function(token) {\n\t\t\tif (token.trim().length == 0) return []; //nothing to autocomplete\n\t\t\tvar distinctVars = {};\n\t\t\t//do this outside of codemirror. I expect jquery to be faster here (just finding dom elements with classnames)\n\t\t\t$(yasqe.getWrapperElement()).find(\".cm-atom\").each(function() {\n\t\t\t\tvar variable = this.innerHTML;\n\t\t\t\tif (variable.indexOf(\"?\") == 0) {\n\t\t\t\t\t//ok, lets check if the next element in the div is an atom as well. In that case, they belong together (may happen sometimes when query is not syntactically valid)\n\t\t\t\t\tvar nextEl = $(this).next();\n\t\t\t\t\tvar nextElClass = nextEl.attr('class');\n\t\t\t\t\tif (nextElClass && nextEl.attr('class').indexOf(\"cm-atom\") >= 0) {\n\t\t\t\t\t\tvariable += nextEl.text();\n\t\t\t\t\t}\n\n\t\t\t\t\t//skip single questionmarks\n\t\t\t\t\tif (variable.length <= 1) return;\n\n\t\t\t\t\t//it should match our token ofcourse\n\t\t\t\t\tif (variable.indexOf(token) !== 0) return;\n\n\t\t\t\t\t//skip exact matches\n\t\t\t\t\tif (variable == token) return;\n\n\t\t\t\t\t//store in map so we have a unique list \n\t\t\t\t\tdistinctVars[variable] = true;\n\n\n\t\t\t\t}\n\t\t\t});\n\t\t\tvar variables = [];\n\t\t\tfor (var variable in distinctVars) {\n\t\t\t\tvariables.push(variable);\n\t\t\t}\n\t\t\tvariables.sort();\n\t\t\treturn variables;\n\t\t},\n\t\tasync: false,\n\t\tbulk: false,\n\t\tautoShow: true,\n\t}\n};\n},{\"jquery\":undefined}],27:[function(require,module,exports){\nvar sparql = require('./sparql.js'),\n $ = (function(){try{return require('jquery')}catch(e){return window.jQuery}})();\nvar quote = function(string) {\n return \"'\" + string + \"'\";\n}\nmodule.exports = {\n createCurlString : function(yasqe, config) {\n var ajaxConfig = sparql.getAjaxConfig(yasqe, config);\n \n var url = yasqe.options.sparql.endpoint;\n if (yasqe.options.sparql.requestMethod == 'GET') {\n url += '?' + $.param(ajaxConfig.data);\n }\n var cmds = [\n 'curl', url,\n '-X', yasqe.options.sparql.requestMethod\n ];\n if (yasqe.options.sparql.requestMethod == 'POST') {\n cmds.push('--data ' + quote($.param(ajaxConfig.data)));\n }\n for (var header in ajaxConfig.headers) {\n cmds.push('-H ' + quote(header + ': ' + ajaxConfig.headers[header]));\n }\n return cmds.join(' ');\n\n\n\n\n }\n}\n\n},{\"./sparql.js\":33,\"jquery\":undefined}],28:[function(require,module,exports){\n/**\n * The default options of YASQE (check the CodeMirror documentation for even\n * more options, such as disabling line numbers, or changing keyboard shortcut\n * keys). Either change the default options by setting YASQE.defaults, or by\n * passing your own options as second argument to the YASQE constructor\n */\nvar $ = (function(){try{return require('jquery')}catch(e){return window.jQuery}})(),\n\tYASQE = require('./main.js');\nYASQE.defaults = $.extend(true, {}, YASQE.defaults, {\n\tmode: \"sparql11\",\n\t/**\n\t * Query string\n\t */\n\tvalue: \"PREFIX rdf: \\nPREFIX rdfs: \\nSELECT * WHERE {\\n ?sub ?pred ?obj .\\n} \\nLIMIT 10\",\n\thighlightSelectionMatches: {\n\t\tshowToken: /\\w/\n\t},\n\ttabMode: \"indent\",\n\tlineNumbers: true,\n\tlineWrapping: true,\n\tbackdrop: false,\n\tfoldGutter: {\n\t\trangeFinder: new YASQE.fold.combine(YASQE.fold.brace, YASQE.fold.prefix)\n\t},\n\tcollapsePrefixesOnLoad: false,\n\tgutters: [\"gutterErrorBar\", \"CodeMirror-linenumbers\", \"CodeMirror-foldgutter\"],\n\tmatchBrackets: true,\n\tfixedGutter: true,\n\tsyntaxErrorCheck: true,\n\t/**\n\t * Extra shortcut keys. Check the CodeMirror manual on how to add your own\n\t *\n\t * @property extraKeys\n\t * @type object\n\t */\n\textraKeys: {\n\t\t//\t\t\t\t\t\"Ctrl-Space\" : function(yasqe) {\n\t\t//\t\t\t\t\t\tYASQE.autoComplete(yasqe);\n\t\t//\t\t\t\t\t},\n\t\t\"Ctrl-Space\": YASQE.autoComplete,\n\n\t\t\"Cmd-Space\": YASQE.autoComplete,\n\t\t\"Ctrl-D\": YASQE.deleteLine,\n\t\t\"Ctrl-K\": YASQE.deleteLine,\n\t\t\"Cmd-D\": YASQE.deleteLine,\n\t\t\"Cmd-K\": YASQE.deleteLine,\n\t\t\"Ctrl-/\": YASQE.commentLines,\n\t\t\"Cmd-/\": YASQE.commentLines,\n\t\t\"Ctrl-Alt-Down\": YASQE.copyLineDown,\n\t\t\"Ctrl-Alt-Up\": YASQE.copyLineUp,\n\t\t\"Cmd-Alt-Down\": YASQE.copyLineDown,\n\t\t\"Cmd-Alt-Up\": YASQE.copyLineUp,\n\t\t\"Shift-Ctrl-F\": YASQE.doAutoFormat,\n\t\t\"Shift-Cmd-F\": YASQE.doAutoFormat,\n\t\t\"Ctrl-]\": YASQE.indentMore,\n\t\t\"Cmd-]\": YASQE.indentMore,\n\t\t\"Ctrl-[\": YASQE.indentLess,\n\t\t\"Cmd-[\": YASQE.indentLess,\n\t\t\"Ctrl-S\": YASQE.storeQuery,\n\t\t\"Cmd-S\": YASQE.storeQuery,\n\t\t\"Ctrl-Enter\": YASQE.executeQuery,\n\t\t\"Cmd-Enter\": YASQE.executeQuery,\n\t\t\"F11\": function(yasqe) {\n\t\t\tyasqe.setOption(\"fullScreen\", !yasqe.getOption(\"fullScreen\"));\n\t\t},\n\t\t\"Esc\": function(yasqe) {\n\t\t\tif (yasqe.getOption(\"fullScreen\")) yasqe.setOption(\"fullScreen\", false);\n\t\t}\n\t},\n\tcursorHeight: 0.9,\n\n\n\t/**\n\t * Show a button with which users can create a link to this query. Set this value to null to disable this functionality.\n\t * By default, this feature is enabled, and the only the query value is appended to the link.\n\t * ps. This function should return an object which is parseable by jQuery.param (http://api.jquery.com/jQuery.param/)\n\t */\n\tcreateShareLink: YASQE.createShareLink,\n\n\tcreateShortLink: null,\n\n\t/**\n\t * Consume links shared by others, by checking the url for arguments coming from a query link. Defaults by only checking the 'query=' argument in the url\n\t */\n\tconsumeShareLink: YASQE.consumeShareLink,\n\n\n\n\n\t/**\n\t * Change persistency settings for the YASQE query value. Setting the values\n\t * to null, will disable persistancy: nothing is stored between browser\n\t * sessions Setting the values to a string (or a function which returns a\n\t * string), will store the query in localstorage using the specified string.\n\t * By default, the ID is dynamically generated using the closest dom ID, to avoid collissions when using multiple YASQE items on one\n\t * page\n\t *\n\t * @type function|string\n\t */\n\tpersistent: function(yasqe) {\n\t\treturn \"yasqe_\" + $(yasqe.getWrapperElement()).closest('[id]').attr('id') + \"_queryVal\";\n\t},\n\n\n\t/**\n\t * Settings for querying sparql endpoints\n\t */\n\tsparql: {\n\t\tqueryName: function(yasqe) {return yasqe.getQueryMode()},\n\t\tshowQueryButton: false,\n\n\t\t/**f\n\t\t * Endpoint to query\n\t\t *\n\t\t * @property sparql.endpoint\n\t\t * @type String|function\n\t\t */\n\t\tendpoint: \"http://dbpedia.org/sparql\",\n\t\t/**\n\t\t * Request method via which to access SPARQL endpoint\n\t\t *\n\t\t * @property sparql.requestMethod\n\t\t * @type String|function\n\t\t */\n\t\trequestMethod: \"POST\",\n\n\t\t/**\n\t\t * @type String|function\n\t\t */\n\t\tacceptHeaderGraph: \"text/turtle,*/*;q=0.9\",\n\t\t/**\n\t\t * @type String|function\n\t\t */\n\t\tacceptHeaderSelect: \"application/sparql-results+json,*/*;q=0.9\",\n\t\t/**\n\t\t * @type String|function\n\t\t */\n\t\tacceptHeaderUpdate: \"text/plain,*/*;q=0.9\",\n\n\t\t/**\n\t\t * Named graphs to query.\n\t\t */\n\t\tnamedGraphs: [],\n\t\t/**\n\t\t * Default graphs to query.\n\t\t */\n\t\tdefaultGraphs: [],\n\n\t\t/**\n\t\t * Additional request arguments. Add them in the form: {name: \"name\", value: \"value\"}\n\t\t */\n\t\targs: [],\n\n\t\t/**\n\t\t * Additional request headers\n\t\t */\n\t\theaders: {},\n\n\t\tgetQueryForAjax: null,\n\t\t/**\n\t\t * Set of ajax callbacks\n\t\t */\n\t\tcallbacks: {\n\t\t\tbeforeSend: null,\n\t\t\tcomplete: null,\n\t\t\terror: null,\n\t\t\tsuccess: null\n\t\t},\n\t\thandlers: {} //keep here for backwards compatability\n\t},\n});\n\n},{\"./main.js\":30,\"jquery\":undefined}],29:[function(require,module,exports){\n'use strict';\nmodule.exports = {\n\tquery: '\t',\n\tqueryInvalid: 'image/svg+xml',\n\tdownload: '\t',\n\tshare: '',\n\twarning: '',\n\tfullscreen: 'image/svg+xml',\n\tsmallscreen: 'image/svg+xml',\n};\n\n},{}],30:[function(require,module,exports){\n'use strict';\n//make sure any console statements\nwindow.console = window.console || {\n\t\"log\": function() {}\n};\n\n/**\n * Load libraries\n */\nvar $ = (function(){try{return require('jquery')}catch(e){return window.jQuery}})(),\n\tCodeMirror = (function(){try{return require('codemirror')}catch(e){return window.CodeMirror}})(),\n\tutils = require('./utils.js'),\n\tyutils = require('yasgui-utils'),\n\timgs = require('./imgs.js');\n\nrequire(\"../lib/deparam.js\");\nrequire('codemirror/addon/fold/foldcode.js');\nrequire('codemirror/addon/fold/foldgutter.js');\nrequire('codemirror/addon/fold/xml-fold.js');\nrequire('codemirror/addon/fold/brace-fold.js');\nrequire('./prefixFold.js');\nrequire('codemirror/addon/hint/show-hint.js');\nrequire('codemirror/addon/search/searchcursor.js');\nrequire('codemirror/addon/edit/matchbrackets.js');\nrequire('codemirror/addon/runmode/runmode.js');\nrequire('codemirror/addon/display/fullscreen.js');\nrequire('../lib/grammar/tokenizer.js');\n\n\n\n/**\n * Main YASQE constructor. Pass a DOM element as argument to append the editor to, and (optionally) pass along config settings (see the YASQE.defaults object below, as well as the regular CodeMirror documentation, for more information on configurability)\n *\n * @constructor\n * @param {DOM-Element} parent element to append editor to.\n * @param {object} settings\n * @class YASQE\n * @return {doc} YASQE document\n */\nvar root = module.exports = function(parent, config) {\n\tvar rootEl = $(\"
      \", {\n\t\tclass: 'yasqe'\n\t}).appendTo($(parent));\n\tconfig = extendConfig(config);\n\tvar yasqe = extendCmInstance(CodeMirror(rootEl[0], config));\n\tpostProcessCmElement(yasqe);\n\treturn yasqe;\n};\n\n/**\n * Extend config object, which we will pass on to the CM constructor later on.\n * Need this, to make sure our own 'onBlur' etc events do not get overwritten by\n * people who add their own onblur events to the config Additionally, need this\n * to include the CM defaults ourselves. CodeMirror has a method for including\n * defaults, but we can't rely on that one: it assumes flat config object, where\n * we have nested objects (e.g. the persistency option)\n *\n * @private\n */\nvar extendConfig = function(config) {\n\tvar extendedConfig = $.extend(true, {}, root.defaults, config);\n\n\t// I know, codemirror deals with default options as well.\n\t//However, it does not do this recursively (i.e. the persistency option)\n\n\n\treturn extendedConfig;\n};\n/**\n * Add extra functions to the CM document (i.e. the codemirror instantiated\n * object)\n *\n * @private\n */\nvar extendCmInstance = function(yasqe) {\n\t//instantiate autocompleters\n\tyasqe.autocompleters = require('./autocompleters/autocompleterBase.js')(root, yasqe);\n\tif (yasqe.options.autocompleters) {\n\t\tyasqe.options.autocompleters.forEach(function(name) {\n\t\t\tif (root.Autocompleters[name]) yasqe.autocompleters.init(name, root.Autocompleters[name]);\n\t\t})\n\t}\n\tyasqe.lastQueryDuration = null;\n\tyasqe.getCompleteToken = function(token, cur) {\n\t\treturn require('./tokenUtils.js').getCompleteToken(yasqe, token, cur);\n\t};\n\tyasqe.getPreviousNonWsToken = function(line, token) {\n\t\treturn require('./tokenUtils.js').getPreviousNonWsToken(yasqe, line, token);\n\t};\n\tyasqe.getNextNonWsToken = function(lineNumber, charNumber) {\n\t\treturn require('./tokenUtils.js').getNextNonWsToken(yasqe, lineNumber, charNumber);\n\t};\n\tyasqe.collapsePrefixes = function(collapse) {\n\t\tif (collapse === undefined) collapse = true;\n\t\tyasqe.foldCode(require('./prefixFold.js').findFirstPrefixLine(yasqe), root.fold.prefix, (collapse ? \"fold\" : \"unfold\"));\n\t};\n\tvar backdrop = null;\n\tvar animateSpeed = null;\n\tyasqe.setBackdrop = function(show) {\n\n\n\t\tif (yasqe.options.backdrop || yasqe.options.backdrop === 0 || yasqe.options.backdrop === '0') {\n\t\t\tif (animateSpeed === null) {\n\t\t\t\tanimateSpeed = +yasqe.options.backdrop;\n\t\t\t\tif (animateSpeed === 1) {\n\t\t\t\t\t//ah, yasqe.options.backdrop was 'true'. Set this to default animate speed 400\n\t\t\t\t\tanimateSpeed = 400;\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\tif (!backdrop) {\n\t\t\t\tbackdrop = $('
      ', {\n\t\t\t\t\t\tclass: 'backdrop'\n\t\t\t\t\t})\n\t\t\t\t\t.click(function() {\n\t\t\t\t\t\t$(this).hide();\n\t\t\t\t\t})\n\t\t\t\t\t.insertAfter($(yasqe.getWrapperElement()));\n\t\t\t}\n\t\t\tif (show) {\n\t\t\t\tbackdrop.show(animateSpeed);\n\t\t\t} else {\n\t\t\t\tbackdrop.hide(animateSpeed);\n\t\t\t}\n\t\t}\n\t};\n\t/**\n\t * Execute query. Pass a callback function, or a configuration object (see\n\t * default settings below for possible values) I.e., you can change the\n\t * query configuration by either changing the default settings, changing the\n\t * settings of this document, or by passing query settings to this function\n\t *\n\t * @method doc.query\n\t * @param function|object\n\t */\n\tyasqe.query = function(callbackOrConfig) {\n\t\troot.executeQuery(yasqe, callbackOrConfig);\n\t};\n\n\tyasqe.getUrlArguments = function(config) {\n\t\treturn root.getUrlArguments(yasqe, config);\n\t};\n\n\t/**\n\t * Fetch defined prefixes from query string\n\t *\n\t * @method doc.getPrefixesFromQuery\n\t * @return object\n\t */\n\tyasqe.getPrefixesFromQuery = function() {\n\t\treturn require('./prefixUtils.js').getPrefixesFromQuery(yasqe);\n\t};\n\n\tyasqe.addPrefixes = function(prefixes) {\n\t\treturn require('./prefixUtils.js').addPrefixes(yasqe, prefixes);\n\t};\n\tyasqe.removePrefixes = function(prefixes) {\n\t\treturn require('./prefixUtils.js').removePrefixes(yasqe, prefixes);\n\t};\n\n\tyasqe.getValueWithoutComments = function() {\n\t\tvar cleanedQuery = \"\";\n\t\troot.runMode(yasqe.getValue(), \"sparql11\", function(stringVal, className) {\n\t\t\tif (className != \"comment\") {\n\t\t\t\tcleanedQuery += stringVal;\n\t\t\t}\n\t\t});\n\t\treturn cleanedQuery;\n\t};\n\t/**\n\t * Fetch the query type (e.g., SELECT||DESCRIBE||INSERT||DELETE||ASK||CONSTRUCT)\n\t *\n\t * @method doc.getQueryType\n\t * @return string\n\t *\n\t */\n\tyasqe.getQueryType = function() {\n\t\treturn yasqe.queryType;\n\t};\n\t/**\n\t * Fetch the query mode: 'query' or 'update'\n\t *\n\t * @method doc.getQueryMode\n\t * @return string\n\t *\n\t */\n\tyasqe.getQueryMode = function() {\n\t\tvar type = yasqe.getQueryType();\n\t\tif (type == \"INSERT\" || type == \"DELETE\" || type == \"LOAD\" || type == \"CLEAR\" || type == \"CREATE\" || type == \"DROP\" || type == \"COPY\" || type == \"MOVE\" || type == \"ADD\") {\n\t\t\treturn \"update\";\n\t\t} else {\n\t\t\treturn \"query\";\n\t\t}\n\n\t};\n\n\tyasqe.setCheckSyntaxErrors = function(isEnabled) {\n\t\tyasqe.options.syntaxErrorCheck = isEnabled;\n\t\tcheckSyntax(yasqe);\n\t};\n\n\tyasqe.enableCompleter = function(name) {\n\t\taddCompleterToSettings(yasqe.options, name);\n\t\tif (root.Autocompleters[name]) yasqe.autocompleters.init(name, root.Autocompleters[name]);\n\t};\n\tyasqe.disableCompleter = function(name) {\n\t\tremoveCompleterFromSettings(yasqe.options, name);\n\t};\n\treturn yasqe;\n};\n\nvar addCompleterToSettings = function(settings, name) {\n\tif (!settings.autocompleters) settings.autocompleters = [];\n\tsettings.autocompleters.push(name);\n};\nvar removeCompleterFromSettings = function(settings, name) {\n\tif (typeof settings.autocompleters == \"object\") {\n\t\tvar index = $.inArray(name, settings.autocompleters);\n\t\tif (index >= 0) {\n\t\t\tsettings.autocompleters.splice(index, 1);\n\t\t\tremoveCompleterFromSettings(settings, name); //just in case. suppose 1 completer is listed twice\n\t\t}\n\t}\n};\nvar postProcessCmElement = function(yasqe) {\n\t/**\n\t * Set doc value\n\t */\n\tvar storageId = utils.getPersistencyId(yasqe, yasqe.options.persistent);\n\tif (storageId) {\n\t\tvar valueFromStorage = yutils.storage.get(storageId);\n\t\tif (valueFromStorage)\n\t\t\tyasqe.setValue(valueFromStorage);\n\t}\n\n\troot.drawButtons(yasqe);\n\n\t/**\n\t * Add event handlers\n\t */\n\tyasqe.on('blur', function(yasqe, eventInfo) {\n\t\troot.storeQuery(yasqe);\n\t});\n\tyasqe.on('change', function(yasqe, eventInfo) {\n\t\tcheckSyntax(yasqe);\n\t\troot.updateQueryButton(yasqe);\n\t\troot.positionButtons(yasqe);\n\t});\n\tyasqe.on('changes', function() {\n\t\t//e.g. on paste\n\t\tcheckSyntax(yasqe);\n\t\troot.updateQueryButton(yasqe);\n\t\troot.positionButtons(yasqe);\n\t});\n\n\tyasqe.on('cursorActivity', function(yasqe, eventInfo) {\n\t\tupdateButtonsTransparency(yasqe);\n\t});\n\tyasqe.prevQueryValid = false;\n\tcheckSyntax(yasqe); // on first load, check as well (our stored or default query might be incorrect)\n\troot.positionButtons(yasqe);\n\n\t$(yasqe.getWrapperElement()).on('mouseenter', '.cm-atom', function() {\n\t\tvar matchText = $(this).text();\n\t\t$(yasqe.getWrapperElement()).find('.cm-atom').filter(function() {\n\t\t\treturn $(this).text() === matchText;\n\t\t}).addClass('matchingVar');\n\t}).on('mouseleave', '.cm-atom', function() {\n\t\t$(yasqe.getWrapperElement()).find('.matchingVar').removeClass('matchingVar');\n\t});\n\t/**\n\t * check url args and modify yasqe settings if needed\n\t */\n\tif (yasqe.options.consumeShareLink) {\n\t\tyasqe.options.consumeShareLink(yasqe, getUrlParams());\n\t\t//and: add a hash listener!\n\t\twindow.addEventListener(\"hashchange\", function() {\n\t\t\tyasqe.options.consumeShareLink(yasqe, getUrlParams());\n\t\t});\n\t}\n\tif (yasqe.options.collapsePrefixesOnLoad) yasqe.collapsePrefixes(true);\n};\n\n/**\n * get url params. first try fetching using hash. If it fails, try the regular query parameters (for backwards compatability)\n */\nvar getUrlParams = function() {\n\t//first try hash\n\tvar urlParams = null;\n\tif (window.location.hash.length > 1) {\n\t\t//firefox does some decoding if we're using window.location.hash (e.g. the + sign in contentType settings)\n\t\t//Don't want this. So simply get the hash string ourselves\n\t\turlParams = $.deparam(location.href.split(\"#\")[1])\n\t}\n\tif ((!urlParams || !('query' in urlParams)) && window.location.search.length > 1) {\n\t\t//ok, then just try regular url params\n\t\turlParams = $.deparam(window.location.search.substring(1));\n\t}\n\treturn urlParams;\n};\n\n\n\n/**\n * Update transparency of buttons. Increase transparency when cursor is below buttons\n */\n\nvar updateButtonsTransparency = function(yasqe) {\n\tyasqe.cursor = $(\".CodeMirror-cursor\");\n\tif (yasqe.buttons && yasqe.buttons.is(\":visible\") && yasqe.cursor.length > 0) {\n\t\tif (utils.elementsOverlap(yasqe.cursor, yasqe.buttons)) {\n\t\t\tyasqe.buttons.find(\"svg\").attr(\"opacity\", \"0.2\");\n\t\t} else {\n\t\t\tyasqe.buttons.find(\"svg\").attr(\"opacity\", \"1.0\");\n\t\t}\n\t}\n};\n\n\n\n\n\n\n\n\n\nvar clearError = null;\nvar checkSyntax = function(yasqe, deepcheck) {\n\n\tyasqe.queryValid = true;\n\n\tyasqe.clearGutter(\"gutterErrorBar\");\n\n\tvar state = null;\n\tfor (var l = 0; l < yasqe.lineCount(); ++l) {\n\t\tvar precise = false;\n\t\tif (!yasqe.prevQueryValid) {\n\t\t\t// we don't want cached information in this case, otherwise the\n\t\t\t// previous error sign might still show up,\n\t\t\t// even though the syntax error might be gone already\n\t\t\tprecise = true;\n\t\t}\n\n\t\tvar token = yasqe.getTokenAt({\n\t\t\tline: l,\n\t\t\tch: yasqe.getLine(l).length\n\t\t}, precise);\n\t\tvar state = token.state;\n\t\tyasqe.queryType = state.queryType;\n\t\tif (state.OK == false) {\n\t\t\tif (!yasqe.options.syntaxErrorCheck) {\n\t\t\t\t//the library we use already marks everything as being an error. Overwrite this class attribute.\n\t\t\t\t$(yasqe.getWrapperElement).find(\".sp-error\").css(\"color\", \"black\");\n\t\t\t\t//we don't want to gutter error, so return\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar warningEl = yutils.svg.getElement(imgs.warning);\n\t\t\tif (state.possibleCurrent && state.possibleCurrent.length > 0) {\n\t\t\t\t//\t\t\t\twarningEl.style.zIndex = \"99999999\";\n\t\t\t\trequire('./tooltip')(yasqe, warningEl, function() {\n\t\t\t\t\tvar expectedEncoded = [];\n\t\t\t\t\tstate.possibleCurrent.forEach(function(expected) {\n\t\t\t\t\t\texpectedEncoded.push(\"\" + $(\"
      \").text(expected).html() + \"\");\n\t\t\t\t\t});\n\t\t\t\t\treturn \"This line is invalid. Expected: \" + expectedEncoded.join(\", \");\n\t\t\t\t});\n\t\t\t}\n\t\t\twarningEl.style.marginTop = \"2px\";\n\t\t\twarningEl.style.marginLeft = \"2px\";\n\t\t\twarningEl.className = 'parseErrorIcon';\n\t\t\tyasqe.setGutterMarker(l, \"gutterErrorBar\", warningEl);\n\n\t\t\tyasqe.queryValid = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\tyasqe.prevQueryValid = yasqe.queryValid;\n\tif (deepcheck) {\n\t\tif (state != null && state.stack != undefined) {\n\t\t\tvar stack = state.stack,\n\t\t\t\tlen = state.stack.length;\n\t\t\t// Because incremental parser doesn't receive end-of-input\n\t\t\t// it can't clear stack, so we have to check that whatever\n\t\t\t// is left on the stack is nillable\n\t\t\tif (len > 1)\n\t\t\t\tyasqe.queryValid = false;\n\t\t\telse if (len == 1) {\n\t\t\t\tif (stack[0] != \"solutionModifier\" && stack[0] != \"?limitOffsetClauses\" && stack[0] != \"?offsetClause\")\n\t\t\t\t\tyasqe.queryValid = false;\n\t\t\t}\n\t\t}\n\t}\n};\n/**\n * Static Utils\n */\n// first take all CodeMirror references and store them in the YASQE object\n$.extend(root, CodeMirror);\n\n\n//add registrar for autocompleters\nroot.Autocompleters = {};\nroot.registerAutocompleter = function(name, constructor) {\n\troot.Autocompleters[name] = constructor;\n\taddCompleterToSettings(root.defaults, name);\n}\n\nroot.autoComplete = function(yasqe) {\n\t//this function gets called when pressing the keyboard shortcut. I.e., autoShow = false\n\tyasqe.autocompleters.autoComplete(false);\n};\n//include the autocompleters we provide out-of-the-box\nroot.registerAutocompleter(\"prefixes\", require(\"./autocompleters/prefixes.js\"));\nroot.registerAutocompleter(\"properties\", require(\"./autocompleters/properties.js\"));\nroot.registerAutocompleter(\"classes\", require(\"./autocompleters/classes.js\"));\nroot.registerAutocompleter(\"variables\", require(\"./autocompleters/variables.js\"));\n\n\nroot.positionButtons = function(yasqe) {\n\tvar scrollBar = $(yasqe.getWrapperElement()).find(\".CodeMirror-vscrollbar\");\n\tvar offset = 0;\n\tif (scrollBar.is(\":visible\")) {\n\t\toffset = scrollBar.outerWidth();\n\t}\n\tif (yasqe.buttons.is(\":visible\")) yasqe.buttons.css(\"right\", offset + 4);\n};\n\n/**\n * Create a share link\n *\n * @method YASQE.createShareLink\n * @param {doc} YASQE document\n * @default {query: doc.getValue()}\n * @return object\n */\nroot.createShareLink = function(yasqe) {\n\t//extend existing link, so first fetch current arguments\n\tvar urlParams = {};\n\tif (window.location.hash.length > 1) urlParams = $.deparam(window.location.hash.substring(1));\n\turlParams['query'] = yasqe.getValue();\n\treturn urlParams;\n};\nroot.getAsCurl = function(yasqe, ajaxConfig) {\n\tvar curl = require('./curl.js');\n\treturn curl.createCurlString(yasqe, ajaxConfig);\n};\n/**\n * Consume the share link, by parsing the document URL for possible yasqe arguments, and setting the appropriate values in the YASQE doc\n *\n * @method YASQE.consumeShareLink\n * @param {doc} YASQE document\n */\nroot.consumeShareLink = function(yasqe, urlParams) {\n\tif (urlParams && urlParams.query) {\n\t\tyasqe.setValue(urlParams.query);\n\t}\n};\nroot.drawButtons = function(yasqe) {\n\tyasqe.buttons = $(\"
      \").appendTo($(yasqe.getWrapperElement()));\n\n\t/**\n\t * draw share link button\n\t */\n\tif (yasqe.options.createShareLink) {\n\n\t\tvar svgShare = $(yutils.svg.getElement(imgs.share));\n\t\tsvgShare.click(function(event) {\n\t\t\t\tevent.stopPropagation();\n\t\t\t\tvar popup = $(\"
      \").appendTo(yasqe.buttons);\n\t\t\t\t$('html').click(function() {\n\t\t\t\t\tif (popup) popup.remove();\n\t\t\t\t});\n\n\t\t\t\tpopup.click(function(event) {\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t});\n\t\t\t\tvar $input = $(\"\").val(location.protocol + '//' + location.host + location.pathname + location.search + \"#\" + $.param(yasqe.options.createShareLink(yasqe)));\n\n\t\t\t\t$input.focus(function() {\n\t\t\t\t\tvar $this = $(this);\n\t\t\t\t\t$this.select();\n\n\t\t\t\t\t// Work around Chrome's little problem\n\t\t\t\t\t$this.mouseup(function() {\n\t\t\t\t\t\t// Prevent further mouseup intervention\n\t\t\t\t\t\t$this.unbind(\"mouseup\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tpopup.empty().append($('
      ', {class:'inputWrapper'}).append($input));\n\t\t\t\tif (yasqe.options.createShortLink) {\n\t\t\t\t\tpopup.addClass('enableShort');\n\t\t\t\t\t$('')\n\t\t\t\t\t\t.addClass('yasqe_btn yasqe_btn-sm yasqe_btn-primary')\n\t\t\t\t\t\t.click(function() {\n\t\t\t\t\t\t\t$(this).parent().find('button').attr('disabled', 'disabled');\n\t\t\t\t\t\t\tyasqe.options.createShortLink($input.val(), function(errString, shortLink) {\n\t\t\t\t\t\t\t\tif (errString) {\n\t\t\t\t\t\t\t\t\t$input.remove();\n\t\t\t\t\t\t\t\t\tpopup.find('.inputWrapper').append($('', {class:\"shortlinkErr\"}).text(errString));\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$input.val(shortLink).focus();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}).appendTo(popup);\n\t\t\t\t}\n\t\t\t\t$('')\n\t\t\t\t\t.addClass('yasqe_btn yasqe_btn-sm yasqe_btn-primary')\n\t\t\t\t\t.click(function() {\n\n\t\t\t\t\t\t$(this).parent().find('button').attr('disabled', 'disabled');\n\t\t\t\t\t\t$input.val(root.getAsCurl(yasqe)).focus();\n\t\t\t\t\t}).appendTo(popup);\n\t\t\t\tvar positions = svgShare.position();\n\t\t\t\tpopup.css(\"top\", (positions.top + svgShare.outerHeight() + parseInt(popup.css('padding-top')) ) + \"px\").css(\"left\", ((positions.left + svgShare.outerWidth()) - popup.outerWidth()) + \"px\");\n\t\t\t\t$input.focus();\n\t\t\t})\n\t\t\t.addClass(\"yasqe_share\")\n\t\t\t.attr(\"title\", \"Share your query\")\n\t\t\t.appendTo(yasqe.buttons);\n\n\t}\n\n\n\t/**\n\t * draw fullscreen button\n\t */\n\n\tvar toggleFullscreen = $('
      ', {\n\t\t\tclass: 'fullscreenToggleBtns'\n\t\t})\n\t\t.append($(yutils.svg.getElement(imgs.fullscreen))\n\t\t\t.addClass(\"yasqe_fullscreenBtn\")\n\t\t\t.attr(\"title\", \"Set editor full screen\")\n\t\t\t.click(function() {\n\t\t\t\tyasqe.setOption(\"fullScreen\", true);\n\t\t\t}))\n\t\t.append($(yutils.svg.getElement(imgs.smallscreen))\n\t\t\t.addClass(\"yasqe_smallscreenBtn\")\n\t\t\t.attr(\"title\", \"Set editor to normale size\")\n\t\t\t.click(function() {\n\t\t\t\tyasqe.setOption(\"fullScreen\", false);\n\t\t\t}))\n\tyasqe.buttons.append(toggleFullscreen);\n\n\n\tif (yasqe.options.sparql.showQueryButton) {\n\t\t$(\"
      \", {\n\t\t\t\tclass: 'yasqe_queryButton'\n\t\t\t})\n\t\t\t.click(function() {\n\t\t\t\tif ($(this).hasClass(\"query_busy\")) {\n\t\t\t\t\tif (yasqe.xhr) yasqe.xhr.abort();\n\t\t\t\t\troot.updateQueryButton(yasqe);\n\t\t\t\t} else {\n\t\t\t\t\tyasqe.query();\n\t\t\t\t}\n\t\t\t})\n\t\t\t.appendTo(yasqe.buttons);\n\t\troot.updateQueryButton(yasqe);\n\t}\n\n};\n\n\nvar queryButtonIds = {\n\t\"busy\": \"loader\",\n\t\"valid\": \"query\",\n\t\"error\": \"queryInvalid\"\n};\n\n/**\n * Update the query button depending on current query status. If no query status is passed via the parameter, it auto-detects the current query status\n *\n * @param {doc} YASQE document\n * @param status {string|null, \"busy\"|\"valid\"|\"error\"}\n */\nroot.updateQueryButton = function(yasqe, status) {\n\tvar queryButton = $(yasqe.getWrapperElement()).find(\".yasqe_queryButton\");\n\tif (queryButton.length == 0) return; //no query button drawn\n\n\t//detect status\n\tif (!status) {\n\t\tstatus = \"valid\";\n\t\tif (yasqe.queryValid === false) status = \"error\";\n\t}\n\n\tif (status != yasqe.queryStatus) {\n\t\tqueryButton\n\t\t\t.empty()\n\t\t\t.removeClass(function(index, classNames) {\n\t\t\t\treturn classNames.split(\" \").filter(function(c) {\n\t\t\t\t\t//remove classname from previous status\n\t\t\t\t\treturn c.indexOf(\"query_\") == 0;\n\t\t\t\t}).join(\" \");\n\t\t\t});\n\n\t\tif (status == \"busy\") {\n\t\t\tqueryButton.append($('
      ', {\n\t\t\t\tclass: 'loader',\n\t\t\t}));\n\t\t\tyasqe.queryStatus = status;\n\t\t} else if (status == \"valid\" || status == \"error\") {\n\t\t\tqueryButton.addClass(\"query_\" + status);\n\t\t\tyutils.svg.draw(queryButton, imgs[queryButtonIds[status]]);\n\t\t\tyasqe.queryStatus = status;\n\t\t}\n\t}\n};\n/**\n * Initialize YASQE from an existing text area (see http://codemirror.net/doc/manual.html#fromTextArea for more info)\n *\n * @method YASQE.fromTextArea\n * @param textArea {DOM element}\n * @param config {object}\n * @returns {doc} YASQE document\n */\nroot.fromTextArea = function(textAreaEl, config) {\n\tconfig = extendConfig(config);\n\t//add yasqe div as parent (needed for styles to be manageable and scoped).\n\t//In this case, I -also- put it as parent el of the text area. This is wrapped in a div now\n\tvar rootEl = $(\"
      \", {\n\t\tclass: 'yasqe'\n\t}).insertBefore($(textAreaEl)).append($(textAreaEl));\n\tvar yasqe = extendCmInstance(CodeMirror.fromTextArea(textAreaEl, config));\n\tpostProcessCmElement(yasqe);\n\treturn yasqe;\n};\n\n\nroot.storeQuery = function(yasqe) {\n\tvar storageId = utils.getPersistencyId(yasqe, yasqe.options.persistent);\n\tif (storageId) {\n\t\tyutils.storage.set(storageId, yasqe.getValue(), \"month\");\n\t}\n};\nroot.commentLines = function(yasqe) {\n\tvar startLine = yasqe.getCursor(true).line;\n\tvar endLine = yasqe.getCursor(false).line;\n\tvar min = Math.min(startLine, endLine);\n\tvar max = Math.max(startLine, endLine);\n\n\t// if all lines start with #, remove this char. Otherwise add this char\n\tvar linesAreCommented = true;\n\tfor (var i = min; i <= max; i++) {\n\t\tvar line = yasqe.getLine(i);\n\t\tif (line.length == 0 || line.substring(0, 1) != \"#\") {\n\t\t\tlinesAreCommented = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\tfor (var i = min; i <= max; i++) {\n\t\tif (linesAreCommented) {\n\t\t\t// lines are commented, so remove comments\n\t\t\tyasqe.replaceRange(\"\", {\n\t\t\t\tline: i,\n\t\t\t\tch: 0\n\t\t\t}, {\n\t\t\t\tline: i,\n\t\t\t\tch: 1\n\t\t\t});\n\t\t} else {\n\t\t\t// Not all lines are commented, so add comments\n\t\t\tyasqe.replaceRange(\"#\", {\n\t\t\t\tline: i,\n\t\t\t\tch: 0\n\t\t\t});\n\t\t}\n\n\t}\n};\n\nroot.copyLineUp = function(yasqe) {\n\tvar cursor = yasqe.getCursor();\n\tvar lineCount = yasqe.lineCount();\n\t// First create new empty line at end of text\n\tyasqe.replaceRange(\"\\n\", {\n\t\tline: lineCount - 1,\n\t\tch: yasqe.getLine(lineCount - 1).length\n\t});\n\t// Copy all lines to their next line\n\tfor (var i = lineCount; i > cursor.line; i--) {\n\t\tvar line = yasqe.getLine(i - 1);\n\t\tyasqe.replaceRange(line, {\n\t\t\tline: i,\n\t\t\tch: 0\n\t\t}, {\n\t\t\tline: i,\n\t\t\tch: yasqe.getLine(i).length\n\t\t});\n\t}\n};\nroot.copyLineDown = function(yasqe) {\n\troot.copyLineUp(yasqe);\n\t// Make sure cursor goes one down (we are copying downwards)\n\tvar cursor = yasqe.getCursor();\n\tcursor.line++;\n\tyasqe.setCursor(cursor);\n};\nroot.doAutoFormat = function(yasqe) {\n\tif (yasqe.somethingSelected()) {\n\t\tvar to = {\n\t\t\tline: yasqe.getCursor(false).line,\n\t\t\tch: yasqe.getSelection().length\n\t\t};\n\t\tautoFormatRange(yasqe, yasqe.getCursor(true), to);\n\t} else {\n\t\tvar totalLines = yasqe.lineCount();\n\t\tvar totalChars = yasqe.getTextArea().value.length;\n\t\tautoFormatRange(yasqe, {\n\t\t\tline: 0,\n\t\t\tch: 0\n\t\t}, {\n\t\t\tline: totalLines,\n\t\t\tch: totalChars\n\t\t});\n\t}\n\n};\n\n\nvar autoFormatRange = function(yasqe, from, to) {\n\tvar absStart = yasqe.indexFromPos(from);\n\tvar absEnd = yasqe.indexFromPos(to);\n\t// Insert additional line breaks where necessary according to the\n\t// mode's syntax\n\tvar res = autoFormatLineBreaks(yasqe.getValue(), absStart, absEnd);\n\n\t// Replace and auto-indent the range\n\tyasqe.operation(function() {\n\t\tyasqe.replaceRange(res, from, to);\n\t\tvar startLine = yasqe.posFromIndex(absStart).line;\n\t\tvar endLine = yasqe.posFromIndex(absStart + res.length).line;\n\t\tfor (var i = startLine; i <= endLine; i++) {\n\t\t\tyasqe.indentLine(i, \"smart\");\n\t\t}\n\t});\n};\n\nvar autoFormatLineBreaks = function(text, start, end) {\n\ttext = text.substring(start, end);\n\tvar breakAfterArray = [\n\t\t[\"keyword\", \"ws\", \"prefixed\", \"ws\", \"uri\"], // i.e. prefix declaration\n\t\t[\"keyword\", \"ws\", \"uri\"] // i.e. base\n\t];\n\tvar breakAfterCharacters = [\"{\", \".\", \";\"];\n\tvar breakBeforeCharacters = [\"}\"];\n\tvar getBreakType = function(stringVal, type) {\n\t\tfor (var i = 0; i < breakAfterArray.length; i++) {\n\t\t\tif (stackTrace.valueOf().toString() == breakAfterArray[i].valueOf()\n\t\t\t\t.toString()) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\tfor (var i = 0; i < breakAfterCharacters.length; i++) {\n\t\t\tif (stringVal == breakAfterCharacters[i]) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\tfor (var i = 0; i < breakBeforeCharacters.length; i++) {\n\t\t\t// don't want to issue 'breakbefore' AND 'breakafter', so check\n\t\t\t// current line\n\t\t\tif ($.trim(currentLine) != '' && stringVal == breakBeforeCharacters[i]) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t};\n\tvar formattedQuery = \"\";\n\tvar currentLine = \"\";\n\tvar stackTrace = [];\n\tCodeMirror.runMode(text, \"sparql11\", function(stringVal, type) {\n\t\tstackTrace.push(type);\n\t\tvar breakType = getBreakType(stringVal, type);\n\t\tif (breakType != 0) {\n\t\t\tif (breakType == 1) {\n\t\t\t\tformattedQuery += stringVal + \"\\n\";\n\t\t\t\tcurrentLine = \"\";\n\t\t\t} else { // (-1)\n\t\t\t\tformattedQuery += \"\\n\" + stringVal;\n\t\t\t\tcurrentLine = stringVal;\n\t\t\t}\n\t\t\tstackTrace = [];\n\t\t} else {\n\t\t\tcurrentLine += stringVal;\n\t\t\tformattedQuery += stringVal;\n\t\t}\n\t\tif (stackTrace.length == 1 && stackTrace[0] == \"sp-ws\")\n\t\t\tstackTrace = [];\n\t});\n\treturn $.trim(formattedQuery.replace(/\\n\\s*\\n/g, '\\n'));\n};\n\nrequire('./sparql.js'),\n\trequire('./defaults.js');\nroot.$ = $;\nroot.version = {\n\t\"CodeMirror\": CodeMirror.version,\n\t\"YASQE\": require(\"../package.json\").version,\n\t\"jquery\": $.fn.jquery,\n\t\"yasgui-utils\": yutils.version\n};\n\n},{\"../lib/deparam.js\":2,\"../lib/grammar/tokenizer.js\":4,\"../package.json\":20,\"./autocompleters/autocompleterBase.js\":21,\"./autocompleters/classes.js\":22,\"./autocompleters/prefixes.js\":23,\"./autocompleters/properties.js\":24,\"./autocompleters/variables.js\":26,\"./curl.js\":27,\"./defaults.js\":28,\"./imgs.js\":29,\"./prefixFold.js\":31,\"./prefixUtils.js\":32,\"./sparql.js\":33,\"./tokenUtils.js\":34,\"./tooltip\":35,\"./utils.js\":36,\"codemirror\":undefined,\"codemirror/addon/display/fullscreen.js\":6,\"codemirror/addon/edit/matchbrackets.js\":7,\"codemirror/addon/fold/brace-fold.js\":8,\"codemirror/addon/fold/foldcode.js\":9,\"codemirror/addon/fold/foldgutter.js\":10,\"codemirror/addon/fold/xml-fold.js\":11,\"codemirror/addon/hint/show-hint.js\":12,\"codemirror/addon/runmode/runmode.js\":13,\"codemirror/addon/search/searchcursor.js\":14,\"jquery\":undefined,\"yasgui-utils\":17}],31:[function(require,module,exports){\nvar CodeMirror = (function(){try{return require('codemirror')}catch(e){return window.CodeMirror}})(),\n\ttokenUtils = require('./tokenUtils.js');\n\n\"use strict\";\nvar lookFor = \"PREFIX\";\nmodule.exports = {\n\tfindFirstPrefixLine: function(cm) {\n\t\tvar lastLine = cm.lastLine();\n\t\tfor (var i = 0; i <= lastLine; ++i) {\n\t\t\tif (findFirstPrefix(cm, i) >= 0) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction findFirstPrefix(cm, line, ch, lineText) {\n\tif (!ch) ch = 0;\n\tif (!lineText) lineText = cm.getLine(line);\n\tlineText = lineText.toUpperCase();\n\tfor (var at = ch, pass = 0;;) {\n\t\tvar found = lineText.indexOf(lookFor, at);\n\t\tif (found == -1) {\n\t\t\tif (pass == 1)\n\t\t\t\tbreak;\n\t\t\tpass = 1;\n\t\t\tat = lineText.length;\n\t\t\tcontinue;\n\t\t}\n\t\tif (pass == 1 && found < ch)\n\t\t\tbreak;\n\t\ttokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));\n\t\tif (!/^(comment|string)/.test(tokenType))\n\t\t\treturn found + 1;\n\t\tat = found - 1;\n\t}\n}\n\nCodeMirror.registerHelper(\"fold\", \"prefix\", function(cm, start) {\n\tvar line = start.line,\n\t\tlineText = cm.getLine(line);\n\n\tvar startCh, tokenType;\n\n\tfunction hasPreviousPrefix() {\n\t\tvar hasPreviousPrefix = false;\n\t\tfor (var i = line - 1; i >= 0; i--) {\n\t\t\tif (cm.getLine(i).toUpperCase().indexOf(lookFor) >= 0) {\n\t\t\t\thasPreviousPrefix = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn hasPreviousPrefix;\n\t}\n\n\n\tfunction findOpening(openCh) {\n\t\tfor (var at = start.ch, pass = 0;;) {\n\t\t\tvar found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1);\n\t\t\tif (found == -1) {\n\t\t\t\tif (pass == 1)\n\t\t\t\t\tbreak;\n\t\t\t\tpass = 1;\n\t\t\t\tat = lineText.length;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (pass == 1 && found < start.ch)\n\t\t\t\tbreak;\n\t\t\ttokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));\n\t\t\tif (!/^(comment|string)/.test(tokenType))\n\t\t\t\treturn found + 1;\n\t\t\tat = found - 1;\n\t\t}\n\t}\n\tvar getLastPrefixPos = function(line, ch) {\n\t\tvar prefixKeywordToken = cm.getTokenAt(CodeMirror.Pos(line, ch + 1));\n\t\tif (!prefixKeywordToken || prefixKeywordToken.type != \"keyword\") return -1;\n\t\tvar prefixShortname = tokenUtils.getNextNonWsToken(cm, line, prefixKeywordToken.end + 1);\n\t\tif (!prefixShortname || prefixShortname.type != \"string-2\") return -1; //missing prefix keyword shortname\n\t\tvar prefixUri = tokenUtils.getNextNonWsToken(cm, line, prefixShortname.end + 1);\n\t\tif (!prefixUri || prefixUri.type != \"variable-3\") return -1; //missing prefix uri\n\t\treturn prefixUri.end;\n\t}\n\n\t//only use opening prefix declaration\n\tif (hasPreviousPrefix())\n\t\treturn;\n\tvar prefixStart = findFirstPrefix(cm, line, start.ch, lineText);\n\n\tif (prefixStart == null)\n\t\treturn;\n\tvar stopAt = '{'; //if this char is there, we won't have a chance of finding more prefixes\n\tvar stopAtNextLine = false;\n\tvar count = 1,\n\t\tlastLine = cm.lastLine(),\n\t\tend, endCh;\n\tvar prefixEndChar = getLastPrefixPos(line, prefixStart);\n\tvar prefixEndLine = line;\n\n\touter: for (var i = line; i <= lastLine; ++i) {\n\t\tif (stopAtNextLine)\n\t\t\tbreak;\n\t\tvar text = cm.getLine(i),\n\t\t\tpos = i == line ? prefixStart + 1 : 0;\n\n\t\tfor (;;) {\n\t\t\tif (!stopAtNextLine && text.indexOf(stopAt) >= 0)\n\t\t\t\tstopAtNextLine = true;\n\n\t\t\tvar nextPrefixDeclaration = text.toUpperCase()\n\t\t\t\t.indexOf(lookFor, pos);\n\n\t\t\tif (nextPrefixDeclaration >= 0) {\n\t\t\t\tif ((endCh = getLastPrefixPos(i, nextPrefixDeclaration)) > 0) {\n\t\t\t\t\tprefixEndChar = endCh;\n\t\t\t\t\tprefixEndLine = i;\n\t\t\t\t\tpos = prefixEndChar;\n\t\t\t\t}\n\t\t\t\tpos++;\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn {\n\t\tfrom: CodeMirror.Pos(line, prefixStart + lookFor.length),\n\t\tto: CodeMirror.Pos(prefixEndLine, prefixEndChar)\n\t};\n});\n},{\"./tokenUtils.js\":34,\"codemirror\":undefined}],32:[function(require,module,exports){\n'use strict';\n/**\n * Append prefix declaration to list of prefixes in query window.\n * \n * @param yasqe\n * @param prefix\n */\nvar addPrefixes = function(yasqe, prefixes) {\n\tvar existingPrefixes = yasqe.getPrefixesFromQuery();\n\t//for backwards compatability, we stil support prefixes value as string (e.g. 'rdf: '\n\tif (typeof prefixes == \"string\") {\n\t\taddPrefixAsString(yasqe, prefixes);\n\t} else {\n\t\tfor (var pref in prefixes) {\n\t\t\tif (!(pref in existingPrefixes))\n\t\t\t\taddPrefixAsString(yasqe, pref + \": <\" + prefixes[pref] + \">\");\n\t\t}\n\t}\n\tyasqe.collapsePrefixes(false);\n};\n\nvar addPrefixAsString = function(yasqe, prefixString) {\n\tvar lastPrefix = null;\n\tvar lastPrefixLine = 0;\n\tvar numLines = yasqe.lineCount();\n\tfor (var i = 0; i < numLines; i++) {\n\t\tvar firstToken = yasqe.getNextNonWsToken(i);\n\t\tif (firstToken != null && (firstToken.string == \"PREFIX\" || firstToken.string == \"BASE\")) {\n\t\t\tlastPrefix = firstToken;\n\t\t\tlastPrefixLine = i;\n\t\t}\n\t}\n\n\tif (lastPrefix == null) {\n\t\tyasqe.replaceRange(\"PREFIX \" + prefixString + \"\\n\", {\n\t\t\tline: 0,\n\t\t\tch: 0\n\t\t});\n\t} else {\n\t\tvar previousIndent = getIndentFromLine(yasqe, lastPrefixLine);\n\t\tyasqe.replaceRange(\"\\n\" + previousIndent + \"PREFIX \" + prefixString, {\n\t\t\tline: lastPrefixLine\n\t\t});\n\t}\n\tyasqe.collapsePrefixes(false);\n};\nvar removePrefixes = function(yasqe, prefixes) {\n\tvar escapeRegex = function(string) {\n\t\t//taken from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript/3561711#3561711\n\t\treturn string.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n\t}\n\tfor (var pref in prefixes) {\n\t\tyasqe.setValue(yasqe.getValue().replace(new RegExp(\"PREFIX\\\\s*\" + pref + \":\\\\s*\" + escapeRegex(\"<\" + prefixes[pref] + \">\") + \"\\\\s*\", \"ig\"), ''));\n\t}\n\tyasqe.collapsePrefixes(false);\n\n};\n\n/**\n * Get defined prefixes from query as array, in format {\"prefix:\" \"uri\"}\n * \n * @param cm\n * @returns {Array}\n */\nvar getPrefixesFromQuery = function(yasqe) {\n\tvar queryPrefixes = {};\n\tvar shouldContinue = true;\n\tvar getPrefixesFromLine = function(lineOffset, colOffset) {\n\t\tif (!shouldContinue) return;\n\t\tif (!colOffset) colOffset = 1;\n\t\tvar token = yasqe.getNextNonWsToken(i, colOffset);\n\t\tif (token) {\n\t\t\tif (token.state.possibleCurrent.indexOf(\"PREFIX\") == -1 && token.state.possibleNext.indexOf(\"PREFIX\") == -1) shouldContinue = false; //we are beyond the place in the query where we can enter prefixes\n\t\t\tif (token.string.toUpperCase() == \"PREFIX\") {\n\t\t\t\tvar prefix = yasqe.getNextNonWsToken(i, token.end + 1);\n\t\t\t\tif (prefix) {\n\t\t\t\t\tvar uri = yasqe.getNextNonWsToken(i, prefix.end + 1);\n\t\t\t\t\tif (uri) {\n\t\t\t\t\t\tvar uriString = uri.string;\n\t\t\t\t\t\tif (uriString.indexOf(\"<\") == 0)\n\t\t\t\t\t\t\turiString = uriString.substring(1);\n\t\t\t\t\t\tif (uriString.slice(-1) == \">\")\n\t\t\t\t\t\t\turiString = uriString\n\t\t\t\t\t\t\t.substring(0, uriString.length - 1);\n\t\t\t\t\t\tqueryPrefixes[prefix.string.slice(0, -1)] = uriString;\n\n\t\t\t\t\t\tgetPrefixesFromLine(lineOffset, uri.end + 1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgetPrefixesFromLine(lineOffset, prefix.end + 1);\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\t\t\t\t\tgetPrefixesFromLine(lineOffset, token.end + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tgetPrefixesFromLine(lineOffset, token.end + 1);\n\t\t\t}\n\t\t}\n\t};\n\n\n\tvar numLines = yasqe.lineCount();\n\tfor (var i = 0; i < numLines; i++) {\n\t\tif (!shouldContinue) break;\n\t\tgetPrefixesFromLine(i);\n\n\t}\n\treturn queryPrefixes;\n};\n\n/**\n * Get the used indentation for a certain line\n * \n * @param yasqe\n * @param line\n * @param charNumber\n * @returns\n */\nvar getIndentFromLine = function(yasqe, line, charNumber) {\n\tif (charNumber == undefined)\n\t\tcharNumber = 1;\n\tvar token = yasqe.getTokenAt({\n\t\tline: line,\n\t\tch: charNumber\n\t});\n\tif (token == null || token == undefined || token.type != \"ws\") {\n\t\treturn \"\";\n\t} else {\n\t\treturn token.string + getIndentFromLine(yasqe, line, token.end + 1);\n\t};\n};\n\nmodule.exports = {\n\taddPrefixes: addPrefixes,\n\tgetPrefixesFromQuery: getPrefixesFromQuery,\n\tremovePrefixes: removePrefixes\n};\n},{}],33:[function(require,module,exports){\n'use strict';\nvar $ = (function(){try{return require('jquery')}catch(e){return window.jQuery}})(),\n\tutils = require('./utils.js'),\n\tYASQE = require('./main.js');\n\nYASQE.getAjaxConfig = function(yasqe, callbackOrConfig) {\n\tvar callback = (typeof callbackOrConfig == \"function\" ? callbackOrConfig : null);\n\tvar config = (typeof callbackOrConfig == \"object\" ? callbackOrConfig : {});\n\n\tif (yasqe.options.sparql)\n\t\tconfig = $.extend({}, yasqe.options.sparql, config);\n\n\t//for backwards compatability, make sure we copy sparql handlers to sparql callbacks\n\tif (config.handlers)\n\t\t$.extend(true, config.callbacks, config.handlers);\n\n\n\tif (!config.endpoint || config.endpoint.length == 0)\n\t\treturn; // nothing to query!\n\n\t/**\n\t * initialize ajax config\n\t */\n\tvar ajaxConfig = {\n\t\turl: (typeof config.endpoint == \"function\" ? config.endpoint(yasqe) : config.endpoint),\n\t\ttype: (typeof config.requestMethod == \"function\" ? config.requestMethod(yasqe) : config.requestMethod),\n\t\theaders: {\n\t\t\tAccept: getAcceptHeader(yasqe, config),\n\t\t}\n\t};\n\tif (config.xhrFields) ajaxConfig.xhrFields = config.xhrFields;\n\t/**\n\t * add complete, beforesend, etc callbacks (if specified)\n\t */\n\tvar handlerDefined = false;\n\tif (config.callbacks) {\n\t\tfor (var handler in config.callbacks) {\n\t\t\tif (config.callbacks[handler]) {\n\t\t\t\thandlerDefined = true;\n\t\t\t\tajaxConfig[handler] = config.callbacks[handler];\n\t\t\t}\n\t\t}\n\t}\n\tajaxConfig.data = yasqe.getUrlArguments(config);\n\tif (!handlerDefined && !callback)\n\t\treturn; // ok, we can query, but have no callbacks. just stop now\n\n\t// if only callback is passed as arg, add that on as 'onComplete' callback\n\tif (callback)\n\t\tajaxConfig.complete = callback;\n\n\n\n\t/**\n\t * merge additional request headers\n\t */\n\tif (config.headers && !$.isEmptyObject(config.headers))\n\t\t$.extend(ajaxConfig.headers, config.headers);\n\n\n\tvar queryStart = new Date();\n\tvar updateYasqe = function() {\n\t\tyasqe.lastQueryDuration = new Date() - queryStart;\n\t\tYASQE.updateQueryButton(yasqe);\n\t\tyasqe.setBackdrop(false);\n\t};\n\t//Make sure the query button is updated again on complete\n\tvar completeCallbacks = [\n\t\tfunction(){require('./main.js').signal(yasqe, 'queryFinish', arguments)},\n\t\tupdateYasqe\n\t];\n\n\tif (ajaxConfig.complete) {\n\t\tcompleteCallbacks.push(ajaxConfig.complete);\n\t}\n\tajaxConfig.complete = completeCallbacks;\n\treturn ajaxConfig;\n};\n\n\n\nYASQE.executeQuery = function(yasqe, callbackOrConfig) {\n\tYASQE.signal(yasqe, 'query', yasqe, callbackOrConfig);\n\tYASQE.updateQueryButton(yasqe, \"busy\");\n\tyasqe.setBackdrop(true);\n\tyasqe.xhr = $.ajax(YASQE.getAjaxConfig(yasqe, callbackOrConfig));\n};\n\n\nYASQE.getUrlArguments = function(yasqe, config) {\n\tvar queryMode = yasqe.getQueryMode();\n\tvar data = [{\n\t\tname: utils.getString(yasqe, yasqe.options.sparql.queryName),\n\t\tvalue: (config.getQueryForAjax? config.getQueryForAjax(yasqe): yasqe.getValue())\n\t}];\n\n\t/**\n\t * add named graphs to ajax config\n\t */\n\tif (config.namedGraphs && config.namedGraphs.length > 0) {\n\t\tvar argName = (queryMode == \"query\" ? \"named-graph-uri\" : \"using-named-graph-uri \");\n\t\tfor (var i = 0; i < config.namedGraphs.length; i++)\n\t\t\tdata.push({\n\t\t\t\tname: argName,\n\t\t\t\tvalue: config.namedGraphs[i]\n\t\t\t});\n\t}\n\t/**\n\t * add default graphs to ajax config\n\t */\n\tif (config.defaultGraphs && config.defaultGraphs.length > 0) {\n\t\tvar argName = (queryMode == \"query\" ? \"default-graph-uri\" : \"using-graph-uri \");\n\t\tfor (var i = 0; i < config.defaultGraphs.length; i++)\n\t\t\tdata.push({\n\t\t\t\tname: argName,\n\t\t\t\tvalue: config.defaultGraphs[i]\n\t\t\t});\n\t}\n\n\t/**\n\t * add additional request args\n\t */\n\tif (config.args && config.args.length > 0) $.merge(data, config.args);\n\n\treturn data;\n}\nvar getAcceptHeader = function(yasqe, config) {\n\tvar acceptHeader = null;\n\tif (config.acceptHeader && !config.acceptHeaderGraph && !config.acceptHeaderSelect && !config.acceptHeaderUpdate) {\n\t\t//this is the old config. For backwards compatability, keep supporting it\n\t\tif (typeof config.acceptHeader == \"function\") {\n\t\t\tacceptHeader = config.acceptHeader(yasqe);\n\t\t} else {\n\t\t\tacceptHeader = config.acceptHeader;\n\t\t}\n\t} else {\n\t\tif (yasqe.getQueryMode() == \"update\") {\n\t\t\tacceptHeader = (typeof config.acceptHeader == \"function\" ? config.acceptHeaderUpdate(yasqe) : config.acceptHeaderUpdate);\n\t\t} else {\n\t\t\tvar qType = yasqe.getQueryType();\n\t\t\tif (qType == \"DESCRIBE\" || qType == \"CONSTRUCT\") {\n\t\t\t\tacceptHeader = (typeof config.acceptHeaderGraph == \"function\" ? config.acceptHeaderGraph(yasqe) : config.acceptHeaderGraph);\n\t\t\t} else {\n\t\t\t\tacceptHeader = (typeof config.acceptHeaderSelect == \"function\" ? config.acceptHeaderSelect(yasqe) : config.acceptHeaderSelect);\n\t\t\t}\n\t\t}\n\t}\n\treturn acceptHeader;\n};\n\nmodule.exports = {\n\tgetAjaxConfig: YASQE.getAjaxConfig\n}\n\n},{\"./main.js\":30,\"./utils.js\":36,\"jquery\":undefined}],34:[function(require,module,exports){\n'use strict';\n/**\n * When typing a query, this query is sometimes syntactically invalid, causing\n * the current tokens to be incorrect This causes problem for autocompletion.\n * http://bla might result in two tokens: http:// and bla. We'll want to combine\n * these\n * \n * @param yasqe {doc}\n * @param token {object}\n * @param cursor {object}\n * @return token {object}\n * @method YASQE.getCompleteToken\n */\nvar getCompleteToken = function(yasqe, token, cur) {\n\tif (!cur) {\n\t\tcur = yasqe.getCursor();\n\t}\n\tif (!token) {\n\t\ttoken = yasqe.getTokenAt(cur);\n\t}\n\tvar prevToken = yasqe.getTokenAt({\n\t\tline: cur.line,\n\t\tch: token.start\n\t});\n\t// not start of line, and not whitespace\n\tif (\n\t\tprevToken.type != null && prevToken.type != \"ws\" && token.type != null && token.type != \"ws\"\n\t) {\n\t\ttoken.start = prevToken.start;\n\t\ttoken.string = prevToken.string + token.string;\n\t\treturn getCompleteToken(yasqe, token, {\n\t\t\tline: cur.line,\n\t\t\tch: prevToken.start\n\t\t}); // recursively, might have multiple tokens which it should include\n\t} else if (token.type != null && token.type == \"ws\") {\n\t\t//always keep 1 char of whitespace between tokens. Otherwise, autocompletions might end up next to the previous node, without whitespace between them\n\t\ttoken.start = token.start + 1;\n\t\ttoken.string = token.string.substring(1);\n\t\treturn token;\n\t} else {\n\t\treturn token;\n\t}\n};\nvar getPreviousNonWsToken = function(yasqe, line, token) {\n\tvar previousToken = yasqe.getTokenAt({\n\t\tline: line,\n\t\tch: token.start\n\t});\n\tif (previousToken != null && previousToken.type == \"ws\") {\n\t\tpreviousToken = getPreviousNonWsToken(yasqe, line, previousToken);\n\t}\n\treturn previousToken;\n}\nvar getNextNonWsToken = function(yasqe, lineNumber, charNumber) {\n\tif (charNumber == undefined)\n\t\tcharNumber = 1;\n\tvar token = yasqe.getTokenAt({\n\t\tline: lineNumber,\n\t\tch: charNumber\n\t});\n\tif (token == null || token == undefined || token.end < charNumber) {\n\t\treturn null;\n\t}\n\tif (token.type == \"ws\") {\n\t\treturn getNextNonWsToken(yasqe, lineNumber, token.end + 1);\n\t}\n\treturn token;\n};\n\nmodule.exports = {\n\tgetPreviousNonWsToken: getPreviousNonWsToken,\n\tgetCompleteToken: getCompleteToken,\n\tgetNextNonWsToken: getNextNonWsToken,\n};\n},{}],35:[function(require,module,exports){\n'use strict';\nvar $ = (function(){try{return require('jquery')}catch(e){return window.jQuery}})(),\n\tutils = require('./utils.js');\n\n/**\n * Write our own tooltip, to avoid loading another library for just this functionality. For now, we only use tooltip for showing parse errors, so this is quite a tailored solution\n * Requirements: \n * \t\tposition tooltip within codemirror frame as much as possible, to avoid z-index issues with external things on page\n * \t\tuse html as content\n */\nmodule.exports = function(yasqe, parent, html) {\n\tvar parent = $(parent);\n\tvar tooltip;\n\tparent.hover(function() {\n\t\t\tif (typeof html == \"function\") html = html();\n\t\t\ttooltip = $(\"
      \").addClass('yasqe_tooltip').html(html).appendTo(parent);\n\t\t\trepositionTooltip();\n\t\t},\n\t\tfunction() {\n\t\t\t$(\".yasqe_tooltip\").remove();\n\t\t});\n\n\n\n\t/**\n\t * only need to take into account top and bottom offset for this usecase\n\t */\n\tvar repositionTooltip = function() {\n\t\tif ($(yasqe.getWrapperElement()).offset().top >= tooltip.offset().top) {\n\t\t\t//shit, move the tooltip down. The tooltip now hovers over the top edge of the yasqe instance\n\t\t\ttooltip.css('bottom', 'auto');\n\t\t\ttooltip.css('top', '26px');\n\t\t}\n\t};\n};\n},{\"./utils.js\":36,\"jquery\":undefined}],36:[function(require,module,exports){\n'use strict';\nvar $ = (function(){try{return require('jquery')}catch(e){return window.jQuery}})();\n\nvar keyExists = function(objectToTest, key) {\n\tvar exists = false;\n\ttry {\n\t\tif (objectToTest[key] !== undefined)\n\t\t\texists = true;\n\t} catch (e) {}\n\treturn exists;\n};\n\nvar getPersistencyId = function(yasqe, persistentIdCreator) {\n\tvar persistencyId = null;\n\n\tif (persistentIdCreator) {\n\t\tif (typeof persistentIdCreator == \"string\") {\n\t\t\tpersistencyId = persistentIdCreator;\n\t\t} else {\n\t\t\tpersistencyId = persistentIdCreator(yasqe);\n\t\t}\n\t}\n\treturn persistencyId;\n};\n\nvar elementsOverlap = (function() {\n\tfunction getPositions(elem) {\n\t\tvar pos, width, height;\n\t\tpos = $(elem).offset();\n\t\twidth = $(elem).width();\n\t\theight = $(elem).height();\n\t\treturn [\n\t\t\t[pos.left, pos.left + width],\n\t\t\t[pos.top, pos.top + height]\n\t\t];\n\t}\n\n\tfunction comparePositions(p1, p2) {\n\t\tvar r1, r2;\n\t\tr1 = p1[0] < p2[0] ? p1 : p2;\n\t\tr2 = p1[0] < p2[0] ? p2 : p1;\n\t\treturn r1[1] > r2[0] || r1[0] === r2[0];\n\t}\n\n\treturn function(a, b) {\n\t\tvar pos1 = getPositions(a),\n\t\t\tpos2 = getPositions(b);\n\t\treturn comparePositions(pos1[0], pos2[0]) && comparePositions(pos1[1], pos2[1]);\n\t};\n})();\n\nvar getString = function(yasqe, item) {\n\tif (typeof item == \"function\") {\n\t\treturn item(yasqe);\n\t} else {\n\t\treturn item;\n\t}\n}\nmodule.exports = {\n\tkeyExists: keyExists,\n\tgetPersistencyId: getPersistencyId,\n\telementsOverlap: elementsOverlap,\n\tgetString:getString\n};\n\n},{\"jquery\":undefined}]},{},[1])(1)\n});\n\n\n//# sourceMappingURL=yasqe.js.map","\"use strict\"\n// Module export pattern from\n// https://github.com/umdjs/umd/blob/master/returnExports.js\n;(function (root, factory) {\n if (typeof define === 'function' && define.amd) {\n // AMD. Register as an anonymous module.\n define([], factory);\n } else if (typeof exports === 'object') {\n // Node. Does not work with strict CommonJS, but\n // only CommonJS-like environments that support module.exports,\n // like Node.\n module.exports = factory();\n } else {\n // Browser globals (root is window)\n root.store = factory();\n }\n}(this, function () {\n\t\n\t// Store.js\n\tvar store = {},\n\t\twin = (typeof window != 'undefined' ? window : global),\n\t\tdoc = win.document,\n\t\tlocalStorageName = 'localStorage',\n\t\tscriptTag = 'script',\n\t\tstorage\n\n\tstore.disabled = false\n\tstore.version = '1.3.20'\n\tstore.set = function(key, value) {}\n\tstore.get = function(key, defaultVal) {}\n\tstore.has = function(key) { return store.get(key) !== undefined }\n\tstore.remove = function(key) {}\n\tstore.clear = function() {}\n\tstore.transact = function(key, defaultVal, transactionFn) {\n\t\tif (transactionFn == null) {\n\t\t\ttransactionFn = defaultVal\n\t\t\tdefaultVal = null\n\t\t}\n\t\tif (defaultVal == null) {\n\t\t\tdefaultVal = {}\n\t\t}\n\t\tvar val = store.get(key, defaultVal)\n\t\ttransactionFn(val)\n\t\tstore.set(key, val)\n\t}\n\tstore.getAll = function() {}\n\tstore.forEach = function() {}\n\n\tstore.serialize = function(value) {\n\t\treturn JSON.stringify(value)\n\t}\n\tstore.deserialize = function(value) {\n\t\tif (typeof value != 'string') { return undefined }\n\t\ttry { return JSON.parse(value) }\n\t\tcatch(e) { return value || undefined }\n\t}\n\n\t// Functions to encapsulate questionable FireFox 3.6.13 behavior\n\t// when about.config::dom.storage.enabled === false\n\t// See https://github.com/marcuswestin/store.js/issues#issue/13\n\tfunction isLocalStorageNameSupported() {\n\t\ttry { return (localStorageName in win && win[localStorageName]) }\n\t\tcatch(err) { return false }\n\t}\n\n\tif (isLocalStorageNameSupported()) {\n\t\tstorage = win[localStorageName]\n\t\tstore.set = function(key, val) {\n\t\t\tif (val === undefined) { return store.remove(key) }\n\t\t\tstorage.setItem(key, store.serialize(val))\n\t\t\treturn val\n\t\t}\n\t\tstore.get = function(key, defaultVal) {\n\t\t\tvar val = store.deserialize(storage.getItem(key))\n\t\t\treturn (val === undefined ? defaultVal : val)\n\t\t}\n\t\tstore.remove = function(key) { storage.removeItem(key) }\n\t\tstore.clear = function() { storage.clear() }\n\t\tstore.getAll = function() {\n\t\t\tvar ret = {}\n\t\t\tstore.forEach(function(key, val) {\n\t\t\t\tret[key] = val\n\t\t\t})\n\t\t\treturn ret\n\t\t}\n\t\tstore.forEach = function(callback) {\n\t\t\tfor (var i=0; idocument.w=window')\n\t\t\tstorageContainer.close()\n\t\t\tstorageOwner = storageContainer.w.frames[0].document\n\t\t\tstorage = storageOwner.createElement('div')\n\t\t} catch(e) {\n\t\t\t// somehow ActiveXObject instantiation failed (perhaps some special\n\t\t\t// security settings or otherwse), fall back to per-path storage\n\t\t\tstorage = doc.createElement('div')\n\t\t\tstorageOwner = doc.body\n\t\t}\n\t\tvar withIEStorage = function(storeFunction) {\n\t\t\treturn function() {\n\t\t\t\tvar args = Array.prototype.slice.call(arguments, 0)\n\t\t\t\targs.unshift(storage)\n\t\t\t\t// See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx\n\t\t\t\t// and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx\n\t\t\t\tstorageOwner.appendChild(storage)\n\t\t\t\tstorage.addBehavior('#default#userData')\n\t\t\t\tstorage.load(localStorageName)\n\t\t\t\tvar result = storeFunction.apply(store, args)\n\t\t\t\tstorageOwner.removeChild(storage)\n\t\t\t\treturn result\n\t\t\t}\n\t\t}\n\n\t\t// In IE7, keys cannot start with a digit or contain certain chars.\n\t\t// See https://github.com/marcuswestin/store.js/issues/40\n\t\t// See https://github.com/marcuswestin/store.js/issues/83\n\t\tvar forbiddenCharsRegex = new RegExp(\"[!\\\"#$%&'()*+,/\\\\\\\\:;<=>?@[\\\\]^`{|}~]\", \"g\")\n\t\tvar ieKeyFix = function(key) {\n\t\t\treturn key.replace(/^d/, '___$&').replace(forbiddenCharsRegex, '___')\n\t\t}\n\t\tstore.set = withIEStorage(function(storage, key, val) {\n\t\t\tkey = ieKeyFix(key)\n\t\t\tif (val === undefined) { return store.remove(key) }\n\t\t\tstorage.setAttribute(key, store.serialize(val))\n\t\t\tstorage.save(localStorageName)\n\t\t\treturn val\n\t\t})\n\t\tstore.get = withIEStorage(function(storage, key, defaultVal) {\n\t\t\tkey = ieKeyFix(key)\n\t\t\tvar val = store.deserialize(storage.getAttribute(key))\n\t\t\treturn (val === undefined ? defaultVal : val)\n\t\t})\n\t\tstore.remove = withIEStorage(function(storage, key) {\n\t\t\tkey = ieKeyFix(key)\n\t\t\tstorage.removeAttribute(key)\n\t\t\tstorage.save(localStorageName)\n\t\t})\n\t\tstore.clear = withIEStorage(function(storage) {\n\t\t\tvar attributes = storage.XMLDocument.documentElement.attributes\n\t\t\tstorage.load(localStorageName)\n\t\t\tfor (var i=attributes.length-1; i>=0; i--) {\n\t\t\t\tstorage.removeAttribute(attributes[i].name)\n\t\t\t}\n\t\t\tstorage.save(localStorageName)\n\t\t})\n\t\tstore.getAll = function(storage) {\n\t\t\tvar ret = {}\n\t\t\tstore.forEach(function(key, val) {\n\t\t\t\tret[key] = val\n\t\t\t})\n\t\t\treturn ret\n\t\t}\n\t\tstore.forEach = withIEStorage(function(storage, callback) {\n\t\t\tvar attributes = storage.XMLDocument.documentElement.attributes\n\t\t\tfor (var i=0, attr; attr=attributes[i]; ++i) {\n\t\t\t\tcallback(attr.name, store.deserialize(storage.getAttribute(attr.name)))\n\t\t\t}\n\t\t})\n\t}\n\n\ttry {\n\t\tvar testKey = '__storejs__'\n\t\tstore.set(testKey, testKey)\n\t\tif (store.get(testKey) != testKey) { store.disabled = true }\n\t\tstore.remove(testKey)\n\t} catch(e) {\n\t\tstore.disabled = true\n\t}\n\tstore.enabled = !store.disabled\n\t\n\treturn store\n}));\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/triplestores/fuseki/webapp/js/lib/yasr.min.js b/triplestores/fuseki/webapp/js/lib/yasr.min.js deleted file mode 100644 index ba53e125a4..0000000000 --- a/triplestores/fuseki/webapp/js/lib/yasr.min.js +++ /dev/null @@ -1,8 +0,0 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;"undefined"!=typeof window?t=window:"undefined"!=typeof global?t=global:"undefined"!=typeof self&&(t=self),t.YASR=e()}}(function(){var e;return function t(e,r,n){function i(a,s){if(!r[a]){if(!e[a]){var l="function"==typeof require&&require;if(!s&&l)return l(a,!0);if(o)return o(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[a]={exports:{}};e[a][0].call(c.exports,function(t){var r=e[a][1][t];return i(r?r:t)},c,c.exports,t,e,r,n)}return r[a].exports}for(var o="function"==typeof require&&require,a=0;a0;try{n=sessionStorage}catch(v){}a.append("");var m=function(e,t){var r=i(e);if(t.disable)return w(r);var n=r.id=r.attr(c)||f+u++;r.p=t.postbackSafe;if(r.is("table")&&!l[n]){r.addClass(f).attr(c,n).before('
      ');r.opt=t;r.g=[];r.c=[];r.w=r.width();r.gc=r.prev();t.marginLeft&&r.gc.css("marginLeft",t.marginLeft);t.marginRight&&r.gc.css("marginRight",t.marginRight);r.cs=p(h?e.cellSpacing||e.currentStyle.borderSpacing:r.css("border-spacing"))||2;r.b=p(h?e.border||e.currentStyle.borderLeftWidth:r.css("border-left-width"))||1;l[n]=r;y(r)}},w=function(e){var t=e.attr(c),e=l[t];if(e&&e.is("table")){e.removeClass(f).gc.remove();delete l[t]}},y=function(e){var t=e.find(">thead>tr>th,>thead>tr>td");t.length||(t=e.find(">tbody>tr:first>th,>tr:first>th,>tbody>tr:first>td, >tr:first>td"));e.cg=e.find("col");e.ln=t.length;e.p&&n&&n[e.id]&&b(e,t);t.each(function(t){var r=i(this),n=i(e.gc.append('
      ')[0].lastChild);n.t=e;n.i=t;n.c=r;r.w=r.width();e.g.push(n);e.c.push(r);r.width(r.w).removeAttr("width");t
      '):n.addClass("JCLRLastGrip").removeClass("JCLRgrip");n.data(f,{i:t,t:e.attr(c)})});e.cg.removeAttr("width");x(e);e.find("td, th").not(t).not("table th, table td").each(function(){i(this).removeAttr("width")})},b=function(e,t){var r,i=0,o=0,a=[];if(t){e.cg.removeAttr("width");if(e.opt.flush){n[e.id]="";return}r=n[e.id].split(";");for(;o*{cursor:"+r.opt.dragCursor+"!important}");n.addClass(r.opt.draggingClass);s=n;if(r.c[t.i].l)for(var u,c=0;c=t.end&&(c=!0);t.state.rowNum++;t.state.colNum=1}}function n(){if(void 0===t.onParseValue)s.push(u);else{var e=t.onParseValue(u,t.state);e!==!1&&s.push(e)}u="";l=0;t.state.colNum++}var i=t.separator,o=t.delimiter;t.state.rowNum||(t.state.rowNum=1);t.state.colNum||(t.state.colNum=1);var a=[],s=[],l=0,u="",c=!1,d=RegExp.escape(i),f=RegExp.escape(o),p=/(D|S|\n|\r|[^DS\r\n]+)/,g=p.source;g=g.replace(/S/g,d);g=g.replace(/D/g,f);p=RegExp(g,"gm");e.replace(p,function(e){if(!c)switch(l){case 0:if(e===i){u+="";n();break}if(e===o){l=1;break}if("\n"===e){n();r();break}if(/^\r$/.test(e))break;u+=e;l=3;break;case 1:if(e===o){l=2;break}u+=e;l=1;break;case 2:if(e===o){u+=e;l=1;break}if(e===i){n();break}if("\n"===e){n();r();break}if(/^\r$/.test(e))break;throw new Error("CSVDataError: Illegal State [Row:"+t.state.rowNum+"][Col:"+t.state.colNum+"]");case 3:if(e===i){n();break}if("\n"===e){n();r();break}if(/^\r$/.test(e))break;if(e===o)throw new Error("CSVDataError: Illegal Quote [Row:"+t.state.rowNum+"][Col:"+t.state.colNum+"]");throw new Error("CSVDataError: Illegal Data [Row:"+t.state.rowNum+"][Col:"+t.state.colNum+"]");default:throw new Error("CSVDataError: Unknown State [Row:"+t.state.rowNum+"][Col:"+t.state.colNum+"]")}});if(0!==s.length){n();r()}return a},splitLines:function(e,t){function r(){a=0;if(t.start&&t.state.rowNum=t.end&&(l=!0);t.state.rowNum++}}var n=t.separator,i=t.delimiter;t.state.rowNum||(t.state.rowNum=1);var o=[],a=0,s="",l=!1,u=RegExp.escape(n),c=RegExp.escape(i),d=/(D|S|\n|\r|[^DS\r\n]+)/,f=d.source;f=f.replace(/S/g,u);f=f.replace(/D/g,c);d=RegExp(f,"gm");e.replace(d,function(e){if(!l)switch(a){case 0:if(e===n){s+=e;a=0;break}if(e===i){s+=e;a=1;break}if("\n"===e){r();break}if(/^\r$/.test(e))break;s+=e;a=3;break;case 1:if(e===i){s+=e;a=2;break}s+=e;a=1;break;case 2:var o=s.substr(s.length-1);if(e===i&&o===i){s+=e;a=1;break}if(e===n){s+=e;a=0;break}if("\n"===e){r();break}if("\r"===e)break;throw new Error("CSVDataError: Illegal state [Row:"+t.state.rowNum+"]");case 3:if(e===n){s+=e;a=0;break}if("\n"===e){r();break}if("\r"===e)break;if(e===i)throw new Error("CSVDataError: Illegal quote [Row:"+t.state.rowNum+"]");throw new Error("CSVDataError: Illegal state [Row:"+t.state.rowNum+"]");default:throw new Error("CSVDataError: Unknown state [Row:"+t.state.rowNum+"]")}});""!==s&&r();return o},parseEntry:function(e,t){function r(){if(void 0===t.onParseValue)o.push(s);else{var e=t.onParseValue(s,t.state);e!==!1&&o.push(e)}s="";a=0;t.state.colNum++}var n=t.separator,i=t.delimiter;t.state.rowNum||(t.state.rowNum=1);t.state.colNum||(t.state.colNum=1);var o=[],a=0,s="";if(!t.match){var l=RegExp.escape(n),u=RegExp.escape(i),c=/(D|S|\n|\r|[^DS\r\n]+)/,d=c.source;d=d.replace(/S/g,l);d=d.replace(/D/g,u);t.match=RegExp(d,"gm")}e.replace(t.match,function(e){switch(a){case 0:if(e===n){s+="";r();break}if(e===i){a=1;break}if("\n"===e||"\r"===e)break;s+=e;a=3;break;case 1:if(e===i){a=2;break}s+=e;a=1;break;case 2:if(e===i){s+=e;a=1;break}if(e===n){r();break}if("\n"===e||"\r"===e)break;throw new Error("CSVDataError: Illegal State [Row:"+t.state.rowNum+"][Col:"+t.state.colNum+"]");case 3:if(e===n){r();break}if("\n"===e||"\r"===e)break;if(e===i)throw new Error("CSVDataError: Illegal Quote [Row:"+t.state.rowNum+"][Col:"+t.state.colNum+"]");throw new Error("CSVDataError: Illegal Data [Row:"+t.state.rowNum+"][Col:"+t.state.colNum+"]");default:throw new Error("CSVDataError: Unknown State [Row:"+t.state.rowNum+"][Col:"+t.state.colNum+"]")}});r();return o}},toArray:function(e,t,r){var t=void 0!==t?t:{},i={};i.callback=void 0!==r&&"function"==typeof r?r:!1;i.separator="separator"in t?t.separator:n.csv.defaults.separator;i.delimiter="delimiter"in t?t.delimiter:n.csv.defaults.delimiter;var o=void 0!==t.state?t.state:{},t={delimiter:i.delimiter,separator:i.separator,onParseEntry:t.onParseEntry,onParseValue:t.onParseValue,state:o},a=n.csv.parsers.parseEntry(e,t);if(!i.callback)return a;i.callback("",a);return void 0},toArrays:function(e,t,r){var t=void 0!==t?t:{},i={};i.callback=void 0!==r&&"function"==typeof r?r:!1;i.separator="separator"in t?t.separator:n.csv.defaults.separator;i.delimiter="delimiter"in t?t.delimiter:n.csv.defaults.delimiter;var o=[],t={delimiter:i.delimiter,separator:i.separator,onParseEntry:t.onParseEntry,onParseValue:t.onParseValue,start:t.start,end:t.end,state:{rowNum:1,colNum:1}};o=n.csv.parsers.parse(e,t);if(!i.callback)return o;i.callback("",o);return void 0},toObjects:function(e,t,r){var t=void 0!==t?t:{},i={};i.callback=void 0!==r&&"function"==typeof r?r:!1;i.separator="separator"in t?t.separator:n.csv.defaults.separator;i.delimiter="delimiter"in t?t.delimiter:n.csv.defaults.delimiter;i.headers="headers"in t?t.headers:n.csv.defaults.headers;t.start="start"in t?t.start:1;i.headers&&t.start++;t.end&&i.headers&&t.end++;var o=[],a=[],t={delimiter:i.delimiter,separator:i.separator,onParseEntry:t.onParseEntry,onParseValue:t.onParseValue,start:t.start,end:t.end,state:{rowNum:1,colNum:1},match:!1},s={delimiter:i.delimiter,separator:i.separator,start:1,end:1,state:{rowNum:1,colNum:1}},l=n.csv.parsers.splitLines(e,s),u=n.csv.toArray(l[0],t),o=n.csv.parsers.splitLines(e,t);t.state.colNum=1;t.state.rowNum=u?2:1;for(var c=0,d=o.length;d>c;c++){var f=n.csv.toArray(o[c],t),p={};for(var g in u)p[u[g]]=f[g];a.push(p);t.state.rowNum++}if(!i.callback)return a;i.callback("",a);return void 0},fromArrays:function(e,t,r){var t=void 0!==t?t:{},o={};o.callback=void 0!==r&&"function"==typeof r?r:!1;o.separator="separator"in t?t.separator:n.csv.defaults.separator;o.delimiter="delimiter"in t?t.delimiter:n.csv.defaults.delimiter;o.escaper="escaper"in t?t.escaper:n.csv.defaults.escaper;o.experimental="experimental"in t?t.experimental:!1;if(!o.experimental)throw new Error("not implemented");var a=[];for(i in e)a.push(e[i]);if(!o.callback)return a;o.callback("",a);return void 0},fromObjects2CSV:function(e,t,r){var t=void 0!==t?t:{},o={};o.callback=void 0!==r&&"function"==typeof r?r:!1;o.separator="separator"in t?t.separator:n.csv.defaults.separator;o.delimiter="delimiter"in t?t.delimiter:n.csv.defaults.delimiter;o.experimental="experimental"in t?t.experimental:!1;if(!o.experimental)throw new Error("not implemented");var a=[];for(i in e)a.push(arrays[i]);if(!o.callback)return a;o.callback("",a);return void 0}};n.csvEntry2Array=n.csv.toArray;n.csv2Array=n.csv.toArrays;n.csv2Dictionary=n.csv.toObjects},{jquery:void 0}],4:[function(e,t,r){function n(){this._events=this._events||{};this._maxListeners=this._maxListeners||void 0}function i(e){return"function"==typeof e}function o(e){return"number"==typeof e}function a(e){return"object"==typeof e&&null!==e}function s(e){return void 0===e}t.exports=n;n.EventEmitter=n;n.prototype._events=void 0;n.prototype._maxListeners=void 0;n.defaultMaxListeners=10;n.prototype.setMaxListeners=function(e){if(!o(e)||0>e||isNaN(e))throw TypeError("n must be a positive number");this._maxListeners=e;return this};n.prototype.emit=function(e){var t,r,n,o,l,u;this._events||(this._events={});if("error"===e&&(!this._events.error||a(this._events.error)&&!this._events.error.length)){t=arguments[1];if(t instanceof Error)throw t;throw TypeError('Uncaught, unspecified "error" event.')}r=this._events[e];if(s(r))return!1;if(i(r))switch(arguments.length){case 1:r.call(this);break;case 2:r.call(this,arguments[1]);break;case 3:r.call(this,arguments[1],arguments[2]);break;default:n=arguments.length;o=new Array(n-1);for(l=1;n>l;l++)o[l-1]=arguments[l];r.apply(this,o)}else if(a(r)){n=arguments.length;o=new Array(n-1);for(l=1;n>l;l++)o[l-1]=arguments[l];u=r.slice();n=u.length;for(l=0;n>l;l++)u[l].apply(this,o)}return!0};n.prototype.addListener=function(e,t){var r;if(!i(t))throw TypeError("listener must be a function");this._events||(this._events={});this._events.newListener&&this.emit("newListener",e,i(t.listener)?t.listener:t);this._events[e]?a(this._events[e])?this._events[e].push(t):this._events[e]=[this._events[e],t]:this._events[e]=t;if(a(this._events[e])&&!this._events[e].warned){var r;r=s(this._maxListeners)?n.defaultMaxListeners:this._maxListeners;if(r&&r>0&&this._events[e].length>r){this._events[e].warned=!0;console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[e].length);"function"==typeof console.trace&&console.trace()}}return this};n.prototype.on=n.prototype.addListener;n.prototype.once=function(e,t){function r(){this.removeListener(e,r);if(!n){n=!0;t.apply(this,arguments)}}if(!i(t))throw TypeError("listener must be a function");var n=!1;r.listener=t;this.on(e,r);return this};n.prototype.removeListener=function(e,t){var r,n,o,s;if(!i(t))throw TypeError("listener must be a function");if(!this._events||!this._events[e])return this;r=this._events[e];o=r.length;n=-1;if(r===t||i(r.listener)&&r.listener===t){delete this._events[e];this._events.removeListener&&this.emit("removeListener",e,t)}else if(a(r)){for(s=o;s-->0;)if(r[s]===t||r[s].listener&&r[s].listener===t){n=s;break}if(0>n)return this;if(1===r.length){r.length=0;delete this._events[e]}else r.splice(n,1);this._events.removeListener&&this.emit("removeListener",e,t)}return this};n.prototype.removeAllListeners=function(e){var t,r;if(!this._events)return this;if(!this._events.removeListener){0===arguments.length?this._events={}:this._events[e]&&delete this._events[e];return this}if(0===arguments.length){for(t in this._events)"removeListener"!==t&&this.removeAllListeners(t);this.removeAllListeners("removeListener");this._events={};return this}r=this._events[e];if(i(r))this.removeListener(e,r);else for(;r.length;)this.removeListener(e,r[r.length-1]);delete this._events[e];return this};n.prototype.listeners=function(e){var t;t=this._events&&this._events[e]?i(this._events[e])?[this._events[e]]:this._events[e].slice():[];return t};n.listenerCount=function(e,t){var r;r=e._events&&e._events[t]?i(e._events[t])?1:e._events[t].length:0;return r}},{}],5:[function(t,r,n){(function(i){"object"==typeof n&&"object"==typeof r?i(function(){try{return t("codemirror")}catch(e){return window.CodeMirror}}()):"function"==typeof e&&e.amd?e(["../../lib/codemirror"],i):i(CodeMirror)})(function(e){function t(e,t,n,i){var o=e.getLineHandle(t.line),l=t.ch-1,u=l>=0&&s[o.text.charAt(l)]||s[o.text.charAt(++l)];if(!u)return null;var c=">"==u.charAt(1)?1:-1;if(n&&c>0!=(l==t.ch))return null;var d=e.getTokenTypeAt(a(t.line,l+1)),f=r(e,a(t.line,l+(c>0?1:0)),c,d||null,i);return null==f?null:{from:a(t.line,l),to:f&&f.pos,match:f&&f.ch==u.charAt(0),forward:c>0}}function r(e,t,r,n,i){for(var o=i&&i.maxScanLineLength||1e4,l=i&&i.maxScanLines||1e3,u=[],c=i&&i.bracketRegex?i.bracketRegex:/[(){}[\]]/,d=r>0?Math.min(t.line+l,e.lastLine()+1):Math.max(e.firstLine()-1,t.line-l),f=t.line;f!=d;f+=r){var p=e.getLine(f);if(p){var g=r>0?0:p.length-1,h=r>0?p.length:-1;if(!(p.length>o)){f==t.line&&(g=t.ch-(0>r?1:0));for(;g!=h;g+=r){var v=p.charAt(g);if(c.test(v)&&(void 0===n||e.getTokenTypeAt(a(f,g+1))==n)){var m=s[v];if(">"==m.charAt(1)==r>0)u.push(v);else{if(!u.length)return{pos:a(f,g),ch:v};u.pop()}}}}}}return f-r==(r>0?e.lastLine():e.firstLine())?!1:null}function n(e,r,n){for(var i=e.state.matchBrackets.maxHighlightLineLength||1e3,s=[],l=e.listSelections(),u=0;u",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<"},l=null;e.defineOption("matchBrackets",!1,function(t,r,n){n&&n!=e.Init&&t.off("cursorActivity",i);if(r){t.state.matchBrackets="object"==typeof r?r:{};t.on("cursorActivity",i)}});e.defineExtension("matchBrackets",function(){n(this,!0)});e.defineExtension("findMatchingBracket",function(e,r,n){return t(this,e,r,n)});e.defineExtension("scanForBracket",function(e,t,n,i){return r(this,e,t,n,i)})})},{codemirror:void 0}],6:[function(t,r,n){(function(i){"object"==typeof n&&"object"==typeof r?i(function(){try{return t("codemirror")}catch(e){return window.CodeMirror}}()):"function"==typeof e&&e.amd?e(["../../lib/codemirror"],i):i(CodeMirror)})(function(e){"use strict";e.registerHelper("fold","brace",function(t,r){function n(n){for(var i=r.ch,l=0;;){var u=0>=i?-1:s.lastIndexOf(n,i-1);if(-1!=u){if(1==l&&u=g;++g)for(var h=t.getLine(g),v=g==a?i:0;;){var m=h.indexOf(l,v),w=h.indexOf(u,v);0>m&&(m=h.length);0>w&&(w=h.length);v=Math.min(m,w);if(v==h.length)break;if(t.getTokenTypeAt(e.Pos(g,v+1))==o)if(v==m)++f;else if(!--f){c=g;d=v;break e}++v}if(null!=c&&(a!=c||d!=i))return{from:e.Pos(a,i),to:e.Pos(c,d)}}});e.registerHelper("fold","import",function(t,r){function n(r){if(rt.lastLine())return null;var n=t.getTokenAt(e.Pos(r,1));/\S/.test(n.string)||(n=t.getTokenAt(e.Pos(r,n.end+1)));if("keyword"!=n.type||"import"!=n.string)return null;for(var i=r,o=Math.min(t.lastLine(),r+10);o>=i;++i){var a=t.getLine(i),s=a.indexOf(";");if(-1!=s)return{startCh:n.end,end:e.Pos(i,s)}}}var i,r=r.line,o=n(r);if(!o||n(r-1)||(i=n(r-2))&&i.end.line==r-1)return null;for(var a=o.end;;){var s=n(a.line+1);if(null==s)break;a=s.end}return{from:t.clipPos(e.Pos(r,o.startCh+1)),to:a}});e.registerHelper("fold","include",function(t,r){function n(r){if(rt.lastLine())return null;var n=t.getTokenAt(e.Pos(r,1));/\S/.test(n.string)||(n=t.getTokenAt(e.Pos(r,n.end+1)));return"meta"==n.type&&"#include"==n.string.slice(0,8)?n.start+8:void 0}var r=r.line,i=n(r);if(null==i||null!=n(r-1))return null;for(var o=r;;){var a=n(o+1);if(null==a)break;++o}return{from:e.Pos(r,i+1),to:t.clipPos(e.Pos(o))}})})},{codemirror:void 0}],7:[function(t,r,n){(function(i){"object"==typeof n&&"object"==typeof r?i(function(){try{return t("codemirror")}catch(e){return window.CodeMirror}}()):"function"==typeof e&&e.amd?e(["../../lib/codemirror"],i):i(CodeMirror)})(function(e){"use strict";function t(t,i,o,a){function s(e){var r=l(t,i);if(!r||r.to.line-r.from.linet.firstLine();){i=e.Pos(i.line-1,0);c=s(!1)}if(c&&!c.cleared&&"unfold"!==a){var d=r(t,o);e.on(d,"mousedown",function(t){f.clear();e.e_preventDefault(t)});var f=t.markText(c.from,c.to,{replacedWith:d,clearOnEnter:!0,__isFold:!0});f.on("clear",function(r,n){e.signal(t,"unfold",t,r,n)});e.signal(t,"fold",t,c.from,c.to)}}function r(e,t){var r=n(e,t,"widget");if("string"==typeof r){var i=document.createTextNode(r);r=document.createElement("span");r.appendChild(i);r.className="CodeMirror-foldmarker"}return r}function n(e,t,r){if(t&&void 0!==t[r])return t[r];var n=e.options.foldOptions;return n&&void 0!==n[r]?n[r]:i[r]}e.newFoldFunction=function(e,r){return function(n,i){t(n,i,{rangeFinder:e,widget:r})}};e.defineExtension("foldCode",function(e,r,n){t(this,e,r,n)});e.defineExtension("isFolded",function(e){for(var t=this.findMarksAt(e),r=0;r=r;r++)t.foldCode(e.Pos(r,0),null,"fold")})};e.commands.unfoldAll=function(t){t.operation(function(){for(var r=t.firstLine(),n=t.lastLine();n>=r;r++)t.foldCode(e.Pos(r,0),null,"unfold")})};e.registerHelper("fold","combine",function(){var e=Array.prototype.slice.call(arguments,0);return function(t,r){for(var n=0;n=s&&(r=i(o.indicatorOpen))}e.setGutterMarker(t,o.gutter,r);++a})}function a(e){var t=e.getViewport(),r=e.state.foldGutter;if(r){e.operation(function(){o(e,t.from,t.to)});r.from=t.from;r.to=t.to}}function s(e,t,r){var n=e.state.foldGutter;if(n){var i=n.options;r==i.gutter&&e.foldCode(d(t,0),i.rangeFinder)}}function l(e){var t=e.state.foldGutter;if(t){var r=t.options;t.from=t.to=0;clearTimeout(t.changeUpdate);t.changeUpdate=setTimeout(function(){a(e)},r.foldOnChangeTimeSpan||600)}}function u(e){var t=e.state.foldGutter;if(t){var r=t.options;clearTimeout(t.changeUpdate);t.changeUpdate=setTimeout(function(){var r=e.getViewport();t.from==t.to||r.from-t.to>20||t.from-r.to>20?a(e):e.operation(function(){if(r.fromt.to){o(e,t.to,r.to);t.to=r.to}})},r.updateViewportTimeSpan||400)}}function c(e,t){var r=e.state.foldGutter;if(r){var n=t.line;n>=r.from&&n=e.max)){e.ch=0;e.text=e.cm.getLine(++e.line);return!0}}function o(e){if(!(e.line<=e.min)){e.text=e.cm.getLine(--e.line);e.ch=e.text.length;return!0}}function a(e){for(;;){var t=e.text.indexOf(">",e.ch);if(-1==t){if(i(e))continue;return}if(n(e,t+1)){var r=e.text.lastIndexOf("/",t),o=r>-1&&!/\S/.test(e.text.slice(r+1,t));e.ch=t+1;return o?"selfClose":"regular"}e.ch=t+1}}function s(e){for(;;){var t=e.ch?e.text.lastIndexOf("<",e.ch-1):-1;if(-1==t){if(o(e))continue;return}if(n(e,t+1)){h.lastIndex=t;e.ch=t;var r=h.exec(e.text);if(r&&r.index==t)return r}else e.ch=t}}function l(e){for(;;){h.lastIndex=e.ch;var t=h.exec(e.text);if(!t){if(i(e))continue;return}if(n(e,t.index+1)){e.ch=t.index+t[0].length;return t}e.ch=t.index+1}}function u(e){for(;;){var t=e.ch?e.text.lastIndexOf(">",e.ch-1):-1;if(-1==t){if(o(e))continue;return}if(n(e,t+1)){var r=e.text.lastIndexOf("/",t),i=r>-1&&!/\S/.test(e.text.slice(r+1,t));e.ch=t+1;return i?"selfClose":"regular"}e.ch=t}}function c(e,t){for(var r=[];;){var n,i=l(e),o=e.line,s=e.ch-(i?i[0].length:0);if(!i||!(n=a(e)))return;if("selfClose"!=n)if(i[1]){for(var u=r.length-1;u>=0;--u)if(r[u]==i[2]){r.length=u;break}if(0>u&&(!t||t==i[2]))return{tag:i[2],from:f(o,s),to:f(e.line,e.ch)}}else r.push(i[2])}}function d(e,t){for(var r=[];;){var n=u(e);if(!n)return;if("selfClose"!=n){var i=e.line,o=e.ch,a=s(e);if(!a)return;if(a[1])r.push(a[2]);else{for(var l=r.length-1;l>=0;--l)if(r[l]==a[2]){r.length=l;break}if(0>l&&(!t||t==a[2]))return{tag:a[2],from:f(e.line,e.ch),to:f(i,o)}}}else s(e)}}var f=e.Pos,p="A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD",g=p+"-:.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040",h=new RegExp("<(/?)(["+p+"]["+g+"]*)","g");e.registerHelper("fold","xml",function(e,t){for(var n=new r(e,t.line,0);;){var i,o=l(n);if(!o||n.line!=t.line||!(i=a(n)))return;if(!o[1]&&"selfClose"!=i){var t=f(n.line,n.ch),s=c(n,o[2]);return s&&{from:t,to:s.from}}}});e.findMatchingTag=function(e,n,i){var o=new r(e,n.line,n.ch,i);if(-1!=o.text.indexOf(">")||-1!=o.text.indexOf("<")){var l=a(o),u=l&&f(o.line,o.ch),p=l&&s(o);if(l&&p&&!(t(o,n)>0)){var g={from:f(o.line,o.ch),to:u,tag:p[2]};if("selfClose"==l)return{open:g,close:null,at:"open"};if(p[1])return{open:d(o,p[2]),close:g,at:"close"};o=new r(e,u.line,u.ch,i);return{open:g,close:c(o,p[2]),at:"open"}}}};e.findEnclosingTag=function(e,t,n){for(var i=new r(e,t.line,t.ch,n);;){var o=d(i);if(!o)break;var a=new r(e,t.line,t.ch,n),s=c(a,o.tag);if(s)return{open:o,close:s}}};e.scanForClosingTag=function(e,t,n,i){var o=new r(e,t.line,t.ch,i?{from:0,to:i}:null);return c(o,n)}})},{codemirror:void 0}],10:[function(t,r,n){(function(i){"object"==typeof n&&"object"==typeof r?i(function(){try{return t("codemirror")}catch(e){return window.CodeMirror}}()):"function"==typeof e&&e.amd?e(["../../lib/codemirror"],i):i(CodeMirror)})(function(e){"use strict";e.defineMode("javascript",function(t,r){function n(e){for(var t,r=!1,n=!1;null!=(t=e.next());){if(!r){if("/"==t&&!n)return;"["==t?n=!0:n&&"]"==t&&(n=!1)}r=!r&&"\\"==t}}function i(e,t,r){he=e;ve=r;return t}function o(e,t){var r=e.next();if('"'==r||"'"==r){t.tokenize=a(r);return t.tokenize(e,t)}if("."==r&&e.match(/^\d+(?:[eE][+\-]?\d+)?/))return i("number","number");if("."==r&&e.match(".."))return i("spread","meta");if(/[\[\]{}\(\),;\:\.]/.test(r))return i(r);if("="==r&&e.eat(">"))return i("=>","operator");if("0"==r&&e.eat(/x/i)){e.eatWhile(/[\da-f]/i);return i("number","number")}if(/\d/.test(r)){e.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);return i("number","number")}if("/"==r){if(e.eat("*")){t.tokenize=s;return s(e,t)}if(e.eat("/")){e.skipToEnd();return i("comment","comment")}if("operator"==t.lastType||"keyword c"==t.lastType||"sof"==t.lastType||/^[\[{}\(,;:]$/.test(t.lastType)){n(e);e.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);return i("regexp","string-2")}e.eatWhile(je);return i("operator","operator",e.current())}if("`"==r){t.tokenize=l;return l(e,t)}if("#"==r){e.skipToEnd();return i("error","error")}if(je.test(r)){e.eatWhile(je);return i("operator","operator",e.current())}if(ke.test(r)){e.eatWhile(ke);var o=e.current(),u=Ce.propertyIsEnumerable(o)&&Ce[o];return u&&"."!=t.lastType?i(u.type,u.style,o):i("variable","variable",o)}}function a(e){return function(t,r){var n,a=!1;if(ye&&"@"==t.peek()&&t.match(Te)){r.tokenize=o;return i("jsonld-keyword","meta")}for(;null!=(n=t.next())&&(n!=e||a);)a=!a&&"\\"==n;a||(r.tokenize=o);return i("string","string")}}function s(e,t){for(var r,n=!1;r=e.next();){if("/"==r&&n){t.tokenize=o;break}n="*"==r}return i("comment","comment")}function l(e,t){for(var r,n=!1;null!=(r=e.next());){if(!n&&("`"==r||"$"==r&&e.eat("{"))){t.tokenize=o;break}n=!n&&"\\"==r}return i("quasi","string-2",e.current())}function u(e,t){t.fatArrowAt&&(t.fatArrowAt=null);var r=e.string.indexOf("=>",e.start);if(!(0>r)){for(var n=0,i=!1,o=r-1;o>=0;--o){var a=e.string.charAt(o),s=Le.indexOf(a);if(s>=0&&3>s){if(!n){++o;break}if(0==--n)break}else if(s>=3&&6>s)++n;else if(ke.test(a))i=!0;else{if(/["'\/]/.test(a))return;if(i&&!n){++o;break}}}i&&!n&&(t.fatArrowAt=o)}}function c(e,t,r,n,i,o){this.indented=e;this.column=t;this.type=r;this.prev=i;this.info=o;null!=n&&(this.align=n)}function d(e,t){for(var r=e.localVars;r;r=r.next)if(r.name==t)return!0;for(var n=e.context;n;n=n.prev)for(var r=n.vars;r;r=r.next)if(r.name==t)return!0}function f(e,t,r,n,i){var o=e.cc;Ee.state=e;Ee.stream=i;Ee.marked=null,Ee.cc=o;Ee.style=t;e.lexical.hasOwnProperty("align")||(e.lexical.align=!0);for(;;){var a=o.length?o.pop():be?k:x;if(a(r,n)){for(;o.length&&o[o.length-1].lex;)o.pop()();return Ee.marked?Ee.marked:"variable"==r&&d(e,n)?"variable-2":t}}}function p(){for(var e=arguments.length-1;e>=0;e--)Ee.cc.push(arguments[e])}function g(){p.apply(null,arguments);return!0}function h(e){function t(t){for(var r=t;r;r=r.next)if(r.name==e)return!0;return!1}var n=Ee.state;if(n.context){Ee.marked="def"; - -if(t(n.localVars))return;n.localVars={name:e,next:n.localVars}}else{if(t(n.globalVars))return;r.globalVars&&(n.globalVars={name:e,next:n.globalVars})}}function v(){Ee.state.context={prev:Ee.state.context,vars:Ee.state.localVars};Ee.state.localVars=Me}function m(){Ee.state.localVars=Ee.state.context.vars;Ee.state.context=Ee.state.context.prev}function w(e,t){var r=function(){var r=Ee.state,n=r.indented;if("stat"==r.lexical.type)n=r.lexical.indented;else for(var i=r.lexical;i&&")"==i.type&&i.align;i=i.prev)n=i.indented;r.lexical=new c(n,Ee.stream.column(),e,null,r.lexical,t)};r.lex=!0;return r}function y(){var e=Ee.state;if(e.lexical.prev){")"==e.lexical.type&&(e.indented=e.lexical.indented);e.lexical=e.lexical.prev}}function b(e){function t(r){return r==e?g():";"==e?p():g(t)}return t}function x(e,t){if("var"==e)return g(w("vardef",t.length),H,b(";"),y);if("keyword a"==e)return g(w("form"),k,x,y);if("keyword b"==e)return g(w("form"),x,y);if("{"==e)return g(w("}"),U,y);if(";"==e)return g();if("if"==e){"else"==Ee.state.lexical.info&&Ee.state.cc[Ee.state.cc.length-1]==y&&Ee.state.cc.pop()();return g(w("form"),k,x,y,X)}return"function"==e?g(ee):"for"==e?g(w("form"),J,x,y):"variable"==e?g(w("stat"),N):"switch"==e?g(w("form"),k,w("}","switch"),b("{"),U,y,y):"case"==e?g(k,b(":")):"default"==e?g(b(":")):"catch"==e?g(w("form"),v,b("("),te,b(")"),x,y,m):"module"==e?g(w("form"),v,ae,m,y):"class"==e?g(w("form"),re,y):"export"==e?g(w("form"),se,y):"import"==e?g(w("form"),le,y):p(w("stat"),k,b(";"),y)}function k(e){return j(e,!1)}function C(e){return j(e,!0)}function j(e,t){if(Ee.state.fatArrowAt==Ee.stream.start){var r=t?R:A;if("("==e)return g(v,w(")"),O(G,")"),y,b("=>"),r,m);if("variable"==e)return p(v,G,b("=>"),r,m)}var n=t?E:S;return Se.hasOwnProperty(e)?g(n):"function"==e?g(ee,n):"keyword c"==e?g(t?L:T):"("==e?g(w(")"),T,pe,b(")"),y,n):"operator"==e||"spread"==e?g(t?C:k):"["==e?g(w("]"),de,y,n):"{"==e?I(P,"}",null,n):"quasi"==e?p(M,n):g()}function T(e){return e.match(/[;\}\)\],]/)?p():p(k)}function L(e){return e.match(/[;\}\)\],]/)?p():p(C)}function S(e,t){return","==e?g(k):E(e,t,!1)}function E(e,t,r){var n=0==r?S:E,i=0==r?k:C;return"=>"==e?g(v,r?R:A,m):"operator"==e?/\+\+|--/.test(t)?g(n):"?"==t?g(k,b(":"),i):g(i):"quasi"==e?p(M,n):";"!=e?"("==e?I(C,")","call",n):"."==e?g(D,n):"["==e?g(w("]"),T,b("]"),y,n):void 0:void 0}function M(e,t){return"quasi"!=e?p():"${"!=t.slice(t.length-2)?g(M):g(k,_)}function _(e){if("}"==e){Ee.marked="string-2";Ee.state.tokenize=l;return g(M)}}function A(e){u(Ee.stream,Ee.state);return p("{"==e?x:k)}function R(e){u(Ee.stream,Ee.state);return p("{"==e?x:C)}function N(e){return":"==e?g(y,x):p(S,b(";"),y)}function D(e){if("variable"==e){Ee.marked="property";return g()}}function P(e,t){if("variable"==e||"keyword"==Ee.style){Ee.marked="property";return g("get"==t||"set"==t?z:q)}if("number"==e||"string"==e){Ee.marked=ye?"property":Ee.style+" property";return g(q)}return"jsonld-keyword"==e?g(q):"["==e?g(k,b("]"),q):void 0}function z(e){if("variable"!=e)return p(q);Ee.marked="property";return g(ee)}function q(e){return":"==e?g(C):"("==e?p(ee):void 0}function O(e,t){function r(n){if(","==n){var i=Ee.state.lexical;"call"==i.info&&(i.pos=(i.pos||0)+1);return g(e,r)}return n==t?g():g(b(t))}return function(n){return n==t?g():p(e,r)}}function I(e,t,r){for(var n=3;n!?|~^]/,Te=/^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/,Le="([{}])",Se={atom:!0,number:!0,variable:!0,string:!0,regexp:!0,"this":!0,"jsonld-keyword":!0},Ee={state:null,column:null,marked:null,cc:null},Me={name:"this",next:{name:"arguments"}};y.lex=!0;return{startState:function(e){var t={tokenize:o,lastType:"sof",cc:[],lexical:new c((e||0)-me,0,"block",!1),localVars:r.localVars,context:r.localVars&&{vars:r.localVars},indented:0};r.globalVars&&"object"==typeof r.globalVars&&(t.globalVars=r.globalVars);return t},token:function(e,t){if(e.sol()){t.lexical.hasOwnProperty("align")||(t.lexical.align=!1);t.indented=e.indentation();u(e,t)}if(t.tokenize!=s&&e.eatSpace())return null;var r=t.tokenize(e,t);if("comment"==he)return r;t.lastType="operator"!=he||"++"!=ve&&"--"!=ve?he:"incdec";return f(t,r,he,ve,e)},indent:function(t,n){if(t.tokenize==s)return e.Pass;if(t.tokenize!=o)return 0;var i=n&&n.charAt(0),a=t.lexical;if(!/^\s*else\b/.test(n))for(var l=t.cc.length-1;l>=0;--l){var u=t.cc[l];if(u==y)a=a.prev;else if(u!=X)break}"stat"==a.type&&"}"==i&&(a=a.prev);we&&")"==a.type&&"stat"==a.prev.type&&(a=a.prev);var c=a.type,d=i==c;return"vardef"==c?a.indented+("operator"==t.lastType||","==t.lastType?a.info+1:0):"form"==c&&"{"==i?a.indented:"form"==c?a.indented+me:"stat"==c?a.indented+(ge(t,n)?we||me:0):"switch"!=a.info||d||0==r.doubleIndentSwitch?a.align?a.column+(d?0:1):a.indented+(d?0:me):a.indented+(/^(?:case|default)\b/.test(n)?me:2*me)},electricInput:/^\s*(?:case .*?:|default:|\{|\})$/,blockCommentStart:be?null:"/*",blockCommentEnd:be?null:"*/",lineComment:be?null:"//",fold:"brace",helperType:be?"json":"javascript",jsonldMode:ye,jsonMode:be}});e.registerHelper("wordChars","javascript",/[\w$]/);e.defineMIME("text/javascript","javascript");e.defineMIME("text/ecmascript","javascript");e.defineMIME("application/javascript","javascript");e.defineMIME("application/x-javascript","javascript");e.defineMIME("application/ecmascript","javascript");e.defineMIME("application/json",{name:"javascript",json:!0});e.defineMIME("application/x-json",{name:"javascript",json:!0});e.defineMIME("application/ld+json",{name:"javascript",jsonld:!0});e.defineMIME("text/typescript",{name:"javascript",typescript:!0});e.defineMIME("application/typescript",{name:"javascript",typescript:!0})})},{codemirror:void 0}],11:[function(t,r,n){(function(i){"object"==typeof n&&"object"==typeof r?i(function(){try{return t("codemirror")}catch(e){return window.CodeMirror}}()):"function"==typeof e&&e.amd?e(["../../lib/codemirror"],i):i(CodeMirror)})(function(e){"use strict";e.defineMode("xml",function(t,r){function n(e,t){function r(r){t.tokenize=r;return r(e,t)}var n=e.next();if("<"==n){if(e.eat("!")){if(e.eat("["))return e.match("CDATA[")?r(a("atom","]]>")):null;if(e.match("--"))return r(a("comment","-->"));if(e.match("DOCTYPE",!0,!0)){e.eatWhile(/[\w\._\-]/);return r(s(1))}return null}if(e.eat("?")){e.eatWhile(/[\w\._\-]/);t.tokenize=a("meta","?>");return"meta"}C=e.eat("/")?"closeTag":"openTag";t.tokenize=i;return"tag bracket"}if("&"==n){var o;o=e.eat("#")?e.eat("x")?e.eatWhile(/[a-fA-F\d]/)&&e.eat(";"):e.eatWhile(/[\d]/)&&e.eat(";"):e.eatWhile(/[\w\.\-:]/)&&e.eat(";");return o?"atom":"error"}e.eatWhile(/[^&<]/);return null}function i(e,t){var r=e.next();if(">"==r||"/"==r&&e.eat(">")){t.tokenize=n;C=">"==r?"endTag":"selfcloseTag";return"tag bracket"}if("="==r){C="equals";return null}if("<"==r){t.tokenize=n;t.state=d;t.tagName=t.tagStart=null;var i=t.tokenize(e,t);return i?i+" tag error":"tag error"}if(/[\'\"]/.test(r)){t.tokenize=o(r);t.stringStartCol=e.column();return t.tokenize(e,t)}e.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);return"word"}function o(e){var t=function(t,r){for(;!t.eol();)if(t.next()==e){r.tokenize=i;break}return"string"};t.isInAttribute=!0;return t}function a(e,t){return function(r,i){for(;!r.eol();){if(r.match(t)){i.tokenize=n;break}r.next()}return e}}function s(e){return function(t,r){for(var i;null!=(i=t.next());){if("<"==i){r.tokenize=s(e+1);return r.tokenize(t,r)}if(">"==i){if(1==e){r.tokenize=n;break}r.tokenize=s(e-1);return r.tokenize(t,r)}}return"meta"}}function l(e,t,r){this.prev=e.context;this.tagName=t;this.indent=e.indented;this.startOfLine=r;(T.doNotIndent.hasOwnProperty(t)||e.context&&e.context.noIndent)&&(this.noIndent=!0)}function u(e){e.context&&(e.context=e.context.prev)}function c(e,t){for(var r;;){if(!e.context)return;r=e.context.tagName;if(!T.contextGrabbers.hasOwnProperty(r)||!T.contextGrabbers[r].hasOwnProperty(t))return;u(e)}}function d(e,t,r){if("openTag"==e){r.tagStart=t.column();return f}return"closeTag"==e?p:d}function f(e,t,r){if("word"==e){r.tagName=t.current();j="tag";return v}j="error";return f}function p(e,t,r){if("word"==e){var n=t.current();r.context&&r.context.tagName!=n&&T.implicitlyClosed.hasOwnProperty(r.context.tagName)&&u(r);if(r.context&&r.context.tagName==n){j="tag";return g}j="tag error";return h}j="error";return h}function g(e,t,r){if("endTag"!=e){j="error";return g}u(r);return d}function h(e,t,r){j="error";return g(e,t,r)}function v(e,t,r){if("word"==e){j="attribute";return m}if("endTag"==e||"selfcloseTag"==e){var n=r.tagName,i=r.tagStart;r.tagName=r.tagStart=null;if("selfcloseTag"==e||T.autoSelfClosers.hasOwnProperty(n))c(r,n);else{c(r,n);r.context=new l(r,n,i==r.indented)}return d}j="error";return v}function m(e,t,r){if("equals"==e)return w;T.allowMissing||(j="error");return v(e,t,r)}function w(e,t,r){if("string"==e)return y;if("word"==e&&T.allowUnquoted){j="string";return v}j="error";return v(e,t,r)}function y(e,t,r){return"string"==e?y:v(e,t,r)}var b=t.indentUnit,x=r.multilineTagIndentFactor||1,k=r.multilineTagIndentPastTag;null==k&&(k=!0);var C,j,T=r.htmlMode?{autoSelfClosers:{area:!0,base:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0,menuitem:!0},implicitlyClosed:{dd:!0,li:!0,optgroup:!0,option:!0,p:!0,rp:!0,rt:!0,tbody:!0,td:!0,tfoot:!0,th:!0,tr:!0},contextGrabbers:{dd:{dd:!0,dt:!0},dt:{dd:!0,dt:!0},li:{li:!0},option:{option:!0,optgroup:!0},optgroup:{optgroup:!0},p:{address:!0,article:!0,aside:!0,blockquote:!0,dir:!0,div:!0,dl:!0,fieldset:!0,footer:!0,form:!0,h1:!0,h2:!0,h3:!0,h4:!0,h5:!0,h6:!0,header:!0,hgroup:!0,hr:!0,menu:!0,nav:!0,ol:!0,p:!0,pre:!0,section:!0,table:!0,ul:!0},rp:{rp:!0,rt:!0},rt:{rp:!0,rt:!0},tbody:{tbody:!0,tfoot:!0},td:{td:!0,th:!0},tfoot:{tbody:!0},th:{td:!0,th:!0},thead:{tbody:!0,tfoot:!0},tr:{tr:!0}},doNotIndent:{pre:!0},allowUnquoted:!0,allowMissing:!0,caseFold:!0}:{autoSelfClosers:{},implicitlyClosed:{},contextGrabbers:{},doNotIndent:{},allowUnquoted:!1,allowMissing:!1,caseFold:!1},L=r.alignCDATA;return{startState:function(){return{tokenize:n,state:d,indented:0,tagName:null,tagStart:null,context:null}},token:function(e,t){!t.tagName&&e.sol()&&(t.indented=e.indentation());if(e.eatSpace())return null;C=null;var r=t.tokenize(e,t);if((r||C)&&"comment"!=r){j=null;t.state=t.state(C||r,e,t);j&&(r="error"==j?r+" error":j)}return r},indent:function(t,r,o){var a=t.context;if(t.tokenize.isInAttribute)return t.tagStart==t.indented?t.stringStartCol+1:t.indented+b;if(a&&a.noIndent)return e.Pass;if(t.tokenize!=i&&t.tokenize!=n)return o?o.match(/^(\s*)/)[0].length:0;if(t.tagName)return k?t.tagStart+t.tagName.length+2:t.tagStart+b*x;if(L&&/$/,blockCommentStart:"",configuration:r.htmlMode?"html":"xml",helperType:r.htmlMode?"html":"xml"}});e.defineMIME("text/xml","xml");e.defineMIME("application/xml","xml");e.mimeModes.hasOwnProperty("text/html")||e.defineMIME("text/html",{name:"xml",htmlMode:!0})})},{codemirror:void 0}],12:[function(t,r,n){(function(){var i;i=function(i){return"object"==typeof n&&"object"==typeof r?i(function(){try{return t("jquery")}catch(e){return window.jQuery}}()):"function"==typeof e&&e.amd?e(["jquery"],i):i(jQuery)};i(function(e){return e.pivotUtilities.d3_renderers={Treemap:function(t,r){var n,i,o,a,s,l,u,c,d,f,p,g,h;o={localeStrings:{},d3:{width:function(){return e(window).width()/1.4},height:function(){return e(window).height()/1.4}}};r=e.extend(o,r);c=e("
      ").css({width:"100%",height:"100%"});f={name:"All",children:[]};n=function(e,t,r){var i,o,a,s,l,u;if(0!==t.length){null==e.children&&(e.children=[]);u=t.shift();l=e.children;for(o=0,a=l.length;a>o;o++){i=l[o];if(i.name===u){n(i,t,r);return}}s={name:u};n(s,t,r);return e.children.push(s)}e.value=r};u=t.getRowKeys();for(s=0,l=u.length;l>s;s++){d=u[s];g=t.getAggregator(d,[]).value();null!=g&&n(f,d,g)}i=d3.scale.category10();h=r.d3.width();a=r.d3.height();p=d3.layout.treemap().size([h,a]).sticky(!0).value(function(e){return e.size});d3.select(c[0]).append("div").style("position","relative").style("width",h+"px").style("height",a+"px").datum(f).selectAll(".node").data(p.padding([15,0,0,0]).value(function(e){return e.value}).nodes).enter().append("div").attr("class","node").style("background",function(e){return null!=e.children?"lightgrey":i(e.name)}).text(function(e){return e.name}).call(function(){this.style("left",function(e){return e.x+"px"}).style("top",function(e){return e.y+"px"}).style("width",function(e){return Math.max(0,e.dx-1)+"px"}).style("height",function(e){return Math.max(0,e.dy-1)+"px"})});return c}}})}).call(this)},{jquery:void 0}],13:[function(t,r,n){(function(){var i;i=function(i){return"object"==typeof n&&"object"==typeof r?i(function(){try{return t("jquery")}catch(e){return window.jQuery}}()):"function"==typeof e&&e.amd?e(["jquery"],i):i(jQuery)};i(function(e){var t;t=function(t,r){return function(n,i){var o,a,s,l,u,c,d,f,p,g,h,v,m,w,y,b,x,k,C,j,T,L,S,E,M,_,A,R,N,D,P;f={localeStrings:{vs:"vs",by:"by"},gchart:{}};i=e.extend(!0,f,i);null==(a=i.gchart).width&&(a.width=window.innerWidth/1.4);null==(s=i.gchart).height&&(s.height=window.innerHeight/1.4);E=n.getRowKeys();0===E.length&&E.push([]);u=n.getColKeys();0===u.length&&u.push([]);p=n.aggregatorName;n.valAttrs.length&&(p+="("+n.valAttrs.join(", ")+")");m=function(){var e,t,r;r=[];for(e=0,t=E.length;t>e;e++){h=E[e];r.push(h.join("-"))}return r}();m.unshift("");k=0;if("ScatterChart"===t){c=[];j=n.tree;for(P in j){_=j[P];for(D in _){o=_[D];c.push([parseFloat(D),parseFloat(P),p+": \n"+o.format(o.value())])}}d=new google.visualization.DataTable;d.addColumn("number",n.colAttrs.join("-"));d.addColumn("number",n.rowAttrs.join("-"));d.addColumn({type:"string",role:"tooltip"});d.addRows(c);v=n.colAttrs.join("-");A=n.rowAttrs.join("-");M=""}else{c=[m];for(w=0,b=u.length;b>w;w++){l=u[w];L=[l.join("-")];k+=L[0].length;for(y=0,x=E.length;x>y;y++){S=E[y];o=n.getAggregator(S,l);if(null!=o.value()){R=o.value();L.push(e.isNumeric(R)?1>R?parseFloat(R.toPrecision(3)):parseFloat(R.toFixed(3)):R)}else L.push(null)}c.push(L)}d=google.visualization.arrayToDataTable(c);M=A=p;v=n.colAttrs.join("-");""!==v&&(M+=" "+i.localeStrings.vs+" "+v);g=n.rowAttrs.join("-");""!==g&&(M+=" "+i.localeStrings.by+" "+g)}C={title:M,hAxis:{title:v,slantedText:k>50},vAxis:{title:A},tooltip:{textStyle:{fontName:"Arial",fontSize:12}}};"ColumnChart"===t&&(C.vAxis.minValue=0);if("ScatterChart"===t){C.legend={position:"none"};C.chartArea={width:"80%",height:"80%"}}else 2===c[0].length&&""===c[0][1]&&(C.legend={position:"none"});e.extend(C,i.gchart,r);T=e("
      ").css({width:"100%",height:"100%"});N=new google.visualization.ChartWrapper({dataTable:d,chartType:t,options:C});N.draw(T[0]);T.bind("dblclick",function(){var e;e=new google.visualization.ChartEditor;google.visualization.events.addListener(e,"ok",function(){return e.getChartWrapper().draw(T[0])});return e.openDialog(N)});return T}};return e.pivotUtilities.gchart_renderers={"Line Chart":t("LineChart"),"Bar Chart":t("ColumnChart"),"Stacked Bar Chart":t("ColumnChart",{isStacked:!0}),"Area Chart":t("AreaChart",{isStacked:!0}),"Scatter Chart":t("ScatterChart")}})}).call(this)},{jquery:void 0}],14:[function(t,r,n){(function(t){function n(){try{return l in t&&t[l]}catch(e){return!1}}function i(e){return e.replace(/^d/,"___$&").replace(g,"___")}var o,a={},s=t.document,l="localStorage",u="script";a.disabled=!1;a.version="1.3.17";a.set=function(e,t){};a.get=function(e,t){};a.has=function(e){return void 0!==a.get(e)};a.remove=function(e){};a.clear=function(){};a.transact=function(e,t,r){if(null==r){r=t;t=null}null==t&&(t={});var n=a.get(e,t);r(n);a.set(e,n)};a.getAll=function(){};a.forEach=function(){};a.serialize=function(e){return JSON.stringify(e)};a.deserialize=function(e){if("string"!=typeof e)return void 0;try{return JSON.parse(e)}catch(t){return e||void 0}};if(n()){o=t[l];a.set=function(e,t){if(void 0===t)return a.remove(e);o.setItem(e,a.serialize(t));return t};a.get=function(e,t){var r=a.deserialize(o.getItem(e));return void 0===r?t:r};a.remove=function(e){o.removeItem(e)};a.clear=function(){o.clear()};a.getAll=function(){var e={};a.forEach(function(t,r){e[t]=r});return e};a.forEach=function(e){for(var t=0;tdocument.w=window');d.close();c=d.w.frames[0].document;o=c.createElement("div")}catch(f){o=s.createElement("div");c=s.body}var p=function(e){return function(){var t=Array.prototype.slice.call(arguments,0);t.unshift(o);c.appendChild(o);o.addBehavior("#default#userData");o.load(l);var r=e.apply(a,t);c.removeChild(o);return r}},g=new RegExp("[!\"#$%&'()*+,/\\\\:;<=>?@[\\]^`{|}~]","g");a.set=p(function(e,t,r){t=i(t);if(void 0===r)return a.remove(t);e.setAttribute(t,a.serialize(r));e.save(l);return r});a.get=p(function(e,t,r){t=i(t);var n=a.deserialize(e.getAttribute(t));return void 0===n?r:n});a.remove=p(function(e,t){t=i(t);e.removeAttribute(t);e.save(l)});a.clear=p(function(e){var t=e.XMLDocument.documentElement.attributes;e.load(l);for(var r,n=0;r=t[n];n++)e.removeAttribute(r.name);e.save(l)});a.getAll=function(e){var t={};a.forEach(function(e,r){t[e]=r});return t};a.forEach=p(function(e,t){for(var r,n=e.XMLDocument.documentElement.attributes,i=0;r=n[i];++i)t(r.name,a.deserialize(e.getAttribute(r.name)))})}try{var h="__storejs__";a.set(h,h);a.get(h)!=h&&(a.disabled=!0);a.remove(h)}catch(f){a.disabled=!0}a.enabled=!a.disabled;"undefined"!=typeof r&&r.exports&&this.module!==r?r.exports=a:"function"==typeof e&&e.amd?e(a):t.store=a})(Function("return this")())},{}],15:[function(e,t,r){t.exports={name:"yasgui-utils",version:"1.6.0",description:"Utils for YASGUI libs",main:"src/main.js",repository:{type:"git",url:"git://github.com/YASGUI/Utils.git"},licenses:[{type:"MIT",url:"http://yasgui.github.io/license.txt"}],author:{name:"Laurens Rietveld"},maintainers:[{name:"Laurens Rietveld",email:"laurens.rietveld@gmail.com",url:"http://laurensrietveld.nl"}],bugs:{url:"https://github.com/YASGUI/Utils/issues"},homepage:"https://github.com/YASGUI/Utils",dependencies:{store:"^1.3.14"},readme:"A simple utils repo for the YASGUI tools\n",readmeFilename:"README.md",_id:"yasgui-utils@1.6.0",_from:"yasgui-utils@>=1.4.1 <2.0.0"}},{}],16:[function(e,t,r){window.console=window.console||{log:function(){}};t.exports={storage:e("./storage.js"),svg:e("./svg.js"),version:{"yasgui-utils":e("../package.json").version},nestedExists:function(e){for(var t=Array.prototype.slice.call(arguments,1),r=0;rt.exp?null:t.val:null}return null}}},{store:14}],18:[function(e,t,r){t.exports={draw:function(e,r){if(e){var n=t.exports.getElement(r);n&&(e.append?e.append(n):e.appendChild(n))}},getElement:function(e){if(e&&0==e.indexOf("=1.11.3",datatables:"^1.10.7",codemirror:"^4.7.0","yasgui-utils":"^1.4.1",pivottable:"^1.2.2","jquery-ui":"^1.10.5",d3:"^3.4.13"},"browserify-shim":{google:"global:google"},browserify:{transform:["browserify-shim"]},optionalShim:{codemirror:{require:"codemirror",global:"CodeMirror"},jquery:{require:"jquery",global:"jQuery"},"../../lib/codemirror":{require:"codemirror",global:"CodeMirror"},datatables:{require:"datatables",global:"jQuery"},d3:{require:"d3",global:"d3"},"jquery-ui/sortable":{require:"jquery-ui/sortable",global:"jQuery"},pivottable:{require:"pivottable",global:"jQuery"}}}},{}],20:[function(e,t,r){"use strict";t.exports=function(e){var t='"',r=",",n="\n",i=e.head.vars,o=e.results.bindings,a=function(){for(var e=0;e
      "),i=function(){r.empty().appendTo(t.resultsContainer);var i=t.results.getBoolean(),o=null,a=null;if(i===!0){o="check";a="True"}else if(i===!1){o="cross";a="False"}else{r.width("140");a="Could not find boolean value in response"}o&&e("yasgui-utils").svg.draw(r,e("./imgs.js")[o]);n("").text(a).appendTo(r)},o=function(){return t.results.getBoolean&&(t.results.getBoolean()===!0||0==t.results.getBoolean())};return{name:null,draw:i,hideFromSelection:!0,getPriority:10,canHandleResults:o}};i.version={"YASR-boolean":e("../package.json").version,jquery:n.fn.jquery}},{"../package.json":19,"./imgs.js":27,jquery:void 0,"yasgui-utils":16}],22:[function(e,t,r){"use strict";var n=function(){try{return e("jquery")}catch(t){return window.jQuery}}();t.exports={output:"table",useGoogleCharts:!0,outputPlugins:["table","error","boolean","rawResponse","pivot","gchart"],drawOutputSelector:!0,drawDownloadIcon:!0,getUsedPrefixes:null,persistency:{prefix:function(e){return"yasr_"+n(e.container).closest("[id]").attr("id")+"_"},outputSelector:function(e){return"selector"},results:{id:function(e){return"results_"+n(e.container).closest("[id]").attr("id")},key:"results",maxSize:1e5}}}},{jquery:void 0}],23:[function(e,t,r){"use strict";var n=function(){try{return e("jquery")}catch(t){return window.jQuery}}(),i=t.exports=function(e){var t=n("
      "),r=n.extend(!0,{},i.defaults),o=function(){var e=null;if(r.tryQueryLink){var t=r.tryQueryLink();e=n("").text(a).addClass("select_"+i).click(function(){e.find("button.selected").removeClass("selected");n(this).addClass("selected");t.options.output=i;t.store();f&&f.hide(400);t.draw()}).appendTo(e);t.options.output==i&&s.addClass("selected")}});e.children().length>1&&t.header.append(e)},i=function(){var r=function(e,t){var r=null,n=window.URL||window.webkitURL||window.mozURL||window.msURL;if(n&&Blob){var i=new Blob([e],{type:t});r=n.createObjectURL(i)}return r},i=n("").append(e("yasgui-utils").svg.getElement(e("./imgs.js").download)).click(function(){var i=t.plugins[t.options.output];if(i&&i.getDownloadInfo){var o=i.getDownloadInfo(),a=r(o.getContent(),o.contentType?o.contentType:"text/plain"),s=n("",{href:a,download:o.filename});e("./utils.js").fireClick(s)}});t.header.append(i)},o=function(){var r=n("").append(e("yasgui-utils").svg.getElement(e("./imgs.js").fullscreen)).click(function(){t.container.addClass("yasr_fullscreen")});t.header.append(r)},a=function(){var r=n("").append(e("yasgui-utils").svg.getElement(e("./imgs.js").smallscreen)).click(function(){t.container.removeClass("yasr_fullscreen")});t.header.append(r)},s=function(){m=n("
      \")\n\n renderer = $(\"\")\n shownAttributes = (c for c in tblCols when c not in opts.hiddenAttributes)\n\n unusedAttrsVerticalAutoOverride = false\n if opts.unusedAttrsVertical == \"auto\"\n attrLength = 0\n attrLength += a.length for a in shownAttributes\n unusedAttrsVerticalAutoOverride = attrLength > 120\n\n if opts.unusedAttrsVertical == true or unusedAttrsVerticalAutoOverride\n colList.addClass('pvtVertList')\n else\n colList.addClass('pvtHorizList')\n\n for i, c of shownAttributes\n do (c) ->\n keys = (k for k of axisValues[c])\n hasExcludedItem = false\n valueList = $(\"
      \").addClass('pvtFilterBox').hide()\n\n valueList.append $(\"

      \").text(\"#{c} (#{keys.length})\")\n if keys.length > opts.menuLimit\n valueList.append $(\"

      \").html(opts.localeStrings.tooMany)\n else\n btns = $(\"

      \").appendTo(valueList)\n btns.append $(\"

      \")\n .appendTo(tr1)\n .append(aggregator)\n .append($(\"
      \"))\n\n #column axes\n $(\"
      \").appendTo(tr1)\n\n tr2 = $(\"
      \")\n\n #the actual pivot table container\n pivotTable = $(\"\").appendTo(tr2)\n\n #finally the renderer dropdown and unused attribs are inserted at the requested location\n if opts.unusedAttrsVertical == true or unusedAttrsVerticalAutoOverride\n uiTable.find('tr:nth-child(1)').prepend rendererControl\n uiTable.find('tr:nth-child(2)').prepend colList\n else\n uiTable.prepend $(\"