| 1 | # always use LF line endings | |
| 2 | ||
| 3 | # ALL FILES: | |
| 4 | # Normalize line endings to LF on checkin and | |
| 5 | # prevent conversion to CRLF when the file is checked out. | |
| 6 | ||
| 7 | * text eol=lf | |
| 8 | ||
| 9 | ||
| 10 | # BINARY FILES: | |
| 11 | # Disable line ending normalize on checkin. | |
| 1 | 12 | |
| 13 | *.bin binary | |
| 14 | *.exe binary | |
| 15 | *.gif binary | |
| 16 | *.jar bina |
| 1 | --- | |
| 2 | name: Bug report | |
| 3 | about: Create a report to help us improve | |
| 4 | title: '' | |
| 5 | labels: bug | |
| 6 | assignees: '' | |
| 7 | ||
| 8 | --- | |
| 9 | ||
| 10 | **Description** | |
| 11 | A concise problem description. | |
| 12 | ||
| 13 | **Replicate** | |
| 14 | Exact and complete steps to reproduce the problem 100% of the time: | |
| 15 | ||
| 16 | 1. Open '...' | |
| 17 | 1. Click '....' | |
| 18 | 1. Click '....' | |
| 19 | ||
| 20 | **Expected** | |
| 21 | Describe the expected behaviour. | |
| 22 | ||
| 23 | **Actual** | |
| 24 | Describe the actual behaviour. | |
| 25 | ||
| 26 | **Screenshots** | |
| 27 | Add screenshots to show the problem, if applicable. | |
| 28 | ||
| 29 | **Environment** | |
| 30 | - Operating System: (Windows, Linux, Mac) | |
| 31 | - Application: e.g., 1.7.16 | |
| 32 | ||
| 33 | **Details** | |
| 34 | Add additional information, if applicable. | |
| 1 | 35 |
| 1 | dist | |
| 2 | *.bin | |
| 3 | *.exe | |
| 4 | /*.jar | |
| 5 | build | |
| 6 | .gradle | |
| 7 | contacted.csv | |
| 8 | video | |
| 9 | .settings | |
| 10 | .classpath | |
| 11 | .idea | |
| 1 | 12 |
| 1 | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | <projectDescription> | |
| 3 | <name>Markdown Writer FX</name> | |
| 4 | <comment></comment> | |
| 5 | <projects> | |
| 6 | </projects> | |
| 7 | <buildSpec> | |
| 8 | <buildCommand> | |
| 9 | <name>org.eclipse.jdt.core.javabuilder</name> | |
| 10 | <arguments> | |
| 11 | </arguments> | |
| 12 | </buildCommand> | |
| 13 | <buildCommand> | |
| 14 | <name>org.eclipse.buildship.core.gradleprojectbuilder</name> | |
| 15 | <arguments> | |
| 16 | </arguments> | |
| 17 | </buildCommand> | |
| 18 | </buildSpec> | |
| 19 | <natures> | |
| 20 | <nature>org.eclipse.jdt.core.javanature</nature> | |
| 21 | <nature>org.eclipse.buildship.core.gradleprojectnature</nature> | |
| 22 | </natures> | |
| 23 | <filteredResources> | |
| 24 | <filter> | |
| 25 | <id>1438449113801</id> | |
| 26 | <name></name> | |
| 27 | <type>26</type> | |
| 28 | <matcher> | |
| 29 | <id>org.eclipse.ui.ide.multiFilter</id> | |
| 30 | <arguments>1.0-projectRelativePath-matches-false-false-build</arguments> | |
| 31 | </matcher> | |
| 32 | </filter> | |
| 33 | <filter> | |
| 34 | <id>1438449113801</id> | |
| 35 | <name></name> | |
| 36 | <type>26</type> | |
| 37 | <matcher> | |
| 38 | <id>org.eclipse.ui.ide.multiFilter</id> | |
| 39 | <arguments>1.0-projectRelativePath-matches-false-false-.gradle</arguments> | |
| 40 | </matcher> | |
| 41 | </filter> | |
| 42 | </filteredResources> | |
| 43 | </projectDescription> | |
| 1 | 44 |
| 1 | # Introduction | |
| 2 | ||
| 3 | This document describes how to build the application and platform binaries. | |
| 4 | ||
| 5 | # Requirements | |
| 6 | ||
| 7 | Download and install the following software packages: | |
| 8 | ||
| 9 | * [OpenJDK 14.0.2](https://openjdk.java.net) (full JDK, including JavaFX) | |
| 10 | * [Gradle 6.4](https:* [Git 2.28.0](https://git-scimport Running the application should trigger a build IntellIJ's IDEA. | |
| 1 | 11 | |
| 12 | ### Importimport |
| 1 | # Contributor Covenant Code of Conduct | |
| 2 | ||
| 3 | ## Our Pledge | |
| 4 | ||
| 5 | In the interest of fostering an open and welcoming environment, we as | |
| 6 | contributors and maintainers pledge to making participation in our project and | |
| 7 | our community a harassment-free experience for everyone, regardless of age, body | |
| 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, | |
| 9 | level of experience, education, socio-economic status, nationality, personal | |
| 10 | appearance, race, religion, or sexual identity and orientation. | |
| 11 | ||
| 12 | ## Our Standards | |
| 13 | ||
| 14 | Examples of behavior that contributes to creating a positive environment | |
| 15 | include: | |
| 16 | ||
| 17 | * Using welcoming and inclusive language | |
| 18 | * Being respectful of differing viewpoints and experiences | |
| 19 | * Gracefully accepting constructive criticism | |
| 20 | * Focusing on what is best for the community | |
| 21 | * Showing empathy towards other community members | |
| 22 | ||
| 23 | Examples of unacceptable behavior by participants include: | |
| 24 | ||
| 25 | * The use of sexualized language or imagery and unwelcome sexual attention or | |
| 26 | advances | |
| 27 | * Trolling, insulting/derogatory comments, and personal or political attacks | |
| 28 | * Public or private harassment | |
| 29 | * Publishing others' private information, such as a physical or electronic | |
| 30 | address, without explicit permission | |
| 31 | * Other conduct which could reasonably be considered inappropriate in a | |
| 32 | professional setting | |
| 33 | ||
| 34 | ## Our Responsibilities | |
| 35 | ||
| 36 | Project maintainers are responsible for clarifying the standards of acceptable | |
| 37 | behavior and are expected to take appropriate and fair corrective action in | |
| 38 | response to any instances of unacceptable behavior. | |
| 39 | ||
| 40 | Project maintainers have the right and responsibility to remove, edit, or | |
| 41 | reject comments, commits, code, wiki edits, issues, and other contributions | |
| 42 | that are not aligned to this Code of Conduct, or to ban temporarily or | |
| 43 | permanently any contributor for other behaviors that they deem inappropriate, | |
| 44 | threatening, offensive, or harmful. | |
| 45 | ||
| 46 | ## Scope | |
| 47 | ||
| 48 | This Code of Conduct applies both within project spaces and in public spaces | |
| 49 | when an individual is representing the project or its community. Examples of | |
| 50 | representing a project or community include using an official project e-mail | |
| 51 | address, posting via an official social media account, or acting as an appointed | |
| 52 | representative at an online or offline event. Representation of a project may be | |
| 53 | further defined and clarified by project maintainers. | |
| 54 | ||
| 55 | ## Enforcement | |
| 56 | ||
| 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be | |
| 58 | reported by contacting the project team at Dave.Jarvis@gmail.com. All | |
| 59 | complaints will be reviewed and investigated and will result in a response that | |
| 60 | is deemed necessary and appropriate to the circumstances. The project team is | |
| 61 | obligated to maintain confidentiality with regard to the reporter of an incident. | |
| 62 | Further details of specific enforcement policies may be posted separately. | |
| 63 | ||
| 64 | Project maintainers who do not follow or enforce the Code of Conduct in good | |
| 65 | faith may face temporary or permanent repercussions as determined by other | |
| 66 | members of the project's leadership. | |
| 67 | ||
| 68 | ## Attribution | |
| 69 | ||
| 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, | |
| 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html | |
| 72 | ||
| 73 | [homepage]: https://www.contributor-covenant.org | |
| 74 | ||
| 75 | For answers to common questions about this code of conduct, see | |
| 76 | https://www.contributor-covenant.org/faq | |
| 1 | 77 |
| 1 | # License | |
| 2 | ||
| 3 | Copyright 2020All rights reserved. | |
| 4 | ||
| 5 | Redist | |
| 6 | Copyright 2015 Karl Tauber | |
| 7 | tribution and use in source and binary forms, with or without | |
| 8 | modification, are permitted provided that the following conditions are met: | |
| 1 | 9 |
| 1 | From https://github.com/greenrobot/EventBus#r8-proguard | |
| 2 | ||
| 3 | -keepattributes *Annotation* | |
| 4 | -keepclassmembers class * { | |
| 5 | @org.greenrobot.eventbus.Subscribe <methods>; | |
| 6 | } | |
| 7 | -keep enum org.greenrobot.eventbus.ThreadMode { *; } | |
| 8 | ||
| 1 | 9 |
| 1 | # R Functions | |
| 2 | ||
| 3 | Import the files in this directory into the application, which include: | |
| 4 | ||
| 5 | * pluralize.R | |
| 6 | * possessive.R | |
| 7 | * conversion.R | |
| 8 | * csv.R | |
| 9 | ||
| 10 | # pluralize.R | |
| 11 | ||
| 12 | This file defines a function that implements most of Damian Conway's [An Algorithmic Approach to English Pluralization](http://blob.perl.org/tpc/1998/User_Applications/Algorithmic%20Approach%20Plurals/Algorithmic_Plurals.html). | |
| 13 | ||
| 14 | ## Usage | |
| 15 | ||
| 16 | Example usages of the pluralize function include: | |
| 17 | ||
| 18 | `r#pluralize( 'mouse' )` - mice | |
| 19 | `r#pluralize( 'buzz' )` - buzzes | |
| 20 | `r#pluralize( 'bus' )` - busses | |
| 21 | ||
| 22 | # possessive.R | |
| 23 | ||
| 24 | This file defines a function that applies possessives to English words. | |
| 25 | ||
| 26 | ## Usage | |
| 27 | ||
| 28 | Example usages of the possessive function include: | |
| 29 | ||
| 30 | `r#pos( 'Ross' )` - Ross' | |
| 31 | `r#pos( 'Ruby' )` - Ruby's | |
| 32 | `r#pos( 'Lois' )` - Lois' | |
| 33 | `r#pos( 'my' )` - mine | |
| 34 | `r#pos( 'Your' )` - Yours | |
| 35 | ||
| 1 | 36 |
| 1 | setwd( '{{application.r.working.directory}}' ) | |
| 2 | assign( "anchor", '{{date.anchor}}', envir = .GlobalEnv ) | |
| 3 | ||
| 4 | source( 'pluralize.R' ) | |
| 5 | source( 'possessive.R' ) | |
| 6 | source( 'conversion.R' ) | |
| 7 | source( 'csv.R' ) | |
| 8 | ||
| 1 | 9 |
| 1 | ||
| 1 | # ----------------------------------------------------------------------------- | |
| 2 | # Copyright 2020, White Magic Software, Ltd. | |
| 3 | # | |
| 4 | # Permission is hereby granted, free of charge, to any person obtaining | |
| 5 | # a copy of this software and associated documentation zzz |
| 1 | # ----------------------------------------------------------------------------- | |
| 2 | # Copyright 2020, White Magic Software, Ltd. | |
| 3 | # | |
| 4 | # Permission is hereby granted, free of charge, to any person obtaining | |
| 5 | # a copy of this software and associated documentation files ----------------------------------------------------------------------------- | |
| 1 | 6 | |
| 7 | # -----------------------------------------------------------------------------# -----------------------------------------------------------------------------2s |
| 1 | # ----------------------------------------------------------------------------- | |
| 2 | # Copyright 2020, White Magic Software, Ltd. | |
| 3 | # | |
| 4 | # Permission is hereby granted, free of charge, to any person obtaining | |
| 5 | # a copy of this software and associated documentation files ----------------------------------------------------------------------------- | |
| 1 | 6 | |
| 7 | # ----------------------------------------------------------------------------- -----------------------------------------------------------------------------es|zz|x|, -zz, -x, -[aeiou]y11. Change -[aeiou]y to -y2. Change -y to -ix. Change -z to -zzze-----------------------------------------------------------------------------# ----------------------------------------------------------------------------------------------------------------------------------------------------------# ----------------------------------------------------------------------------------------------------------------------------------------------------------# ----------------------------------------------------------------------------- | |
| 8 | "Bhutanese", | |
| 9 | "bison", | |
| 10 | "bream", | |
| 11 | "Burmese", | |
| 12 | "carp", | |
| 13 | "chassis", | |
| 14 | "Chinese", | |
| 15 | "clippers", | |
| 16 | "cod", | |
| 17 | "contretemps", | |
| 18 | "corps", | |
| 19 | "debris", | |
| 20 | "djinn", | |
| 21 | "eland", | |
| 22 | "elk", | |
| 23 | "flounder", | |
| 24 | "fracas", | |
| 25 | "gallows", | |
| 26 | "graffiti", | |
| 27 | "headquarters", | |
| 28 | ||
| 29 | "hovercraft", | |
| 30 | "innings", | |
| 31 | "Japanese", | |
| 32 | "Lebanese", | |
| 33 | "mackerel", | |
| 34 | "means", | |
| 35 | "mews", | |
| 36 | "mice", | |
| 37 | "mumps", | |
| 38 | ||
| 39 | "pliers", | |
| 40 | "Portuguese", | |
| 41 | "proceedings", | |
| 42 | "salmon", | |
| 43 | "scissors", | |
| 44 | "sea-bass", | |
| 45 | "Senegalese", | |
| 46 | "shears", | |
| 47 | ||
| 48 | "spacecraft", | |
| 49 | "swine", | |
| 50 | "trout", | |
| 51 | "tuna", | |
| 52 | "Vietnamese", | |
| 53 | "watercraft", | |
| 54 | "whiting", | |
| 55 | "wildebeest" | |
| 56 | -----------------------------------------------------------------------------# ----------------------------------------------------------------------------- | |
| 57 | pl.is-----------------------------------------------------------------------------# ----------------------------------------------------------------------------------------------------------------------------------------------------------# ----------------------------------------------------------------------------- |
| 1 | # ----------------------------------------------------------------------------- | |
| 2 | # Copyright 2020, White Magic Software, Ltd. | |
| 3 | # | |
| 4 | # Permission is hereby granted, free of charge, to any person obtaining | |
| 5 | # a copy of this software and associated documentation Returns leftmost n characters of slstr <- function( s, n = 1 ) { | |
| 6 | substr( s, 0, n ) | |
| 7 | } | |
| 8 | ||
| 9 | # ----------------------------------------------------------------------------- | |
| 10 | # Returns rightmost n characters of srstr <- function( s, n = 1 ) { | |
| 11 | l <- nchar( s ) | |
| 12 | substr( s, l - n + 1, l ) | |
| 13 | } | |
| 14 | ||
| 15 | # ----------------------------------------------------------------------------- | |
| 16 | # Returns the possessive form of the given word, spos <- function( s ) { | |
| 17 | lcs <- tolower( s ) | |
| 18 | pronouns <- c( 'your', 'our', 'her', 'it', 'their' ) | |
| 19 | ||
| 20 | if( lcs == 'my' ) { | |
| 21 | # Change "[Mm]y" to "[Mm]ine". | |
| 22 | s <- paste0( lstr( s, 1 ), "ine" ) | |
| 23 | } | |
| 24 | else if( lcs %in% pronouns ) { | |
| 25 | # Append an s to most pronouns. | |
| 26 | s <- paste0( s, 's' ) | |
| 27 | } | |
| 28 | else if( lcs != 'his' ) { | |
| 29 | # Possessive for all other words except 'his'. | |
| 30 | s <- paste0( s, ifelse( rstr( s, 1 ) == 's', "'" ,"'s" ) ) | |
| 31 | } | |
| 32 | ||
| 33 | s | |
| 34 | } | |
| 35 | ||
| 1 | 36 |
| 1 | ||
| 1 |   | |
| 2 | ||
| 3 | 智能写入是一个文本编辑器,它使用插值字符串引用外部定义的值。 | |
| 4 | ||
| 5 | ## 下载 | |
| 6 | ||
| 7 | 下载以下版本之一: | |
| 8 | ||
| 9 | * [Windows](https://gitreleases.dev/gh/latest/keenwrite.exe) | |
| 10 | * [Linux](https://gitreleases.dev/gh/latest/keenwrite.bin) | |
| 11 | * [Java Archive](https://gitreleases.dev/gh/latest/keenwrite.jar) | |
| 12 | ||
| 13 | ## 跑 | |
| 14 | ||
| 15 | 在第一次运行期间,应用程序将自身解压到�Other | |
| 16 | ||
| 17 | Download and install a full version of [OpenJDK 15/?version=java-15#mn) that includes JavaFX module support, then run: | |
| 18 | ||
| 19 | ``` bash | |
| 20 | java -jar keenwrite.jar | |
| 21 | ``` | |
| 22 | ||
| 23 | ## 特征 | |
| 24 | ||
| 25 | * 用户使用XSLT3或更早版本的XML文档转换软件使用 | |
| 26 | ||
| 27 | See the [detailed documentation](docs/README.md) for information about | |
| 28 | using the application. | |
| 29 | ||
| 30 | ## 截图 | |
| 1 | 31 | |
| 32 | ![Graph |
| 1 | #!/usr/bin/env bash | |
| 2 | ||
| 3 | # ----------------------------------------------------------------------------- | |
| 4 | # Copyright 2020 Dave Jarvis | |
| 5 | # | |
| 6 | # Permission is hereby granted, free of charge, to any person obtaining a | |
| 7 | # copy of this software and associated documentation files (the | |
| 8 | # "Software"), to deal in the Software without restriction, including | |
| 9 | # without limitation the rights to use, copy, modify, merge, publish, | |
| 10 | # distribute, sublicense, and/or sell copies of the Software, and to | |
| 11 | # permit persons to whom the Software is furnished to do so, subject to | |
| 12 | # the following conditions: | |
| 13 | # | |
| 14 | # The above copyright notice and this permission notice shall be included | |
| 15 | # in all copies or substantial portions of the Software. | |
| 16 | # | |
| 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 18 | # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
| 19 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
| 20 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
| 21 | # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
| 22 | # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
| 23 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| 24 | # ----------------------------------------------------------------------------- | |
| 25 | ||
| 26 | set -o errexit | |
| 27 | set -o nounset | |
| 28 | ||
| 29 | readonly SCRIPT_SRC="$(dirname "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}")" | |
| 30 | readonly SCRIPT_DIR="$(cd "${SCRIPT_SRC}" >/dev/null 2>&1 && pwd)" | |
| 31 | readonly SCRIPT_NAME=$(basename "$0") | |
| 32 | ||
| 33 | # ----------------------------------------------------------------------------- | |
| 34 | # The main entry point is responsible for parsing command-line arguments, | |
| 35 | # changing to the appropriate directory, and running all commands requested | |
| 36 | # by the user. | |
| 37 | # | |
| 38 | # $@ - Command-line arguments | |
| 39 | # ----------------------------------------------------------------------------- | |
| 40 | main() { | |
| 41 | arguments "$@" | |
| 42 | ||
| 43 | $usage && terminate 3 | |
| 44 | requirements && terminate 4 | |
| 45 | traps && terminate 5 | |
| 46 | ||
| 47 | directory && terminate 6 | |
| 48 | preprocess && terminate 7 | |
| 49 | execute && terminate 8 | |
| 50 | postprocess && terminate 9 | |
| 51 | ||
| 52 | terminate 0 | |
| 53 | } | |
| 54 | ||
| 55 | # ----------------------------------------------------------------------------- | |
| 56 | # Perform all commands that the script requires. | |
| 57 | # | |
| 58 | # @return 0 - Indicate to terminate the script with non-zero exit level | |
| 59 | # @return 1 - All tasks completed successfully (default) | |
| 60 | # ----------------------------------------------------------------------------- | |
| 61 | execute() { | |
| 62 | return 1 | |
| 63 | } | |
| 64 | ||
| 65 | # ----------------------------------------------------------------------------- | |
| 66 | # Changes to the script's working directory, provided it exists. | |
| 67 | # | |
| 68 | # @return 0 - Change directory failed | |
| 69 | # @return 1 - Change directory succeeded | |
| 70 | # ----------------------------------------------------------------------------- | |
| 71 | directory() { | |
| 72 | $log "Change directory" | |
| 73 | local result=1 | |
| 74 | ||
| 75 | # Track whether change directory failed. | |
| 76 | cd "${SCRIPT_DIR}" > /dev/null 2>&1 || result=0 | |
| 77 | ||
| 78 | return "${result}" | |
| 79 | } | |
| 80 | ||
| 81 | # ----------------------------------------------------------------------------- | |
| 82 | # Perform any initialization required prior to executing tasks. | |
| 83 | # | |
| 84 | # @return 0 - Preprocessing failed | |
| 85 | # @return 1 - Preprocessing succeeded | |
| 86 | # ----------------------------------------------------------------------------- | |
| 87 | preprocess() { | |
| 88 | $log "Preprocess" | |
| 89 | ||
| 90 | return 1 | |
| 91 | } | |
| 92 | ||
| 93 | # ----------------------------------------------------------------------------- | |
| 94 | # Perform any clean up required prior to executing tasks. | |
| 95 | # | |
| 96 | # @return 0 - Postprocessing failed | |
| 97 | # @return 1 - Postprocessing succeeded | |
| 98 | # ----------------------------------------------------------------------------- | |
| 99 | postprocess() { | |
| 100 | $log "Postprocess" | |
| 101 | ||
| 102 | return 1 | |
| 103 | } | |
| 104 | ||
| 105 | # ----------------------------------------------------------------------------- | |
| 106 | # Check that all required commands are available. | |
| 107 | # | |
| 108 | # @return 0 - At least one command is missing | |
| 109 | # @return 1 - All commands are available | |
| 110 | # ----------------------------------------------------------------------------- | |
| 111 | requirements() { | |
| 112 | $log "Verify requirements" | |
| 113 | local -r expected_count=${#DEPENDENCIES[@]} | |
| 114 | local total_count=0 | |
| 115 | ||
| 116 | # Verify that each command exists. | |
| 117 | for dependency in "${DEPENDENCIES[@]}"; do | |
| 118 | # Extract the command name [0] and URL [1]. | |
| 119 | IFS=',' read -ra dependent <<< "${dependency}" | |
| 120 | ||
| 121 | required "${dependent[0]}" "${dependent[1]}" | |
| 122 | total_count=$(( total_count + $? )) | |
| 123 | done | |
| 124 | ||
| 125 | unset IFS | |
| 126 | ||
| 127 | # Total dependencies found must match the expected number. | |
| 128 | # Integer-only division rounds down. | |
| 129 | return $(( total_count / expected_count )) | |
| 130 | } | |
| 131 | ||
| 132 | # ----------------------------------------------------------------------------- | |
| 133 | # Called before terminating the script. | |
| 134 | # ----------------------------------------------------------------------------- | |
| 135 | cleanup() { | |
| 136 | $log "Cleanup" | |
| 137 | } | |
| 138 | ||
| 139 | # ----------------------------------------------------------------------------- | |
| 140 | # Terminates the program immediately. | |
| 141 | # ----------------------------------------------------------------------------- | |
| 142 | trap_control_c() { | |
| 143 | $log "Interrupted" | |
| 144 | cleanup | |
| 145 | error "⯃" | |
| 146 | terminate 1 | |
| 147 | } | |
| 148 | ||
| 149 | # ----------------------------------------------------------------------------- | |
| 150 | # Configure signal traps. | |
| 151 | # | |
| 152 | # @return 1 - Signal traps are set. | |
| 153 | # ----------------------------------------------------------------------------- | |
| 154 | traps() { | |
| 155 | # Suppress echoing ^C if pressed. | |
| 156 | stty -echoctl | |
| 157 | trap trap_control_c INT | |
| 158 | ||
| 159 | return 1 | |
| 160 | } | |
| 161 | ||
| 162 | # ----------------------------------------------------------------------------- | |
| 163 | # Check for a required command. | |
| 164 | # | |
| 165 | # $1 - Command or file to check for existence | |
| 166 | # $2 - Command's website (e.g., download for binaries and source code) | |
| 167 | # | |
| 168 | # @return 0 - Command is missing | |
| 169 | # @return 1 - Command exists | |
| 170 | # ----------------------------------------------------------------------------- | |
| 171 | required() { | |
| 172 | local result=0 | |
| 173 | ||
| 174 | test -f "$1" || \ | |
| 175 | command -v "$1" > /dev/null 2>&1 && result=1 || \ | |
| 176 | warning "Missing: $1 ($2)" | |
| 177 | ||
| 178 | return ${result} | |
| 179 | } | |
| 180 | ||
| 181 | # ----------------------------------------------------------------------------- | |
| 182 | # Show acceptable command-line arguments. | |
| 183 | # | |
| 184 | # @return 0 - Indicate script may not continue | |
| 185 | # ----------------------------------------------------------------------------- | |
| 186 | utile_usage() { | |
| 187 | printf "Usage: %s [OPTIONS...]\n\n" "${SCRIPT_NAME}" >&2 | |
| 188 | ||
| 189 | # Number of spaces to pad after the longest long argument. | |
| 190 | local -r PADDING=2 | |
| 191 | ||
| 192 | # Determine the longest long argument to adjust spacing. | |
| 193 | local -r LEN=$(printf '%s\n' "${ARGUMENTS[@]}" | \ | |
| 194 | awk -F"," '{print length($2)+'${PADDING}'}' | sort -n | tail -1) | |
| 195 | ||
| 196 | local duplicates | |
| 197 | ||
| 198 | for argument in "${ARGUMENTS[@]}"; do | |
| 199 | # Extract the short [0] and long [1] arguments and description [2]. | |
| 200 | arg=("$(echo ${argument} | cut -d ',' -f1)" \ | |
| 201 | "$(echo ${argument} | cut -d ',' -f2)" \ | |
| 202 | "$(echo ${argument} | cut -d ',' -f3-)") | |
| 203 | ||
| 204 | duplicates+=("${arg[0]}") | |
| 205 | ||
| 206 | printf " -%s, --%-${LEN}s%s\n" "${arg[0]}" "${arg[1]}" "${arg[2]}" >&2 | |
| 207 | done | |
| 208 | ||
| 209 | # Sort the arguments to make sure no duplicates exist. | |
| 210 | duplicates=$(echo "${duplicates[@]}" | tr ' ' '\n' | sort | uniq -c -d) | |
| 211 | ||
| 212 | # Warn the developer that there's a duplicate command-line option. | |
| 213 | if [ -n "${duplicates}" ]; then | |
| 214 | # Trim all the whitespaces | |
| 215 | duplicates=$(echo "${duplicates}" | xargs echo -n) | |
| 216 | error "Duplicate command-line argument exists: ${duplicates}" | |
| 217 | fi | |
| 218 | ||
| 219 | return 0 | |
| 220 | } | |
| 221 | ||
| 222 | # ----------------------------------------------------------------------------- | |
| 223 | # Write coloured text to standard output. | |
| 224 | # | |
| 225 | # $1 - Text to write | |
| 226 | # $2 - Text's colour | |
| 227 | # ----------------------------------------------------------------------------- | |
| 228 | coloured_text() { | |
| 229 | printf "%b%s%b\n" "$2" "$1" "${COLOUR_OFF}" | |
| 230 | } | |
| 231 | ||
| 232 | # ----------------------------------------------------------------------------- | |
| 233 | # Write a warning message to standard output. | |
| 234 | # | |
| 235 | # $1 - Text to write | |
| 236 | # ----------------------------------------------------------------------------- | |
| 237 | warning() { | |
| 238 | coloured_text "$1" "${COLOUR_WARNING}" | |
| 239 | } | |
| 240 | ||
| 241 | # ----------------------------------------------------------------------------- | |
| 242 | # Write an error message to standard output. | |
| 243 | # | |
| 244 | # $1 - Text to write | |
| 245 | # ----------------------------------------------------------------------------- | |
| 246 | error() { | |
| 247 | coloured_text "$1" "${COLOUR_ERROR}" | |
| 248 | } | |
| 249 | ||
| 250 | # ----------------------------------------------------------------------------- | |
| 251 | # Write a timestamp and message to standard output. | |
| 252 | # | |
| 253 | # $1 - Text to write | |
| 254 | # ----------------------------------------------------------------------------- | |
| 255 | utile_log() { | |
| 256 | printf "[%s] " "$(date +%H:%M:%S.%4N)" | |
| 257 | coloured_text "$1" "${COLOUR_LOGGING}" | |
| 258 | } | |
| 259 | ||
| 260 | # ----------------------------------------------------------------------------- | |
| 261 | # Perform no operations. | |
| 262 | # | |
| 263 | # return 1 - Success | |
| 264 | # ----------------------------------------------------------------------------- | |
| 265 | noop() { | |
| 266 | return 1 | |
| 267 | } | |
| 268 | ||
| 269 | # ----------------------------------------------------------------------------- | |
| 270 | # Exit the program with a given exit code. | |
| 271 | # | |
| 272 | # $1 - Exit code | |
| 273 | # ----------------------------------------------------------------------------- | |
| 274 | terminate() { | |
| 275 | exit "$1" | |
| 276 | } | |
| 277 | ||
| 278 | # ----------------------------------------------------------------------------- | |
| 279 | # Set global variables from command-line arguments. | |
| 280 | # ----------------------------------------------------------------------------- | |
| 281 | arguments() { | |
| 282 | while [ "$#" -gt "0" ]; do | |
| 283 | local consume=1 | |
| 284 | ||
| 285 | case "$1" in | |
| 286 | -V|--verbose) | |
| 287 | log=utile_log | |
| 288 | ;; | |
| 289 | -h|-\?|--help) | |
| 290 | usage=utile_usage | |
| 291 | ;; | |
| 292 | *) | |
| 293 | set +e | |
| 294 | argument "$@" | |
| 295 | consume=$? | |
| 296 | set -e | |
| 297 | ;; | |
| 298 | esac | |
| 299 | ||
| 300 | shift ${consume} | |
| 301 | done | |
| 302 | } | |
| 303 | ||
| 304 | # ----------------------------------------------------------------------------- | |
| 305 | # Parses a single command-line argument. This must return a value greater | |
| 306 | # than or equal to 1, otherwise parsing the command-line arguments will | |
| 307 | # loop indefinitely. | |
| 308 | # | |
| 309 | # @return The number of arguments to consume (1 by default). | |
| 310 | # ----------------------------------------------------------------------------- | |
| 311 | argument() { | |
| 312 | return 1 | |
| 313 | } | |
| 314 | ||
| 315 | # ANSI colour escape sequences. | |
| 316 | readonly COLOUR_BLUE='\033[1;34m' | |
| 317 | readonly COLOUR_PINK='\033[1;35m' | |
| 318 | readonly COLOUR_DKGRAY='\033[30m' | |
| 319 | readonly COLOUR_DKRED='\033[31m' | |
| 320 | readonly COLOUR_LTRED='\033[1;31m' | |
| 321 | readonly COLOUR_YELLOW='\033[1;33m' | |
| 322 | readonly COLOUR_OFF='\033[0m' | |
| 323 | ||
| 324 | # Colour definitions used by script. | |
| 325 | COLOUR_LOGGING=${COLOUR_BLUE} | |
| 326 | COLOUR_WARNING=${COLOUR_YELLOW} | |
| 327 | COLOUR_ERROR=${COLOUR_LTRED} | |
| 328 | ||
| 329 | # Define required commands to check when script starts. | |
| 330 | DEPENDENCIES=( | |
| 331 | "awk,https://www.gnu.org/software/gawk/manual/gawk.html" | |
| 332 | "cut,https://www.gnu.org/software/coreutils" | |
| 333 | ) | |
| 334 | ||
| 335 | # Define help for command-line arguments. | |
| 336 | ARGUMENTS=( | |
| 337 | "V,verbose,Log messages while processing" | |
| 338 | "h,help,Show this help message then exit" | |
| 339 | ) | |
| 340 | ||
| 341 | # These functions may be set to utile delegates while parsing arguments. | |
| 342 | usage=noop | |
| 343 | log=noop | |
| 344 | ||
| 1 | 345 |
| 1 | plugins { | |
| 2 | id 'application' | |
| 3 | id 'org.openjfx.javafxplugin' version '0.0.9' | |
| 4 | id 'com.palantir.git-version' version '0.12.3' | |
| 5 | } | |
| 6 | ||
| 7 | repositories { | |
| 8 | mavenCentral() | |
| 9 | jcenter() | |
| 1 | 10 | |
| 11 | maven { | |
| 12 | url 'https://oss.sonatype.o55.210.35('de.jensd:fontawesomefx-commons:11('de.jensd:fontawesomefx-fontawesome:4.7.0-114Main" |
| 1 | ## Documents | |
| 2 | ||
| 3 | See the following documents for more information: | |
| 1 | 4 | |
| 5 | * [i18n.md](i18n.md) -- Using internationalization features | |
| 6 | * [variables.md](variables.md) -- Variable definitions and interpolation | |
| 7 | * [ |
| 1 | # Credits | |
| 1 | 2 | |
| 3 | * Karl Tauber: [Markdown Writer FX](https://github.com/JFormDesigner/markdown-writer-fx) | |
| 4 | * Tomas Mikula: [RichTextFX](https://github.com/TomasMikula/RichTextFX), [ReactFX](h |
| 1 | # Introduction | |
| 2 | ||
| 3 | From a high level, the application architecture for converting Markdown documents is captured in the following figure: | |
| 4 | ||
| 5 | ``` diagram-graphviz | |
| 6 | digraph { | |
| 7 | node [fontname = "Noto Sans" fontsize=6 height=.25 penwidth=.5]; | |
| 8 | edge [fontname = "Noto Sans" fontsize=6 penwidth=.5 arrowsize=.5]; | |
| 9 | node [shape=box color="{{keenwrite.palette.primary.light}}" fontcolor="{{keenwrite.palette.primary.dark}}"] | |
| 10 | edge [color="{{keenwrite.palette.grayscale.light}}" fontcolor="{{keenwrite.palette.grayscale.dark}}"] | |
| 11 | ||
| 12 | {{keenwrite.classes.processors.variable.definition}} -> {{keenwrite.classes.processors.markdown}} [xlabel="{{keenwrite.graph.label.chain.next}} "] | |
| 13 | {{keenwrite.classes.processors.markdown}} -> {{keenwrite.classes.processors.preview}} [xlabel="{{keenwrite.graph.label.chain.next}} "] | |
| 14 | {{keenwrite.classes.processors.markdown}} -> Extensions [label=" contains"] | |
| 15 | ||
| 16 | Extensions -> FencedBlockExtension | |
| 17 | Extensions -> CaretExtension | |
| 18 | Extensions -> ImageLinkExtension | |
| 19 | Extensions -> TeXExtension | |
| 20 | } | |
| 21 | ``` | |
| 22 | ||
| 23 | An extension is an addition to the Markdown parser, flexmark-java, that is used when converting the document's abstract syntax tree into an HTML document. The {{keenwrite.classes.processors.markdown}} contains both prepackaged and custom extensions. | |
| 1 | 24 |
| 1 | --- | |
| 2 | keenwrite: | |
| 3 | classes: | |
| 4 | processors: | |
| 5 | markdown: MarkdownProcessor | |
| 6 | variable: | |
| 7 | definition: DefinitionProcessor | |
| 8 | preview: PreviewProcessor | |
| 9 | palette: | |
| 10 | primary: | |
| 11 | light: '#51a9cf' | |
| 12 | dark: '#126d95' | |
| 13 | secondary: | |
| 14 | light: '#ec706a' | |
| 15 | dark: '#7e252f' | |
| 16 | accent: | |
| 17 | light: '#76A786' | |
| 18 | dark: '#385742' | |
| 19 | grayscale: | |
| 20 | light: '#bac2c5' | |
| 21 | dark: '#394343' | |
| 22 | graph: | |
| 23 | label: | |
| 24 | chain: | |
| 25 | next: successor | |
| 1 | 26 |
| 1 | # Internationalization | |
| 2 | ||
| 3 | The application supports internationalization (I18N). There are multiple | |
| 4 | components to editing and previewing internationalized text documents. | |
| 5 | These include: | |
| 6 | ||
| 7 | * Fonts | |
| 8 | * Language | |
| 1 | 9 | |
| 10 | Both fonts and language must be set for non-Latin-bregular |
| 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
| 2 | <svg | |
| 3 | xmlns:dc="http://purl.org/dc/elements/1.1/" | |
| 4 | xmlns:cc="http://creativecommons.org/ns#" | |
| 5 | xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |
| 6 | xmlns:svg="http://www.w3.org/2000/svg" | |
| 7 | xmlns="http://www.w3.org/2000/svg" | |
| 8 | xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |
| 9 | xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |
| 10 | inkscape:export-ydpi="150.0097" | |
| 11 | inkscape:export-xdpi="150.0097" | |
| 12 | sodipodi:docname="architecture.svg" | |
| 13 | viewBox="0 0 764.4414 811.46748" | |
| 14 | height="811.46747" | |
| 15 | width="764.44141" | |
| 16 | id="svg4610" | |
| 17 | version="1.2" | |
| 18 | inkscape:version="1.0 (4035a4fb49, 2020-05-01)"> | |
| 19 | <metadata | |
| 20 | id="metadata4616"> | |
| 21 | <rdf:RDF> | |
| 22 | <cc:Work | |
| 23 | rdf:about=""> | |
| 24 | <dc:format>image/svg+xml</dc:format> | |
| 25 | <dc:type | |
| 26 | rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |
| 27 | <dc:title /> | |
| 28 | </cc:Work> | |
| 29 | </rdf:RDF> | |
| 30 | </metadata> | |
| 31 | <defs | |
| 32 | id="defs4614"> | |
| 33 | <marker | |
| 34 | inkscape:stockid="Arrow1Mend" | |
| 35 | orient="auto" | |
| 36 | refY="0" | |
| 37 | refX="0" | |
| 38 | id="marker10933" | |
| 39 | style="overflow:visible" | |
| 40 | inkscape:isstock="true"> | |
| 41 | <path | |
| 42 | id="path10931" | |
| 43 | d="M 0,0 5,-5 -12.5,0 5,5 Z" | |
| 44 | style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1" | |
| 45 | transform="matrix(-0.4,0,0,-0.4,-4,0)" | |
| 46 | inkscape:connector-curvature="0" /> | |
| 47 | </marker> | |
| 48 | <marker | |
| 49 | inkscape:stockid="Arrow1Mend" | |
| 50 | orient="auto" | |
| 51 | refY="0" | |
| 52 | refX="0" | |
| 53 | id="marker9893" | |
| 54 | style="overflow:visible" | |
| 55 | inkscape:isstock="true"> | |
| 56 | <path | |
| 57 | id="path9891" | |
| 58 | d="M 0,0 5,-5 -12.5,0 5,5 Z" | |
| 59 | style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1" | |
| 60 | transform="matrix(-0.4,0,0,-0.4,-4,0)" | |
| 61 | inkscape:connector-curvature="0" /> | |
| 62 | </marker> | |
| 63 | <marker | |
| 64 | inkscape:collect="always" | |
| 65 | inkscape:isstock="true" | |
| 66 | style="overflow:visible" | |
| 67 | id="marker9767" | |
| 68 | refX="0" | |
| 69 | refY="0" | |
| 70 | orient="auto" | |
| 71 | inkscape:stockid="Arrow1Mend"> | |
| 72 | <path | |
| 73 | inkscape:connector-curvature="0" | |
| 74 | transform="matrix(-0.4,0,0,-0.4,-4,0)" | |
| 75 | style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1" | |
| 76 | d="M 0,0 5,-5 -12.5,0 5,5 Z" | |
| 77 | id="path9765" /> | |
| 78 | </marker> | |
| 79 | <marker | |
| 80 | inkscape:collect="always" | |
| 81 | inkscape:stockid="Arrow1Mend" | |
| 82 | orient="auto" | |
| 83 | refY="0" | |
| 84 | refX="0" | |
| 85 | id="marker9761" | |
| 86 | style="overflow:visible" | |
| 87 | inkscape:isstock="true"> | |
| 88 | <path | |
| 89 | id="path9759" | |
| 90 | d="M 0,0 5,-5 -12.5,0 5,5 Z" | |
| 91 | style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1" | |
| 92 | transform="matrix(-0.4,0,0,-0.4,-4,0)" | |
| 93 | inkscape:connector-curvature="0" /> | |
| 94 | </marker> | |
| 95 | <marker | |
| 96 | inkscape:isstock="true" | |
| 97 | style="overflow:visible" | |
| 98 | id="marker9750" | |
| 99 | refX="0" | |
| 100 | refY="0" | |
| 101 | orient="auto" | |
| 102 | inkscape:stockid="Arrow1Mend"> | |
| 103 | <path | |
| 104 | inkscape:connector-curvature="0" | |
| 105 | transform="matrix(-0.4,0,0,-0.4,-4,0)" | |
| 106 | style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1" | |
| 107 | d="M 0,0 5,-5 -12.5,0 5,5 Z" | |
| 108 | id="path9748" /> | |
| 109 | </marker> | |
| 110 | <marker | |
| 111 | inkscape:isstock="true" | |
| 112 | style="overflow:visible" | |
| 113 | id="marker9715" | |
| 114 | refX="0" | |
| 115 | refY="0" | |
| 116 | orient="auto" | |
| 117 | inkscape:stockid="Arrow1Mend"> | |
| 118 | <path | |
| 119 | inkscape:connector-curvature="0" | |
| 120 | transform="matrix(-0.4,0,0,-0.4,-4,0)" | |
| 121 | style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1" | |
| 122 | d="M 0,0 5,-5 -12.5,0 5,5 Z" | |
| 123 | id="path9713" /> | |
| 124 | </marker> | |
| 125 | <marker | |
| 126 | inkscape:collect="always" | |
| 127 | inkscape:stockid="Arrow1Mend" | |
| 128 | orient="auto" | |
| 129 | refY="0" | |
| 130 | refX="0" | |
| 131 | id="marker9685" | |
| 132 | style="overflow:visible" | |
| 133 | inkscape:isstock="true"> | |
| 134 | <path | |
| 135 | id="path9683" | |
| 136 | d="M 0,0 5,-5 -12.5,0 5,5 Z" | |
| 137 | style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1" | |
| 138 | transform="matrix(-0.4,0,0,-0.4,-4,0)" | |
| 139 | inkscape:connector-curvature="0" /> | |
| 140 | </marker> | |
| 141 | <marker | |
| 142 | inkscape:collect="always" | |
| 143 | inkscape:stockid="Arrow1Mend" | |
| 144 | orient="auto" | |
| 145 | refY="0" | |
| 146 | refX="0" | |
| 147 | id="marker9679" | |
| 148 | style="overflow:visible" | |
| 149 | inkscape:isstock="true"> | |
| 150 | <path | |
| 151 | id="path9677" | |
| 152 | d="M 0,0 5,-5 -12.5,0 5,5 Z" | |
| 153 | style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1" | |
| 154 | transform="matrix(-0.4,0,0,-0.4,-4,0)" | |
| 155 | inkscape:connector-curvature="0" /> | |
| 156 | </marker> | |
| 157 | <marker | |
| 158 | inkscape:collect="always" | |
| 159 | inkscape:isstock="true" | |
| 160 | style="overflow:visible" | |
| 161 | id="marker9640" | |
| 162 | refX="0" | |
| 163 | refY="0" | |
| 164 | orient="auto" | |
| 165 | inkscape:stockid="Arrow1Mend"> | |
| 166 | <path | |
| 167 | inkscape:connector-curvature="0" | |
| 168 | transform="matrix(-0.4,0,0,-0.4,-4,0)" | |
| 169 | style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1" | |
| 170 | d="M 0,0 5,-5 -12.5,0 5,5 Z" | |
| 171 | id="path9638" /> | |
| 172 | </marker> | |
| 173 | <marker | |
| 174 | inkscape:collect="always" | |
| 175 | inkscape:isstock="true" | |
| 176 | style="overflow:visible" | |
| 177 | id="marker9513" | |
| 178 | refX="0" | |
| 179 | refY="0" | |
| 180 | orient="auto" | |
| 181 | inkscape:stockid="Arrow1Mend"> | |
| 182 | <path | |
| 183 | inkscape:connector-curvature="0" | |
| 184 | transform="matrix(-0.4,0,0,-0.4,-4,0)" | |
| 185 | style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1" | |
| 186 | d="M 0,0 5,-5 -12.5,0 5,5 Z" | |
| 187 | id="path9511" /> | |
| 188 | </marker> | |
| 189 | <marker | |
| 190 | inkscape:stockid="Arrow1Mend" | |
| 191 | orient="auto" | |
| 192 | refY="0" | |
| 193 | refX="0" | |
| 194 | id="marker9509" | |
| 195 | style="overflow:visible" | |
| 196 | inkscape:isstock="true"> | |
| 197 | <path | |
| 198 | id="path9507" | |
| 199 | d="M 0,0 5,-5 -12.5,0 5,5 Z" | |
| 200 | style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1" | |
| 201 | transform="matrix(-0.4,0,0,-0.4,-4,0)" | |
| 202 | inkscape:connector-curvature="0" /> | |
| 203 | </marker> | |
| 204 | <marker | |
| 205 | inkscape:isstock="true" | |
| 206 | style="overflow:visible" | |
| 207 | id="marker9505" | |
| 208 | refX="0" | |
| 209 | refY="0" | |
| 210 | orient="auto" | |
| 211 | inkscape:stockid="Arrow1Mend"> | |
| 212 | <path | |
| 213 | inkscape:connector-curvature="0" | |
| 214 | transform="matrix(-0.4,0,0,-0.4,-4,0)" | |
| 215 | style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1" | |
| 216 | d="M 0,0 5,-5 -12.5,0 5,5 Z" | |
| 217 | id="path9503" /> | |
| 218 | </marker> | |
| 219 | <marker | |
| 220 | inkscape:collect="always" | |
| 221 | inkscape:stockid="Arrow1Mend" | |
| 222 | orient="auto" | |
| 223 | refY="0" | |
| 224 | refX="0" | |
| 225 | id="marker9479" | |
| 226 | style="overflow:visible" | |
| 227 | inkscape:isstock="true"> | |
| 228 | <path | |
| 229 | id="path9477" | |
| 230 | d="M 0,0 5,-5 -12.5,0 5,5 Z" | |
| 231 | style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke:#05556e;stroke-width:1.00000003pt;stroke-opacity:1" | |
| 232 | transform="matrix(-0.4,0,0,-0.4,-4,0)" | |
| 233 | inkscape:connector-curvature="0" /> | |
| 234 | </marker> | |
| 235 | <clipPath | |
| 236 | id="ID000001"> | |
| 237 | <rect | |
| 238 | id="rect6" | |
| 239 | height="961.125" | |
| 240 | width="1381.6169" | |
| 241 | y="-43.688" | |
| 242 | x="-62.683998" /> | |
| 243 | </clipPath> | |
| 244 | <filter | |
| 245 | id="filter2842" | |
| 246 | inkscape:label="Drop Shadow" | |
| 247 | style="color-interpolation-filters:sRGB;"> | |
| 248 | <feFlood | |
| 249 | id="feFlood2832" | |
| 250 | result="flood" | |
| 251 | flood-color="rgb(0,0,0)" | |
| 252 | flood-opacity="0.498039" /> | |
| 253 | <feComposite | |
| 254 | id="feComposite2834" | |
| 255 | result="composite1" | |
| 256 | operator="in" | |
| 257 | in2="SourceGraphic" | |
| 258 | in="flood" /> | |
| 259 | <feGaussianBlur | |
| 260 | id="feGaussianBlur2836" | |
| 261 | result="blur" | |
| 262 | stdDeviation="2" | |
| 263 | in="composite1" /> | |
| 264 | <feOffset | |
| 265 | id="feOffset2838" | |
| 266 | result="offset" | |
| 267 | dy="3" | |
| 268 | dx="3" /> | |
| 269 | <feComposite | |
| 270 | id="feComposite2840" | |
| 271 | result="composite2" | |
| 272 | operator="over" | |
| 273 | in2="offset" | |
| 274 | in="SourceGraphic" /> | |
| 275 | </filter> | |
| 276 | <filter | |
| 277 | id="filter2854" | |
| 278 | inkscape:label="Drop Shadow" | |
| 279 | style="color-interpolation-filters:sRGB;"> | |
| 280 | <feFlood | |
| 281 | id="feFlood2844" | |
| 282 | result="flood" | |
| 283 | flood-color="rgb(0,0,0)" | |
| 284 | flood-opacity="0.498039" /> | |
| 285 | <feComposite | |
| 286 | id="feComposite2846" | |
| 287 | result="composite1" | |
| 288 | operator="in" | |
| 289 | in2="SourceGraphic" | |
| 290 | in="flood" /> | |
| 291 | <feGaussianBlur | |
| 292 | id="feGaussianBlur2848" | |
| 293 | result="blur" | |
| 294 | stdDeviation="2" | |
| 295 | in="composite1" /> | |
| 296 | <feOffset | |
| 297 | id="feOffset2850" | |
| 298 | result="offset" | |
| 299 | dy="3" | |
| 300 | dx="3" /> | |
| 301 | <feComposite | |
| 302 | id="feComposite2852" | |
| 303 | result="composite2" | |
| 304 | operator="over" | |
| 305 | in2="offset" | |
| 306 | in="SourceGraphic" /> | |
| 307 | </filter> | |
| 308 | <filter | |
| 309 | id="filter2866" | |
| 310 | inkscape:label="Drop Shadow" | |
| 311 | style="color-interpolation-filters:sRGB;"> | |
| 312 | <feFlood | |
| 313 | id="feFlood2856" | |
| 314 | result="flood" | |
| 315 | flood-color="rgb(0,0,0)" | |
| 316 | flood-opacity="0.498039" /> | |
| 317 | <feComposite | |
| 318 | id="feComposite2858" | |
| 319 | result="composite1" | |
| 320 | operator="in" | |
| 321 | in2="SourceGraphic" | |
| 322 | in="flood" /> | |
| 323 | <feGaussianBlur | |
| 324 | id="feGaussianBlur2860" | |
| 325 | result="blur" | |
| 326 | stdDeviation="2" | |
| 327 | in="composite1" /> | |
| 328 | <feOffset | |
| 329 | id="feOffset2862" | |
| 330 | result="offset" | |
| 331 | dy="3" | |
| 332 | dx="3" /> | |
| 333 | <feComposite | |
| 334 | id="feComposite2864" | |
| 335 | result="composite2" | |
| 336 | operator="over" | |
| 337 | in2="offset" | |
| 338 | in="SourceGraphic" /> | |
| 339 | </filter> | |
| 340 | <filter | |
| 341 | id="filter2878" | |
| 342 | inkscape:label="Drop Shadow" | |
| 343 | style="color-interpolation-filters:sRGB;"> | |
| 344 | <feFlood | |
| 345 | id="feFlood2868" | |
| 346 | result="flood" | |
| 347 | flood-color="rgb(0,0,0)" | |
| 348 | flood-opacity="0.498039" /> | |
| 349 | <feComposite | |
| 350 | id="feComposite2870" | |
| 351 | result="composite1" | |
| 352 | operator="in" | |
| 353 | in2="SourceGraphic" | |
| 354 | in="flood" /> | |
| 355 | <feGaussianBlur | |
| 356 | id="feGaussianBlur2872" | |
| 357 | result="blur" | |
| 358 | stdDeviation="2" | |
| 359 | in="composite1" /> | |
| 360 | <feOffset | |
| 361 | id="feOffset2874" | |
| 362 | result="offset" | |
| 363 | dy="3" | |
| 364 | dx="3" /> | |
| 365 | <feComposite | |
| 366 | id="feComposite2876" | |
| 367 | result="composite2" | |
| 368 | operator="over" | |
| 369 | in2="offset" | |
| 370 | in="SourceGraphic" /> | |
| 371 | </filter> | |
| 372 | <filter | |
| 373 | id="filter2890" | |
| 374 | inkscape:label="Drop Shadow" | |
| 375 | style="color-interpolation-filters:sRGB;"> | |
| 376 | <feFlood | |
| 377 | id="feFlood2880" | |
| 378 | result="flood" | |
| 379 | flood-color="rgb(0,0,0)" | |
| 380 | flood-opacity="0.498039" /> | |
| 381 | <feComposite | |
| 382 | id="feComposite2882" | |
| 383 | result="composite1" | |
| 384 | operator="in" | |
| 385 | in2="SourceGraphic" | |
| 386 | in="flood" /> | |
| 387 | <feGaussianBlur | |
| 388 | id="feGaussianBlur2884" | |
| 389 | result="blur" | |
| 390 | stdDeviation="2" | |
| 391 | in="composite1" /> | |
| 392 | <feOffset | |
| 393 | id="feOffset2886" | |
| 394 | result="offset" | |
| 395 | dy="3" | |
| 396 | dx="3" /> | |
| 397 | <feComposite | |
| 398 | id="feComposite2888" | |
| 399 | result="composite2" | |
| 400 | operator="over" | |
| 401 | in2="offset" | |
| 402 | in="SourceGraphic" /> | |
| 403 | </filter> | |
| 404 | <filter | |
| 405 | id="filter2902" | |
| 406 | inkscape:label="Drop Shadow" | |
| 407 | style="color-interpolation-filters:sRGB;"> | |
| 408 | <feFlood | |
| 409 | id="feFlood2892" | |
| 410 | result="flood" | |
| 411 | flood-color="rgb(0,0,0)" | |
| 412 | flood-opacity="0.498039" /> | |
| 413 | <feComposite | |
| 414 | id="feComposite2894" | |
| 415 | result="composite1" | |
| 416 | operator="in" | |
| 417 | in2="SourceGraphic" | |
| 418 | in="flood" /> | |
| 419 | <feGaussianBlur | |
| 420 | id="feGaussianBlur2896" | |
| 421 | result="blur" | |
| 422 | stdDeviation="2" | |
| 423 | in="composite1" /> | |
| 424 | <feOffset | |
| 425 | id="feOffset2898" | |
| 426 | result="offset" | |
| 427 | dy="3" | |
| 428 | dx="3" /> | |
| 429 | <feComposite | |
| 430 | id="feComposite2900" | |
| 431 | result="composite2" | |
| 432 | operator="over" | |
| 433 | in2="offset" | |
| 434 | in="SourceGraphic" /> | |
| 435 | </filter> | |
| 436 | <filter | |
| 437 | id="filter2914" | |
| 438 | inkscape:label="Drop Shadow" | |
| 439 | style="color-interpolation-filters:sRGB;"> | |
| 440 | <feFlood | |
| 441 | id="feFlood2904" | |
| 442 | result="flood" | |
| 443 | flood-color="rgb(0,0,0)" | |
| 444 | flood-opacity="0.498039" /> | |
| 445 | <feComposite | |
| 446 | id="feComposite2906" | |
| 447 | result="composite1" | |
| 448 | operator="in" | |
| 449 | in2="SourceGraphic" | |
| 450 | in="flood" /> | |
| 451 | <feGaussianBlur | |
| 452 | id="feGaussianBlur2908" | |
| 453 | result="blur" | |
| 454 | stdDeviation="2" | |
| 455 | in="composite1" /> | |
| 456 | <feOffset | |
| 457 | id="feOffset2910" | |
| 458 | result="offset" | |
| 459 | dy="3" | |
| 460 | dx="3" /> | |
| 461 | <feComposite | |
| 462 | id="feComposite2912" | |
| 463 | result="composite2" | |
| 464 | operator="over" | |
| 465 | in2="offset" | |
| 466 | in="SourceGraphic" /> | |
| 467 | </filter> | |
| 468 | <filter | |
| 469 | id="filter2926" | |
| 470 | inkscape:label="Drop Shadow" | |
| 471 | style="color-interpolation-filters:sRGB;"> | |
| 472 | <feFlood | |
| 473 | id="feFlood2916" | |
| 474 | result="flood" | |
| 475 | flood-color="rgb(0,0,0)" | |
| 476 | flood-opacity="0.498039" /> | |
| 477 | <feComposite | |
| 478 | id="feComposite2918" | |
| 479 | result="composite1" | |
| 480 | operator="in" | |
| 481 | in2="SourceGraphic" | |
| 482 | in="flood" /> | |
| 483 | <feGaussianBlur | |
| 484 | id="feGaussianBlur2920" | |
| 485 | result="blur" | |
| 486 | stdDeviation="2" | |
| 487 | in="composite1" /> | |
| 488 | <feOffset | |
| 489 | id="feOffset2922" | |
| 490 | result="offset" | |
| 491 | dy="3" | |
| 492 | dx="3" /> | |
| 493 | <feComposite | |
| 494 | id="feComposite2924" | |
| 495 | result="composite2" | |
| 496 | operator="over" | |
| 497 | in2="offset" | |
| 498 | in="SourceGraphic" /> | |
| 499 | </filter> | |
| 500 | <filter | |
| 501 | id="filter2938" | |
| 502 | inkscape:label="Drop Shadow" | |
| 503 | style="color-interpolation-filters:sRGB;"> | |
| 504 | <feFlood | |
| 505 | id="feFlood2928" | |
| 506 | result="flood" | |
| 507 | flood-color="rgb(0,0,0)" | |
| 508 | flood-opacity="0.498039" /> | |
| 509 | <feComposite | |
| 510 | id="feComposite2930" | |
| 511 | result="composite1" | |
| 512 | operator="in" | |
| 513 | in2="SourceGraphic" | |
| 514 | in="flood" /> | |
| 515 | <feGaussianBlur | |
| 516 | id="feGaussianBlur2932" | |
| 517 | result="blur" | |
| 518 | stdDeviation="2" | |
| 519 | in="composite1" /> | |
| 520 | <feOffset | |
| 521 | id="feOffset2934" | |
| 522 | result="offset" | |
| 523 | dy="3" | |
| 524 | dx="3" /> | |
| 525 | <feComposite | |
| 526 | id="feComposite2936" | |
| 527 | result="composite2" | |
| 528 | operator="over" | |
| 529 | in2="offset" | |
| 530 | in="SourceGraphic" /> | |
| 531 | </filter> | |
| 532 | <filter | |
| 533 | id="filter2950" | |
| 534 | inkscape:label="Drop Shadow" | |
| 535 | style="color-interpolation-filters:sRGB;"> | |
| 536 | <feFlood | |
| 537 | id="feFlood2940" | |
| 538 | result="flood" | |
| 539 | flood-color="rgb(0,0,0)" | |
| 540 | flood-opacity="0.498039" /> | |
| 541 | <feComposite | |
| 542 | id="feComposite2942" | |
| 543 | result="composite1" | |
| 544 | operator="in" | |
| 545 | in2="SourceGraphic" | |
| 546 | in="flood" /> | |
| 547 | <feGaussianBlur | |
| 548 | id="feGaussianBlur2944" | |
| 549 | result="blur" | |
| 550 | stdDeviation="2" | |
| 551 | in="composite1" /> | |
| 552 | <feOffset | |
| 553 | id="feOffset2946" | |
| 554 | result="offset" | |
| 555 | dy="3" | |
| 556 | dx="3" /> | |
| 557 | <feComposite | |
| 558 | id="feComposite2948" | |
| 559 | result="composite2" | |
| 560 | operator="over" | |
| 561 | in2="offset" | |
| 562 | in="SourceGraphic" /> | |
| 563 | </filter> | |
| 564 | <filter | |
| 565 | id="filter2962" | |
| 566 | inkscape:label="Drop Shadow" | |
| 567 | style="color-interpolation-filters:sRGB;"> | |
| 568 | <feFlood | |
| 569 | id="feFlood2952" | |
| 570 | result="flood" | |
| 571 | flood-color="rgb(0,0,0)" | |
| 572 | flood-opacity="0.498039" /> | |
| 573 | <feComposite | |
| 574 | id="feComposite2954" | |
| 575 | result="composite1" | |
| 576 | operator="in" | |
| 577 | in2="SourceGraphic" | |
| 578 | in="flood" /> | |
| 579 | <feGaussianBlur | |
| 580 | id="feGaussianBlur2956" | |
| 581 | result="blur" | |
| 582 | stdDeviation="2" | |
| 583 | in="composite1" /> | |
| 584 | <feOffset | |
| 585 | id="feOffset2958" | |
| 586 | result="offset" | |
| 587 | dy="3" | |
| 588 | dx="3" /> | |
| 589 | <feComposite | |
| 590 | id="feComposite2960" | |
| 591 | result="composite2" | |
| 592 | operator="over" | |
| 593 | in2="offset" | |
| 594 | in="SourceGraphic" /> | |
| 595 | </filter> | |
| 596 | <filter | |
| 597 | id="filter2974" | |
| 598 | inkscape:label="Drop Shadow" | |
| 599 | style="color-interpolation-filters:sRGB;"> | |
| 600 | <feFlood | |
| 601 | id="feFlood2964" | |
| 602 | result="flood" | |
| 603 | flood-color="rgb(0,0,0)" | |
| 604 | flood-opacity="0.498039" /> | |
| 605 | <feComposite | |
| 606 | id="feComposite2966" | |
| 607 | result="composite1" | |
| 608 | operator="in" | |
| 609 | in2="SourceGraphic" | |
| 610 | in="flood" /> | |
| 611 | <feGaussianBlur | |
| 612 | id="feGaussianBlur2968" | |
| 613 | result="blur" | |
| 614 | stdDeviation="2" | |
| 615 | in="composite1" /> | |
| 616 | <feOffset | |
| 617 | id="feOffset2970" | |
| 618 | result="offset" | |
| 619 | dy="3" | |
| 620 | dx="3" /> | |
| 621 | <feComposite | |
| 622 | id="feComposite2972" | |
| 623 | result="composite2" | |
| 624 | operator="over" | |
| 625 | in2="offset" | |
| 626 | in="SourceGraphic" /> | |
| 627 | </filter> | |
| 628 | <filter | |
| 629 | id="filter2986" | |
| 630 | inkscape:label="Drop Shadow" | |
| 631 | style="color-interpolation-filters:sRGB;"> | |
| 632 | <feFlood | |
| 633 | id="feFlood2976" | |
| 634 | result="flood" | |
| 635 | flood-color="rgb(0,0,0)" | |
| 636 | flood-opacity="0.498039" /> | |
| 637 | <feComposite | |
| 638 | id="feComposite2978" | |
| 639 | result="composite1" | |
| 640 | operator="in" | |
| 641 | in2="SourceGraphic" | |
| 642 | in="flood" /> | |
| 643 | <feGaussianBlur | |
| 644 | id="feGaussianBlur2980" | |
| 645 | result="blur" | |
| 646 | stdDeviation="2" | |
| 647 | in="composite1" /> | |
| 648 | <feOffset | |
| 649 | id="feOffset2982" | |
| 650 | result="offset" | |
| 651 | dy="3" | |
| 652 | dx="3" /> | |
| 653 | <feComposite | |
| 654 | id="feComposite2984" | |
| 655 | result="composite2" | |
| 656 | operator="over" | |
| 657 | in2="offset" | |
| 658 | in="SourceGraphic" /> | |
| 659 | </filter> | |
| 660 | </defs> | |
| 661 | <sodipodi:namedview | |
| 662 | inkscape:snap-text-baseline="false" | |
| 663 | inkscape:document-rotation="0" | |
| 664 | fit-margin-bottom="20" | |
| 665 | fit-margin-right="20" | |
| 666 | fit-margin-left="20" | |
| 667 | fit-margin-top="20" | |
| 668 | inkscape:current-layer="svg4610" | |
| 669 | inkscape:cy="370.55742" | |
| 670 | inkscape:cx="398.61418" | |
| 671 | inkscape:zoom="1.3753763" | |
| 672 | showgrid="false" | |
| 673 | id="namedview4612" | |
| 674 | inkscape:window-height="1280" | |
| 675 | inkscape:window-width="2055" | |
| 676 | inkscape:pageshadow="2" | |
| 677 | inkscape:pageopacity="1" | |
| 678 | guidetolerance="10" | |
| 679 | gridtolerance="10" | |
| 680 | objecttolerance="10" | |
| 681 | borderopacity="1" | |
| 682 | bordercolor="#666666" | |
| 683 | pagecolor="#ffffff" | |
| 684 | inkscape:window-x="215" | |
| 685 | inkscape:window-y="26" | |
| 686 | inkscape:window-maximized="0" /> | |
| 687 | <path | |
| 688 | sodipodi:nodetypes="ccssssc" | |
| 689 | inkscape:connector-curvature="0" | |
| 690 | style="fill:#333333;fill-opacity:0.0666667;fill-rule:nonzero;stroke:#df4d65;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 691 | d="M 53.35547,445.11522 V 790.96744 H 741.0332 c 1.6112,0 2.90821,-1.29701 2.90821,-2.9082 V 448.02342 c 0,-1.6112 -1.297,-2.9082 -2.90821,-2.9082 z" | |
| 692 | id="path9961" /> | |
| 693 | <path | |
| 694 | sodipodi:nodetypes="sssccssss" | |
| 695 | id="path9940" | |
| 696 | d="m 20.5,787.82486 c 0,0.87013 0.35019,1.65683 0.91797,2.22461 0.56778,0.56778 1.35253,0.91797 2.22265,0.91797 H 53.35547 V 445.11522 H 23.64062 c -0.87012,0 -1.65487,0.35019 -2.22265,0.91797 -0.56778,0.56778 -0.91797,1.35254 -0.91797,2.22266 z" | |
| 697 | style="fill:#df4d65;fill-opacity:1;fill-rule:nonzero;stroke:#df4d65;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 698 | inkscape:connector-curvature="0" /> | |
| 699 | <path | |
| 700 | sodipodi:nodetypes="sssccssss" | |
| 701 | id="path11125" | |
| 702 | d="m 20.5,423.31014 c 0,0.87013 0.35019,1.65683 0.91797,2.22461 0.56778,0.56778 1.354494,0.9764 2.22265,0.91797 H 53.35547 V 210.6005 H 23.64062 c -0.87012,0 -1.65487,0.3502 -2.22265,0.918 C 20.85019,212.08629 20.5,212.871 20.5,213.74109 Z" | |
| 703 | style="fill:#3e3e3e;fill-opacity:1;fill-rule:nonzero;stroke:#3e3e3e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 704 | inkscape:connector-curvature="0" /> | |
| 705 | <path | |
| 706 | sodipodi:nodetypes="ccssssc" | |
| 707 | inkscape:connector-curvature="0" | |
| 708 | style="fill:#333333;fill-opacity:0.0666667;fill-rule:nonzero;stroke:#3e3e3e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 709 | d="m 53.35547,210.6005 v 215.85222 h 687.67774 c 1.6112,0 2.9082,-1.29701 2.9082,-2.9082 V 213.5087 c 0,-1.6112 -1.29701,-2.90352 -2.9082,-2.9082 z" | |
| 710 | id="path11123" /> | |
| 711 | <path | |
| 712 | id="path6150" | |
| 713 | d="m 557.756,222.53493 c -0.87012,0 -1.65683,0.35019 -2.22461,0.91797 -0.56778,0.56778 -0.91797,1.35253 -0.91797,2.22265 v 29.71485 h 165.6211 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91797,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z" | |
| 714 | style="fill:#c53bd7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2926)" | |
| 715 | inkscape:connector-curvature="0" | |
| 716 | sodipodi:nodetypes="sssccssss" /> | |
| 717 | <path | |
| 718 | sodipodi:nodetypes="ccssssc" | |
| 719 | id="path6134" | |
| 720 | d="m 720.75716,255.39041 h -165.6211 v 152.63392 c 0,1.6112 1.29701,2.90821 2.90821,2.90821 h 159.80469 c 1.6112,0 2.9082,-1.29701 2.9082,-2.90821 z" | |
| 721 | style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2926)" | |
| 722 | inkscape:connector-curvature="0" /> | |
| 723 | <path | |
| 724 | id="path6082" | |
| 725 | d="m 317.13559,222.53494 c -0.87011,0 -1.65683,0.35019 -2.2246,0.91797 -0.56779,0.56778 -0.91798,1.35253 -0.91798,2.22265 v 29.71485 h 165.62111 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91798,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z" | |
| 726 | style="fill:#3dd092;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2938)" | |
| 727 | inkscape:connector-curvature="0" | |
| 728 | sodipodi:nodetypes="sssccssss" /> | |
| 729 | <path | |
| 730 | sodipodi:nodetypes="ccssssc" | |
| 731 | id="path6080" | |
| 732 | d="M 479.61412,255.39041 H 313.99301 v 152.63392 c 0,1.6112 1.29701,2.90821 2.90821,2.90821 h 159.80469 c 1.6112,0 2.90821,-1.29701 2.90821,-2.90821 z" | |
| 733 | style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2938)" | |
| 734 | inkscape:connector-curvature="0" /> | |
| 735 | <path | |
| 736 | id="path10980" | |
| 737 | d="M 53.35547,20.500012 V 188.35224 h 687.67774 c 1.6112,0 2.9082,-1.29701 2.9082,-2.9082 V 23.408212 c 0,-1.6112 -1.29701,-2.912886 -2.9082,-2.9082 z" | |
| 738 | style="fill:#333333;fill-opacity:0.0666667;fill-rule:nonzero;stroke:#3e3e3e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 739 | inkscape:connector-curvature="0" | |
| 740 | sodipodi:nodetypes="ccssssc" /> | |
| 741 | <path | |
| 742 | inkscape:connector-curvature="0" | |
| 743 | style="fill:#3e3e3e;fill-opacity:1;fill-rule:nonzero;stroke:#3e3e3e;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 744 | d="m 20.5,185.20966 c 0,0.87013 0.35019,1.65683 0.91797,2.22461 0.56778,0.56778 1.35253,0.91797 2.22265,0.91797 H 53.35547 V 20.500012 H 23.64062 c -0.87012,0 -1.65487,0.350201 -2.22265,0.918 -0.56778,0.5678 -0.91797,1.3525 -0.91797,2.2226 z" | |
| 745 | id="path10982" | |
| 746 | sodipodi:nodetypes="sssccssss" /> | |
| 747 | <path | |
| 748 | sodipodi:nodetypes="sssccssss" | |
| 749 | inkscape:connector-curvature="0" | |
| 750 | style="fill:#c53bd7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2962)" | |
| 751 | d="m 557.75599,36.704447 c -0.87012,0 -1.65683,0.35019 -2.22461,0.91797 -0.56778,0.56778 -0.91797,1.35253 -0.91797,2.22265 v 29.71485 h 165.6211 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91797,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z" | |
| 752 | id="path4857" /> | |
| 753 | <path | |
| 754 | inkscape:connector-curvature="0" | |
| 755 | style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2962)" | |
| 756 | d="M 720.23451,69.559917 H 554.61341 V 169.2396 c 0,1.6112 1.29701,2.90821 2.90821,2.90821 h 159.80469 c 1.6112,0 2.9082,-1.29701 2.9082,-2.90821 z" | |
| 757 | id="path4853" /> | |
| 758 | <path | |
| 759 | sodipodi:nodetypes="sssccssss" | |
| 760 | inkscape:connector-curvature="0" | |
| 761 | style="fill:#3dd092;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2974)" | |
| 762 | d="m 317.13558,36.704447 c -0.87011,0 -1.65683,0.35019 -2.2246,0.91797 -0.56779,0.56778 -0.91798,1.35253 -0.91798,2.22265 v 29.71485 h 165.62111 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91798,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z" | |
| 763 | id="path5726" /> | |
| 764 | <path | |
| 765 | inkscape:connector-curvature="0" | |
| 766 | style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2974)" | |
| 767 | d="M 479.61411,69.559917 H 313.993 V 169.2396 c 0,1.6112 1.29701,2.90821 2.90821,2.90821 H 476.7059 c 1.6112,0 2.90821,-1.29701 2.90821,-2.90821 z" | |
| 768 | id="path5724" /> | |
| 769 | <path | |
| 770 | id="path4721" | |
| 771 | d="m 235.85308,44.704447 c 0.87012,0 1.65488,0.35019 2.22266,0.91797 0.56778,0.56778 0.91797,1.35253 0.91797,2.22265 v -0.23242 c 0,-1.6112 -1.297,-2.9082 -2.9082,-2.9082 z" | |
| 772 | style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 773 | inkscape:connector-curvature="0" /> | |
| 774 | <path | |
| 775 | sodipodi:nodetypes="sssccssss" | |
| 776 | id="path4719" | |
| 777 | d="m 76.515197,36.704447 c -0.870125,0 -1.656831,0.35019 -2.22461,0.91797 -0.567778,0.56778 -0.917968,1.35253 -0.917968,2.22265 v 29.71485 H 238.99371 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91797,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z" | |
| 778 | style="fill:#46c7f0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2986)" | |
| 779 | inkscape:connector-curvature="0" /> | |
| 780 | <path | |
| 781 | id="path4723" | |
| 782 | d="M 238.99372,69.559917 H 73.372613 V 169.2396 c 0,1.6112 1.29701,2.90821 2.90821,2.90821 H 236.08552 c 1.6112,0 2.9082,-1.29701 2.9082,-2.90821 z" | |
| 783 | style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2986)" | |
| 784 | inkscape:connector-curvature="0" /> | |
| 785 | <path | |
| 786 | id="rect4622" | |
| 787 | d="m 76.280822,44.704447 c -1.611195,0 -2.908203,1.297 -2.908203,2.9082 v 0.23242 c 0,-0.87012 0.35019,-1.65487 0.917968,-2.22265 0.567779,-0.56778 1.354485,-0.91797 2.22461,-0.91797 z" | |
| 788 | style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 789 | inkscape:connector-curvature="0" /> | |
| 790 | <path | |
| 791 | sodipodi:nodetypes="cc" | |
| 792 | inkscape:connector-curvature="0" | |
| 793 | id="path9889" | |
| 794 | d="m 397.61301,500.62068 -0.50618,32.59418" | |
| 795 | style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:1.9694221;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9893)" /> | |
| 796 | <path | |
| 797 | style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9715)" | |
| 798 | d="m 554.61351,648.83688 -69.6817,47.69253" | |
| 799 | id="path9711" | |
| 800 | inkscape:connector-curvature="0" | |
| 801 | sodipodi:nodetypes="cc" /> | |
| 802 | <path | |
| 803 | sodipodi:nodetypes="cc" | |
| 804 | inkscape:connector-curvature="0" | |
| 805 | id="path9675" | |
| 806 | d="M 554.61351,567.95047 484.93181,615.643" | |
| 807 | style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9679)" /> | |
| 808 | <rect | |
| 809 | ry="3.9839513" | |
| 810 | rx="3.9205718" | |
| 811 | y="537.09552" | |
| 812 | x="554.61353" | |
| 813 | height="32.855" | |
| 814 | width="165.621" | |
| 815 | id="rect9618" | |
| 816 | style="opacity:1;fill:#c53bd7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2842)" /> | |
| 817 | <rect | |
| 818 | ry="3.9839513" | |
| 819 | rx="3.9205718" | |
| 820 | y="537.09552" | |
| 821 | x="73.372665" | |
| 822 | height="32.855" | |
| 823 | width="165.621" | |
| 824 | id="rect9614" | |
| 825 | style="opacity:1;fill:#46c7f0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2914)" /> | |
| 826 | <path | |
| 827 | inkscape:connector-curvature="0" | |
| 828 | style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 829 | d="m 235.85308,545.09525 c 0.87012,0 1.65488,0.35019 2.22266,0.91797 0.56778,0.56778 0.91797,1.35253 0.91797,2.22265 v -0.23242 c 0,-1.6112 -1.297,-2.9082 -2.9082,-2.9082 z" | |
| 830 | id="path9323" /> | |
| 831 | <path | |
| 832 | inkscape:connector-curvature="0" | |
| 833 | style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 834 | d="m 76.280823,545.09525 c -1.611195,0 -2.908203,1.297 -2.908203,2.9082 v 0.23242 c 0,-0.87012 0.35019,-1.65487 0.917968,-2.22265 0.567779,-0.56778 1.354485,-0.91797 2.22461,-0.91797 z" | |
| 835 | id="path9327" /> | |
| 836 | <rect | |
| 837 | style="opacity:1;fill:#3dd092;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2902)" | |
| 838 | id="rect9616" | |
| 839 | width="165.621" | |
| 840 | height="32.855" | |
| 841 | x="313.99307" | |
| 842 | y="537.09552" | |
| 843 | rx="3.9205718" | |
| 844 | ry="3.9839513" /> | |
| 845 | <path | |
| 846 | sodipodi:nodetypes="cc" | |
| 847 | inkscape:connector-curvature="0" | |
| 848 | id="path9491" | |
| 849 | d="m 240.99257,554.11276 65.23376,-1.01307" | |
| 850 | style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9513)" /> | |
| 851 | <path | |
| 852 | style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9640)" | |
| 853 | d="m 481.61298,554.11276 65.23376,-1.01307" | |
| 854 | id="path9501" | |
| 855 | inkscape:connector-curvature="0" | |
| 856 | sodipodi:nodetypes="cc" /> | |
| 857 | <rect | |
| 858 | ry="3.9839513" | |
| 859 | rx="3.9205718" | |
| 860 | y="617.79578" | |
| 861 | x="313.99307" | |
| 862 | height="32.855" | |
| 863 | width="165.621" | |
| 864 | id="rect9620" | |
| 865 | style="opacity:1;fill:#3dd092;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2890)" /> | |
| 866 | <path | |
| 867 | sodipodi:nodetypes="cc" | |
| 868 | inkscape:connector-curvature="0" | |
| 869 | id="path9681" | |
| 870 | d="m 481.61298,634.81299 65.23376,-1.01307" | |
| 871 | style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9685)" /> | |
| 872 | <rect | |
| 873 | style="opacity:1;fill:#c53bd7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2854)" | |
| 874 | id="rect9687" | |
| 875 | width="165.621" | |
| 876 | height="32.855" | |
| 877 | x="554.61353" | |
| 878 | y="617.79578" | |
| 879 | rx="3.9205718" | |
| 880 | ry="3.9839513" /> | |
| 881 | <path | |
| 882 | style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9750)" | |
| 883 | d="m 481.61298,715.51321 65.23376,-1.01307" | |
| 884 | id="path9734" | |
| 885 | inkscape:connector-curvature="0" | |
| 886 | sodipodi:nodetypes="cc" /> | |
| 887 | <rect | |
| 888 | ry="3.9839513" | |
| 889 | rx="3.9205718" | |
| 890 | y="698.49591" | |
| 891 | x="554.61353" | |
| 892 | height="32.855" | |
| 893 | width="165.621" | |
| 894 | id="rect9736" | |
| 895 | style="opacity:1;fill:#c53bd7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2866)" /> | |
| 896 | <path | |
| 897 | id="path9830" | |
| 898 | d="m 356.40451,489.45323 c -0.80426,0 -1.45167,0.64741 -1.45167,1.45166 v 0.11602 c 0,-0.43433 0.1748,-0.82605 0.45822,-1.10946 0.28341,-0.28342 0.6761,-0.45822 1.11043,-0.45822 z" | |
| 899 | style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.10902636;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 900 | inkscape:connector-curvature="0" /> | |
| 901 | <rect | |
| 902 | style="opacity:1;fill:#ffb73a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.9391377;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 903 | id="rect9826" | |
| 904 | width="120.98324" | |
| 905 | height="24" | |
| 906 | x="336.82672" | |
| 907 | y="477.86002" | |
| 908 | rx="2.8639088" | |
| 909 | ry="2.9102066" /> | |
| 910 | <path | |
| 911 | id="path10514" | |
| 912 | d="m 235.85301,637.23875 c 0.87012,0 1.65488,0.35019 2.22266,0.91797 0.56778,0.56778 0.91797,1.35253 0.91797,2.22265 v -0.23242 c 0,-1.6112 -1.297,-2.9082 -2.9082,-2.9082 z" | |
| 913 | style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 914 | inkscape:connector-curvature="0" /> | |
| 915 | <rect | |
| 916 | style="opacity:1;fill:#3dd092;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.02355671;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2878)" | |
| 917 | id="rect9717" | |
| 918 | width="165.621" | |
| 919 | height="32.855" | |
| 920 | x="313.99307" | |
| 921 | y="698.49591" | |
| 922 | rx="3.9205718" | |
| 923 | ry="3.9839513" /> | |
| 924 | <path | |
| 925 | id="path10537" | |
| 926 | d="M 238.99366,636.97465 H 73.372671 V 729.175 c 0,1.2055 0.970418,2.17592 2.175911,2.17592 H 236.81776 c 1.20549,0 2.1759,-0.97042 2.1759,-2.17592 z" | |
| 927 | style="opacity:1;fill:#333333;fill-opacity:0.93333333;fill-rule:nonzero;stroke:none;stroke-width:0.16342013;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 928 | inkscape:connector-curvature="0" | |
| 929 | sodipodi:nodetypes="ccssssc" /> | |
| 930 | <path | |
| 931 | sodipodi:nodetypes="sssccssss" | |
| 932 | id="path10516" | |
| 933 | d="m 75.723937,612.39226 c -0.651025,0 -1.239637,0.26201 -1.664447,0.68682 -0.424811,0.42482 -0.686822,1.01196 -0.686822,1.66299 v 22.23258 H 238.99366 v -22.23258 c 0,-0.65103 -0.26201,-1.23817 -0.68682,-1.66299 -0.42481,-0.42481 -1.01197,-0.68682 -1.66299,-0.68682 z" | |
| 934 | style="opacity:1;fill:#ffb73a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.16342013;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 935 | inkscape:connector-curvature="0" /> | |
| 936 | <path | |
| 937 | style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker10933)" | |
| 938 | d="m 240.99257,715.51318 65.23376,-1.01307" | |
| 939 | id="path10929" | |
| 940 | inkscape:connector-curvature="0" | |
| 941 | sodipodi:nodetypes="cc" /> | |
| 942 | <path | |
| 943 | style="fill:#df4d65;fill-opacity:1;fill-rule:evenodd;stroke-width:0.05250736" | |
| 944 | d="m 399.47357,99.155037 -0.12716,0.0127 -0.12716,0.0141 -0.12574,0.0141 -0.12716,0.0155 -0.61883,0.967813 -0.29106,0.9325 -0.17943,0.91977 -0.1215,1.09073 -0.30943,0.0636 -0.308,0.0678 -0.308,0.0735 -0.30801,0.0763 -0.58069,-0.93108 -0.5609,-0.75023 -0.66687,-0.71349 -0.97912,-0.6033 -0.12009,0.0409 -0.1201,0.0424 -0.12009,0.0424 -0.12009,0.0424 -0.38854,1.08085 -0.0763,0.97487 0.0297,0.93673 0.12575,1.08932 -0.28823,0.1314 -0.28681,0.13563 -0.28398,0.13987 -0.28117,0.14271 -0.77425,-0.77849 -0.7149,-0.60612 -0.80816,-0.54819 -1.0879,-0.37017 -0.10879,0.0678 -0.10738,0.0679 -0.10738,0.0678 -0.10738,0.0678 -0.13846,1.14018 0.14129,0.9664 0.23735,0.90706 0.36594,1.03563 -0.25149,0.19215 -0.24865,0.19497 -0.24585,0.19922 -0.24442,0.20204 -0.92825,-0.58634 -0.83077,-0.43234 -0.90988,-0.35463 -1.14301,-0.11868 -0.0904,0.0904 -0.0904,0.089 -0.089,0.0904 -0.0904,0.0904 0.11868,1.14301 0.35462,0.90988 0.43234,0.83218 0.58634,0.92684 -0.20204,0.24442 -0.19921,0.24584 -0.19498,0.24867 -0.19215,0.25148 -1.03563,-0.36593 -0.90705,-0.23736 -0.96641,-0.14128 -1.14018,0.13845 -0.0678,0.10738 -0.0678,0.10738 -0.0678,0.10738 -0.0678,0.10879 0.37016,1.0879 0.5482,0.80816 0.60612,0.71491 0.77848,0.77425 -0.1427,0.28117 -0.13987,0.28398 -0.13564,0.28681 -0.13139,0.28823 -1.09073,-0.12575 -0.93532,-0.0297 -0.97487,0.0763 -1.08084,0.38854 -0.0424,0.12009 -0.0424,0.12009 -0.0424,0.1201 -0.0409,0.12009 0.6033,0.97912 0.7135,0.66686 0.75023,0.56091 0.93107,0.58069 -0.0763,0.30801 -0.0735,0.308 -0.0678,0.308 -0.0636,0.30942 -1.09073,0.1215 -0.91977,0.17944 -0.9325,0.29105 -0.96781,0.61883 -0.0156,0.12717 -0.0141,0.12574 -0.0141,0.12716 -0.0127,0.12716 0.80533,0.81804 0.84348,0.49168 0.85619,0.38006 1.03704,0.36028 -0.006,0.31648 -0.003,0.31648 0.003,0.31648 0.006,0.31648 -1.03704,0.35887 -0.85619,0.38006 -0.84348,0.49168 -0.80533,0.81946 0.0127,0.12716 0.0141,0.12574 0.0141,0.12716 0.0156,0.12574 0.96781,0.62026 0.9325,0.29104 0.91977,0.17944 1.09073,0.12009 0.0636,0.30942 0.0678,0.30941 0.0735,0.30801 0.0763,0.30659 -0.93107,0.5821 -0.75023,0.56091 -0.7135,0.66687 -0.6033,0.97771 0.0409,0.12008 0.0424,0.12151 0.0424,0.1201 0.0424,0.11868 1.08084,0.38995 0.97487,0.0763 0.93532,-0.0297 1.09073,-0.12574 0.13139,0.28822 0.13564,0.2854 0.13987,0.28399 0.1427,0.28257 -0.77848,0.77425 -0.60612,0.7135 -0.5482,0.80957 -0.37016,1.08791 0.0678,0.10737 0.0678,0.10879 0.0678,0.10738 0.0678,0.10738 1.14018,0.13846 0.96641,-0.1427 0.90705,-0.23736 1.03563,-0.36452 0.19215,0.25149 0.19498,0.24866 0.19921,0.24584 0.20204,0.24302 -0.58634,0.92825 -0.43234,0.83076 -0.35462,0.9113 -0.11868,1.14159 0.0904,0.0918 0.089,0.089 0.0904,0.0904 0.0904,0.089 1.14301,-0.11868 0.90988,-0.35321 0.83077,-0.43375 0.92825,-0.58493 0.24442,0.20204 0.24585,0.19921 0.24865,0.19497 0.25149,0.19216 -0.36594,1.03563 -0.23735,0.90564 -0.14129,0.9664 0.13846,1.14018 0.10738,0.0692 0.10738,0.0678 0.10738,0.0678 0.10879,0.0664 1.0879,-0.37017 0.80816,-0.54677 0.7149,-0.60754 0.77425,-0.77708 0.28117,0.14271 0.28398,0.13987 0.28681,0.13422 0.28823,0.13139 -0.12575,1.09074 -0.0297,0.93673 0.0763,0.97346 0.38854,1.08084 0.12009,0.0438 0.12009,0.0424 0.1201,0.041 0.12009,0.0409 0.97912,-0.60188 0.66687,-0.71349 0.5609,-0.75165 0.58069,-0.93108 0.30801,0.0777 0.308,0.072 0.308,0.0692 0.30943,0.0636 0.1215,1.09073 0.17943,0.91978 0.29106,0.93249 0.61883,0.9664 0.12716,0.0156 0.12574,0.0141 0.12716,0.0141 0.12716,0.0141 0.81806,-0.80533 0.49167,-0.8449 0.38006,-0.85619 0.36028,-1.03704 0.31648,0.007 0.31648,0.003 0.31649,-0.003 0.31648,-0.007 0.36028,1.03704 0.37865,0.85619 0.49167,0.8449 0.81947,0.80533 0.12715,-0.0141 0.12574,-0.0141 0.12717,-0.0141 0.12574,-0.0156 0.62025,-0.9664 0.29104,-0.93249 0.17944,-0.91978 0.12009,-1.09073 0.30942,-0.0636 0.30942,-0.0692 0.30799,-0.072 0.3066,-0.0777 0.58211,0.93108 0.5609,0.75165 0.66687,0.71349 0.97771,0.60188 0.12009,-0.0409 0.1215,-0.041 0.1201,-0.0424 0.11868,-0.0438 0.38995,-1.08084 0.0763,-0.97346 -0.0297,-0.93673 -0.12574,-1.09074 0.28822,-0.13139 0.2854,-0.13422 0.28398,-0.13987 0.28258,-0.14271 0.77424,0.77708 0.7135,0.60754 0.80957,0.54677 1.08791,0.37017 0.10737,-0.0664 0.10879,-0.0678 0.10738,-0.0678 0.10738,-0.0692 0.13847,-1.14018 -0.14271,-0.9664 -0.23737,-0.90564 -0.36452,-1.03563 0.25149,-0.19216 0.24866,-0.19497 0.24585,-0.19921 0.24301,-0.20204 0.92825,0.58493 0.83077,0.43375 0.91129,0.35321 1.1416,0.11868 0.0904,-0.089 0.0904,-0.0904 0.0904,-0.089 0.089,-0.0918 -0.11868,-1.14159 -0.35321,-0.9113 -0.43375,-0.83076 -0.58492,-0.92825 0.20203,-0.24302 0.19921,-0.24584 0.19498,-0.24866 0.19215,-0.25149 1.03563,0.36452 0.90564,0.23736 0.9664,0.1427 1.14018,-0.13846 0.0692,-0.10738 0.0678,-0.10738 0.0678,-0.10879 0.0664,-0.10737 -0.37017,-1.08791 -0.54677,-0.80957 -0.60754,-0.7135 -0.77706,-0.77425 0.1427,-0.28257 0.13986,-0.28399 0.13423,-0.2854 0.13139,-0.28822 1.09073,0.12574 0.93674,0.0297 0.97345,-0.0763 1.08085,-0.38995 0.0438,-0.11868 0.0424,-0.1201 0.0409,-0.12151 0.041,-0.12008 -0.6019,-0.97771 -0.71349,-0.66687 -0.75164,-0.56091 -0.93108,-0.5821 0.0777,-0.30659 0.072,-0.30801 0.0692,-0.30941 0.0636,-0.30942 1.09073,-0.12009 0.91978,-0.17944 0.93249,-0.29104 0.9664,-0.62026 0.0155,-0.12574 0.0141,-0.12716 0.0141,-0.12574 0.0141,-0.12716 -0.80533,-0.81946 -0.8449,-0.49168 -0.85619,-0.38006 -1.03704,-0.35887 0.007,-0.31648 0.003,-0.31648 -0.003,-0.31648 -0.007,-0.31648 1.03704,-0.36028 0.85619,-0.38006 0.8449,-0.49168 0.80533,-0.81804 -0.0141,-0.12716 -0.0141,-0.12716 -0.0141,-0.12574 -0.0155,-0.12717 -0.9664,-0.61883 -0.93249,-0.29105 -0.91978,-0.17944 -1.09073,-0.1215 -0.0636,-0.30942 -0.0692,-0.308 -0.072,-0.308 -0.0777,-0.30801 0.93108,-0.58069 0.75164,-0.56091 0.71349,-0.66686 0.6019,-0.97912 -0.041,-0.12009 -0.0409,-0.1201 -0.0424,-0.12009 -0.0438,-0.12009 -1.08085,-0.38854 -0.97345,-0.0763 -0.93674,0.0297 -1.09073,0.12575 -0.13139,-0.28823 -0.13423,-0.28681 -0.13986,-0.28398 -0.1427,-0.28117 0.77706,-0.77425 0.60754,-0.71491 0.54677,-0.80816 0.37017,-1.0879 -0.0664,-0.10879 -0.0678,-0.10738 -0.0678,-0.10738 -0.0692,-0.10738 -1.14018,-0.13845 -0.9664,0.14128 -0.90564,0.23736 -1.03563,0.36593 -0.19215,-0.25148 -0.19498,-0.24867 -0.19921,-0.24584 -0.20203,-0.24442 0.58492,-0.92684 0.43375,-0.83218 0.35321,-0.90988 0.11868,-1.14301 -0.089,-0.0904 -0.0904,-0.0904 -0.0904,-0.089 -0.0904,-0.0904 -1.1416,0.11868 -0.91129,0.35463 -0.83077,0.43234 -0.92825,0.58634 -0.24301,-0.20204 -0.24585,-0.19922 -0.24866,-0.19497 -0.25149,-0.19215 0.36452,-1.03563 0.23737,-0.90706 0.14271,-0.9664 -0.13847,-1.14018 -0.10738,-0.0678 -0.10738,-0.0678 -0.10879,-0.0679 -0.10737,-0.0678 -1.08791,0.37017 -0.80957,0.54819 -0.7135,0.60612 -0.77424,0.77849 -0.28258,-0.14271 -0.28398,-0.13987 -0.2854,-0.13563 -0.28822,-0.1314 0.12574,-1.08932 0.0297,-0.93673 -0.0763,-0.97487 -0.38995,-1.08085 -0.11868,-0.0424 -0.1201,-0.0424 -0.1215,-0.0424 -0.12009,-0.0409 -0.97771,0.6033 -0.66687,0.71349 -0.5609,0.75023 -0.58211,0.93108 -0.3066,-0.0763 -0.30799,-0.0735 -0.30942,-0.0678 -0.30942,-0.0636 -0.12009,-1.09073 -0.17944,-0.91977 -0.29104,-0.9325 -0.62025,-0.967813 -0.12574,-0.0155 -0.12717,-0.0141 -0.12574,-0.0141 -0.12715,-0.0127 -0.81947,0.80533 -0.49167,0.843483 -0.37865,0.8562 -0.36028,1.03704 -0.31648,-0.006 -0.31649,-0.003 -0.31648,0.003 -0.31648,0.006 -0.36028,-1.03704 -0.38006,-0.8562 -0.49167,-0.843483 z m 2.68302,20.688573 a 5.3990039,5.3990039 0 0 1 5.39856,5.39997 5.3990039,5.3990039 0 0 1 -5.39856,5.39855 5.3990039,5.3990039 0 0 1 -5.39996,-5.39855 5.3990039,5.3990039 0 0 1 5.39996,-5.39997 z" | |
| 945 | id="path5693" | |
| 946 | inkscape:connector-curvature="0" /> | |
| 947 | <path | |
| 948 | inkscape:connector-curvature="0" | |
| 949 | d="m 380.9529,101.31918 a 4.37599,4.37599 0 0 1 -4.37599,4.37599 4.37599,4.37599 0 0 1 -4.37599,-4.37599 4.37599,4.37599 0 0 1 4.37599,-4.375983 4.37599,4.37599 0 0 1 4.37599,4.375983 z m 4.63493,-1.27213 c -0.32212,-0.118873 -0.95326,0.0926 -0.92258,-0.401293 -0.13877,-0.39635 -0.21401,-0.74537 0.27363,-0.88946 0.78055,-0.47633 1.45123,-1.16128 1.74461,-2.04171 0.15411,-0.39145 -0.3432,-0.48754 -0.63657,-0.53536 -0.91614,-0.25589 -1.86519,0.0578 -2.73328,0.35995 -0.11023,-0.31345 -0.69059,-0.56868 -0.47901,-0.88657 0.56405,-0.84324 0.99162,-1.8335 0.85012,-2.86709 -0.031,-0.41955 -0.52073,-0.29038 -0.8058,-0.20618 -0.93646,0.16692 -1.65537,0.86143 -2.30642,1.51029 -0.23528,-0.23464 -0.86896,-0.21274 -0.81624,-0.59097 0.14241,-1.00446 0.0978,-2.08217 -0.47806,-2.95201 -0.20995,-0.36459 -0.59514,-0.0357 -0.81544,0.16385 -0.7713,0.55671 -1.11768,1.49434 -1.42274,2.36143 -0.3138,-0.10927 -0.87519,0.18536 -0.99181,-0.17826 -0.30757,-0.96675 -0.81528,-1.91841 -1.71153,-2.45229 -0.34734,-0.23737 -0.55176,0.22606 -0.66364,0.50149 -0.45331,0.83622 -0.35865,1.83127 -0.25723,2.74482 -0.33012,0.0378 -0.70817,0.54672 -0.97098,0.26977 -0.69651,-0.73763 -1.56687,-1.37476 -2.60601,-1.46682 -0.41593,-0.0631 -0.39904,0.443 -0.38034,0.73971 -0.0456,0.95009 0.47143,1.80554 0.95918,2.58463 -0.28104,0.17725 -0.40076,0.79984 -0.75777,0.6643 -0.94759,-0.36236 -2.00818,-0.55864 -2.98437,-0.1908 -0.40215,0.12357 -0.16723,0.57227 -0.0217,0.83147 0.37114,0.8758 1.2081,1.42221 1.98561,1.91248 -0.17632,0.28163 -0.0141,0.89453 -0.39449,0.92732 -1.01097,0.0847 -2.05173,0.367983 -2.77166,1.122963 -0.3087,0.2858 0.0976,0.58816 0.34122,0.75853 0.71439,0.62804 1.70558,0.75716 2.6188,0.8616 -0.0367,0.33025 0.37548,0.81204 0.0469,1.00665 -0.87415,0.51488 -1.68886,1.22174 -2.00994,2.2143 -0.15411,0.39144 0.3432,0.48753 0.63657,0.53535 0.91612,0.25589 1.86516,-0.0578 2.73323,-0.35995 0.11029,0.31341 0.69063,0.56869 0.47905,0.88657 -0.56412,0.8432 -0.99155,1.83352 -0.85015,2.86709 0.031,0.41952 0.52075,0.2904 0.80584,0.20618 0.93644,-0.16692 1.65537,-0.86139 2.30637,-1.51029 0.2353,0.23464 0.86901,0.21272 0.81629,0.59098 -0.14241,1.00446 -0.0978,2.08215 0.47802,2.95202 0.20997,0.36455 0.59517,0.0357 0.81548,-0.16387 0.77125,-0.55674 1.11768,-1.49435 1.42274,-2.36142 0.31379,0.10926 0.8752,-0.18537 0.99181,0.17824 0.30754,0.96678 0.81527,1.91842 1.71153,2.45229 0.34733,0.23738 0.55172,-0.22608 0.66362,-0.50146 0.45335,-0.83621 0.35866,-1.83128 0.25725,-2.74484 0.33011,-0.0378 0.70812,-0.54672 0.97093,-0.26977 0.69656,0.7376 1.5669,1.37477 2.60606,1.46683 0.41593,0.0632 0.39897,-0.44304 0.38032,-0.73972 0.0457,-0.95011 -0.4715,-1.8055 -0.95916,-2.58463 0.28105,-0.17722 0.40074,-0.79983 0.75772,-0.6643 0.94761,0.36234 2.00821,0.55865 2.98442,0.1908 0.40215,-0.12357 0.16723,-0.57228 0.0217,-0.83146 -0.37116,-0.87579 -1.20814,-1.42218 -1.98561,-1.91249 0.17632,-0.28163 0.0141,-0.89453 0.39449,-0.92732 1.01097,-0.0847 2.05173,-0.36799 2.77166,-1.12295 0.3087,-0.28581 -0.0976,-0.58817 -0.34122,-0.75854 -0.47483,-0.43652 -1.13407,-0.61787 -1.75144,-0.75008 z" | |
| 950 | style="fill:#05556e;fill-opacity:1;fill-rule:evenodd;stroke-width:0.04014921" | |
| 951 | id="path5687" /> | |
| 952 | <path | |
| 953 | style="fill:#05556e;fill-opacity:1;stroke-width:0.11881336" | |
| 954 | id="path4816" | |
| 955 | d="m 619.92265,90.37586 h 2.72717 v 2.71445 h 2.51374 v -2.71445 h 2.72716 v 8.21477 h -2.72716 v -2.73825 h -2.49003 v 2.73825 h -2.75088 m 11.57268,-5.47651 h -2.40702 v -2.73826 h 7.55307 v 2.73826 h -2.41888 v 5.47651 h -2.72717 m 6.34363,-8.21477 h 2.8576 l 1.75487,2.89303 1.75487,-2.89303 h 2.8576 v 8.21477 h -2.72717 v -4.07167 l -1.90901,2.95256 -1.90902,-2.95256 v 4.07167 h -2.67974 m 10.57667,-8.21477 h 2.72717 v 5.50033 h 3.86546 v 2.71444 h -6.59263" | |
| 956 | inkscape:connector-curvature="0" /> | |
| 957 | <path | |
| 958 | id="path4818" | |
| 959 | d="m 619.82779,146.45062 -3.91289,-44.09786 h 43.01811 l -3.91289,44.07405 -17.63174,4.90505" | |
| 960 | inkscape:connector-curvature="0" | |
| 961 | style="fill:#e44d26;stroke-width:0.11881336" /> | |
| 962 | <path | |
| 963 | id="path4820" | |
| 964 | d="m 637.42396,147.58164 v -41.60962 h 17.5843 l -3.3556,37.62129" | |
| 965 | inkscape:connector-curvature="0" | |
| 966 | style="fill:#f16529;stroke-width:0.11881336" /> | |
| 967 | <path | |
| 968 | id="path4822" | |
| 969 | d="m 623.90669,111.3652 h 13.51727 v 5.40508 h -7.61236 l 0.498,5.53605 h 7.11436 v 5.39318 h -12.04697 m 0.23714,2.71444 h 5.40691 l 0.37943,4.32169 6.02349,1.61914 v 5.64319 L 626.373,138.90255" | |
| 970 | inkscape:connector-curvature="0" | |
| 971 | style="fill:#ebebeb;stroke-width:0.11881336" /> | |
| 972 | <path | |
| 973 | id="path4824" | |
| 974 | d="m 650.89379,111.3652 h -13.49355 v 5.40508 h 12.99555 m -0.48615,5.53605 h -12.5094 v 5.40508 h 6.64006 l -0.62843,7.02423 -6.01163,1.61914 v 5.61938 l 11.02724,-3.07161" | |
| 975 | inkscape:connector-curvature="0" | |
| 976 | style="fill:#ffffff;stroke-width:0.11881336" /> | |
| 977 | <path | |
| 978 | sodipodi:nodetypes="cc" | |
| 979 | inkscape:connector-curvature="0" | |
| 980 | id="path5804" | |
| 981 | d="m 240.99252,105.07517 65.2338,-1.01308" | |
| 982 | style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9479)" /> | |
| 983 | <path | |
| 984 | style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9505)" | |
| 985 | d="m 481.61302,105.07517 65.2337,-1.01308" | |
| 986 | id="path9497" | |
| 987 | inkscape:connector-curvature="0" | |
| 988 | sodipodi:nodetypes="cc" /> | |
| 989 | <path | |
| 990 | inkscape:connector-curvature="0" | |
| 991 | style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 992 | d="m 235.85308,230.53494 c 0.87012,0 1.65488,0.35019 2.22266,0.91797 0.56778,0.56778 0.91797,1.35253 0.91797,2.22265 v -0.23242 c 0,-1.6112 -1.297,-2.9082 -2.9082,-2.9082 z" | |
| 993 | id="path6102" /> | |
| 994 | <path | |
| 995 | inkscape:connector-curvature="0" | |
| 996 | style="opacity:1;fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.21841836;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 997 | d="m 76.280823,230.53494 c -1.611195,0 -2.908203,1.297 -2.908203,2.9082 v 0.23242 c 0,-0.87012 0.35019,-1.65487 0.917968,-2.22265 0.567779,-0.56778 1.354485,-0.91797 2.22461,-0.91797 z" | |
| 998 | id="path6106" /> | |
| 999 | <path | |
| 1000 | inkscape:connector-curvature="0" | |
| 1001 | style="fill:#46c7f0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2950)" | |
| 1002 | d="m 76.515198,222.53494 c -0.870125,0 -1.656831,0.35019 -2.22461,0.91797 -0.567778,0.56778 -0.917968,1.35253 -0.917968,2.22265 v 29.71485 h 165.62109 v -29.71485 c 0,-0.87012 -0.35019,-1.65487 -0.91797,-2.22265 -0.56778,-0.56778 -1.35254,-0.91797 -2.22266,-0.91797 z" | |
| 1003 | id="path6104" | |
| 1004 | sodipodi:nodetypes="sssccssss" /> | |
| 1005 | <path | |
| 1006 | sodipodi:nodetypes="ccssssc" | |
| 1007 | inkscape:connector-curvature="0" | |
| 1008 | style="fill:#e6e7e7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.218418;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter2950)" | |
| 1009 | d="M 238.99371,255.39041 H 73.37262 v 152.63392 c 0,1.6112 1.297008,2.90821 2.908203,2.90821 H 236.08551 c 1.6112,0 2.9082,-1.29701 2.9082,-2.90821 z" | |
| 1010 | id="path6100" /> | |
| 1011 | <path | |
| 1012 | style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9509)" | |
| 1013 | d="m 240.99257,328.95043 65.23376,-1.01307" | |
| 1014 | id="path9485" | |
| 1015 | inkscape:connector-curvature="0" | |
| 1016 | sodipodi:nodetypes="cc" /> | |
| 1017 | <path | |
| 1018 | sodipodi:nodetypes="cc" | |
| 1019 | inkscape:connector-curvature="0" | |
| 1020 | id="path9757" | |
| 1021 | d="m 481.61298,300.08996 65.23376,-1.01307" | |
| 1022 | style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9761)" /> | |
| 1023 | <path | |
| 1024 | style="opacity:1;vector-effect:none;fill:#05556e;fill-opacity:1;stroke:#05556e;stroke-width:3.94158769;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker9767)" | |
| 1025 | d="M 552.61456,372.04139 487.3808,371.02832" | |
| 1026 | id="path9763" | |
| 1027 | inkscape:connector-curvature="0" | |
| 1028 | sodipodi:nodetypes="cc" /> | |
| 1029 | <text | |
| 1030 | id="text2269" | |
| 1031 | y="62.149761" | |
| 1032 | x="115.43707" | |
| 1033 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1034 | xml:space="preserve"><tspan | |
| 1035 | y="62.149761" | |
| 1036 | x="115.43707" | |
| 1037 | id="tspan2267" | |
| 1038 | sodipodi:role="line">Text Edit</tspan></text> | |
| 1039 | <text | |
| 1040 | transform="rotate(-90)" | |
| 1041 | id="text2273" | |
| 1042 | y="43.507812" | |
| 1043 | x="-132.24059" | |
| 1044 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1045 | xml:space="preserve"><tspan | |
| 1046 | y="43.507812" | |
| 1047 | x="-132.24059" | |
| 1048 | id="tspan2271" | |
| 1049 | sodipodi:role="line">Today</tspan></text> | |
| 1050 | <text | |
| 1051 | id="text2277" | |
| 1052 | y="61.540386" | |
| 1053 | x="358.88168" | |
| 1054 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1055 | xml:space="preserve"><tspan | |
| 1056 | y="61.540386" | |
| 1057 | x="358.88168" | |
| 1058 | id="tspan2275" | |
| 1059 | sodipodi:role="line">Process</tspan></text> | |
| 1060 | <text | |
| 1061 | id="text2281" | |
| 1062 | y="59.34898" | |
| 1063 | x="605.30872" | |
| 1064 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1065 | xml:space="preserve"><tspan | |
| 1066 | y="59.34898" | |
| 1067 | x="605.30872" | |
| 1068 | id="tspan2279" | |
| 1069 | sodipodi:role="line">Output</tspan></text> | |
| 1070 | <text | |
| 1071 | id="text2285" | |
| 1072 | y="245.17946" | |
| 1073 | x="605.30872" | |
| 1074 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1075 | xml:space="preserve"><tspan | |
| 1076 | y="245.17946" | |
| 1077 | x="605.30872" | |
| 1078 | id="tspan2283" | |
| 1079 | sodipodi:role="line">Output</tspan></text> | |
| 1080 | <text | |
| 1081 | id="text2289" | |
| 1082 | y="247.37088" | |
| 1083 | x="358.88168" | |
| 1084 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1085 | xml:space="preserve"><tspan | |
| 1086 | y="247.37088" | |
| 1087 | x="358.88168" | |
| 1088 | id="tspan2287" | |
| 1089 | sodipodi:role="line">Process</tspan></text> | |
| 1090 | <text | |
| 1091 | id="text2293" | |
| 1092 | y="247.98026" | |
| 1093 | x="115.43707" | |
| 1094 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1095 | xml:space="preserve"><tspan | |
| 1096 | y="247.98026" | |
| 1097 | x="115.43707" | |
| 1098 | id="tspan2291" | |
| 1099 | sodipodi:role="line">Text Edit</tspan></text> | |
| 1100 | <text | |
| 1101 | transform="rotate(-90)" | |
| 1102 | id="text2297" | |
| 1103 | y="43.630859" | |
| 1104 | x="-363.15442" | |
| 1105 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1106 | xml:space="preserve"><tspan | |
| 1107 | y="43.630859" | |
| 1108 | x="-363.15442" | |
| 1109 | id="tspan2295" | |
| 1110 | sodipodi:role="line">Proposed</tspan></text> | |
| 1111 | <text | |
| 1112 | id="text2301" | |
| 1113 | y="314.01108" | |
| 1114 | x="98.034729" | |
| 1115 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none" | |
| 1116 | xml:space="preserve"><tspan | |
| 1117 | id="tspan2299" | |
| 1118 | sodipodi:role="line" | |
| 1119 | x="98.034729" | |
| 1120 | y="314.01108">R Markdown</tspan></text> | |
| 1121 | <text | |
| 1122 | id="text2305" | |
| 1123 | y="285.84311" | |
| 1124 | x="107.43903" | |
| 1125 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none" | |
| 1126 | xml:space="preserve"><tspan | |
| 1127 | id="tspan2303" | |
| 1128 | sodipodi:role="line" | |
| 1129 | x="107.43903" | |
| 1130 | y="285.84311">Markdown</tspan></text> | |
| 1131 | <text | |
| 1132 | id="text2309" | |
| 1133 | y="342.91147" | |
| 1134 | x="134.3277" | |
| 1135 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none" | |
| 1136 | xml:space="preserve"><tspan | |
| 1137 | id="tspan2307" | |
| 1138 | sodipodi:role="line" | |
| 1139 | x="134.3277" | |
| 1140 | y="342.91147">XML</tspan></text> | |
| 1141 | <text | |
| 1142 | id="text2313" | |
| 1143 | y="370.34702" | |
| 1144 | x="113.56207" | |
| 1145 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none" | |
| 1146 | xml:space="preserve"><tspan | |
| 1147 | id="tspan2311" | |
| 1148 | sodipodi:role="line" | |
| 1149 | x="113.56207" | |
| 1150 | y="370.34702">DocBook</tspan></text> | |
| 1151 | <text | |
| 1152 | id="text2317" | |
| 1153 | y="398.51498" | |
| 1154 | x="114.3526" | |
| 1155 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none" | |
| 1156 | xml:space="preserve"><tspan | |
| 1157 | id="tspan2315" | |
| 1158 | sodipodi:role="line" | |
| 1159 | x="114.3526" | |
| 1160 | y="398.51498">AsciiDoc</tspan></text> | |
| 1161 | <text | |
| 1162 | transform="rotate(-90)" | |
| 1163 | id="text2329" | |
| 1164 | y="43.507812" | |
| 1165 | x="-774.87335" | |
| 1166 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1167 | xml:space="preserve"><tspan | |
| 1168 | y="43.507812" | |
| 1169 | x="-774.87335" | |
| 1170 | id="tspan2327" | |
| 1171 | sodipodi:role="line">Example Processing Combination</tspan></text> | |
| 1172 | <text | |
| 1173 | id="text2333" | |
| 1174 | y="562.05426" | |
| 1175 | x="135.31207" | |
| 1176 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#f3fbfe;fill-opacity:1;stroke:none" | |
| 1177 | xml:space="preserve"><tspan | |
| 1178 | y="562.05426" | |
| 1179 | x="135.31207" | |
| 1180 | id="tspan2331" | |
| 1181 | sodipodi:role="line">XML</tspan></text> | |
| 1182 | <text | |
| 1183 | id="text2337" | |
| 1184 | y="495.6918" | |
| 1185 | x="381.64142" | |
| 1186 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#333333;fill-opacity:0.866667;stroke:none" | |
| 1187 | xml:space="preserve"><tspan | |
| 1188 | y="495.6918" | |
| 1189 | x="381.64142" | |
| 1190 | id="tspan2335" | |
| 1191 | sodipodi:role="line">XSLT</tspan></text> | |
| 1192 | <text | |
| 1193 | id="text2341" | |
| 1194 | y="562.05426" | |
| 1195 | x="323.97742" | |
| 1196 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1197 | xml:space="preserve"><tspan | |
| 1198 | y="562.05426" | |
| 1199 | x="323.97742" | |
| 1200 | id="tspan2339" | |
| 1201 | sodipodi:role="line">XSLT Processor</tspan></text> | |
| 1202 | <text | |
| 1203 | id="text2345" | |
| 1204 | y="562.54059" | |
| 1205 | x="579.27557" | |
| 1206 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1207 | xml:space="preserve"><tspan | |
| 1208 | y="562.54059" | |
| 1209 | x="579.27557" | |
| 1210 | id="tspan2343" | |
| 1211 | sodipodi:role="line">R Markdown</tspan></text> | |
| 1212 | <text | |
| 1213 | id="text2349" | |
| 1214 | y="643.24084" | |
| 1215 | x="588.75018" | |
| 1216 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1217 | xml:space="preserve"><tspan | |
| 1218 | y="643.24084" | |
| 1219 | x="588.75018" | |
| 1220 | id="tspan2347" | |
| 1221 | sodipodi:role="line">Markdown</tspan></text> | |
| 1222 | <text | |
| 1223 | id="text2353" | |
| 1224 | y="642.63147" | |
| 1225 | x="339.61023" | |
| 1226 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1227 | xml:space="preserve"><tspan | |
| 1228 | y="642.63147" | |
| 1229 | x="339.61023" | |
| 1230 | id="tspan2351" | |
| 1231 | sodipodi:role="line">R Processor</tspan></text> | |
| 1232 | <text | |
| 1233 | id="text2357" | |
| 1234 | y="722.93903" | |
| 1235 | x="318.43912" | |
| 1236 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:21.3333px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1237 | xml:space="preserve"><tspan | |
| 1238 | y="722.93903" | |
| 1239 | x="318.43912" | |
| 1240 | id="tspan2355" | |
| 1241 | sodipodi:role="line">Variable Processor</tspan></text> | |
| 1242 | <text | |
| 1243 | id="text2361" | |
| 1244 | y="723.3316" | |
| 1245 | x="604.07831" | |
| 1246 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1247 | xml:space="preserve"><tspan | |
| 1248 | y="723.3316" | |
| 1249 | x="604.07831" | |
| 1250 | id="tspan2359" | |
| 1251 | sodipodi:role="line">HTML5</tspan></text> | |
| 1252 | <text | |
| 1253 | id="text2365" | |
| 1254 | y="630.84766" | |
| 1255 | x="81.211723" | |
| 1256 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#333333;fill-opacity:0.866667;stroke:none" | |
| 1257 | xml:space="preserve"><tspan | |
| 1258 | y="630.84766" | |
| 1259 | x="81.211723" | |
| 1260 | id="tspan2363" | |
| 1261 | sodipodi:role="line">Structured Data Source</tspan></text> | |
| 1262 | <text | |
| 1263 | id="text2369" | |
| 1264 | y="756.39404" | |
| 1265 | x="215.65826" | |
| 1266 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none" | |
| 1267 | xml:space="preserve"><tspan | |
| 1268 | y="756.39404" | |
| 1269 | x="215.65826" | |
| 1270 | id="tspan2367" | |
| 1271 | sodipodi:role="line">interpolated values</tspan></text> | |
| 1272 | <g | |
| 1273 | transform="translate(-0.25585322,11.831789)" | |
| 1274 | id="g2523"> | |
| 1275 | <text | |
| 1276 | xml:space="preserve" | |
| 1277 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1278 | x="156.49219" | |
| 1279 | y="708.2467" | |
| 1280 | id="text2373"><tspan | |
| 1281 | sodipodi:role="line" | |
| 1282 | id="tspan2371" | |
| 1283 | x="156.49219" | |
| 1284 | y="708.2467">CSON</tspan></text> | |
| 1285 | <text | |
| 1286 | xml:space="preserve" | |
| 1287 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1288 | x="156.49219" | |
| 1289 | y="688.41504" | |
| 1290 | id="text2377"><tspan | |
| 1291 | sodipodi:role="line" | |
| 1292 | id="tspan2375" | |
| 1293 | x="156.49219" | |
| 1294 | y="688.41504">JSONNET</tspan></text> | |
| 1295 | <text | |
| 1296 | xml:space="preserve" | |
| 1297 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1298 | x="156.49219" | |
| 1299 | y="668.24695" | |
| 1300 | id="text2381"><tspan | |
| 1301 | sodipodi:role="line" | |
| 1302 | id="tspan2379" | |
| 1303 | x="156.49219" | |
| 1304 | y="668.24695">JSON5</tspan></text> | |
| 1305 | <text | |
| 1306 | xml:space="preserve" | |
| 1307 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1308 | x="156.49219" | |
| 1309 | y="648.07886" | |
| 1310 | id="text2385"><tspan | |
| 1311 | sodipodi:role="line" | |
| 1312 | id="tspan2383" | |
| 1313 | x="156.49219" | |
| 1314 | y="648.07886">JSON</tspan></text> | |
| 1315 | <text | |
| 1316 | xml:space="preserve" | |
| 1317 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1318 | x="94.110725" | |
| 1319 | y="648.41534" | |
| 1320 | id="text2389"><tspan | |
| 1321 | sodipodi:role="line" | |
| 1322 | id="tspan2387" | |
| 1323 | x="94.110725" | |
| 1324 | y="648.41534">YAML</tspan></text> | |
| 1325 | <text | |
| 1326 | xml:space="preserve" | |
| 1327 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1328 | x="94.110725" | |
| 1329 | y="668.24695" | |
| 1330 | id="text2393"><tspan | |
| 1331 | sodipodi:role="line" | |
| 1332 | id="tspan2391" | |
| 1333 | x="94.110725" | |
| 1334 | y="668.24695">TOML</tspan></text> | |
| 1335 | <text | |
| 1336 | xml:space="preserve" | |
| 1337 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:16.4059px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:0.933333;stroke:none" | |
| 1338 | x="94.110725" | |
| 1339 | y="688.41504" | |
| 1340 | id="text2397"><tspan | |
| 1341 | sodipodi:role="line" | |
| 1342 | id="tspan2395" | |
| 1343 | x="94.110725" | |
| 1344 | y="688.41504">XML</tspan></text> | |
| 1345 | </g> | |
| 1346 | <g | |
| 1347 | transform="translate(-1.2304677,-0.85937628)" | |
| 1348 | id="g2593"> | |
| 1349 | <g | |
| 1350 | id="g2532"> | |
| 1351 | <rect | |
| 1352 | id="rect4698" | |
| 1353 | ry="2.7292624" | |
| 1354 | y="91.740654" | |
| 1355 | x="129.16347" | |
| 1356 | height="32.205296" | |
| 1357 | width="54.039394" | |
| 1358 | style="fill:none;stroke:#05556e;stroke-width:2.72926;stroke-opacity:1" /> | |
| 1359 | <path | |
| 1360 | style="fill:#05556e;fill-opacity:1;stroke-width:0.272926" | |
| 1361 | id="path4700" | |
| 1362 | d="M 135.98663,117.12279 V 98.56381 h 5.45852 l 5.45853,6.82315 5.45852,-6.82315 h 5.45853 v 18.55898 h -5.45853 v -10.64412 l -5.45852,6.82315 -5.45853,-6.82315 v 10.64412 z m 34.11578,0 -8.18779,-9.00657 h 5.45852 v -9.55241 h 5.45853 v 9.55241 h 5.45852 z" | |
| 1363 | inkscape:connector-curvature="0" /> | |
| 1364 | </g> | |
| 1365 | <text | |
| 1366 | xml:space="preserve" | |
| 1367 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none" | |
| 1368 | x="108.73981" | |
| 1369 | y="152.80437" | |
| 1370 | id="text2407"><tspan | |
| 1371 | sodipodi:role="line" | |
| 1372 | id="tspan2405" | |
| 1373 | x="108.73981" | |
| 1374 | y="152.80437">Markdown</tspan></text> | |
| 1375 | </g> | |
| 1376 | <path | |
| 1377 | inkscape:connector-curvature="0" | |
| 1378 | d="m 417.86562,272.90923 c -2.81873,0.35302 -5.58858,1.78683 -7.90222,4.10047 -1.79226,1.78682 -3.43787,4.20365 -5.01832,7.35911 -1.28173,2.56347 -2.29191,5.21927 -2.90019,7.59265 l -0.1738,0.68975 -0.68975,0.35302 c -0.96673,0.49423 -1.81398,1.01561 -2.77528,1.69993 -3.29666,2.35709 -6.15341,5.19211 -8.53222,8.46705 -0.23354,0.32586 -0.45621,0.58656 -0.49966,0.58656 -0.038,0 -0.33673,-0.0435 -0.65716,-0.0923 -0.73863,-0.11949 -3.19891,-0.13578 -4.11676,-0.0272 -3.79633,0.46164 -7.25593,1.57502 -11.41613,3.68228 -3.00339,1.5207 -4.93685,2.87304 -6.8323,4.77391 -2.37881,2.37882 -3.80176,5.01832 -4.21452,7.82076 -0.0978,0.62457 -0.0978,2.39511 0,3.0414 0.51052,3.55193 2.55804,6.94636 5.27358,8.74404 3.15003,2.08554 7.40256,2.6558 12.27424,1.65105 3.62253,-0.75492 7.20161,-2.14527 10.77526,-4.19822 3.47046,-1.99321 5.87643,-4.18193 7.57093,-6.87575 0.27155,-0.43449 0.35845,-0.52682 0.53224,-0.59199 2.79701,-1.01018 4.74677,-2.05295 6.96265,-3.72572 2.02036,-1.5207 3.43244,-2.85675 6.0991,-5.77324 0.68432,-0.74949 0.8038,-0.91785 0.84182,-1.16225 0.0326,-0.17379 0.0543,-0.20095 0.15207,-0.17922 0.51595,0.10319 2.20502,0.11948 2.94908,0.0272 2.08553,-0.25526 4.05701,-1.10251 6.01763,-2.57976 2.61778,-1.97691 5.06177,-5.27901 6.78885,-9.17853 2.59606,-5.86556 3.57908,-10.80785 3.01425,-15.19073 -0.14121,-1.12423 -0.28241,-1.74881 -0.59742,-2.71554 -0.42905,-1.29803 -1.08621,-2.55804 -1.89001,-3.62796 -0.43449,-0.57026 -1.57502,-1.70536 -2.14528,-2.12898 -1.59131,-1.17855 -3.93753,-2.13442 -6.03936,-2.46028 -0.66259,-0.10319 -2.29735,-0.14664 -2.85132,-0.0815 z m 2.44399,7.82076 c 1.94433,0.46707 3.2152,2.04751 3.5302,4.39917 0.0815,0.58656 0.0815,2.10183 0,2.7427 -0.32043,2.62864 -1.26544,5.70263 -2.61235,8.48878 -1.01561,2.10725 -1.79226,3.34011 -2.88933,4.58383 -0.32587,0.36931 -1.38493,1.31975 -1.42838,1.2763 -0.005,-0.005 0.0706,-0.34216 0.1738,-0.74406 0.24983,-0.97759 0.34215,-1.56958 0.3856,-2.41683 0.0706,-1.58044 -0.27155,-3.09571 -0.98302,-4.30684 -1.20027,-2.05295 -3.17175,-3.41072 -5.47453,-3.78547 -0.11405,-0.0163 -0.20638,-0.0489 -0.20638,-0.076 0,-0.0217 0.19552,-0.53768 0.42905,-1.15139 1.41752,-3.67684 2.66666,-5.83298 4.30142,-7.40799 1.0482,-1.01562 1.70536,-1.40665 2.73726,-1.62933 0.51596,-0.11405 1.49355,-0.0978 2.03666,0.0272 z m -10.34078,17.93885 c 0.52139,0.54311 0.56483,0.76579 0.46164,2.25933 l -0.0326,0.51596 -0.14121,-0.21725 c -0.22811,-0.34215 -0.40733,-0.72233 -0.52682,-1.1188 -0.0652,-0.20095 -0.15207,-0.43992 -0.20095,-0.53224 -0.0706,-0.13035 -0.17922,-0.91243 -0.19008,-1.34691 0,-0.11949 0.29871,0.0923 0.63,0.43991 z m -7.36997,3.01425 c 0.3856,2.28649 1.18397,4.05159 2.44941,5.40393 l 0.45078,0.47793 -0.13577,0.14664 c -0.0706,0.0815 -0.46165,0.51052 -0.86355,0.9613 -1.55328,1.73795 -2.81873,2.98167 -4.05158,3.97012 -0.41819,0.34216 -0.78208,0.61915 -0.79837,0.61915 -0.0163,0 -0.0435,-0.0923 -0.0652,-0.20638 -0.076,-0.4019 -0.46708,-1.4664 -0.8038,-2.15614 -0.54311,-1.12424 -1.14596,-2.0095 -2.08554,-3.0577 l -0.45621,-0.50509 0.41276,-0.50509 c 1.19484,-1.47182 2.92192,-3.26951 4.43177,-4.62728 0.85811,-0.76578 1.37949,-1.21656 1.39578,-1.20027 0.005,0.005 0.0597,0.315 0.11949,0.67888 z m -16.52135,9.77052 c -0.0163,0.11405 -0.0815,0.54311 -0.14664,0.9613 -0.22267,1.47182 -0.23353,3.57365 -0.0272,4.78478 0.19008,1.10251 0.57569,2.11812 1.08078,2.81873 0.27699,0.38018 0.87441,0.97759 1.22199,1.20027 l 0.23354,0.1575 -0.15207,0.12492 c -0.60285,0.48879 -2.54174,1.58044 -4.18193,2.34622 -2.4114,1.12967 -4.36659,1.7651 -6.62049,2.16157 -0.77664,0.13578 -0.99932,0.15207 -2.09096,0.15207 -0.98846,0 -1.30889,-0.0217 -1.67278,-0.0978 -1.5207,-0.33672 -2.53088,-0.97216 -3.1989,-2.0095 -0.53225,-0.82552 -0.72234,-1.48268 -0.72777,-2.43855 0,-1.56415 0.57027,-2.68296 2.17244,-4.27969 1.78682,-1.77597 3.93753,-3.05227 7.72299,-4.5784 2.01493,-0.81467 4.20366,-1.37407 5.75151,-1.4664 0.74406,-0.0434 0.66803,-0.0652 0.63544,0.16294 z m 6.13712,3.5302 c -0.0163,0.0543 -0.0272,0.0109 -0.0272,-0.0923 0,-0.10319 0.0109,-0.14664 0.0272,-0.0978 0.0109,0.0543 0.0109,0.14121 0,0.19009 z" | |
| 1379 | id="path8164" | |
| 1380 | style="fill:#df4d65;fill-opacity:1;stroke:none;stroke-width:0.00543108" /> | |
| 1381 | <g | |
| 1382 | transform="translate(1.378418e-5,1.0193503)" | |
| 1383 | id="g1168"> | |
| 1384 | <text | |
| 1385 | id="text1158" | |
| 1386 | y="364.17905" | |
| 1387 | x="349.05551" | |
| 1388 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none" | |
| 1389 | xml:space="preserve"><tspan | |
| 1390 | id="tspan1156" | |
| 1391 | sodipodi:role="line" | |
| 1392 | x="349.05551" | |
| 1393 | y="364.17905">Processor</tspan></text> | |
| 1394 | <text | |
| 1395 | xml:space="preserve" | |
| 1396 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none" | |
| 1397 | x="370.40707" | |
| 1398 | y="392.17905" | |
| 1399 | id="text1162"><tspan | |
| 1400 | y="392.17905" | |
| 1401 | x="370.40707" | |
| 1402 | sodipodi:role="line" | |
| 1403 | id="tspan1160">Chain</tspan></text> | |
| 1404 | </g> | |
| 1405 | <g | |
| 1406 | transform="translate(0,-2.3144459)" | |
| 1407 | id="g1206"> | |
| 1408 | <text | |
| 1409 | xml:space="preserve" | |
| 1410 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none" | |
| 1411 | x="586.44855" | |
| 1412 | y="327.56967" | |
| 1413 | id="text1190"><tspan | |
| 1414 | y="327.56967" | |
| 1415 | x="586.44855" | |
| 1416 | sodipodi:role="line" | |
| 1417 | id="tspan1188">Processor-</tspan></text> | |
| 1418 | <text | |
| 1419 | id="text1194" | |
| 1420 | y="355.56967" | |
| 1421 | x="588.43488" | |
| 1422 | style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:24px;line-height:1.25;font-family:'Roboto Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#05556e;fill-opacity:1;stroke:none" | |
| 1423 | xml:space="preserve"><tspan | |
| 1424 | id="tspan1192" | |
| 1425 | sodipodi:role="line" | |
| 1426 | x="588.43488" | |
| 1427 | y="355.56967">dependent</tspan></text> | |
| 1428 | </g> | |
| 1429 | </svg> | |
| 1 | 1430 |
| 1 | ||
| 1 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"> | |
| 2 | <title>HTML5 Logo</title> | |
| 3 | <path d="M108.4 0h23v22.8h21.2V0h23v69h-23V46h-21v23h-23.2M206 23h-20.3V0h63.7v23H229v46h-23M259.5 0h24.1l14.8 24.3L313.2 0h24.1v69h-23V34.8l-16.1 24.8l-16.1-24.8v34.2h-22.6M348.7 0h23v46.2h32.6V69h-55.6"/> | |
| 4 | <path fill="#e44d26" d="M107.6 471l-33-370.4h362.8l-33 370.2L255.7 512"/> | |
| 5 | <path fill="#f16529" d="M256 480.5V131H404.3L376 447"/> | |
| 6 | <path fill="#ebebeb" d="M142 176.3h114v45.4h-64.2l4.2 46.5h60v45.3H154.4M156.4 336.3H202l3.2 36.3 50.8 13.6v47.4l-93.2-26"/> | |
| 7 | <path fill="#fff" d="M369.6 176.3H255.8v45.4h109.6M361.3 268.2H255.8v45.4h56l-5.3 59-50.7 13.6v47.2l93-25.8"/> | |
| 8 | </svg> |
| 1 | <?xml version="1.0" standalone="no"?> | |
| 2 | <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" | |
| 3 | "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> | |
| 4 | <svg version="1.0" xmlns="http://www.w3.org/2000/svg" | |
| 5 | width="1280.000000pt" height="1123.000000pt" viewBox="0 0 1280.000000 1123.000000" | |
| 6 | preserveAspectRatio="xMidYMid meet"> | |
| 7 | <metadata> | |
| 8 | Created by potrace 1.15, written by Peter Selinger 2001-2017 | |
| 9 | </metadata> | |
| 10 | <g transform="translate(0.000000,1123.000000) scale(0.100000,-0.100000)" | |
| 11 | fill="#000000" stroke="none"> | |
| 12 | <path d="M10280 11220 c-519 -65 -1029 -329 -1455 -755 -330 -329 -633 -774 | |
| 13 | -924 -1355 -236 -472 -422 -961 -534 -1398 l-32 -127 -127 -65 c-178 -91 -334 | |
| 14 | -187 -511 -313 -607 -434 -1133 -956 -1571 -1559 -43 -60 -84 -108 -92 -108 | |
| 15 | -7 0 -62 8 -121 17 -136 22 -589 25 -758 5 -699 -85 -1336 -290 -2102 -678 | |
| 16 | -553 -280 -909 -529 -1258 -879 -438 -438 -700 -924 -776 -1440 -18 -115 -18 | |
| 17 | -441 0 -560 94 -654 471 -1279 971 -1610 580 -384 1363 -489 2260 -304 667 | |
| 18 | 139 1326 395 1984 773 639 367 1082 770 1394 1266 50 80 66 97 98 109 515 186 | |
| 19 | 874 378 1282 686 372 280 632 526 1123 1063 126 138 148 169 155 214 6 32 10 | |
| 20 | 37 28 33 95 -19 406 -22 543 -5 384 47 747 203 1108 475 482 364 932 972 1250 | |
| 21 | 1690 478 1080 659 1990 555 2797 -26 207 -52 322 -110 500 -79 239 -200 471 | |
| 22 | -348 668 -80 105 -290 314 -395 392 -293 217 -725 393 -1112 453 -122 19 -423 | |
| 23 | 27 -525 15z m450 -1440 c358 -86 592 -377 650 -810 15 -108 15 -387 0 -505 | |
| 24 | -59 -484 -233 -1050 -481 -1563 -187 -388 -330 -615 -532 -844 -60 -68 -255 | |
| 25 | -243 -263 -235 -1 1 13 63 32 137 46 180 63 289 71 445 13 291 -50 570 -181 | |
| 26 | 793 -221 378 -584 628 -1008 697 -21 3 -38 9 -38 14 0 4 36 99 79 212 261 677 | |
| 27 | 491 1074 792 1364 193 187 314 259 504 300 95 21 275 18 375 -5z m-1904 -3303 | |
| 28 | c96 -100 104 -141 85 -416 l-6 -95 -26 40 c-42 63 -75 133 -97 206 -12 37 -28 | |
| 29 | 81 -37 98 -13 24 -33 168 -35 248 0 22 55 -17 116 -81z m-1357 -555 c71 -421 | |
| 30 | 218 -746 451 -995 l83 -88 -25 -27 c-13 -15 -85 -94 -159 -177 -286 -320 -519 | |
| 31 | -549 -746 -731 -77 -63 -144 -114 -147 -114 -3 0 -8 17 -12 38 -14 74 -86 270 | |
| 32 | -148 397 -100 207 -211 370 -384 563 l-84 93 76 93 c220 271 538 602 816 852 | |
| 33 | 158 141 254 224 257 221 1 -1 11 -58 22 -125z m-3042 -1799 c-3 -21 -15 -100 | |
| 34 | -27 -177 -41 -271 -43 -658 -5 -881 35 -203 106 -390 199 -519 51 -70 161 | |
| 35 | -180 225 -221 l43 -29 -28 -23 c-111 -90 -468 -291 -770 -432 -444 -208 -804 | |
| 36 | -325 -1219 -398 -143 -25 -184 -28 -385 -28 -182 0 -241 4 -308 18 -280 62 | |
| 37 | -466 179 -589 370 -98 152 -133 273 -134 449 0 288 105 494 400 788 329 327 | |
| 38 | 725 562 1422 843 371 150 774 253 1059 270 137 8 123 12 117 -30z m1130 -650 | |
| 39 | c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/> | |
| 40 | </g> | |
| 41 | </svg> | |
| 1 | 42 |
| 1 | ||
| 1 | <svg xmlns="http://www.w3.org/2000/svg" width="208" height="128" viewBox="0 0 208 128"><rect width="198" height="118" x="5" y="5" ry="10" stroke="#000" stroke-width="10" fill="none"/><path d="M30 98V30h20l20 25 20-25h20v68H90V59L70 84 50 59v39zm125 0l-30-33h20V30h20v35h20z"/></svg> |
| 1 | ||
| 1 | <?xml version="1.0" encoding="UTF-8" standalone="no" ?> | |
| 2 | <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> | |
| 3 | <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1280" height="1024" viewBox="0 0 1280 1024" xml:space="preserve"> | |
| 4 | <desc>Created with Fabric.js 3.6.3</desc> | |
| 5 | <defs> | |
| 6 | </defs> | |
| 7 | <g transform="matrix(1.9692780337941629 0 0 1.9692780337941629 640.0153846153846 512.012312418764)" id="background-logo" > | |
| 8 | <rect style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(255,255,255); fill-rule: nonzero; opacity: 1;" paint-order="stroke" x="-325" y="-260" rx="0" ry="0" width="650" height="520" /> | |
| 9 | </g> | |
| 10 | <g transform="matrix(1.9692780337941629 0 0 1.9692780337941629 640.0170725174504 420.4016715831266)" id="logo-logo" > | |
| 11 | <g style="" paint-order="stroke" > | |
| 12 | <g transform="matrix(2.537 0 0 -2.537 -86.35385711719567 85.244912)" > | |
| 13 | <linearGradient id="SVGID_1_302284" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-24.348526 -27.478867 -27.478867 24.348526 138.479 129.67187)" x1="0" y1="0" x2="1" y2="0"> | |
| 14 | <stop offset="0%" style="stop-color:rgb(245,132,41);stop-opacity: 1"/> | |
| 15 | <stop offset="100%" style="stop-color:rgb(251,173,23);stop-opacity: 1"/> | |
| 16 | </linearGradient> | |
| 17 | <path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: url(#SVGID_1_302284); fill-rule: nonzero; opacity: 1;" paint-order="stroke" transform=" translate(-127.92674550729492, -117.16399999999999)" d="m 118.951 124.648 c -9.395 -14.441 -5.243 -20.693 -5.243 -20.693 v 0 c 0 0 6.219 9.126 9.771 5.599 v 0 c 3.051 -3.023 -2.415 -8.668 -2.415 -8.668 v 0 c 0 0 33.24 13.698 17.995 28.872 v 0 c 0 0 -3.203 3.683 -7.932 3.684 v 0 c -3.46 0 -7.736 -1.97 -12.176 -8.794" stroke-linecap="round" /> | |
| 18 | </g> | |
| 19 | <g transform="matrix(2.537 0 0 -2.537 -84.52085711719567 70.2729119999999)" > | |
| 20 | <path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(250,220,153); fill-rule: nonzero; opacity: 1;" paint-order="stroke" transform=" translate(11.9895, -1.2609990716440347)" d="m 0 0 c 0 0 -6.501 6.719 -11.093 5.443 c -5.584 -1.545 -12.886 -12.078 -12.886 -12.078 c 0 0 5.98 16.932 15.29 15.731 C -1.19 8.127 0 0 0 0" stroke-linecap="round" /> | |
| 21 | </g> | |
| 22 | <g transform="matrix(2.537 0 0 -2.537 -22.327857117195663 48.729911999999956)" > | |
| 23 | <path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(201,158,82); fill-rule: nonzero; opacity: 1;" paint-order="stroke" transform=" translate(-4.189, -10.432)" d="m 0 0 l -0.87 16.89 l 3.995 3.974 l 6.123 -6.156 z" stroke-linecap="round" /> | |
| 24 | </g> | |
| 25 | <g transform="matrix(2.537 0 0 -2.537 -11.3118571171957 24.124911999999966)" > | |
| 26 | <path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(201,158,82); fill-rule: nonzero; opacity: 1;" paint-order="stroke" transform=" translate(4.0955, -2.037)" d="m 0 0 l -2.081 -2.069 l -6.11 6.143 l 2.081 2.069 z" stroke-linecap="round" /> | |
| 27 | </g> | |
| 28 | <g transform="matrix(2.537 0 0 -2.537 46.27614288280432 -57.96708800000005)" > | |
| 29 | <path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(217,170,93); fill-rule: nonzero; opacity: 1;" paint-order="stroke" transform=" translate(12.070999999999998, 9.599000000000004)" d="m 0 0 c -1.226 0.69 -2.81 0.523 -3.862 -0.524 c -1.275 -1.268 -1.28 -3.33 -0.013 -4.604 l -31.681 -31.501 l -6.11 6.143 c 19.224 19.305 25.369 35.582 25.369 35.582 c 15.857 2.364 27.851 8.624 33.821 12.335 z" stroke-linecap="round" /> | |
| 30 | </g> | |
| 31 | <g transform="matrix(2.537 0 0 -2.537 -26.842857117195706 8.501911999999976)" > | |
| 32 | <path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(217,170,93); fill-rule: nonzero; opacity: 1;" paint-order="stroke" transform=" translate(4.1075, -2.0525)" d="M 0 0 L -2.081 -2.069 L -8.215 4.11 L -6.141 6.174 Z" stroke-linecap="round" /> | |
| 33 | </g> | |
| 34 | <g transform="matrix(2.537 0 0 -2.537 -51.495857117195726 19.491911999999985)" > | |
| 35 | <path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(217,170,93); fill-rule: nonzero; opacity: 1;" paint-order="stroke" transform=" translate(10.434000000000001, -1.0939999999999994)" d="m 0 0 l -3.995 -3.974 l -16.873 0.96 l 14.752 9.176 z" stroke-linecap="round" /> | |
| 36 | </g> | |
| 37 | <g transform="matrix(2.537 0 0 -2.537 55.72014288280434 -48.441088000000036)" > | |
| 38 | <path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(201,158,82); fill-rule: nonzero; opacity: 1;" paint-order="stroke" transform=" translate(9.671499999999998, 11.999499999999998)" d="M 0 0 L 17.536 17.443 C 13.788 11.486 7.47 -0.468 5.021 -16.312 c 0 0 -15.526 -6.982 -35.765 -25.13 l -6.135 6.168 l 31.681 31.5 c 1.273 -1.28 3.33 -1.279 4.604 -0.012 C 0.435 -2.764 0.629 -1.223 0 0" stroke-linecap="round" /> | |
| 39 | </g> | |
| 40 | </g> | |
| 41 | </g> | |
| 42 | <g transform="matrix(1.9692780337941629 0 0 1.9692780337941629 643.7363123827618 766.1975713477327)" id="text-logo-path" > | |
| 43 | <path style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(247,149,33); fill-rule: nonzero; opacity: 1;" paint-order="stroke" transform=" translate(-186.83999999999997, 27.08)" d="M 4.47 -6.1 L 4.47 -6.1 L 4.47 -47.5 Q 4.47 -50.27 6.43 -52.23 Q 8.39 -54.19 11.16 -54.19 L 11.16 -54.19 Q 14.01 -54.19 15.95 -52.23 Q 17.89 -50.27 17.89 -47.5 L 17.89 -47.5 L 17.89 -30.09 L 34.95 -51.97 Q 35.74 -52.97 36.94 -53.58 Q 38.13 -54.19 39.42 -54.19 L 39.42 -54.19 Q 41.77 -54.19 43.42 -52.5 Q 45.07 -50.82 45.07 -48.5 L 45.07 -48.5 Q 45.07 -46.46 43.82 -44.93 L 43.82 -44.93 L 32.93 -31.44 L 46.8 -9.81 Q 47.84 -8.11 47.84 -6.27 L 47.84 -6.27 Q 47.84 -3.33 45.9 -1.39 Q 43.96 0.55 41.19 0.55 L 41.19 0.55 Q 39.42 0.55 37.89 -0.29 Q 36.37 -1.14 35.43 -2.57 L 35.43 -2.57 L 23.78 -21.15 L 17.89 -13.9 L 17.89 -6.1 Q 17.89 -3.33 15.93 -1.39 Q 13.97 0.55 11.16 0.55 L 11.16 0.55 Q 8.39 0.55 6.43 -1.39 Q 4.47 -3.33 4.47 -6.1 Z M 50.27 -19.24 L 50.27 -19.24 Q 50.27 -25.13 52.71 -29.78 Q 55.16 -34.43 59.7 -37.06 Q 64.24 -39.69 70.27 -39.69 L 70.27 -39.69 Q 76.37 -39.69 80.78 -37.09 Q 85.18 -34.49 87.43 -30.32 Q 89.69 -26.14 89.69 -21.6 L 89.69 -21.6 Q 89.69 -18.69 88.33 -17.26 Q 86.98 -15.84 83.86 -15.84 L 83.86 -15.84 L 62.89 -15.84 Q 63.23 -12.38 65.38 -10.31 Q 67.53 -8.25 70.86 -8.25 L 70.86 -8.25 Q 72.84 -8.25 74.19 -8.91 Q 75.54 -9.57 76.62 -10.64 L 76.62 -10.64 Q 77.62 -11.58 78.42 -12.03 Q 79.22 -12.48 80.43 -12.48 L 80.43 -12.48 Q 82.61 -12.48 84.19 -10.89 Q 85.77 -9.29 85.77 -7.04 L 85.77 -7.04 Q 85.77 -4.54 83.62 -2.77 L 83.62 -2.77 Q 81.71 -1.14 78.16 -0.03 Q 74.61 1.07 70.58 1.07 L 70.58 1.07 Q 64.76 1.07 60.13 -1.42 Q 55.5 -3.92 52.89 -8.53 Q 50.27 -13.14 50.27 -19.24 Z M 62.96 -23.57 L 62.96 -23.57 L 76.96 -23.57 Q 76.82 -26.97 74.93 -28.97 Q 73.05 -30.96 70.06 -30.96 L 70.06 -30.96 Q 67.08 -30.96 65.21 -28.97 Q 63.34 -26.97 62.96 -23.57 Z M 91.63 -19.24 L 91.63 -19.24 Q 91.63 -25.13 94.07 -29.78 Q 96.52 -34.43 101.06 -37.06 Q 105.6 -39.69 111.63 -39.69 L 111.63 -39.69 Q 117.73 -39.69 122.14 -37.09 Q 126.54 -34.49 128.79 -30.32 Q 131.04 -26.14 131.04 -21.6 L 131.04 -21.6 Q 131.04 -18.69 129.69 -17.26 Q 128.34 -15.84 125.22 -15.84 L 125.22 -15.84 L 104.25 -15.84 Q 104.59 -12.38 106.74 -10.31 Q 108.89 -8.25 112.22 -8.25 L 112.22 -8.25 Q 114.2 -8.25 115.55 -8.91 Q 116.9 -9.57 117.98 -10.64 L 117.98 -10.64 Q 118.98 -11.58 119.78 -12.03 Q 120.58 -12.48 121.79 -12.48 L 121.79 -12.48 Q 123.97 -12.48 125.55 -10.89 Q 127.13 -9.29 127.13 -7.04 L 127.13 -7.04 Q 127.13 -4.54 124.98 -2.77 L 124.98 -2.77 Q 123.07 -1.14 119.52 -0.03 Q 115.96 1.07 111.94 1.07 L 111.94 1.07 Q 106.12 1.07 101.49 -1.42 Q 96.86 -3.92 94.24 -8.53 Q 91.63 -13.14 91.63 -19.24 Z M 104.32 -23.57 L 104.32 -23.57 L 118.32 -23.57 Q 118.18 -26.97 116.29 -28.97 Q 114.4 -30.96 111.42 -30.96 L 111.42 -30.96 Q 108.44 -30.96 106.57 -28.97 Q 104.7 -26.97 104.32 -23.57 Z M 135.03 -6.03 L 135.03 -6.03 L 135.03 -33.14 Q 135.03 -35.64 136.85 -37.46 Q 138.67 -39.28 141.13 -39.28 L 141.13 -39.28 Q 143.7 -39.28 145.52 -37.46 Q 147.34 -35.64 147.34 -33.14 L 147.34 -33.14 L 147.34 -32.17 Q 148.97 -35.36 152.09 -37.42 Q 155.21 -39.49 159.82 -39.49 L 159.82 -39.49 Q 166.93 -39.49 170.19 -35.47 Q 173.44 -31.44 173.44 -24.44 L 173.44 -24.44 L 173.44 -6.03 Q 173.44 -3.33 171.5 -1.39 Q 169.56 0.55 166.86 0.55 L 166.86 0.55 Q 164.15 0.55 162.19 -1.39 Q 160.24 -3.33 160.24 -6.03 L 160.24 -6.03 L 160.24 -22.36 Q 160.24 -26.35 158.54 -27.91 Q 156.84 -29.47 154.65 -29.47 L 154.65 -29.47 Q 152.02 -29.47 150.13 -27.58 Q 148.24 -25.69 148.24 -20.73 L 148.24 -20.73 L 148.24 -6.03 Q 148.24 -3.33 146.3 -1.39 Q 144.36 0.55 141.65 0.55 L 141.65 0.55 Q 138.95 0.55 136.99 -1.39 Q 135.03 -3.33 135.03 -6.03 Z M 177.71 -47.56 L 177.71 -47.56 Q 177.71 -50.34 179.63 -52.26 Q 181.56 -54.19 184.23 -54.19 L 184.23 -54.19 Q 186.58 -54.19 188.39 -52.73 Q 190.19 -51.27 190.71 -48.99 L 190.71 -48.99 L 197.88 -15.12 L 206.52 -48.64 Q 207.07 -51.07 209.12 -52.63 Q 211.16 -54.19 213.69 -54.19 L 213.69 -54.19 Q 216.26 -54.19 218.25 -52.57 Q 220.25 -50.96 220.8 -48.64 L 220.8 -48.64 L 229.4 -15.39 L 236.64 -49.33 Q 237.06 -51.38 238.76 -52.78 Q 240.46 -54.19 242.61 -54.19 L 242.61 -54.19 Q 245.17 -54.19 246.94 -52.4 Q 248.71 -50.62 248.71 -48.05 L 248.71 -48.05 Q 248.71 -47.56 248.57 -46.73 L 248.57 -46.73 L 239.69 -7.38 Q 238.9 -3.99 236.11 -1.72 Q 233.32 0.55 229.68 0.55 L 229.68 0.55 Q 226.14 0.55 223.37 -1.61 Q 220.59 -3.78 219.73 -7.11 L 219.73 -7.11 L 213.07 -33.45 L 206.38 -7.11 Q 205.51 -3.71 202.79 -1.58 Q 200.07 0.55 196.53 0.55 L 196.53 0.55 Q 192.89 0.55 190.17 -1.72 Q 187.45 -3.99 186.65 -7.38 L 186.65 -7.38 L 177.85 -46.14 Q 177.71 -47.15 177.71 -47.56 Z M 253.35 -6.03 L 253.35 -6.03 L 253.35 -33.14 Q 253.35 -35.64 255.17 -37.46 Q 256.99 -39.28 259.46 -39.28 L 259.46 -39.28 Q 262.02 -39.28 263.84 -37.46 Q 265.66 -35.64 265.66 -33.14 L 265.66 -33.14 L 265.66 -31.44 L 265.94 -31.44 Q 266.8 -33.56 268.1 -35.24 Q 269.4 -36.92 270.69 -37.61 L 270.69 -37.61 Q 271.9 -38.24 273.46 -38.27 L 273.46 -38.27 Q 276.65 -38.27 278.14 -36.45 Q 279.63 -34.63 279.63 -32.52 L 279.63 -32.52 Q 279.63 -30.33 278.11 -28.62 Q 276.58 -26.9 274.08 -26.9 L 274.08 -26.9 Q 272.59 -26.9 271.07 -26.26 Q 269.54 -25.62 268.47 -24.34 L 268.47 -24.34 Q 266.56 -21.98 266.56 -17.68 L 266.56 -17.68 L 266.56 -6.03 Q 266.56 -3.33 264.62 -1.39 Q 262.68 0.55 259.98 0.55 L 259.98 0.55 Q 257.27 0.55 255.31 -1.39 Q 253.35 -3.33 253.35 -6.03 Z M 282.41 -49.71 L 282.41 -49.71 Q 282.41 -52 284.03 -53.61 Q 285.66 -55.23 287.95 -55.23 L 287.95 -55.23 L 291.21 -55.23 Q 293.5 -55.23 295.13 -53.6 Q 296.76 -51.97 296.76 -49.71 L 296.76 -49.71 Q 296.76 -47.43 295.11 -45.8 Q 293.46 -44.17 291.21 -44.17 L 291.21 -44.17 L 287.95 -44.17 Q 285.66 -44.17 284.03 -45.8 Q 282.41 -47.43 282.41 -49.71 Z M 282.96 -6.03 L 282.96 -6.03 L 282.96 -32.66 Q 282.96 -35.36 284.92 -37.32 Q 286.88 -39.28 289.58 -39.28 L 289.58 -39.28 Q 292.29 -39.28 294.23 -37.32 Q 296.17 -35.36 296.17 -32.66 L 296.17 -32.66 L 296.17 -6.03 Q 296.17 -3.33 294.21 -1.39 Q 292.25 0.55 289.58 0.55 L 289.58 0.55 Q 286.88 0.55 284.92 -1.39 Q 282.96 -3.33 282.96 -6.03 Z M 299.43 -34.29 L 299.43 -34.29 Q 299.43 -36.12 300.71 -37.41 Q 301.99 -38.69 303.76 -38.69 L 303.76 -38.69 L 306.19 -38.69 L 306.46 -43.96 Q 306.6 -46.32 308.34 -47.98 Q 310.07 -49.64 312.5 -49.64 L 312.5 -49.64 Q 314.99 -49.64 316.76 -47.86 Q 318.53 -46.07 318.53 -43.58 L 318.53 -43.58 L 318.53 -38.69 L 322.72 -38.69 Q 324.49 -38.69 325.77 -37.41 Q 327.06 -36.12 327.06 -34.36 L 327.06 -34.36 Q 327.06 -32.52 325.77 -31.24 Q 324.49 -29.95 322.72 -29.95 L 322.72 -29.95 L 318.81 -29.95 L 318.81 -14.14 Q 318.81 -11.23 320.05 -10.02 Q 321.3 -8.81 323.83 -8.81 L 323.83 -8.81 Q 325.46 -8.46 326.61 -7.14 Q 327.75 -5.82 327.75 -4.06 L 327.75 -4.06 Q 327.75 -2.57 326.94 -1.39 Q 326.12 -0.21 324.84 0.35 L 324.84 0.35 Q 322 0.83 318.11 0.87 L 318.11 0.87 Q 311.28 0.9 308.44 -2.5 L 308.44 -2.5 Q 305.67 -5.79 305.67 -12.65 L 305.67 -12.65 Q 305.67 -12.83 305.67 -13 L 305.67 -13 L 305.74 -29.95 L 303.76 -29.95 Q 301.99 -29.95 300.71 -31.24 Q 299.43 -32.52 299.43 -34.29 Z M 329.8 -19.24 L 329.8 -19.24 Q 329.8 -25.13 332.24 -29.78 Q 334.68 -34.43 339.23 -37.06 Q 343.77 -39.69 349.8 -39.69 L 349.8 -39.69 Q 355.9 -39.69 360.3 -37.09 Q 364.71 -34.49 366.96 -30.32 Q 369.21 -26.14 369.21 -21.6 L 369.21 -21.6 Q 369.21 -18.69 367.86 -17.26 Q 366.51 -15.84 363.39 -15.84 L 363.39 -15.84 L 342.42 -15.84 Q 342.76 -12.38 344.91 -10.31 Q 347.06 -8.25 350.39 -8.25 L 350.39 -8.25 Q 352.37 -8.25 353.72 -8.91 Q 355.07 -9.57 356.14 -10.64 L 356.14 -10.64 Q 357.15 -11.58 357.95 -12.03 Q 358.74 -12.48 359.96 -12.48 L 359.96 -12.48 Q 362.14 -12.48 363.72 -10.89 Q 365.3 -9.29 365.3 -7.04 L 365.3 -7.04 Q 365.3 -4.54 363.15 -2.77 L 363.15 -2.77 Q 361.24 -1.14 357.69 -0.03 Q 354.13 1.07 350.11 1.07 L 350.11 1.07 Q 344.29 1.07 339.66 -1.42 Q 335.03 -3.92 332.41 -8.53 Q 329.8 -13.14 329.8 -19.24 Z M 342.48 -23.57 L 342.48 -23.57 L 356.49 -23.57 Q 356.35 -26.97 354.46 -28.97 Q 352.57 -30.96 349.59 -30.96 L 349.59 -30.96 Q 346.61 -30.96 344.74 -28.97 Q 342.87 -26.97 342.48 -23.57 Z" stroke-linecap="round" /> | |
| 44 | </g> | |
| 45 | </svg> |
| 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
| 2 | <svg | |
| 3 | xmlns:dc="http://purl.org/dc/elements/1.1/" | |
| 4 | xmlns:cc="http://creativecommons.org/ns#" | |
| 5 | xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |
| 6 | xmlns:svg="http://www.w3.org/2000/svg" | |
| 7 | xmlns="http://www.w3.org/2000/svg" | |
| 8 | xmlns:xlink="http://www.w3.org/1999/xlink" | |
| 9 | xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |
| 10 | xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |
| 11 | height="197.4767" | |
| 12 | viewBox="0 0 695.99768 197.4767" | |
| 13 | width="695.99768" | |
| 14 | version="1.1" | |
| 15 | id="svg37" | |
| 16 | sodipodi:docname="new-logo-text.svg" | |
| 17 | inkscape:version="1.0.1 (3bc2e813f5, 2020-09-07)"> | |
| 18 | <metadata | |
| 19 | id="metadata43"> | |
| 20 | <rdf:RDF> | |
| 21 | <cc:Work | |
| 22 | rdf:about=""> | |
| 23 | <dc:format>image/svg+xml</dc:format> | |
| 24 | <dc:type | |
| 25 | rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |
| 26 | <dc:title></dc:title> | |
| 27 | </cc:Work> | |
| 28 | </rdf:RDF> | |
| 29 | </metadata> | |
| 30 | <defs | |
| 31 | id="defs41"> | |
| 32 | <linearGradient | |
| 33 | id="a" | |
| 34 | gradientTransform="matrix(-8.7796153,42.985832,-42.985832,-8.7796153,514.83476,136.06192)" | |
| 35 | gradientUnits="userSpaceOnUse" | |
| 36 | x1=".152358" | |
| 37 | x2=".968809" | |
| 38 | y1="-.044912" | |
| 39 | y2="-.049471"> | |
| 40 | <stop | |
| 41 | offset="0" | |
| 42 | stop-color="#ec706a" | |
| 43 | id="stop2" /> | |
| 44 | <stop | |
| 45 | offset="1" | |
| 46 | stop-color="#ecd980" | |
| 47 | id="stop4" /> | |
| 48 | </linearGradient> | |
| 49 | </defs> | |
| 50 | <path | |
| 51 | style="fill:url(#a);fill-opacity:1.0;fill-rule:nonzero;stroke:none;stroke-width:1.226;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0" | |
| 52 | paint-order="stroke" | |
| 53 | d="m 496.76229,150.80474 c -4.25368,20.68081 3.28191,25.95476 3.28191,25.95476 v 0 c 0,0 3.00963,-13.19543 8.64082,-10.76172 v 0 c 4.83401,2.08299 1.12516,10.97002 1.12516,10.97002 v 0 c 0,0 31.78993,-30.5076 7.60484,-40.99434 v 0 c 0,0 -5.30287,-2.76791 -10.69842,-0.65209 v 0 c -3.94735,1.54891 -7.94375,5.71058 -9.95431,15.48337" | |
| 54 | stroke-linecap="round" | |
| 55 | id="path14" /> | |
| 56 | <path | |
| 57 | d="m 530.80335,138.63592 -10.99206,-16.95952 1.75995,-6.49966 10.01483,2.71233 z" | |
| 58 | fill="#126d95" | |
| 59 | id="path9" /> | |
| 60 | <path | |
| 61 | d="m 533.0598,112.36676 -0.91739,3.38458 -9.99361,-2.70665 0.91739,-3.38458 z" | |
| 62 | fill="#126d95" | |
| 63 | id="path11" /> | |
| 64 | <g | |
| 65 | fill="#51a9cf" | |
| 66 | id="g19" | |
| 67 | transform="translate(-295.50101,-692.52836)"> | |
| 68 | <path | |
| 69 | d="m 834.01973,741.0381 c -1.68105,0.0185 -3.22054,1.13771 -3.68367,2.84981 -0.56186,2.07405 0.665,4.21099 2.73743,4.77241 l -13.96475,51.52944 -9.99361,-2.70665 c 8.36013,-31.46487 4.99411,-51.98144 4.99411,-51.98144 14.99782,-11.92097 23.67,-25.56577 27.63101,-32.97331 z" | |
| 70 | id="path13" /> | |
| 71 | <path | |
| 72 | d="m 818.56767,802.18881 -0.9174,3.38458 -10.03996,-2.72957 0.91314,-3.37522 z" | |
| 73 | id="path15" /> | |
| 74 | <path | |
| 75 | d="m 817.07405,807.70594 -1.75995,6.49966 -18.03534,9.08805 9.78412,-18.31044 z" | |
| 76 | id="path17" /> | |
| 77 | </g> | |
| 78 | <path | |
| 79 | d="m 540.69709,49.12083 7.72577,-28.52932 c -0.3195,8.40427 0.28451,24.55036 7.21678,42.41047 0,0 -11.89603,16.50235 -21.99788,47.3763 l -10.03442,-2.71758 13.96533,-51.5284 c 2.08221,0.56405 4.21039,-0.66603 4.77182,-2.73844 0.45427,-1.67248 -0.26571,-3.38317 -1.64739,-4.27302" | |
| 80 | fill="#126d95" | |
| 81 | id="path21" /> | |
| 82 | <text | |
| 83 | transform="translate(-295.73751 -689.6407)" | |
| 84 | id="text25" /> | |
| 85 | <g | |
| 86 | style="font-style:italic;font-weight:800;font-size:133.333;font-family:Merriweather Sans;letter-spacing:0;word-spacing:0;fill:#51a9cf" | |
| 87 | id="g35"> | |
| 88 | <text | |
| 89 | x="16.133343" | |
| 90 | y="130.6234" | |
| 91 | id="text29"><tspan | |
| 92 | x="16.133343" | |
| 93 | y="130.6234" | |
| 94 | id="tspan27">KeenWr</tspan></text> | |
| 95 | <text | |
| 96 | x="552.53137" | |
| 97 | y="130.6234" | |
| 98 | id="text33"><tspan | |
| 99 | x="552.53137" | |
| 100 | y="130.6234" | |
| 101 | id="tspan31">te</tspan></text> | |
| 102 | </g> | |
| 103 | </svg> | |
| 1 | 104 |
| 1 | ||
| 1 | <svg height="197.4767" viewBox="0 0 493.25561 197.4767" width="493.25562" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientTransform="matrix(-8.7796153 42.985832 -42.985832 -8.7796153 810.33577 8312.52749 -472.07353)"/><text fill="#51a9cf" font-family="'Noto Serif CJK SC'" font-size="35.1025" letter-spacing="0" transform="matrix(3.7983969 0 0 3.7983969 -330.7653 961.00598)" word-spacing="0"><tspan x="91.011719" y="-209.05206"><tspan x="91.011719" y="-209.05206">智能写<tspan fill="#51a9cf"/></tspan></tspan><tspan x="91.011719" y="-165.17393"/></text><g transform="tran377.88503/svg> |
| 1 | 1 | |
| 2 | Blues | |
| 3 | Light - 51a9cf | |
| 4 | Dark - 126d95 | |
| 5 | ||
| 6 | Red & Yellow | |
| 7 | Light yellow - ecd980 | |
| 8 | Light red - ec706a | |
| 9 | Dark red - 7e252f | |
| 10 | ||
| 11 | Greens | |
| 12 | Light - 76A786 | |
| 13 | Dark - 385742 | |
| 14 | ||
| 15 | Grayscale | |
| 16 | Light - bac2c5 | |
| 17 | Dark - 394343 | |
| 18 | ||
| 19 |
| 1 | # Introduction | |
| 2 | ||
| 3 | This document describes how to use the [R](https://www.r-project.org/) | |
| 4 | programming language from within the application. The application uses an | |
| 5 | interpreter known as [Renjin](https://www.renjin.org/) to integrate with R. | |
| 6 | ||
| 7 | # Hello world | |
| 8 | ||
| 9 | Complete the following steps to see R in action: | |
| 10 | ||
| 11 | 1. Start the application. | |
| 12 | 1. Click **File → New** to create a new file. | |
| 13 | 1. Click **File → Save As**. | |
| 14 | 1. Set **Name** to: `addition.Rmd` | |
| 15 | 1. Click **Save**. | |
| 16 | ||
| 17 | Setting the file name extension tells the application what processor to | |
| 18 | use when transforming the contents for display in the preview pane. Continue | |
| 19 | by typing in the following text, including the backticks: | |
| 20 | ||
| 21 | ```r | |
| 22 | `r#1 + 1` | |
| 23 | ``` | |
| 24 | ||
| 25 | The preview pane shows the result of `1` plus `1`: | |
| 26 | ||
| 27 | ``` | |
| 28 | 2.0 | |
| 29 | ``` | |
| 30 | ||
| 31 | # Bootstrap script | |
| 32 | ||
| 33 | Being able to run R code while editing an R Markdown document is convenient. | |
| 34 | Having the ability to call functions is where the power of R can be | |
| 35 | leveraged. | |
| 36 | ||
| 37 | Complete the following steps to call an R function from your own library: | |
| 38 | ||
| 39 | 1. Click **File → New** to create a new file. | |
| 40 | 1. Click **File → Save As**. | |
| 41 | 1. Browse to your home directory. | |
| 42 | 1. Set **Name** to: `library.R`. | |
| 43 | 1. Click **Save**. | |
| 44 | 1. Set the contents to: | |
| 45 | ``` r | |
| 46 | sum <- function( a, b ) { | |
| 47 | a + b | |
| 48 | } | |
| 49 | ``` | |
| 50 | 1. Click the **Save** icon. | |
| 51 | 1. Click **R → Script**. | |
| 52 | 1. Set the **R Startup Script** contents to: | |
| 53 | ``` r | |
| 54 | source( 'library.R' ); | |
| 55 | ``` | |
| 56 | 1. Click **OK**. | |
| 57 | 1. Create a new file. | |
| 58 | 1. Set the contents to: | |
| 59 | ``` r | |
| 60 | `r#sum( 5, 5 )` | |
| 61 | ``` | |
| 62 | 1. Save the file as `sum.R`. | |
| 63 | ||
| 64 | The preview panel shows the result of calling the `sum` function: | |
| 65 | ||
| 66 | ``` | |
| 67 | 10.0 | |
| 68 | ``` | |
| 69 | ||
| 70 | This shows how the bootstrap script can load `library.R`, which defines | |
| 71 | a `sum` function that is called by name in the Markdown document. | |
| 72 | ||
| 73 | # Working directory | |
| 74 | ||
| 75 | R files may be sourced from any directory, not just the user's home | |
| 76 | directory. Accomplish this as follows: | |
| 77 | ||
| 78 | 1. Click **R → Directory**. | |
| 79 | 1. Set **Directory** to a different directory. | |
| 80 | 1. Click **OK**. | |
| 81 | 1. Create the directory if it does not exist. | |
| 82 | 1. Move `library.R` into the directory. | |
| 83 | 1. Append a new function to `library.R` as follows: | |
| 84 | ``` r | |
| 85 | mul <- function( a, b ) { | |
| 86 | a * b | |
| 87 | } | |
| 88 | ``` | |
| 89 | 1. Click **R → Script**. | |
| 90 | 1. Set the **R Startup Script** contents to: | |
| 91 | ``` r | |
| 92 | setwd( '{{application.r.working.directory}}' ); | |
| 93 | source( 'library.R' ); | |
| 94 | ``` | |
| 95 | 1. Change `sum.Rmd` to: | |
| 96 | ``` r | |
| 97 | `r#mul( 5, 5 )` | |
| 98 | ``` | |
| 99 | 1. Close the file `sum.Rmd`. | |
| 100 | 1. Confirm saving the file when prompted. | |
| 101 | 1. Re-open `sum.Rmd`. | |
| 102 | ||
| 103 | The preview panel shows: | |
| 104 | ||
| 105 | ``` | |
| 106 | 25.0 | |
| 107 | ``` | |
| 108 | ||
| 109 | Calling `setwd` using `'{{application.r.working.directory}}'` changes the | |
| 110 | working directory where the R engine searches for source files. | |
| 111 | ||
| 112 | # YAML variable definitions | |
| 113 | ||
| 114 | To see how variable definitions work in R, try the following: | |
| 115 | ||
| 116 | 1. Create a new file. | |
| 117 | 1. Change the contents to (use spaces not tabs): | |
| 118 | ``` yaml | |
| 119 | project: | |
| 120 | title: Project Title | |
| 121 | author: Author Name | |
| 122 | ``` | |
| 123 | 1. Save the file as `definitions.yaml`. | |
| 124 | 1. Click **File → Open**. | |
| 125 | 1. Set **Source Files** to **Variable Files**. | |
| 126 | 1. Select `definitions.yaml`. | |
| 127 | 1. Click **Open**. | |
| 128 | 1. Open `sum.Rmd` if it is not already open. | |
| 129 | 1. Type: `je` | |
| 130 | 1. Press `Ctrl+Space` | |
| 131 | ||
| 132 | The editor inserts the following text (matches `je` against Pro**je**ct): | |
| 133 | ||
| 134 | ``` r | |
| 135 | `r#x( v$project$title )` | |
| 136 | ``` | |
| 137 | ||
| 138 | The preview panel shows: | |
| 139 | ||
| 140 | ``` | |
| 141 | r#x( 'Project Title' ) | |
| 142 | ``` | |
| 143 | ||
| 144 | This is because the application inserts variable reference names based | |
| 145 | on the type of file being edited. By default, the R engine does not have | |
| 146 | a function named `x` defined. | |
| 147 | ||
| 148 | Continue as follows: | |
| 149 | ||
| 150 | 1. Click **R → Script**. | |
| 151 | 1. Append the following: | |
| 152 | ``` r | |
| 153 | x <- function( s ) { | |
| 154 | tryCatch( { | |
| 155 | r = eval( parse( text = s ) ) | |
| 156 | ||
| 157 | ifelse( is.atomic( r ), r, s ); | |
| 158 | }, | |
| 159 | warning = function( w ) { s }, | |
| 160 | error = function( e ) { s } ) | |
| 161 | } | |
| 162 | ``` | |
| 163 | 1. Click **OK**. | |
| 164 | 1. Close and re-open `sum.Rmd`. | |
| 165 | ||
| 166 | The preview panel shows: | |
| 167 | ||
| 168 | ``` | |
| 169 | 25.0 | |
| 170 | ||
| 171 | Project Title | |
| 172 | ``` | |
| 173 | ||
| 174 | The `x` function attempts to evaluate the expression defined by the YAML | |
| 175 | variable. This means that the YAML variables can also include expressions | |
| 176 | that R is capable of evaluating. | |
| 177 | ||
| 178 | While the `x` function can be defined within the R Startup Script, it is | |
| 179 | better practice to put it into its own library so that it can be reused | |
| 180 | outside of the application. | |
| 181 | ||
| 1 | 182 |
| 1 | *Song of the Yellow Bird*: | |
| 2 | ||
| 3 | 翩翩黃鳥, | |
| 4 | 雌雄相依。 | |
| 5 | 念我之獨, | |
| 6 | 誰其與歸? | |
| 7 | ||
| 8 | English translation: | |
| 9 | ||
| 10 | Orioles fly smoothly | |
| 11 | Female and male cuddle close together | |
| 12 | Thinking of my loneliness | |
| 13 | Whom shall I go with? | |
| 14 | ||
| 15 | Fonts: | |
| 16 | ||
| 17 | * Regular: 활판 인쇄술 | |
| 18 | * Bold: **활판 인쇄술** | |
| 19 | * Monospace: `활판 인쇄술` | |
| 20 | * Monospace bold: **`활판 인쇄술`** | |
| 21 | * Math: $E=mc^2$ | |
| 22 | ||
| 1 | 23 |
| 1 | --- | |
| 2 | formula: | |
| 3 | sqrt: | |
| 4 | value: "420" | |
| 5 | quadratic: | |
| 6 | a: "25" | |
| 7 | b: "84.906" | |
| 8 | c: "20" | |
| 1 | 9 |
| 1 |  | |
| 2 | ||
| 3 | Given the quadratic formula: | |
| 4 | ||
| 5 | $x = \frac{-b \pm \sqrt{b^2 -4ac}}{2a}$ | |
| 6 | ||
| 7 | Formatted in an R Markdown document as follows: | |
| 8 | ||
| 9 | $x = \frac{-b \pm \sqrt{b^2 -4ac}}{2a}$ | |
| 10 | ||
| 11 | We can substitute the following values: | |
| 12 | ||
| 13 | $a = `r# x(v$formula$quadratic$a)`, b = `r# x(v$formula$quadratic$b)`, c = `r# x(v$formula$quadratic$c)`$ | |
| 14 | ||
| 15 | `r# -x(v$formula$quadratic$b) + sqrt( v$formula$quadratic$b^2 - 4 * v$formula$quadratic$a * v$formula$quadratic$c )` | |
| 16 | ||
| 17 | To arrive at two solutions: | |
| 18 | ||
| 19 | $x = \frac{-b + \sqrt{b^2 -4ac}}{2a} = `r# (-x(v$formula$quadratic$b) + sqrt( x(v$formula$quadratic$b)^2 - 4 * x(v$formula$quadratic$a) * x(v$formula$quadratic$c) )) / (2 * x(v$formula$quadratic$a))`$ | |
| 20 | ||
| 21 | $x = \frac{-b - \sqrt{b^2 -4ac}}{2a} = `r# (-x(v$formula$quadratic$b) - sqrt( x(v$formula$quadratic$b)^2 - 4 * x(v$formula$quadratic$a) * x(v$formula$quadratic$c) )) / (2 * x(v$formula$quadratic$a))`$ | |
| 22 | ||
| 23 | Changing the variable values is reflected in the output immediately. | |
| 1 | 24 |
| 1 | #  | |
| 2 | ||
| 3 | # Real-time equation rendering | |
| 4 | ||
| 5 | Interpolated variables within R calculations, formatted as an equation: | |
| 6 | ||
| 7 | $\sqrt{`r#x( v$formula$sqrt$value)`} = \pm `r# round(sqrt(x( v$formula$sqrt$value )),5)`$ | |
| 8 | ||
| 9 | # Maxwell's equations | |
| 10 | ||
| 11 | $rot \vec{E} = \frac{1}{c} \frac{\partial{\vec{B}}}{\partial t}, div \vec{B} = 0$ | |
| 12 | ||
| 13 | $rot \vec{B} = \frac{1}{c} \frac{\partial{\vec{E}}}{\partial t} + \frac{4\pi}{c} \vec{j}, div \vec{E} = 4 \pi \rho_{\varepsilon}$ | |
| 14 | ||
| 15 | # Time-dependent Schrödinger equation | |
| 16 | ||
| 17 | $- \frac{{\hbar ^2 }}{{2m}}\frac{{\partial ^2 \psi (x,t)}}{{\partial x^2 }} + U(x)\psi (x,t) = i\hbar \frac{{\partial \psi (x,t)}}{{\partial t}}$ | |
| 18 | ||
| 19 | # Discrete-time Fourier transforms | |
| 20 | ||
| 21 | Unit step function: $u(n) \Leftrightarrow \frac{1}{1-e^{-jw}} + \sum_{k=-\infty}^{\infty} \pi \delta (\omega + 2\pi k)$ | |
| 22 | ||
| 23 | Shifted delta: $\delta (n - n_o ) \Leftrightarrow e^{ - j\omega n_o }$ | |
| 24 | ||
| 25 | # Faraday's Law | |
| 26 | ||
| 27 | $\oint_C {E \cdot d\ell = - \frac{d}{{dt}}} \int_S {B_n dA}$ | |
| 28 | ||
| 29 | # Infinite series | |
| 30 | ||
| 31 | $sin(x) = \sum_{n = 1}^{\infty} {\frac{{( { - 1})^{n - 1} x^{2n - 1} }}{{( {2n - 1})!}}}$ | |
| 32 | ||
| 33 | # Magnetic flux | |
| 34 | ||
| 35 | $\phi _m = \int_S {N{{B}} \cdot {{\hat n}}dA = } \int_S {NB_n dA}$ | |
| 36 | ||
| 37 | # Driven oscillation amplitude | |
| 38 | ||
| 39 | $A = \frac{{F_0 }}{{\sqrt {m^2 ( {\omega _0^2 - \omega ^2 } )^2 + b^2 \omega ^2 } }}$ | |
| 40 | ||
| 41 | # Optics | |
| 42 | ||
| 43 | $\phi = \frac{{2\pi }}{\lambda }a sin(\theta)$ | |
| 1 | 44 |
| 1 | # Introduction | |
| 2 | ||
| 3 | The Scalable Vector Graphics (SVG) drawing software---[Batik](https://xmlgraphics.apache.org/batik/)---that's used by the application may be unable to read certain SVG files produced by [Inkscape](https://inkscape.org/). The result is that embedding the vector graphics files may trigger the following issues: | |
| 4 | ||
| 5 | * Unable to create nested element | |
| 6 | * Black blocks, no text displayed | |
| 7 | * Black text instead of coloured | |
| 8 | ||
| 9 | The remainder of this document explains these problems and how to fix them. | |
| 10 | ||
| 11 | # Nested element | |
| 12 | ||
| 13 | When referencing a vector graphic using Markdown, the status bar may show the following error: | |
| 14 | ||
| 15 | > The current document is unable to create an element of the requested type (namespace: http://www.w3.org/2000/svg, name: flowRoot). | |
| 16 | ||
| 17 | This error is due to a version mismatch of the `flowRoot` element that Inkscape creates. | |
| 18 | ||
| 19 | ## Fix | |
| 20 | ||
| 21 | Resolve the issue by changing the SVG version number as follows: | |
| 22 | ||
| 23 | 1. Edit the vector graphics file using any text editor. | |
| 24 | 1. Find `version="1.1"` and change it to `version="1.2"`. | |
| 25 | 1. Save the file. | |
| 26 | ||
| 27 | The SVG will now appear inside the application; however, the text may appear as black blocks. | |
| 28 | ||
| 29 | # Black blocks | |
| 30 | ||
| 31 | Depending on how text is added to a vector graphic in Inkscape, the text may be inserted within an element called a `flowRoot`. Although Batik recognizes `flowRoot` for SVG version 1.2, it cannot fully interpret the contents. Black blocks are drawn instead of the text, such as those depicted in the following figure: | |
| 32 | ||
| 33 |  | |
| 34 | ||
| 35 | ## Fix | |
| 36 | ||
| 37 | Resolve the issue by "unflowing" all text elements as follows: | |
| 38 | ||
| 39 | 1. Start Inkscape. | |
| 40 | 1. Load the SVG file. | |
| 41 | 1. Select all the text elements. | |
| 42 | 1. Click **Text → Unflow**. | |
| 43 | ||
| 44 | The text may change size and position; recreate the text without dragging using the text tool. After all the text areas have been recreated, continue as follows: | |
| 45 | ||
| 46 | 1. Click **Edit → XML Editor**. | |
| 47 | 1. Expand the **XML Editor** to see more elements. | |
| 48 | 1. Delete all elements named `svg:flowRoot`. | |
| 49 | 1. Save the file. | |
| 50 | ||
| 51 | When the illustration is reloaded, the black blocks will have disappeared, but the text elements ignore any assigned colour. | |
| 52 | ||
| 53 | # Black text | |
| 54 | ||
| 55 | When an SVG `style` attribute contains a reference to `-inkscape-font-specification`, Batik ignores all values that follow said reference. This results in black text, such as: | |
| 56 | ||
| 57 |  | |
| 58 | ||
| 59 | ## Fix | |
| 60 | ||
| 61 | Resolve the issue of colourless text as follows: | |
| 62 | ||
| 63 | 1. Open the SVG file in a plain text editor. | |
| 64 | 1. Remove all references `-inkscape-font-specification:'<FONT>';`, including the trailing (or leading) semicolon. | |
| 65 | 1. Save the file. | |
| 66 | ||
| 67 | When the illustration is reloaded, the colours will have reappeared, such as: | |
| 68 | ||
| 69 |  | |
| 70 | ||
| 1 | 71 |
| 1 | # Themes | |
| 2 | ||
| 3 | The application provides bundled themes and the ability to add custom | |
| 4 | themes. This document describes the interplay between bundled themes | |
| 5 | and building your own theme. | |
| 1 | 6 | |
| 7 | A theme is a set of styles, similar to cascading style sheet classes, | |
| 8 | thainstruct the user interface on how to apply | |
| 9 | highlights, drop-shadows, gradients, and so forththemes/themethemethemethemeThemes** to view the themthemethemethemethemesthemethemthemeSend in your themes! If you have a theme | |
| 10 | project, or improvements to an existing theme, do pass |
| 1 | # Introduction | |
| 2 | ||
| 3 | This document describes how to use the application. | |
| 4 | ||
| 5 | # Variable definitions | |
| 1 | 6 | |
| 7 | Variable definitions provide a way to insert key names having associated values into a document. The variable names and values are declared inside an external filbookending the key name within{{key}} 1 | |
| 8 | key_2: {{key}}{{novel.author}}Variable Files** to listVariable{{novel.author}}uble brace{{novel.title}}{{novel.title}} |
| 1 | #!/usr/bin/env bash | |
| 2 | ||
| 3 | # Outputs font names for all font files. | |
| 4 | ||
| 5 | find src/main/resources/fonts -type f \( -name "*otf" -o -name "*ttf" \) -exec \ | |
| 6 | fc-scan --format "%{foundry}: %{family}\n" {} \; | uniq | sort | |
| 7 | ||
| 1 | 8 |
| 1 | # Fonts | |
| 2 | ||
| 3 | For best results, it is recommended that the Noto Font family is installed | |
| 4 | on the system. The required font families include: | |
| 1 | 5 | |
| 6 | * Sans-serif --- editor pane | |
| 7 | * Serif --- preview pane | |
| 8 | * Serif monospace --- prevnt familie |
| 1 | org.gradle.jvmargs=-Xmx1G -XX:MaxPermSize=512m | |
| 2 | org.gradle.daemon=true | |
| 3 | org.gradle.parallel=true | |
| 4 | ||
| 1 | 5 |
| 1 | <svg height='19pt' viewBox='0 0 25 19' width='25pt' xmlns='http://www.w3.org/2000/svg'><g fill='#454545'><path d='m8.042969 11.085938c.332031 1.445312 1.660156 2.503906 3.214843 2.558593zm0 0'/><path d='m6.792969 9.621094-.300781.226562.242187.195313c.015625-.144531.03125-.28125.058594-.421875zm0 0'/><path d='m10.597656.949219-2.511718.207031c-.777344.066406-1.429688.582031-1.636719 1.292969l-.367188 1.253906-3.414062.28125c-1.027344.085937-1.792969.949219-1.699219 1.925781l.976562 10.621094c.089844.976562.996094 1.699219 2.023438 1.613281l11.710938-.972656-3.117188-2.484375c-.246094.0625-.5.109375-.765625.132812-2.566406.210938-4.835937-1.597656-5.0625-4.039062-.023437-.25-.019531-.496094 0-.738281l-.242187-.195313.300781-.226562c.359375-1.929688 2.039062-3.472656 4.191406-3.652344.207031-.015625.414063-.015625.617187-.007812l.933594-.707032zm0 0'/><path d='m10.234375 11.070312 2.964844 2.820313c.144531.015625.285156.027344.433593.027344 1.890626 0 3.429688-1.460938 3.429688-3.257813 0-1.792968-1.539062-3.257812-3.429688-3.257812-1.890624 0-3.429687 1.464844-3.429687 3.257812 0 .140625.011719.277344.03125.410156zm0 0'/><path d='m14.488281.808594 1.117188 4.554687-1.042969.546875c2.25.476563 3.84375 2.472656 3.636719 4.714844-.199219 2.191406-2.050781 3.871094-4.285157 4.039062l2.609376 2.957032 4.4375.371094c1.03125.085937 1.9375-.640626 2.027343-1.617188l.976563-10.617188c.089844-.980468-.667969-1.839843-1.699219-1.925781l-3.414063-.285156-.371093-1.253906c-.207031-.710938-.859375-1.226563-1.636719-1.289063zm0 0'/></g></svg> | |
| 1 | 2 |
| 1 | #!/usr/bin/env bash | |
| 1 | 2 | |
| 3 | # --------------------------------------------------------------------------- | |
| 4 | # This script cross-compiles application launchers for different platforms. | |
| 5 | # | |
| 6 | # The application binaries are self-contained launchers that do not need | |
| 7 | # to 2" | |
| 8 | ARG_JAVA_UPDATE="10 |
| 1 | 1 | |
| 2 | Apache License | |
| 3 | Version 2.0, January 2004 | |
| 4 | http://www.apache.org/licenses/ | |
| 5 | ||
| 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | |
| 7 | ||
| 8 | 1. Definitions. | |
| 9 | ||
| 10 | "Licen[][yyyy] [name of copyright owner] |
| 1 | Released into the Public Domain by David Croft. | |
| 2 | ||
| 3 | http://www.davidc.net/programming/java/java-preferences-using-file-backing-store | |
| 4 | http://creativecommons.org/publicdomain/zero/1.0/ | |
| 5 | ||
| 6 | CC0 1.0 Universal (CC0 1.0) | |
| 7 | ||
| 8 | Public Domain Dedication | |
| 9 | ||
| 10 | This is a human-readable summary of the Legal Code (read the full text). | |
| 11 | ||
| 12 | Disclaimer | |
| 13 | ||
| 14 | No Copyright | |
| 15 | ||
| 16 | * The person who associated a work with this deed has dedicated the work to the public domain by waiving all of his or her rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. | |
| 17 | ||
| 18 | * You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission. See Other Information below. | |
| 19 | ||
| 20 | This license is acceptable for Free Cultural Works. | |
| 21 | ||
| 22 | Other Information | |
| 23 | ||
| 24 | * In no way are the patent or trademark rights of any person affected by CC0, nor are the rights that other persons may have in the work or in how the work is used, such as publicity or privacy rights. | |
| 25 | * Unless expressly stated otherwise, the person who associated a work with this deed makes no warranties about the work, and disclaims liability for all uses of the work, to the fullest extent permitted by applicable law. | |
| 26 | * When using or citing the work, you should not imply endorsement by the author or the affirmer. | |
| 27 | ||
| 1 | 28 |
| 1 | Copyright (c) 2015-2016, Atlassian Pty Ltd | |
| 2 | All rights reserved. | |
| 3 | ||
| 4 | Copyright (c) 2016-2018, Vladimir Schneider, | |
| 5 | All rights reserved. | |
| 6 | ||
| 7 | Redistribution and use in source and binary forms, with or without | |
| 8 | modification, are permitted provided that the following conditions are met: | |
| 1 | 9 | |
| 10 | * Redistributions of source code |
| 1 | Copyright (c) 2014, TomasMikula | |
| 2 | All rights reserved. | |
| 3 | ||
| 4 | Redistribution and use in source and binary forms, with or without | |
| 5 | modification, are permitted provided that the following conditions are met: | |
| 1 | 6 | |
| 7 | * Redistributions of source code |
| 1 | 1 | |
| 2 | Apache License | |
| 3 | Version 2.0, January 2004 | |
| 4 | http://www.apache.org/licenses/ | |
| 5 | ||
| 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | |
| 7 | ||
| 8 | 1. Definitions. | |
| 9 | ||
| 10 | "Licen[][yyyy] [name of copyright owner] |
| 1 | MIT License | |
| 2 | ||
| 3 | Copyright (c) 2019 Raul Garcia | |
| 4 | ||
| 5 | Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 6 | of this software and associated documentation files (the "Software"), to deal | |
| 7 | in the Software without restriction, including without limitation the rights | |
| 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 9 | copies of the Software, and to permit persons to whom the Software is | |
| 10 | furnished to do so, subject to the following conditions: | |
| 11 | ||
| 12 | The above copyright notice and this permission notice shall be included in all | |
| 13 | copies or substantial portions of the Software. | |
| 14 | ||
| 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| 21 | SOFTWARE. | |
| 1 | 22 |
| 1 | Version: MPL 1.1/GPL 2.0/LGPL 2.1 | |
| 2 | ||
| 3 | The contents of this file are subject to the Mozilla Public License Version | |
| 4 | 1.1 (the "License"); you may not use this file except in compliance with | |
| 5 | the License. You may obtain a copy of the License at | |
| 6 | http://www.mozilla.org/MPL/ | |
| 7 | ||
| 8 | Software distributed under the License is distributed on an "AS IS" basis, | |
| 9 | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License | |
| 10 | for the specific language governing rights and limitations under the | |
| 11 | License. | |
| 12 | ||
| 13 | The Original Code is Mozilla Universal charset detector code. | |
| 14 | ||
| 15 | The Initial Developer of the Original Code is | |
| 16 | Netscape Communications Corporation. | |
| 17 | Portions created by the Initial Developer are Copyright (C) 2001 | |
| 18 | the Initial Developer. All Rights Reserved. | |
| 19 | ||
| 20 | Contributor(s): | |
| 21 | Shy Shalom <shooshX@gmail.com> | |
| 22 | Kohei TAKETA <k-tak@void.in> (Java port) | |
| 23 | ||
| 24 | Alternatively, the contents of this file may be used under the terms of | |
| 25 | either the GNU General Public License Version 2 or later (the "GPL"), or | |
| 26 | the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), | |
| 27 | in which case the provisions of the GPL or the LGPL are applicable instead | |
| 28 | of those above. If you wish to allow use of your version of this file only | |
| 29 | under the terms of either the GPL or the LGPL, and not to allow others to | |
| 30 | use your version of this file under the terms of the MPL, indicate your | |
| 31 | decision by deleting the provisions above and replace them with the notice | |
| 32 | and other provisions required by the GPL or the LGPL. If you do not delete | |
| 33 | the provisions above, a recipient may use your version of this file under | |
| 34 | the terms of any one of the MPL, the GPL or the LGPL. | |
| 35 | ||
| 1 | 36 |
| 1 | Copyright (c) 2015 Karl Tauber <karl@jformdesigner.com> | |
| 2 | All rights reserved. | |
| 3 | ||
| 4 | Redistribution and use in source and binary forms, with or without | |
| 5 | modification, are permitted provided that the following conditions are met: | |
| 6 | ||
| 7 | * Redistributions of source code | |
| 8 | * in the | |
| 9 | ||
| 1 | 10 |
| 1 | Copyright (c) 2000 Mikael Grev | |
| 2 | All rights reserved. | |
| 3 | ||
| 4 | Redistribution and use in source and binary forms, with or without | |
| 5 | modification, are permitted provided that the following conditions | |
| 6 | are met: | |
| 7 | 1. Redistributions of source code2. in the | |
| 8 | 3. The name of the author may not be used to endorse or promote products | |
| 9 | derived from this software without specific prior written permission. | |
| 10 | ||
| 11 | AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
| 12 | ||
| 13 | ||
| 14 | IN NO EVENT SHALL THE AUTHOR | |
| 15 | INCIDENTAL, | |
| 16 | NOT OF | |
| 17 | ||
| 1 | 18 |
| 1 | Apache License | |
| 2 | Version 2.0, January 2004 | |
| 3 | http://www.apache.org/licenses/ | |
| 4 | ||
| 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | |
| 6 | ||
| 7 | 1. Definitions. | |
| 8 | ||
| 9 | "License" shall mean the terms and conditions for use, reproduction, | |
| 10 | and distribution as defined by Sections 1 through 9 of this document. | |
| 11 | ||
| 12 | "Licensor" shall mean the copyright owner or entity authorized by | |
| 13 | the copyright owner that is granting the License. | |
| 14 | ||
| 15 | "Legal Entity" shall mean the union of the acting entity and all | |
| 16 | other entities that control, are controlled by, or are under common | |
| 17 | control with that entity. For the purposes of this definition, | |
| 18 | "control" means (i) the power, direct or indirect, to cause the | |
| 19 | direction or management of such entity, whether by contract or | |
| 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the | |
| 21 | outstanding shares, or (iii) beneficial ownership of such entity. | |
| 22 | ||
| 23 | "You" (or "Your") shall mean an individual or Legal Entity | |
| 24 | exercising permissions granted by this License. | |
| 25 | ||
| 26 | "Source" form shall mean the preferred form for making modifications, | |
| 27 | including but not limited to software source code, documentation | |
| 28 | source, and configuration files. | |
| 29 | ||
| 30 | "Object" form shall mean any form resulting from mechanical | |
| 31 | transformation or translation of a Source form, including but | |
| 32 | not limited to compiled object code, generated documentation, | |
| 33 | and conversions to other media types. | |
| 34 | ||
| 35 | "Work" shall mean the work of authorship, whether in Source or | |
| 36 | Object form, made available under the License, as indicated by a | |
| 37 | copyright notice that is included in or attached to the work | |
| 38 | (an example is provided in the Appendix below). | |
| 39 | ||
| 40 | "Derivative Works" shall mean any work, whether in Source or Object | |
| 41 | form, that is based on (or derived from) the Work and for which the | |
| 42 | editorial revisions, annotations, elaborations, or other modifications | |
| 43 | represent, as a whole, an original work of authorship. For the purposes | |
| 44 | of this License, Derivative Works shall not include works that remain | |
| 45 | separable from, or merely link (or bind by name) to the interfaces of, | |
| 46 | the Work and Derivative Works thereof. | |
| 47 | ||
| 48 | "Contribution" shall mean any work of authorship, including | |
| 49 | the original version of the Work and any modifications or additions | |
| 50 | to that Work or Derivative Works thereof, that is intentionally | |
| 51 | submitted to Licensor for inclusion in the Work by the copyright owner | |
| 52 | or by an individual or Legal Entity authorized to submit on behalf of | |
| 53 | the copyright owner. For the purposes of this definition, "submitted" | |
| 54 | means any form of electronic, verbal, or written communication sent | |
| 55 | to the Licensor or its representatives, including but not limited to | |
| 56 | communication on electronic mailing lists, source code control systems, | |
| 57 | and issue tracking systems that are managed by, or on behalf of, the | |
| 58 | Licensor for the purpose of discussing and improving the Work, but | |
| 59 | excluding communication that is conspicuously marked or otherwise | |
| 60 | designated in writing by the copyright owner as "Not a Contribution." | |
| 61 | ||
| 62 | "Contributor" shall mean Licensor and any individual or Legal Entity | |
| 63 | on behalf of whom a Contribution has been received by Licensor and | |
| 64 | subsequently incorporated within the Work. | |
| 65 | ||
| 66 | 2. Grant of Copyright License. Subject to the terms and conditions of | |
| 67 | this License, each Contributor hereby grants to You a perpetual, | |
| 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |
| 69 | copyright license to reproduce, prepare Derivative Works of, | |
| 70 | publicly display, publicly perform, sublicense, and distribute the | |
| 71 | Work and such Derivative Works in Source or Object form. | |
| 72 | ||
| 73 | 3. Grant of Patent License. Subject to the terms and conditions of | |
| 74 | this License, each Contributor hereby grants to You a perpetual, | |
| 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |
| 76 | (except as stated in this section) patent license to make, have made, | |
| 77 | use, offer to sell, sell, import, and otherwise transfer the Work, | |
| 78 | where such license applies only to those patent claims licensable | |
| 79 | by such Contributor that are necessarily infringed by their | |
| 80 | Contribution(s) alone or by combination of their Contribution(s) | |
| 81 | with the Work to which such Contribution(s) was submitted. If You | |
| 82 | institute patent litigation against any entity (including a | |
| 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work | |
| 84 | or a Contribution incorporated within the Work constitutes direct | |
| 85 | or contributory patent infringement, then any patent licenses | |
| 86 | granted to You under this License for that Work shall terminate | |
| 87 | as of the date such litigation is filed. | |
| 88 | ||
| 89 | 4. Redistribution. You may reproduce and distribute copies of the | |
| 90 | Work or Derivative Works thereof in any medium, with or without | |
| 91 | modifications, and in Source or Object form, provided that You | |
| 92 | meet the following conditions: | |
| 93 | ||
| 94 | (a) You must give any other recipients of the Work or | |
| 95 | Derivative Works a copy of this License; and | |
| 96 | ||
| 97 | (b) You must cause any modified files to carry prominent notices | |
| 98 | stating that You changed the files; and | |
| 99 | ||
| 100 | (c) You must retain, in the Source form of any Derivative Works | |
| 101 | that You distribute, all copyright, patent, trademark, and | |
| 102 | attribution notices from the Source form of the Work, | |
| 103 | excluding those notices that do not pertain to any part of | |
| 104 | the Derivative Works; and | |
| 105 | ||
| 106 | (d) If the Work includes a "NOTICE" text file as part of its | |
| 107 | distribution, then any Derivative Works that You distribute must | |
| 108 | include a readable copy of the attribution notices contained | |
| 109 | within such NOTICE file, excluding those notices that do not | |
| 110 | pertain to any part of the Derivative Works, in at least one | |
| 111 | of the following places: within a NOTICE text file distributed | |
| 112 | as part of the Derivative Works; within the Source form or | |
| 113 | documentation, if provided along with the Derivative Works; or, | |
| 114 | within a display generated by the Derivative Works, if and | |
| 115 | wherever such third-party notices normally appear. The contents | |
| 116 | of the NOTICE file are for informational purposes only and | |
| 117 | do not modify the License. You may add Your own attribution | |
| 118 | notices within Derivative Works that You distribute, alongside | |
| 119 | or as an addendum to the NOTICE text from the Work, provided | |
| 120 | that such additional attribution notices cannot be construed | |
| 121 | as modifying the License. | |
| 122 | ||
| 123 | You may add Your own copyright statement to Your modifications and | |
| 124 | may provide additional or different license terms and conditions | |
| 125 | for use, reproduction, or distribution of Your modifications, or | |
| 126 | for any such Derivative Works as a whole, provided Your use, | |
| 127 | reproduction, and distribution of the Work otherwise complies with | |
| 128 | the conditions stated in this License. | |
| 129 | ||
| 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, | |
| 131 | any Contribution intentionally submitted for inclusion in the Work | |
| 132 | by You to the Licensor shall be under the terms and conditions of | |
| 133 | this License, without any additional terms or conditions. | |
| 134 | Notwithstanding the above, nothing herein shall supersede or modify | |
| 135 | the terms of any separate license agreement you may have executed | |
| 136 | with Licensor regarding such Contributions. | |
| 137 | ||
| 138 | 6. Trademarks. This License does not grant permission to use the trade | |
| 139 | names, trademarks, service marks, or product names of the Licensor, | |
| 140 | except as required for reasonable and customary use in describing the | |
| 141 | origin of the Work and reproducing the content of the NOTICE file. | |
| 142 | ||
| 143 | 7. Disclaimer of Warranty. Unless required by applicable law or | |
| 144 | agreed to in writing, Licensor provides the Work (and each | |
| 145 | Contributor provides its Contributions) on an "AS IS" BASIS, | |
| 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
| 147 | implied, including, without limitation, any warranties or conditions | |
| 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | |
| 149 | PARTICULAR PURPOSE. You are solely responsible for determining the | |
| 150 | appropriateness of using or redistributing the Work and assume any | |
| 151 | risks associated with Your exercise of permissions under this License. | |
| 152 | ||
| 153 | 8. Limitation of Liability. In no event and under no legal theory, | |
| 154 | whether in tort (including negligence), contract, or otherwise, | |
| 155 | unless required by applicable law (such as deliberate and grossly | |
| 156 | negligent acts) or agreed to in writing, shall any Contributor be | |
| 157 | liable to You for damages, including any direct, indirect, special, | |
| 158 | incidental, or consequential damages of any character arising as a | |
| 159 | result of this License or out of the use or inability to use the | |
| 160 | Work (including but not limited to damages for loss of goodwill, | |
| 161 | work stoppage, computer failure or malfunction, or any and all | |
| 162 | other commercial damages or losses), even if such Contributor | |
| 163 | has been advised of the possibility of such damages. | |
| 164 | ||
| 165 | 9. Accepting Warranty or Additional Liability. While redistributing | |
| 166 | the Work or Derivative Works thereof, You may choose to offer, | |
| 167 | and charge a fee for, acceptance of support, warranty, indemnity, | |
| 168 | or other liability obligations and/or rights consistent with this | |
| 169 | License. However, in accepting such obligations, You may act only | |
| 170 | on Your own behalf and on Your sole responsibility, not on behalf | |
| 171 | of any other Contributor, and only if You agree to indemnify, | |
| 172 | defend, and hold each Contributor harmless for any liability | |
| 173 | incurred by, or claims asserted against, such Contributor by reason | |
| 174 | of your accepting any such warranty or additional liability. | |
| 175 | ||
| 176 | END OF TERMS AND CONDITIONS | |
| 177 | ||
| 178 | APPENDIX: How to apply the Apache License to your work. | |
| 179 | ||
| 180 | To apply the Apache License to your work, attach the following | |
| 181 | boilerplate notice, with the fields enclosed by brackets "{}" | |
| 182 | replaced with your own identifying information. (Don't include | |
| 183 | the brackets!) The text should be enclosed in the appropriate | |
| 184 | comment syntax for the file format. We also recommend that a | |
| 185 | file or class name and description of purpose be included on the | |
| 186 | same "printed page" as the copyright notice for easier | |
| 187 | identification within third-party archives. | |
| 188 | ||
| 189 | Copyright {yyyy} {name of copyright owner} | |
| 190 | ||
| 191 | Licensed under the Apache License, Version 2.0 (the "License"); | |
| 192 | you may not use this file except in compliance with the License. | |
| 193 | You may obtain a copy of the License at | |
| 194 | ||
| 195 | http://www.apache.org/licenses/LICENSE-2.0 | |
| 196 | ||
| 197 | Unless required by applicable law or agreed to in writing, software | |
| 198 | distributed under the License is distributed on an "AS IS" BASIS, | |
| 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| 200 | See the License for the specific language governing permissions and | |
| 201 | limitations under the License. | |
| 1 | 202 |
| 1 | Copyright (c) 2013-2014, Tomas Mikula | |
| 2 | All rights reserved. | |
| 3 | ||
| 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | |
| 1 | 5 | |
| 6 | 1. Redistributions of source code |
| 1 | GNU GENERAL PUBLIC LICENSE | |
| 2 | Version 2, June 1991 | |
| 3 | ||
| 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. | |
| 5 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| 6 | Everyone is permitted to copy and distribute verbatim copies | |
| 7 | of this license document, but changing it is not allowed. | |
| 8 | ||
| 9 | Preamble | |
| 10 | ||
| 11 | The licenses for most software are designed to take away your | |
| 12 | freedom to share and change it. By contrast, the GNU General Public | |
| 13 | License is intended to guarantee your freedom to share and change free | |
| 14 | software--to make sure the software is free for all its users. This | |
| 15 | General Public License applies to most of the Free Software | |
| 16 | Foundation's software and to any other program whose authors commit to | |
| 17 | using it. (Some other Free Software Foundation software is covered by | |
| 18 | the GNU Library General Public License instead.) You can apply it to | |
| 19 | your programs, too. | |
| 20 | ||
| 21 | When we speak of free software, we are referring to freedom, not | |
| 22 | price. Our General Public Licenses are designed to make sure that you | |
| 23 | have the freedom to distribute copies of free software (and charge for | |
| 24 | this service if you wish), that you receive source code or can get it | |
| 25 | if you want it, that you can change the software or use pieces of it | |
| 26 | in new free programs; and that you know you can do these things. | |
| 27 | ||
| 28 | To protect your rights, we need to make restrictions that forbid | |
| 29 | anyone to deny you these rights or to ask you to surrender the rights. | |
| 30 | These restrictions translate to certain responsibilities for you if you | |
| 31 | distribute copies of the software, or if you modify it. | |
| 32 | ||
| 33 | For example, if you distribute copies of such a program, whether | |
| 34 | gratis or for a fee, you must give the recipients all the rights that | |
| 35 | you have. You must make sure that they, too, receive or can get the | |
| 36 | source code. And you must show them these terms so they know their | |
| 37 | rights. | |
| 38 | ||
| 39 | We protect your rights with two steps: (1) copyright the software, and | |
| 40 | (2) offer you this license which gives you legal permission to copy, | |
| 41 | distribute and/or modify the software. | |
| 42 | ||
| 43 | Also, for each author's protection and ours, we want to make certain | |
| 44 | that everyone understands that there is no warranty for this free | |
| 45 | software. If the software is modified by someone else and passed on, we | |
| 46 | want its recipients to know that what they have is not the original, so | |
| 47 | that any problems introduced by others will not reflect on the original | |
| 48 | authors' reputations. | |
| 49 | ||
| 50 | Finally, any free program is threatened constantly by software | |
| 51 | patents. We wish to avoid the danger that redistributors of a free | |
| 52 | program will individually obtain patent licenses, in effect making the | |
| 53 | program proprietary. To prevent this, we have made it clear that any | |
| 54 | patent must be licensed for everyone's free use or not licensed at all. | |
| 55 | ||
| 56 | The precise terms and conditions for copying, distribution and | |
| 57 | modification follow. | |
| 58 | ||
| 59 | GNU GENERAL PUBLIC LICENSE | |
| 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | |
| 61 | ||
| 62 | 0. This License applies to any program or other work which contains | |
| 63 | a notice placed by the copyright holder saying it may be distributed | |
| 64 | under the terms of this General Public License. The "Program", below, | |
| 65 | refers to any such program or work, and a "work based on the Program" | |
| 66 | means either the Program or any derivative work under copyright law: | |
| 67 | that is to say, a work containing the Program or a portion of it, | |
| 68 | either verbatim or with modifications and/or translated into another | |
| 69 | language. (Hereinafter, translation is included without limitation in | |
| 70 | the term "modification".) Each licensee is addressed as "you". | |
| 71 | ||
| 72 | Activities other than copying, distribution and modification are not | |
| 73 | covered by this License; they are outside its scope. The act of | |
| 74 | running the Program is not restricted, and the output from the Program | |
| 75 | is covered only if its contents constitute a work based on the | |
| 76 | Program (independent of having been made by running the Program). | |
| 77 | Whether that is true depends on what the Program does. | |
| 78 | ||
| 79 | 1. You may copy and distribute verbatim copies of the Program's | |
| 80 | source code as you receive it, in any medium, provided that you | |
| 81 | conspicuously and appropriately publish on each copy an appropriate | |
| 82 | copyright notice and disclaimer of warranty; keep intact all the | |
| 83 | notices that refer to this License and to the absence of any warranty; | |
| 84 | and give any other recipients of the Program a copy of this License | |
| 85 | along with the Program. | |
| 86 | ||
| 87 | You may charge a fee for the physical act of transferring a copy, and | |
| 88 | you may at your option offer warranty protection in exchange for a fee. | |
| 89 | ||
| 90 | 2. You may modify your copy or copies of the Program or any portion | |
| 91 | of it, thus forming a work based on the Program, and copy and | |
| 92 | distribute such modifications or work under the terms of Section 1 | |
| 93 | above, provided that you also meet all of these conditions: | |
| 94 | ||
| 95 | a) You must cause the modified files to carry prominent notices | |
| 96 | stating that you changed the files and the date of any change. | |
| 97 | ||
| 98 | b) You must cause any work that you distribute or publish, that in | |
| 99 | whole or in part contains or is derived from the Program or any | |
| 100 | part thereof, to be licensed as a whole at no charge to all third | |
| 101 | parties under the terms of this License. | |
| 102 | ||
| 103 | c) If the modified program normally reads commands interactively | |
| 104 | when run, you must cause it, when started running for such | |
| 105 | interactive use in the most ordinary way, to print or display an | |
| 106 | announcement including an appropriate copyright notice and a | |
| 107 | notice that there is no warranty (or else, saying that you provide | |
| 108 | a warranty) and that users may redistribute the program under | |
| 109 | these conditions, and telling the user how to view a copy of this | |
| 110 | License. (Exception: if the Program itself is interactive but | |
| 111 | does not normally print such an announcement, your work based on | |
| 112 | the Program is not required to print an announcement.) | |
| 113 | ||
| 114 | These requirements apply to the modified work as a whole. If | |
| 115 | identifiable sections of that work are not derived from the Program, | |
| 116 | and can be reasonably considered independent and separate works in | |
| 117 | themselves, then this License, and its terms, do not apply to those | |
| 118 | sections when you distribute them as separate works. But when you | |
| 119 | distribute the same sections as part of a whole which is a work based | |
| 120 | on the Program, the distribution of the whole must be on the terms of | |
| 121 | this License, whose permissions for other licensees extend to the | |
| 122 | entire whole, and thus to each and every part regardless of who wrote it. | |
| 123 | ||
| 124 | Thus, it is not the intent of this section to claim rights or contest | |
| 125 | your rights to work written entirely by you; rather, the intent is to | |
| 126 | exercise the right to control the distribution of derivative or | |
| 127 | collective works based on the Program. | |
| 128 | ||
| 129 | In addition, mere aggregation of another work not based on the Program | |
| 130 | with the Program (or with a work based on the Program) on a volume of | |
| 131 | a storage or distribution medium does not bring the other work under | |
| 132 | the scope of this License. | |
| 133 | ||
| 134 | 3. You may copy and distribute the Program (or a work based on it, | |
| 135 | under Section 2) in object code or executable form under the terms of | |
| 136 | Sections 1 and 2 above provided that you also do one of the following: | |
| 137 | ||
| 138 | a) Accompany it with the complete corresponding machine-readable | |
| 139 | source code, which must be distributed under the terms of Sections | |
| 140 | 1 and 2 above on a medium customarily used for software interchange; or, | |
| 141 | ||
| 142 | b) Accompany it with a written offer, valid for at least three | |
| 143 | years, to give any third party, for a charge no more than your | |
| 144 | cost of physically performing source distribution, a complete | |
| 145 | machine-readable copy of the corresponding source code, to be | |
| 146 | distributed under the terms of Sections 1 and 2 above on a medium | |
| 147 | customarily used for software interchange; or, | |
| 148 | ||
| 149 | c) Accompany it with the information you received as to the offer | |
| 150 | to distribute corresponding source code. (This alternative is | |
| 151 | allowed only for noncommercial distribution and only if you | |
| 152 | received the program in object code or executable form with such | |
| 153 | an offer, in accord with Subsection b above.) | |
| 154 | ||
| 155 | The source code for a work means the preferred form of the work for | |
| 156 | making modifications to it. For an executable work, complete source | |
| 157 | code means all the source code for all modules it contains, plus any | |
| 158 | associated interface definition files, plus the scripts used to | |
| 159 | control compilation and installation of the executable. However, as a | |
| 160 | special exception, the source code distributed need not include | |
| 161 | anything that is normally distributed (in either source or binary | |
| 162 | form) with the major components (compiler, kernel, and so on) of the | |
| 163 | operating system on which the executable runs, unless that component | |
| 164 | itself accompanies the executable. | |
| 165 | ||
| 166 | If distribution of executable or object code is made by offering | |
| 167 | access to copy from a designated place, then offering equivalent | |
| 168 | access to copy the source code from the same place counts as | |
| 169 | distribution of the source code, even though third parties are not | |
| 170 | compelled to copy the source along with the object code. | |
| 171 | ||
| 172 | 4. You may not copy, modify, sublicense, or distribute the Program | |
| 173 | except as expressly provided under this License. Any attempt | |
| 174 | otherwise to copy, modify, sublicense or distribute the Program is | |
| 175 | void, and will automatically terminate your rights under this License. | |
| 176 | However, parties who have received copies, or rights, from you under | |
| 177 | this License will not have their licenses terminated so long as such | |
| 178 | parties remain in full compliance. | |
| 179 | ||
| 180 | 5. You are not required to accept this License, since you have not | |
| 181 | signed it. However, nothing else grants you permission to modify or | |
| 182 | distribute the Program or its derivative works. These actions are | |
| 183 | prohibited by law if you do not accept this License. Therefore, by | |
| 184 | modifying or distributing the Program (or any work based on the | |
| 185 | Program), you indicate your acceptance of this License to do so, and | |
| 186 | all its terms and conditions for copying, distributing or modifying | |
| 187 | the Program or works based on it. | |
| 188 | ||
| 189 | 6. Each time you redistribute the Program (or any work based on the | |
| 190 | Program), the recipient automatically receives a license from the | |
| 191 | original licensor to copy, distribute or modify the Program subject to | |
| 192 | these terms and conditions. You may not impose any further | |
| 193 | restrictions on the recipients' exercise of the rights granted herein. | |
| 194 | You are not responsible for enforcing compliance by third parties to | |
| 195 | this License. | |
| 196 | ||
| 197 | 7. If, as a consequence of a court judgment or allegation of patent | |
| 198 | infringement or for any other reason (not limited to patent issues), | |
| 199 | conditions are imposed on you (whether by court order, agreement or | |
| 200 | otherwise) that contradict the conditions of this License, they do not | |
| 201 | excuse you from the conditions of this License. If you cannot | |
| 202 | distribute so as to satisfy simultaneously your obligations under this | |
| 203 | License and any other pertinent obligations, then as a consequence you | |
| 204 | may not distribute the Program at all. For example, if a patent | |
| 205 | license would not permit royalty-free redistribution of the Program by | |
| 206 | all those who receive copies directly or indirectly through you, then | |
| 207 | the only way you could satisfy both it and this License would be to | |
| 208 | refrain entirely from distribution of the Program. | |
| 209 | ||
| 210 | If any portion of this section is held invalid or unenforceable under | |
| 211 | any particular circumstance, the balance of the section is intended to | |
| 212 | apply and the section as a whole is intended to apply in other | |
| 213 | circumstances. | |
| 214 | ||
| 215 | It is not the purpose of this section to induce you to infringe any | |
| 216 | patents or other property right claims or to contest validity of any | |
| 217 | such claims; this section has the sole purpose of protecting the | |
| 218 | integrity of the free software distribution system, which is | |
| 219 | implemented by public license practices. Many people have made | |
| 220 | generous contributions to the wide range of software distributed | |
| 221 | through that system in reliance on consistent application of that | |
| 222 | system; it is up to the author/donor to decide if he or she is willing | |
| 223 | to distribute software through any other system and a licensee cannot | |
| 224 | impose that choice. | |
| 225 | ||
| 226 | This section is intended to make thoroughly clear what is believed to | |
| 227 | be a consequence of the rest of this License. | |
| 228 | ||
| 229 | 8. If the distribution and/or use of the Program is restricted in | |
| 230 | certain countries either by patents or by copyrighted interfaces, the | |
| 231 | original copyright holder who places the Program under this License | |
| 232 | may add an explicit geographical distribution limitation excluding | |
| 233 | those countries, so that distribution is permitted only in or among | |
| 234 | countries not thus excluded. In such case, this License incorporates | |
| 235 | the limitation as if written in the body of this License. | |
| 236 | ||
| 237 | 9. The Free Software Foundation may publish revised and/or new versions | |
| 238 | of the General Public License from time to time. Such new versions will | |
| 239 | be similar in spirit to the present version, but may differ in detail to | |
| 240 | address new problems or concerns. | |
| 241 | ||
| 242 | Each version is given a distinguishing version number. If the Program | |
| 243 | specifies a version number of this License which applies to it and "any | |
| 244 | later version", you have the option of following the terms and conditions | |
| 245 | either of that version or of any later version published by the Free | |
| 246 | Software Foundation. If the Program does not specify a version number of | |
| 247 | this License, you may choose any version ever published by the Free Software | |
| 248 | Foundation. | |
| 249 | ||
| 250 | 10. If you wish to incorporate parts of the Program into other free | |
| 251 | programs whose distribution conditions are different, write to the author | |
| 252 | to ask for permission. For software which is copyrighted by the Free | |
| 253 | Software Foundation, write to the Free Software Foundation; we sometimes | |
| 254 | make exceptions for this. Our decision will be guided by the two goals | |
| 255 | of preserving the free status of all derivatives of our free software and | |
| 256 | of promoting the sharing and reuse of software generally. | |
| 257 | ||
| 258 | NO WARRANTY | |
| 259 | ||
| 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | |
| 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN | |
| 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | |
| 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | |
| 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | |
| 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS | |
| 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE | |
| 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | |
| 268 | REPAIR OR CORRECTION. | |
| 269 | ||
| 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | |
| 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | |
| 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | |
| 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | |
| 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | |
| 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | |
| 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | |
| 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | |
| 278 | POSSIBILITY OF SUCH DAMAGES. | |
| 279 | ||
| 280 | END OF TERMS AND CONDITIONS | |
| 281 | ||
| 282 | How to Apply These Terms to Your New Programs | |
| 283 | ||
| 284 | If you develop a new program, and you want it to be of the greatest | |
| 285 | possible use to the public, the best way to achieve this is to make it | |
| 286 | free software which everyone can redistribute and change under these terms. | |
| 287 | ||
| 288 | To do so, attach the following notices to the program. It is safest | |
| 289 | to attach them to the start of each source file to most effectively | |
| 290 | convey the exclusion of warranty; and each file should have at least | |
| 291 | the "copyright" line and a pointer to where the full notice is found. | |
| 292 | ||
| 293 | <one line to give the program's name and a brief idea of what it does.> | |
| 294 | Copyright (C) <year> <name of author> | |
| 295 | ||
| 296 | This program is free software; you can redistribute it and/or modify | |
| 297 | it under the terms of the GNU General Public License as published by | |
| 298 | the Free Software Foundation; either version 2 of the License, or | |
| 299 | (at your option) any later version. | |
| 300 | ||
| 301 | This program is distributed in the hope that it will be useful, | |
| 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 304 | GNU General Public License for more details. | |
| 305 | ||
| 306 | You should have received a copy of the GNU General Public License | |
| 307 | along with this program; if not, write to the Free Software | |
| 308 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
| 309 | ||
| 310 | ||
| 311 | Also add information on how to contact you by electronic and paper mail. | |
| 312 | ||
| 313 | If the program is interactive, make it output a short notice like this | |
| 314 | when it starts in an interactive mode: | |
| 315 | ||
| 316 | Gnomovision version 69, Copyright (C) year name of author | |
| 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | |
| 318 | This is free software, and you are welcome to redistribute it | |
| 319 | under certain conditions; type `show c' for details. | |
| 320 | ||
| 321 | The hypothetical commands `show w' and `show c' should show the appropriate | |
| 322 | parts of the General Public License. Of course, the commands you use may | |
| 323 | be called something other than `show w' and `show c'; they could even be | |
| 324 | mouse-clicks or menu items--whatever suits your program. | |
| 325 | ||
| 326 | You should also get your employer (if you work as a programmer) or your | |
| 327 | school, if any, to sign a "copyright disclaimer" for the program, if | |
| 328 | necessary. Here is a sample; alter the names: | |
| 329 | ||
| 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program | |
| 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. | |
| 332 | ||
| 333 | <signature of Ty Coon>, 1 April 1989 | |
| 334 | Ty Coon, President of Vice | |
| 335 | ||
| 336 | This General Public License does not permit incorporating your program into | |
| 337 | proprietary programs. If your program is a subroutine library, you may | |
| 338 | consider it more useful to permit linking proprietary applications with the | |
| 339 | library. If this is what you want to do, use the GNU Library General | |
| 340 | Public License instead of this License. | |
| 1 | 341 |
| 1 | Copyright (c) 2013-2017, Tomas Mikula and contributors | |
| 2 | All rights reserved. | |
| 3 | ||
| 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: | |
| 1 | 5 | |
| 6 | 1. Redistributions of source code. | |
| 7 | COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS |
| 1 | Mozilla Public License | |
| 2 | Version 2.0 | |
| 3 | ||
| 4 | 1. Definitions | |
| 5 | ||
| 6 | 1.1. “Contributor” | |
| 7 | means each individual or legal entity that creates, contributes | |
| 8 | to the creation of, or owns Covered Software. | |
| 9 | ||
| 10 | 1.2. “Contributor Version” | |
| 11 | means the combination of the Contributions of others (if any) | |
| 12 | used by a Contributor and that particular Contributor’s | |
| 13 | Contribution. | |
| 14 | ||
| 15 | 1.3. “Contribution” | |
| 16 | means Covered Software of a particular Contributor. | |
| 17 | ||
| 18 | 1.4. “Covered Software” | |
| 19 | means Source Code Form to which the initial Contributor has | |
| 20 | attached the notice in Exhibit A, the Executable Form of such | |
| 21 | Source Code Form, and Modifications of such Source Code Form, in | |
| 22 | each case including portions thereof. | |
| 23 | ||
| 24 | 1.5. “Incompatible With Secondary Licenses” | |
| 25 | means | |
| 26 | ||
| 27 | a. that the initial Contributor has attached the notice described | |
| 28 | in Exhibit B to the Covered Software; or | |
| 29 | b. that the Covered Software was made available under the terms | |
| 30 | of version 1.1 or earlier of the License, but not also under | |
| 31 | the terms of a Secondary License. | |
| 32 | ||
| 33 | 1.6. “Executable Form” | |
| 34 | means any form of the work other than Source Code Form. | |
| 35 | ||
| 36 | 1.7. “Larger Work” | |
| 37 | means a work that combines Covered Software with other material, | |
| 38 | in a separate file or files, that is not Covered Software. | |
| 39 | ||
| 40 | 1.8. “License” | |
| 41 | means this document. | |
| 42 | ||
| 43 | 1.9. “Licensable” | |
| 44 | means having the right to grant, to the maximum extent possible, | |
| 45 | whether at the time of the initial grant or subsequently, any | |
| 46 | and all of the rights conveyed by this License. | |
| 47 | ||
| 48 | 1.10. “Modifications” | |
| 49 | means any of the following: | |
| 50 | ||
| 51 | a. any file in Source Code Form that results from an addition to, | |
| 52 | deletion from, or modification of the contents of Covered | |
| 53 | Software; or | |
| 54 | b. any new file in Source Code Form that contains any Covered | |
| 55 | Software. | |
| 56 | ||
| 57 | 1.11. “Patent Claims” of a Contributor | |
| 58 | means any patent claim(s), including without limitation, method, | |
| 59 | process, and apparatus claims, in any patent Licensable by such | |
| 60 | Contributor that would be infringed, but for the grant of the | |
| 61 | License, by the making, using, selling, offering for sale, | |
| 62 | having made, import, or transfer of either its Contributions or | |
| 63 | its Contributor Version. | |
| 64 | ||
| 65 | 1.12. “Secondary License” | |
| 66 | means either the GNU General Public License, Version 2.0, the | |
| 67 | GNU Lesser General Public License, Version 2.1, the GNU Affero | |
| 68 | General Public License, Version 3.0, or any later versions of | |
| 69 | those licenses. | |
| 70 | ||
| 71 | 1.13. “Source Code Form” | |
| 72 | means the form of the work preferred for making modifications. | |
| 73 | ||
| 74 | 1.14. “You” (or “Your”) | |
| 75 | means an individual or a legal entity exercising rights under | |
| 76 | this License. For legal entities, “You” includes any entity that | |
| 77 | controls, is controlled by, or is under common control with You. | |
| 78 | For purposes of this definition, “control” means (a) the power, | |
| 79 | direct or indirect, to cause the direction or management of such | |
| 80 | entity, whether by contract or otherwise, or (b) ownership of | |
| 81 | more than fifty percent (50%) of the outstanding shares or | |
| 82 | beneficial ownership of such entity. | |
| 83 | ||
| 84 | 2. License Grants and Conditions | |
| 85 | ||
| 86 | 2.1. Grants | |
| 87 | ||
| 88 | Each Contributor hereby grants You a world-wide, royalty-free, | |
| 89 | non-exclusive license: | |
| 90 | a. under intellectual property rights (other than patent or trademark) | |
| 91 | Licensable by such Contributor to use, reproduce, make available, | |
| 92 | modify, display, perform, distribute, and otherwise exploit its | |
| 93 | Contributions, either on an unmodified basis, with Modifications, | |
| 94 | or as part of a Larger Work; and | |
| 95 | b. under Patent Claims of such Contributor to make, use, sell, offer | |
| 96 | for sale, have made, import, and otherwise transfer either its | |
| 97 | Contributions or its Contributor Version. | |
| 98 | ||
| 99 | 2.2. Effective Date | |
| 100 | ||
| 101 | The licenses granted in Section 2.1 with respect to any Contribution | |
| 102 | become effective for each Contribution on the date the Contributor | |
| 103 | first distributes such Contribution. | |
| 104 | ||
| 105 | 2.3. Limitations on Grant Scope | |
| 106 | ||
| 107 | The licenses granted in this Section 2 are the only rights granted | |
| 108 | under this License. No additional rights or licenses will be implied | |
| 109 | from the distribution or licensing of Covered Software under this | |
| 110 | License. Notwithstanding Section 2.1(b) above, no patent license is | |
| 111 | granted by a Contributor: | |
| 112 | a. for any code that a Contributor has removed from Covered Software; | |
| 113 | or | |
| 114 | b. for infringements caused by: (i) Your and any other third party’s | |
| 115 | modifications of Covered Software, or (ii) the combination of its | |
| 116 | Contributions with other software (except as part of its | |
| 117 | Contributor Version); or | |
| 118 | c. under Patent Claims infringed by Covered Software in the absence of | |
| 119 | its Contributions. | |
| 120 | ||
| 121 | This License does not grant any rights in the trademarks, service | |
| 122 | marks, or logos of any Contributor (except as may be necessary to | |
| 123 | comply with the notice requirements in Section 3.4). | |
| 124 | ||
| 125 | 2.4. Subsequent Licenses | |
| 126 | ||
| 127 | No Contributor makes additional grants as a result of Your choice to | |
| 128 | distribute the Covered Software under a subsequent version of this | |
| 129 | License (see Section 10.2) or under the terms of a Secondary License | |
| 130 | (if permitted under the terms of Section 3.3). | |
| 131 | ||
| 132 | 2.5. Representation | |
| 133 | ||
| 134 | Each Contributor represents that the Contributor believes its | |
| 135 | Contributions are its original creation(s) or it has sufficient rights | |
| 136 | to grant the rights to its Contributions conveyed by this License. | |
| 137 | ||
| 138 | 2.6. Fair Use | |
| 139 | ||
| 140 | This License is not intended to limit any rights You have under | |
| 141 | applicable copyright doctrines of fair use, fair dealing, or other | |
| 142 | equivalents. | |
| 143 | ||
| 144 | 2.7. Conditions | |
| 145 | ||
| 146 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted | |
| 147 | in Section 2.1. | |
| 148 | ||
| 149 | 3. Responsibilities | |
| 150 | ||
| 151 | 3.1. Distribution of Source Form | |
| 152 | ||
| 153 | All distribution of Covered Software in Source Code Form, including any | |
| 154 | Modifications that You create or to which You contribute, must be under | |
| 155 | the terms of this License. You must inform recipients that the Source | |
| 156 | Code Form of the Covered Software is governed by the terms of this | |
| 157 | License, and how they can obtain a copy of this License. You may not | |
| 158 | attempt to alter or restrict the recipients’ rights in the Source Code | |
| 159 | Form. | |
| 160 | ||
| 161 | 3.2. Distribution of Executable Form | |
| 162 | ||
| 163 | If You distribute Covered Software in Executable Form then: | |
| 164 | a. such Covered Software must also be made available in Source Code | |
| 165 | Form, as described in Section 3.1, and You must inform recipients | |
| 166 | of the Executable Form how they can obtain a copy of such Source | |
| 167 | Code Form by reasonable means in a timely manner, at a charge no | |
| 168 | more than the cost of distribution to the recipient; and | |
| 169 | b. You may distribute such Executable Form under the terms of this | |
| 170 | License, or sublicense it under different terms, provided that the | |
| 171 | license for the Executable Form does not attempt to limit or alter | |
| 172 | the recipients’ rights in the Source Code Form under this License. | |
| 173 | ||
| 174 | 3.3. Distribution of a Larger Work | |
| 175 | ||
| 176 | You may create and distribute a Larger Work under terms of Your choice, | |
| 177 | provided that You also comply with the requirements of this License for | |
| 178 | the Covered Software. If the Larger Work is a combination of Covered | |
| 179 | Software with a work governed by one or more Secondary Licenses, and | |
| 180 | the Covered Software is not Incompatible With Secondary Licenses, this | |
| 181 | License permits You to additionally distribute such Covered Software | |
| 182 | under the terms of such Secondary License(s), so that the recipient of | |
| 183 | the Larger Work may, at their option, further distribute the Covered | |
| 184 | Software under the terms of either this License or such Secondary | |
| 185 | License(s). | |
| 186 | ||
| 187 | 3.4. Notices | |
| 188 | ||
| 189 | You may not remove or alter the substance of any license notices | |
| 190 | (including copyright notices, patent notices, disclaimers of warranty, | |
| 191 | or limitations of liability) contained within the Source Code Form of | |
| 192 | the Covered Software, except that You may alter any license notices to | |
| 193 | the extent required to remedy known factual inaccuracies. | |
| 194 | ||
| 195 | 3.5. Application of Additional Terms | |
| 196 | ||
| 197 | You may choose to offer, and to charge a fee for, warranty, support, | |
| 198 | indemnity or liability obligations to one or more recipients of Covered | |
| 199 | Software. However, You may do so only on Your own behalf, and not on | |
| 200 | behalf of any Contributor. You must make it absolutely clear that any | |
| 201 | such warranty, support, indemnity, or liability obligation is offered | |
| 202 | by You alone, and You hereby agree to indemnify every Contributor for | |
| 203 | any liability incurred by such Contributor as a result of warranty, | |
| 204 | support, indemnity or liability terms You offer. You may include | |
| 205 | additional disclaimers of warranty and limitations of liability | |
| 206 | specific to any jurisdiction. | |
| 207 | ||
| 208 | 4. Inability to Comply Due to Statute or Regulation | |
| 209 | ||
| 210 | If it is impossible for You to comply with any of the terms of this | |
| 211 | License with respect to some or all of the Covered Software due to | |
| 212 | statute, judicial order, or regulation then You must: (a) comply with | |
| 213 | the terms of this License to the maximum extent possible; and (b) | |
| 214 | describe the limitations and the code they affect. Such description | |
| 215 | must be placed in a text file included with all distributions of the | |
| 216 | Covered Software under this License. Except to the extent prohibited by | |
| 217 | statute or regulation, such description must be sufficiently detailed | |
| 218 | for a recipient of ordinary skill to be able to understand it. | |
| 219 | ||
| 220 | 5. Termination | |
| 221 | ||
| 222 | 5.1. The rights granted under this License will terminate automatically | |
| 223 | if You fail to comply with any of its terms. However, if You become | |
| 224 | compliant, then the rights granted under this License from a particular | |
| 225 | Contributor are reinstated (a) provisionally, unless and until such | |
| 226 | Contributor explicitly and finally terminates Your grants, and (b) on | |
| 227 | an ongoing basis, if such Contributor fails to notify You of the | |
| 228 | non-compliance by some reasonable means prior to 60 days after You have | |
| 229 | come back into compliance. Moreover, Your grants from a particular | |
| 230 | Contributor are reinstated on an ongoing basis if such Contributor | |
| 231 | notifies You of the non-compliance by some reasonable means, this is | |
| 232 | the first time You have received notice of non-compliance with this | |
| 233 | License from such Contributor, and You become compliant prior to 30 | |
| 234 | days after Your receipt of the notice. | |
| 235 | ||
| 236 | 5.2. If You initiate litigation against any entity by asserting a | |
| 237 | patent infringement claim (excluding declaratory judgment actions, | |
| 238 | counter-claims, and cross-claims) alleging that a Contributor Version | |
| 239 | directly or indirectly infringes any patent, then the rights granted to | |
| 240 | You by any and all Contributors for the Covered Software under | |
| 241 | Section 2.1 of this License shall terminate. | |
| 242 | ||
| 243 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all | |
| 244 | end user license agreements (excluding distributors and resellers) | |
| 245 | which have been validly granted by You or Your distributors under this | |
| 246 | License prior to termination shall survive termination. | |
| 247 | ||
| 248 | 6. Disclaimer of Warranty | |
| 249 | ||
| 250 | Covered Software is provided under this License on an “as is” basis, | |
| 251 | without warranty of any kind, either expressed, implied, or statutory, | |
| 252 | including, without limitation, warranties that the Covered Software is | |
| 253 | free of defects, merchantable, fit for a particular purpose or | |
| 254 | non-infringing. The entire risk as to the quality and performance of | |
| 255 | the Covered Software is with You. Should any Covered Software prove | |
| 256 | defective in any respect, You (not any Contributor) assume the cost of | |
| 257 | any necessary servicing, repair, or correction. This disclaimer of | |
| 258 | warranty constitutes an essential part of this License. No use of any | |
| 259 | Covered Software is authorized under this License except under this | |
| 260 | disclaimer. | |
| 261 | ||
| 262 | 7. Limitation of Liability | |
| 263 | ||
| 264 | Under no circumstances and under no legal theory, whether tort | |
| 265 | (including negligence), contract, or otherwise, shall any Contributor, | |
| 266 | or anyone who distributes Covered Software as permitted above, be | |
| 267 | liable to You for any direct, indirect, special, incidental, or | |
| 268 | consequential damages of any character including, without limitation, | |
| 269 | damages for lost profits, loss of goodwill, work stoppage, computer | |
| 270 | failure or malfunction, or any and all other commercial damages or | |
| 271 | losses, even if such party shall have been informed of the possibility | |
| 272 | of such damages. This limitation of liability shall not apply to | |
| 273 | liability for death or personal injury resulting from such party’s | |
| 274 | negligence to the extent applicable law prohibits such limitation. Some | |
| 275 | jurisdictions do not allow the exclusion or limitation of incidental or | |
| 276 | consequential damages, so this exclusion and limitation may not apply | |
| 277 | to You. | |
| 278 | ||
| 279 | 8. Litigation | |
| 280 | ||
| 281 | Any litigation relating to this License may be brought only in the | |
| 282 | courts of a jurisdiction where the defendant maintains its principal | |
| 283 | place of business and such litigation shall be governed by laws of that | |
| 284 | jurisdiction, without reference to its conflict-of-law provisions. | |
| 285 | Nothing in this Section shall prevent a party’s ability to bring | |
| 286 | cross-claims or counter-claims. | |
| 287 | ||
| 288 | 9. Miscellaneous | |
| 289 | ||
| 290 | This License represents the complete agreement concerning the subject | |
| 291 | matter hereof. If any provision of this License is held to be | |
| 292 | unenforceable, such provision shall be reformed only to the extent | |
| 293 | necessary to make it enforceable. Any law or regulation which provides | |
| 294 | that the language of a contract shall be construed against the drafter | |
| 295 | shall not be used to construe this License against a Contributor. | |
| 296 | ||
| 297 | 10. Versions of the License | |
| 298 | ||
| 299 | 10.1. New Versions | |
| 300 | ||
| 301 | Mozilla Foundation is the license steward. Except as provided in | |
| 302 | Section 10.3, no one other than the license steward has the right to | |
| 303 | modify or publish new versions of this License. Each version will be | |
| 304 | given a distinguishing version number. | |
| 305 | ||
| 306 | 10.2. Effect of New Versions | |
| 307 | ||
| 308 | You may distribute the Covered Software under the terms of the version | |
| 309 | of the License under which You originally received the Covered | |
| 310 | Software, or under the terms of any subsequent version published by the | |
| 311 | license steward. | |
| 312 | ||
| 313 | 10.3. Modified Versions | |
| 314 | ||
| 315 | If you create software not governed by this License, and you want to | |
| 316 | create a new license for such software, you may create and use a | |
| 317 | modified version of this License if you rename the license and remove | |
| 318 | any references to the name of the license steward (except to note that | |
| 319 | such modified license differs from this License). | |
| 320 | ||
| 321 | 10.4. Distributing Source Code Form that is Incompatible With Secondary | |
| 322 | Licenses | |
| 323 | ||
| 324 | If You choose to distribute Source Code Form that is Incompatible With | |
| 325 | Secondary Licenses under the terms of this version of the License, the | |
| 326 | notice described in Exhibit B of this License must be attached. | |
| 327 | ||
| 328 | Exhibit A - Source Code Form License Notice | |
| 329 | ||
| 330 | This Source Code Form is subject to the terms of the Mozilla Public | |
| 331 | License, v. 2.0. If a copy of the MPL was not distributed with this | |
| 332 | file, You can obtain one at https://mozilla.org/MPL/2.0/. | |
| 333 | ||
| 334 | If it is not possible or desirable to put the notice in a particular | |
| 335 | file, then You may include the notice in a location (such as a LICENSE | |
| 336 | file in a relevant directory) where a recipient would be likely to look | |
| 337 | for such a notice. | |
| 338 | ||
| 339 | You may add additional accurate notices of copyright ownership. | |
| 340 | ||
| 341 | Exhibit B - “Incompatible With Secondary Licenses” Notice | |
| 342 | ||
| 343 | This Source Code Form is “Incompatible With Secondary Licenses”, as | |
| 344 | defined by the Mozilla Public License, v. 2.0. | |
| 1 | 345 |
| 1 | Copyright (c) 2014, TomasMikula | |
| 2 | All rights reserved. | |
| 3 | ||
| 4 | Redistribution and use in source and binary forms, with or without modification, | |
| 5 | are permitted provided that the following conditions are met: | |
| 6 | ||
| 7 | * Redistributions of source code | |
| 8 | . | |
| 9 | ||
| 10 | * | |
| 11 | ||
| 12 | ||
| 13 | ||
| 14 | ||
| 15 | ||
| 16 | ||
| 17 | ( | |
| 18 | ||
| 19 | ||
| 20 | ||
| 1 | 21 |
| 1 | Copyright (c) 2014, TomasMikula | |
| 2 | All rights reserved. | |
| 3 | ||
| 4 | Redistribution and use in source and binary forms, with or without | |
| 5 | modification, are permitted provided that the following conditions are met: | |
| 6 | ||
| 7 | * Redistributions of source code | |
| 8 | . | |
| 9 | ||
| 10 | * | |
| 11 | ||
| 12 | ||
| 13 | ||
| 14 | ||
| 15 | ||
| 16 | ||
| 17 | ||
| 18 | ||
| 19 | ||
| 20 | ||
| 21 | ||
| 1 | 22 |
| 1 | URL: https://github.com/googlefonts/noto-cjk | |
| 2 | ||
| 3 | Version: 1.002 or later | |
| 4 | ||
| 5 | License: SIL Open Font License v1.1 | |
| 6 | ||
| 7 | License File: LICENSE | |
| 8 | ||
| 9 | Note: prior releases of the CJK fonts were issued under the Apache 2 | |
| 10 | license. This was changed to the SIL OFL v1.1 starting with Version 1.002. | |
| 11 | ||
| 12 | Description: | |
| 13 | Noto CJK fonts, supporting Simplified Chinese, Traditional Chinese, | |
| 14 | Japanese, and Korean. The supported scripts are Han, Hiragana, Katakana, | |
| 15 | Hangul, and Bopomofo. Latin, Greek, Cyrillic, and various symbols are also | |
| 16 | supported for compatibility with CJK standards. | |
| 17 | ||
| 18 | The fonts in this directory are developed by Google and Adobe and are | |
| 19 | released as open source under the Apache license version 2.0. The copyright | |
| 20 | is held by Adobe, while the trademarks on the names are held by Google. | |
| 21 | ||
| 22 | A README-formats file has been added explaining the different formats | |
| 23 | provided and their features and limitations. | |
| 1 | 24 |
| 1 | 1 | |
| 2 | Apache License | |
| 3 | Version 2.0, January 2004 | |
| 4 | http://www.apache.org/licenses/ | |
| 5 | ||
| 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | |
| 7 | ||
| 8 | 1. Definitions. | |
| 9 | ||
| 10 | "Licen[][yyyy] [name of copyright owner] |
| 1 | Copyright 2018 The Noto Project Authors (https://github.com/googlei18n/noto-fonts) | |
| 2 | ||
| 3 | This Font Software is licensed under the SIL Open Font License, | |
| 4 | Version 1.1. | |
| 1 | 5 | |
| 6 | This license is cop |
| 1 | Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. | |
| 1 | 2 | |
| 3 | This Font Software is licensed under the SIL Open Font License, Version | |
| 4 |
| 1 | Copyright 2014-2019 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. | |
| 2 | ||
| 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. | |
| 4 | ||
| 5 | This license is cop | |
| 6 | creation | |
| 7 | provide a free and | |
| 8 | improved in partnership | |
| 9 | ||
| 10 | to components as | |
| 11 | deleting, | |
| 12 | components of the | |
| 13 | the Font Software to a | |
| 14 | modify, | |
| 15 | ||
| 16 | in corresponding | |
| 17 | primary font name as | |
| 1 | 18 | |
| 19 | using |
| 1 | package com.github.javaparser; | |
| 2 | ||
| 3 | import com.github.javaparser.ast.CompilationUnit; | |
| 4 | import com.github.javaparser.ast.body.MethodDeclaration; | |
| 5 | import com.github.javaparser.ast.body.TypeDeclaration; | |
| 6 | import com.github.javaparser.ast.stmt.BlockStmt; | |
| 7 | import com.github.javaparser.ast.stmt.Statement; | |
| 8 | ||
| 9 | import java.io.File; | |
| 10 | import java.io.FileNotFoundException; | |
| 11 | import java.util.List; | |
| 12 | import java.util.Optional; | |
| 13 | ||
| 14 | import static com.github.javaparser.StaticJavaParser.parseStatement; | |
| 15 | import static java.lang.String.format; | |
| 16 | ||
| 17 | public class Main { | |
| 18 | public static void main( final String[] args ) throws FileNotFoundException { | |
| 19 | final File sourceFile = new File( args[ 0 ] ); | |
| 20 | final JavaParser parser = new JavaParser(); | |
| 21 | final ParseResult<CompilationUnit> pr = parser.parse( sourceFile ); | |
| 22 | final Optional<CompilationUnit> ocu = pr.getResult(); | |
| 23 | ||
| 24 | if( ocu.isPresent() ) { | |
| 25 | final CompilationUnit cu = ocu.get(); | |
| 26 | final List<TypeDeclaration<?>> types = cu.getTypes(); | |
| 27 | ||
| 28 | for( final TypeDeclaration<?> type : types ) { | |
| 29 | final List<MethodDeclaration> methods = type.getMethods(); | |
| 30 | ||
| 31 | for( final MethodDeclaration method : methods ) { | |
| 32 | final Optional<BlockStmt> body = method.getBody(); | |
| 33 | final String m = format( "%s::%s( %s )", | |
| 34 | type.getNameAsString(), | |
| 35 | method.getNameAsString(), | |
| 36 | method.getParameters().toString() ); | |
| 37 | ||
| 38 | final String mBegan = format( | |
| 39 | "System.out.println(\"BEGAN %s\");", m ); | |
| 40 | final String mEnded = format( | |
| 41 | "System.out.println(\"ENDED %s\");", m ); | |
| 42 | ||
| 43 | final Statement sBegan = parseStatement( mBegan ); | |
| 44 | final Statement sEnded = parseStatement( mEnded ); | |
| 45 | ||
| 46 | body.ifPresent( ( b ) -> { | |
| 47 | final int i = b.getStatements().size(); | |
| 48 | ||
| 49 | b.addStatement( 0, sBegan ); | |
| 50 | ||
| 51 | // Insert before any "return" statement. | |
| 52 | b.addStatement( i, sEnded ); | |
| 53 | } ); | |
| 54 | } | |
| 55 | ||
| 56 | System.out.println( cu.toString() ); | |
| 57 | } | |
| 58 | } | |
| 59 | } | |
| 60 | } | |
| 1 | 61 |
| 1 | # Logging | |
| 2 | ||
| 3 | The files in this directory can be used to log the entry/exit to every | |
| 4 | method for debugging purposes. These changes are not meant to be pushed | |
| 5 | onto the mainline branch (i.e., not for production use). | |
| 1 | 6 | |
| 7 | The instructions are relative to the directthe `inject` script to rlogging | |
| 8 | versions |
| 1 | #!/usr/bin/env bash | |
| 2 | ||
| 3 | echo "Parsing" | |
| 4 | find ../src/main/java -type f -name "*.java" -exec \ | |
| 5 | sh -c 'echo {}; java -cp jp.jar com.github.javaparser.Main {} > {}.jp' \; | |
| 6 | ||
| 7 | echo "Renaming" | |
| 8 | # The +10c ensures that files without code are skipped. | |
| 9 | find ../src/main/java -type f -name "*.jp" -size +10c -exec \ | |
| 10 | sh -c 'echo {}; mv {} $(dirname {})/$(basename {} .jp)' \; | |
| 11 | ||
| 1 | 12 |
| 1 | #!/usr/bin/env bash | |
| 2 | ||
| 3 | # --------------------------------------------------------------------------- | |
| 4 | # This script builds Windows, Linux, and Java archive binaries for a | |
| 5 | # release. | |
| 6 | # --------------------------------------------------------------------------- | |
| 7 | ||
| 8 | source $HOME/bin/build-template | |
| 9 | ||
| 10 | readonly FILE_PROPERTIES="${SCRIPT_DIR}/src/main/resources/bootstrap.properties" | |
| 11 | readonly BIN_INSTALLER="${SCRIPT_DIR}/installer" | |
| 12 | ||
| 13 | DEPENDENCIES=( | |
| 14 | "gradle,https://gradle.org" | |
| 15 | "${FILE_PROPERTIES},File containing application name" | |
| 16 | ) | |
| 17 | ||
| 18 | execute() { | |
| 19 | $log "Build Windows installer binary" | |
| 20 | ${BIN_INSTALLER} -o windows | |
| 21 | ||
| 22 | $log "Build Linux installer binary" | |
| 23 | ${BIN_INSTALLER} -o linux | |
| 24 | ||
| 25 | $log "Build Java archive" | |
| 26 | gradle clean jar | |
| 27 | mv "build/libs/${application_title}.jar" . | |
| 28 | } | |
| 29 | ||
| 30 | preprocess() { | |
| 31 | while IFS='=' read -r key value; do | |
| 32 | if [[ "${key}" = "" || "${key}" = "#"* ]]; then | |
| 33 | continue | |
| 34 | fi | |
| 35 | ||
| 36 | key=$(echo $key | tr '.' '_') | |
| 37 | eval ${key}=\${value} | |
| 38 | done < "${FILE_PROPERTIES}" | |
| 39 | ||
| 40 | application_title="${application_title,,}" | |
| 41 | ||
| 42 | return 1 | |
| 43 | } | |
| 44 | ||
| 45 | main "$@" | |
| 46 | ||
| 1 | 47 |
| 1 | 1 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite; | |
| 3 | ||
| 4 | import com.keenwrite.io.FileType; | |
| 5 | ||
| 6 | import java.nio.file.Path; | |
| 1 | 7 | |
| 8 | import static com.keenwrite.Constants.GLOB_PREFIX_FILE; | |
| 9 | import static com.keenwri |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite; | |
| 3 | ||
| 4 | import java.io.InputStream; | |
| 5 | import java.util.Calendar; | |
| 6 | import java.dURL.setGlobalUser/** | |
| 7 | * Order matters, this must be populated before deriving the app title. | |
| 8 | */in = openResourceP.load( in VERSION = Launcher.getVersion();YEAR = getYear(); | |
| 9 | ||
| 10 | @SuppressWarnings( "SameParameterValue" ) | |
| 11 | private static InputStream openResource( final String path ) { | |
| 12 | returnpath ); | |
| 13 | } | |
| 14 | ||
| 15 | private static String getYear() { | |
| 16 | return Integer.toString( Calendar.getInstance().get( Calendar.YEAR ) ); | |
| 17 | } | |
| 18 | } | |
| 1 | 19 |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite; | |
| 3 | ||
| 4 | import com.keenwrite.service.Settings; | |
| 5 | import javafx.scene.control.ToolBar; | |
| 6 | import javafx.scene.control.TreeItem; | |
| 7 | import javafx.scene.image.Image; | |
| 8 | import javafx.scene.image.ImageView; | |
| 9 | ||
| 10 | import javArrayList; | |
| 11 | import java.util.ListTHEMthemeList<Image> LOGOS = createImages( | |
| 12 | "file.logo.16", | |
| 13 | "file.logo.32", | |
| 14 | "file.logo.128", | |
| 15 | "file.logo.256", | |
| 16 | "file.logo.512" | |
| 17 | ); | |
| 18 | Image ICON_DIALOG = LOGOS.get( 1 );ImageView ICON_DIALOG_NODE = new ImageView( ICON_DIALOG ); | |
| 19 | hemeTHEMEheme to applyTHEMEicon size for {@link ToolBar}, {@link TreeItem}s, etcICON_SIZE_DEFAULT = "1.2emthe given file names to images, such as application icons. | |
| 20 | * | |
| 21 | * @param keys The file names to convert to images. | |
| 22 | * @retimages loaded from the file name references. | |
| 23 | */ | |
| 24 | private static List<Image> createImages( final String... keys ) { | |
| 25 | final List<Image> images = new ArrayList<>( keys.length ); | |
| 26 | ||
| 27 | for( final var key : keys ) { | |
| 28 | images.add( new Image( get( key ) ) ); | |
| 29 | } | |
| 30 | ||
| 31 | return images; | |
| 32 | } | |
| 33 | } | |
| 1 | 34 |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite; | |
| 3 | editors.TextDefinitioneditors.TextEditoreditorsex ) { | |
| 4 | BLANK, ex |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite; | |
| 3 | ||
| 4 | import java.io.File; | |
| 5 | import java.nio.file.Path; | |
| 6 | ||
| 7 | import static org.apache.commons.io.FilenameUtils.removeExtension; | |
| 1 | 8 | |
| 9 | /** | |
| 10 | * Provides controls for processo Treat image links relatively Treat image links relatively Treat image links relatively Image links must use absolute directories |
| 1 | ||
| 1 | /* Copyright 2020-2021 -- All rights reserved. */ | |
| 2 | package com.keenwritecom.keenwrite.Bootstrap.APP_TITLE;*APP_VERSIONAPP_YEAR |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite; | |
| 3 | ||
| 4 | import com.keenwrite.; | |
| 5 | import javafx.application.Application; | |
| 6 | import javafx.event.Eve private MainScene mMainScenSee MainScene::createScene(). | |
| 7 | // | |
| 8 | // JavaFX Bugfor( final var menu : mMainScene.getMenuBar().getMenus() ) { | |
| 9 | menu.hide(); | |
| 10 | } | |
| 1 | 11 | |
| 12 | ) );mMainScene = new MainScene( mWorkspace ); | |
| 13 | stage.setScene( mMainScene/** | |
| 14 | * Returns a key released event without any modifier keys held. | |
| 15 | * | |
| 16 | * @param code The key code representing a key to simulate releasing. | |
| 17 | * @return An instance of {@link KeyEvent} ) { | |
| 18 | return keyUp( code, false |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite; | |
| 1 | 3 | |
| 4 | import com.keenwrite.TextDefinition; | |
| 5 | import com.keenwrite.editors.TextEditor; | |
| 6 | import com.keenwrite.edito |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite; | |
| 1 | 3 | |
| 4 | import com.keenwrite.io.FileModifiedListener; | |
| 5 | import com.keenwrite.io.FileWatchService; | |
| 6 | import com.keenwrite.preferences.Workspace; | |
| 7 | import com.keenwrite.uu |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite; | |
| 1 | 3 | |
| 4 | import com.keenwrite.preferences.KeyEnumeration |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite; | |
| 3 | ||
| 4 | import java.util.HashMap; | |
| 5 | import java.util.Map; | |
| 6 | import java.util.ServiceLoader; | |
| 1 | 7 | |
| 8 | /** | |
| 9 | * Responsible for loading services. The services are treated as singleton |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.editors; | |
| 3 | ||
| 4 | import com.keenwrite.editors.definition.DefinitionEditor; | |
| 5 | import com.keenwrite.editors.definition.DefinitionTreeItem; | |
| 6 | import com.keenwrite.editors.markdown.MarkdownEditor; | |
| 7 | import com.keenwrite.sigils.Tokens; | |
| 8 | import javafx.scene.control.TreeItem; | |
| 9 | ||
| 10 | import java.util.Map; | |
| 11 | ||
| 12 | /** | |
| 13 | * Differentiates an instance of {@link TextResource} from an instance of | |
| 14 | * {@link DefinitionEditor} or {@link MarkdownEditor}. | |
| 15 | */ | |
| 16 | public interface TextDefinition extends TextResource { | |
| 17 | /** | |
| 18 | * Converts the definitions into a map, ready for interpolation. | |
| 19 | * | |
| 20 | * @return The list of key value pairs delimited with tokens. | |
| 21 | */ | |
| 22 | Map<String, String> toMap(); | |
| 23 | ||
| 24 | /** | |
| 25 | * Performs string interpolation on the values in the given map. This will | |
| 26 | * change any value in the map that contains a variable that matches | |
| 27 | * the definition regex pattern against the given {@link Tokens}. | |
| 28 | * | |
| 29 | * @param map Contains values that represent references to keys. | |
| 30 | * @param tokens The beginning and ending tokens that delimit variables. | |
| 31 | */ | |
| 32 | Map<String, String> interpolate( Map<String, String> map, Tokens tokens ); | |
| 33 | ||
| 34 | /** | |
| 35 | * Requests that the visual representation be expanded to the given | |
| 36 | * node. | |
| 37 | * | |
| 38 | * @param node Request expansion to this node. | |
| 39 | */ | |
| 40 | <T> void expand( TreeItem<T> node ); | |
| 41 | ||
| 42 | /** | |
| 43 | * Adds a new item to the definition hierarchy. | |
| 44 | */ | |
| 45 | void createDefinition(); | |
| 46 | ||
| 47 | /** | |
| 48 | * Edits the currently selected definition in the hierarchy. | |
| 49 | */ | |
| 50 | void renameDefinition(); | |
| 51 | ||
| 52 | /** | |
| 53 | * Removes the currently selected definition in the hierarchy. | |
| 54 | */ | |
| 55 | void deleteDefinitions(); | |
| 56 | ||
| 57 | /** | |
| 58 | * Finds the definition that exact matches the given text. | |
| 59 | * | |
| 60 | * @param text The value to find, never {@code null}. | |
| 61 | * @return The leaf that contains the given value. | |
| 62 | */ | |
| 63 | DefinitionTreeItem<String> findLeafExact( String text ); | |
| 64 | ||
| 65 | /** | |
| 66 | * Finds the definition that starts with the given text. | |
| 67 | * | |
| 68 | * @param text The value to find, never {@code null}. | |
| 69 | * @return The leaf that starts with the given value. | |
| 70 | */ | |
| 71 | DefinitionTreeItem<String> findLeafStartsWith( String text ); | |
| 72 | ||
| 73 | /** | |
| 74 | * Finds the definition that contains the given text, matching case. | |
| 75 | * | |
| 76 | * @param text The value to find, never {@code null}. | |
| 77 | * @return The leaf that contains the exact given value. | |
| 78 | */ | |
| 79 | DefinitionTreeItem<String> findLeafContains( String text ); | |
| 80 | ||
| 81 | /** | |
| 82 | * Finds the definition that contains the given text, ignoring case. | |
| 83 | * | |
| 84 | * @param text The value to find, never {@code null}. | |
| 85 | * @return The leaf that contains the given value, regardless of case. | |
| 86 | */ | |
| 87 | DefinitionTreeItem<String> findLeafContainsNoCase( String text ); | |
| 88 | ||
| 89 | /** | |
| 90 | * Answers whether there are any definitions written. | |
| 91 | * | |
| 92 | * @return {@code true} when there are no definitions. | |
| 93 | */ | |
| 94 | boolean isEmpty(); | |
| 95 | } | |
| 1 | 96 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.editors; | |
| 1 | 3 | |
| 4 | import com.keenwrite.Caret; | |
| 5 | import javafx.scene.control.IndexRange; | |
| 6 | import org.fxmisc.flowless.VirtualizedScrollPane; | |
| 7 | import org.fx |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.editors; | |
| 1 | 3 | |
| 4 | import com.keenwrite.io.MediaType; | |
| 5 | import javafx.beans.property.ReadOnlyBooleanProperty; | |
| 6 | import javafx.scene.Node; | |
| 7 | import org.mozilla.universalchaevents.StatusEvent |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.editors.definition; | |
| 1 | 3 | |
| 4 | import com.keenwrite.Constants; | |
| 5 | import com.keenwrite.editors.TextDefinition; | |
| 6 | import com.keenwrite.sigils.Tokens; | |
| 7 | import com.keenwrite.uACTION_PREFIXConstantsConstants.ACTION_PREFIX + "ACTION_PREFIX + "ACTION_PREFIX + "ACTION_PREFIX + " |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.editorsfinal String text, | |
| 3 | ||
| 4 | new TreeItemMapper().toPath( getParent()Answers whether there are any definitions in this tree{@code true} when there are no definitions in the tree; {@code | |
| 5 | * false} when there is at least one definition present. | |
| 6 | */ | |
| 7 | public boolean isEmpty() { | |
| 8 | return getChildren().isEmpty(); | |
| 9 | } | |
| 10 | } | |
| 1 | 11 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.editors.definition; | |
| 3 | ||
| 4 | import javafx.scene.control.TreeItem; | |
| 5 | import javafx.scene.control.TreeView; | |
| 6 | ||
| 7 | /** | |
| 8 | * Marker interface for top-most {@link TreeItem}. This class allows the | |
| 9 | * {@link TreeItemMapper} to ignore the topmost definition. Such contortions | |
| 10 | * are necessary because {@link TreeView} requires a root item that isn't part | |
| 11 | * of the user's definition file. | |
| 12 | * <p> | |
| 13 | * Another approach would be to associate object pairs per {@link TreeItem}, | |
| 14 | * but that would be a waste of memory since the only "exception" case is | |
| 15 | * the root {@link TreeItem}. | |
| 16 | * </p> | |
| 17 | * | |
| 18 | * @param <T> The type of {@link TreeItem} to store in the {@link TreeView}. | |
| 19 | */ | |
| 20 | public final class RootTreeItem<T> extends DefinitionTreeItem<T> { | |
| 21 | /** | |
| 22 | * Default constructor, calls the superclass, no other behaviour. | |
| 23 | * | |
| 24 | * @param value The {@link TreeItem} node name to construct the superclass. | |
| 25 | * @see TreeItemMapper#toMap(TreeItem) for details on how this | |
| 26 | * class is used. | |
| 27 | */ | |
| 28 | public RootTreeItem( final T value ) { | |
| 29 | super( value ); | |
| 30 | } | |
| 31 | } | |
| 1 | 32 |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.editorskeenwrite.preview.HtmlPreviewfinal |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.editors.definition; | |
| 3 | ||
| 4 | import javafx.scene.control.TreeItem; | |
| 1 | 5 | |
| 6 | /** | |
| 7 | * |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | ||
| 3 | /** | |
| 4 | * This package contains classes that pertain to hierarchical, structured | |
| 5 | * data formats, which can be used as interpolated variables. | |
| 6 | */ | |
| 7 | package com.keenwrite.editors.definition; | |
| 1 | 8 |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.editorsObjectMapperkeenwrite.events.StatusEvent.clueclue( ex ); |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | ||
| 3 | /** | |
| 4 | * This package contains classes that can parse YAML documents into a GUI | |
| 5 | * representation. | |
| 6 | */ | |
| 7 | package com.keenwrite.editors.def.yaml; | |
| 1 | 8 |
| 1 | ||
| 1 | /* Copyright 2020-2021 -- All rights reserved. */ | |
| 2 | package com.keenwrite, url, and titlefinal |
| 1 | ||
| 1 | /* | |
| 2 | * Copyright 2020-2021 White Magic Software, Ltd. | |
| 3 | * | |
| 4 | * All rights reserved. | |
| 5 | * | |
| 6 | * Redistribution and use in source and binary forms, with or without | |
| 7 | * modification, are permitted provided that the following conditions are met: | |
| 8 | * | |
| 9 | * o Redfinal |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.editors.markdown; | |
| 3 | ||
| 4 | import com.keenwrite.ConstantsdTextEditor; | |
| 5 | import com.keenwrite.spelling.impl.TextEditorSpellerMessages.get.fireTextEditorFocusWorkspaceCONTROL_DOWNSHIFT_DOWNthis( DOCUMENT_DEFAULT, workspace ); | |
| 6 | }Spellchecker( mTextAreaathefireTextEditorFocusSpellcheckerareaspeller = new TextEditorSpeller(); | |
| 7 | speller.checkDocument( textarea ); | |
| 8 | speller.checkParagraphs( textarea ); | |
| 9 | } | |
| 10 | ||
| 11 | privaINSERT ), this::onInsertPressed( event )Editor, editorTODO: 105 - Insert key toggle overwrite (typeover) mode | |
| 12 | * | |
| 13 | * @param ignored Unused. | |
| 14 | */ | |
| 15 | private void onInsertPressed( ( l )( l )ge} | |
| 1 | 16 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.events; | |
| 3 | ||
| 4 | import static com.keenwrite. | |
| 5 | /** | |
| 6 | * Marker interface for all application events. | |
| 7 | */ | |
| 8 | public interface AppEvent {default} | |
| 1 | 9 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.events; | |
| 3 | ||
| 4 | import org.greenrobot.eventbus.EventBus; | |
| 1 | 5 | |
| 6 | /** | |
| 7 | * Responsible for delegating interactions to the event bus library. This | |
| 8 | * class decouples the rest | |
| 9 | .builder().logNoSubscriberMessages( false ).installDefaultEventBus |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.events; | |
| 3 | ||
| 4 | import com.keenwrite.ui.outline.DocumentOutline; | |
| 5 | ||
| 6 | /** | |
| 7 | * Collates information about a caret event, which is typically triggered when | |
| 8 | * the user double-clicks in the {@link DocumentOutline}. | |
| 9 | */ | |
| 10 | public class CaretNavigationEvent implements AppEvent { | |
| 11 | /** | |
| 12 | * Absolute document offset. | |
| 13 | */ | |
| 14 | private final int mOffset; | |
| 15 | ||
| 16 | private CaretNavigationEvent( final int offset ) { | |
| 17 | mOffset = offset; | |
| 18 | } | |
| 19 | ||
| 20 | /** | |
| 21 | * Publishes an event that requests moving the caret to the given offset. | |
| 22 | * | |
| 23 | * @param offset Move the caret to this document offset. | |
| 24 | */ | |
| 25 | public static void fireCaretNavigationEvent( final int offset ) { | |
| 26 | new CaretNavigationEvent( offset ).fire(); | |
| 27 | } | |
| 28 | ||
| 29 | public int getOffset() { | |
| 30 | return mOffset; | |
| 31 | } | |
| 32 | } | |
| 1 | 33 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.events; | |
| 3 | ||
| 4 | import org.jsoup.nodes.Document; | |
| 5 | ||
| 6 | import static com.keenwrite.util.MurmurHash.hash32; | |
| 7 | import static java.lang.System.currentTimeMillis; | |
| 8 | ||
| 9 | /** | |
| 10 | * Collates information about an HTML document that has changed. | |
| 11 | */ | |
| 12 | public class DocumentChangedEvent implements AppEvent { | |
| 13 | private static final int SEED = (int) currentTimeMillis(); | |
| 14 | ||
| 15 | private final String mText; | |
| 16 | ||
| 17 | /** | |
| 18 | * Hash the document so subscribers are only informed upon changes. | |
| 19 | */ | |
| 20 | private static int sHash; | |
| 21 | ||
| 22 | /** | |
| 23 | * Creates an event with the new plain text document, having all variables | |
| 24 | * substituted and all markup removed. | |
| 25 | * | |
| 26 | * @param text The document text that has changed since the last time this | |
| 27 | * type of event was fired. | |
| 28 | */ | |
| 29 | private DocumentChangedEvent( final String text ) { | |
| 30 | mText = text; | |
| 31 | } | |
| 32 | ||
| 33 | /** | |
| 34 | * When the given document may have changed. This will only fire a change | |
| 35 | * event if the given document has changed from the last time this | |
| 36 | * event was fired. The document is first converted to plain text before | |
| 37 | * the comparison is made. | |
| 38 | * | |
| 39 | * @param html The document that may have changed. | |
| 40 | */ | |
| 41 | public static void fireDocumentChangedEvent( final Document html ) { | |
| 42 | final var text = html.wholeText(); | |
| 43 | final var hash = hash32( text, 0, text.length(), SEED ); | |
| 44 | ||
| 45 | if( hash != sHash ) { | |
| 46 | sHash = hash; | |
| 47 | new DocumentChangedEvent( text ).fire(); | |
| 48 | } | |
| 49 | } | |
| 50 | ||
| 51 | /** | |
| 52 | * Returns the text that has changed. | |
| 53 | * | |
| 54 | * @return The new document text. | |
| 55 | */ | |
| 56 | public String getDocument() { | |
| 57 | return mText; | |
| 58 | } | |
| 59 | ||
| 60 | /** | |
| 61 | * Returns the document. | |
| 62 | * | |
| 63 | * @return The value from {@link #getDocument()}. | |
| 64 | */ | |
| 65 | @Override | |
| 66 | public String toString() { | |
| 67 | return getDocument(); | |
| 68 | } | |
| 69 | } | |
| 1 | 70 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.events; | |
| 3 | ||
| 4 | import com.keenwrite.preview.HtmlPanel; | |
| 5 | ||
| 6 | import java.net.URI; | |
| 7 | ||
| 8 | /** | |
| 9 | * Collates information about a file requested to be opened. This can be called | |
| 10 | * when the user clicks a hyperlink in the {@link HtmlPanel}. | |
| 11 | */ | |
| 12 | public class FileOpenEvent implements AppEvent { | |
| 13 | private final URI mUri; | |
| 14 | ||
| 15 | private FileOpenEvent( final URI uri ) { | |
| 16 | assert uri != null; | |
| 17 | mUri = uri; | |
| 18 | } | |
| 19 | ||
| 20 | /** | |
| 21 | * Fires a new file open event using the given {@link URI} instance. | |
| 22 | * | |
| 23 | * @param uri The instance of {@link URI} to open as a file in a text editor. | |
| 24 | */ | |
| 25 | public static void fireFileOpenEvent( final URI uri ) { | |
| 26 | new FileOpenEvent( uri ).fire(); | |
| 27 | } | |
| 28 | ||
| 29 | /** | |
| 30 | * Returns the requested file name to be opened. | |
| 31 | * | |
| 32 | * @return A file reference that can be opened in a text editor. | |
| 33 | */ | |
| 34 | public URI getUri() { | |
| 35 | return mUri; | |
| 36 | } | |
| 37 | } | |
| 1 | 38 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.events; | |
| 3 | ||
| 4 | /** | |
| 5 | * Collates information about an object that has gained focus. This is typically | |
| 6 | * used by text resource editors (such as text editors and definition editors). | |
| 7 | */ | |
| 8 | public class FocusEvent<T> implements AppEvent { | |
| 9 | private final T mNode; | |
| 10 | ||
| 11 | protected FocusEvent( final T node ) { | |
| 12 | mNode = node; | |
| 13 | } | |
| 14 | ||
| 15 | /** | |
| 16 | * This method is used to help update the UI whenever a component has gained | |
| 17 | * input focus. | |
| 18 | * | |
| 19 | * @return The object that has gained focus. | |
| 20 | */ | |
| 21 | public T get() { | |
| 22 | return mNode; | |
| 23 | } | |
| 24 | } | |
| 1 | 25 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.events; | |
| 3 | ||
| 4 | import com.keenwrite.processors.Processor; | |
| 5 | ||
| 6 | /** | |
| 7 | * Collates information about a document heading that has been parsed, after | |
| 8 | * all pertinent {@link Processor}s applied. | |
| 9 | */ | |
| 10 | public class ParseHeadingEvent implements AppEvent { | |
| 11 | private static final int NEW_OUTLINE_LEVEL = 0; | |
| 12 | ||
| 13 | /** | |
| 14 | * The heading text, which may be {@code null} upon creating a new outline. | |
| 15 | */ | |
| 16 | private final String mText; | |
| 17 | ||
| 18 | /** | |
| 19 | * The heading level, which will be set to {@link #NEW_OUTLINE_LEVEL} if this | |
| 20 | * event indicates that the existing outline should be cleared anew. | |
| 21 | */ | |
| 22 | private final int mLevel; | |
| 23 | ||
| 24 | /** | |
| 25 | * Offset into the text where the heading is found. | |
| 26 | */ | |
| 27 | private final int mOffset; | |
| 28 | ||
| 29 | private ParseHeadingEvent( | |
| 30 | final int level, final String text, final int offset ) { | |
| 31 | mText = text; | |
| 32 | mLevel = level; | |
| 33 | mOffset = offset; | |
| 34 | } | |
| 35 | ||
| 36 | /** | |
| 37 | * Call to indicate a new outline is to be created. | |
| 38 | */ | |
| 39 | public static void fireNewOutlineEvent() { | |
| 40 | new ParseHeadingEvent( NEW_OUTLINE_LEVEL, "Document", 0 ).fire(); | |
| 41 | } | |
| 42 | ||
| 43 | /** | |
| 44 | * Call to indicate that a new heading must be added to the document outline. | |
| 45 | * | |
| 46 | * @param text The heading text (parsed and processed). | |
| 47 | * @param level A value between 1 and 6. | |
| 48 | * @param offset Absolute offset into document where heading is found. | |
| 49 | */ | |
| 50 | public static void fireNewHeadingEvent( | |
| 51 | final int level, final String text, final int offset ) { | |
| 52 | assert text != null; | |
| 53 | assert 1 <= level && level <= 6; | |
| 54 | assert 0 <= offset; | |
| 55 | new ParseHeadingEvent( level, text, offset ).fire(); | |
| 56 | } | |
| 57 | ||
| 58 | public boolean isNewOutline() { | |
| 59 | return getLevel() == NEW_OUTLINE_LEVEL; | |
| 60 | } | |
| 61 | ||
| 62 | public int getLevel() { | |
| 63 | return mLevel; | |
| 64 | } | |
| 65 | ||
| 66 | /** | |
| 67 | * Returns the text description for the heading. | |
| 68 | * | |
| 69 | * @return The post-parsed and processed heading text from the document. | |
| 70 | */ | |
| 71 | public String getText() { | |
| 72 | return mText; | |
| 73 | } | |
| 74 | ||
| 75 | /** | |
| 76 | * Returns an offset into the document where the heading is found. | |
| 77 | * | |
| 78 | * @return A zero-based document offset. | |
| 79 | */ | |
| 80 | public int getOffset() { | |
| 81 | return mOffset; | |
| 82 | } | |
| 83 | ||
| 84 | @Override | |
| 85 | public String toString() { | |
| 86 | return getText(); | |
| 87 | } | |
| 88 | } | |
| 1 | 89 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.events; | |
| 3 | ||
| 4 | import com.keenwrite.MainApp; | |
| 5 | ||
| 6 | import java.util.stream.Collectors; | |
| 1 | 7 | |
| 8 | import static com.keenwrite.flexmark |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.events; | |
| 3 | ||
| 4 | import com.keenwrite.editors.TextDefinition; | |
| 1 | 5 | |
| 6 | public class TextDefinitionDefinition> { | |
| 7 | protected TextDefinitionDefinitionDefinition} editor | |
| 8 | * subscribers may perform an actionDefinitionFocus( final TextDefinition editor ) { | |
| 9 | new TextDefinition |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.events; | |
| 3 | ||
| 4 | import com.keenwrite.editors.TextEditor; | |
| 5 | ||
| 6 | TextEditorFocusfire(); | |
| 7 | } | |
| 8 | } | |
| 1 | 9 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.events; | |
| 3 | ||
| 4 | /** | |
| 5 | * Collates information about the word count changing. | |
| 6 | */ | |
| 7 | public class WordCountEvent implements AppEvent { | |
| 8 | /** | |
| 9 | * Number of words in the document. | |
| 10 | */ | |
| 11 | private final int mCount; | |
| 12 | ||
| 13 | private WordCountEvent( final int count ) { | |
| 14 | mCount = count; | |
| 15 | } | |
| 16 | ||
| 17 | /** | |
| 18 | * Publishes an event that indicates the number of words in the document. | |
| 19 | * | |
| 20 | * @param count The approximate number of words in the document. | |
| 21 | */ | |
| 22 | public static void fireWordCountEvent( final int count ) { | |
| 23 | new WordCountEvent( count ).fire(); | |
| 24 | } | |
| 25 | ||
| 26 | public int getCount() { | |
| 27 | return mCount; | |
| 28 | } | |
| 29 | } | |
| 1 | 30 |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved.final |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | ||
| 3 | /** | |
| 4 | * This package contains classes to help with word count. In logographic, | |
| 5 | * or other non-alphabetic languages, word tokenization cannot rely on | |
| 6 | * spaces. Instead, we need to employ a more sophisticated approach using | |
| 7 | * natural language parsing (NLP). | |
| 8 | */ | |
| 9 | package com.keenwrite.heuristics; | |
| 1 | 10 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.io; | |
| 3 | ||
| 4 | import java.io.File; | |
| 5 | import java.util.EventObject; | |
| 6 | ||
| 7 | /** | |
| 8 | * Responsible for indicating that a file has been modified by the file system. | |
| 9 | */ | |
| 10 | public class FileEvent extends EventObject { | |
| 11 | ||
| 12 | /** | |
| 13 | * Constructs a new event that indicates the source of a file system event. | |
| 14 | * | |
| 15 | * @param file The {@link File} that has succumb to a file system event. | |
| 16 | */ | |
| 17 | public FileEvent( final File file ) { | |
| 18 | super( file ); | |
| 19 | } | |
| 20 | ||
| 21 | /** | |
| 22 | * Returns the source as an instance of {@link File}. | |
| 23 | * | |
| 24 | * @return The {@link File} being watched. | |
| 25 | */ | |
| 26 | public File getFile() { | |
| 27 | return (File) getSource(); | |
| 28 | } | |
| 29 | } | |
| 1 | 30 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.io; | |
| 3 | ||
| 4 | import java.util.EventListener; | |
| 5 | import java.util.function.Consumer; | |
| 6 | ||
| 7 | /** | |
| 8 | * Responsible for informing listeners when a file has been modified. | |
| 9 | */ | |
| 10 | public interface FileModifiedListener | |
| 11 | extends EventListener, Consumer<FileEvent> { | |
| 12 | } | |
| 1 | 13 |
| 1 | ||
| 1 | /* Copyright 2020-2021 -- All rights reserved. */ | |
| 2 | package com.keenwrite.io {@code | |
| 3 | * settings.properties} |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.io; | |
| 3 | ||
| 4 | import org.renjin.repackaged.guava.collect.BiMap; | |
| 5 | import org.renjin.repackaged.guava.collect.HashBiMap; | |
| 6 | ||
| 7 | import java.io.File; | |
| 8 | import java.io.IOExceptioFileSystems.getDefault;mWatchService = createtry { | |
| 9 | private WatchService createWatchService() { | |
| 10 | try { | |
| 11 | return return } | |
| 12 | } | |
| 1 | 13 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.io; | |
| 3 | ||
| 4 | import java.net.MalformedURLException; | |
| 5 | import java.net.URI; | |
| 6 | import java.net.URL; | |
| 7 | import java.net.http.HttpClient; | |
| 8 | import java.net.http.HttpRequest; | |
| 1 | 9 | |
| 10 | im |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.io; | |
| 3 | ||
| 4 | import java.io.File; | |
| 5 | import java.nio.file.Path; | |
| 1 | 6 | |
| 7 | import static com.keenwrite.io.MediaType.TypeName.*; | |
| 8 | import static com.kee |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.io; | |
| 3 | ||
| 4 | import java.util.Set; | |
| 5 | ||
| 6 | import static com.keenwrite.io.MediaType.*; | |
| 7 | import static java.util.Set.of; | |
| 1 | 8 | |
| 9 | /** | |
| 10 | * Responsible for associating file extensions with |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.io; | |
| 3 | ||
| 4 | import java.nio.file.WatchEvent; | |
| 5 | import java.nio.file.WatchKey; | |
| 6 | import java.nio.file.WatchService; | |
| 7 | import java.nio.file.Watchable; | |
| 8 | import java.util.List; | |
| 9 | import java.util.concurrent.TimeUnit; | |
| 10 | ||
| 11 | /** | |
| 12 | * Responsible for polling the file system to see whether a file has been | |
| 13 | * updated. This is instantiated when an instance of {@link WatchService} | |
| 14 | * cannot be created using the Java API. | |
| 15 | * <p> | |
| 16 | * This is a skeleton class to avoid {@code null} references. In theory, | |
| 17 | * it should never get instantiated. If the application is run on a system | |
| 18 | * that does not support file system events, this should eliminate NPEs. | |
| 19 | * </p> | |
| 20 | */ | |
| 21 | public class PollingWatchService implements WatchService { | |
| 22 | private final WatchKey EMPTY_KEY = new WatchKey() { | |
| 23 | private final Watchable WATCHABLE = new Watchable() { | |
| 24 | @Override | |
| 25 | public WatchKey register( | |
| 26 | final WatchService watcher, | |
| 27 | final WatchEvent.Kind<?>[] events, | |
| 28 | final WatchEvent.Modifier... modifiers ) { | |
| 29 | return EMPTY_KEY; | |
| 30 | } | |
| 31 | ||
| 32 | @Override | |
| 33 | public WatchKey register( | |
| 34 | final WatchService watcher, final WatchEvent.Kind<?>... events ) { | |
| 35 | return EMPTY_KEY; | |
| 36 | } | |
| 37 | }; | |
| 38 | ||
| 39 | @Override | |
| 40 | public boolean isValid() { | |
| 41 | return false; | |
| 42 | } | |
| 43 | ||
| 44 | @Override | |
| 45 | public List<WatchEvent<?>> pollEvents() { | |
| 46 | return List.of(); | |
| 47 | } | |
| 48 | ||
| 49 | @Override | |
| 50 | public boolean reset() { | |
| 51 | return false; | |
| 52 | } | |
| 53 | ||
| 54 | @Override | |
| 55 | public void cancel() { | |
| 56 | } | |
| 57 | ||
| 58 | @Override | |
| 59 | public Watchable watchable() { | |
| 60 | return WATCHABLE; | |
| 61 | } | |
| 62 | }; | |
| 63 | ||
| 64 | @Override | |
| 65 | public void close() { | |
| 66 | } | |
| 67 | ||
| 68 | @Override | |
| 69 | public WatchKey poll() { | |
| 70 | return EMPTY_KEY; | |
| 71 | } | |
| 72 | ||
| 73 | @Override | |
| 74 | public WatchKey poll( final long timeout, final TimeUnit unit ) { | |
| 75 | return EMPTY_KEY; | |
| 76 | } | |
| 77 | ||
| 78 | @Override | |
| 79 | public WatchKey take() { | |
| 80 | return EMPTY_KEY; | |
| 81 | } | |
| 82 | } | |
| 1 | 83 |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved.final |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.preferences; | |
| 3 | ||
| 4 | import javafx.beans.property.SimpleObjectProperty; | |
| 5 | ||
| 6 | import java.io.File; | |
| 1 | 7 | |
| 8 | public final class FileProperty extends SimpleObjectProperty<File |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.preferences; | |
| 3 | ||
| 4 | /** | |
| 5 | * Responsible for creating a type hierarchy of preference storage keys. | |
| 6 | */ | |
| 7 | public class Key { | |
| 8 | private final Key mParent; | |
| 9 | private final String mName; | |
| 10 | ||
| 11 | private Key( final Key parent, final String name ) { | |
| 12 | mParent = parent; | |
| 13 | mName = name; | |
| 14 | } | |
| 15 | ||
| 16 | /** | |
| 17 | * Returns a new key with no parent. | |
| 18 | * | |
| 19 | * @param name The key name, never {@code null}. | |
| 20 | * @return The new {@link Key} instance with a name but no parent. | |
| 21 | */ | |
| 22 | public static Key key( final String name ) { | |
| 23 | assert name != null && !name.isEmpty(); | |
| 24 | return key( null, name ); | |
| 25 | } | |
| 26 | ||
| 27 | /** | |
| 28 | * Returns a new key with a given parent. | |
| 29 | * | |
| 30 | * @param parent The parent of this {@link Key}, or {@code null} if this is | |
| 31 | * the topmost key in the chain. | |
| 32 | * @param name The key name, never {@code null}. | |
| 33 | * @return The new {@link Key} instance with a name and parent. | |
| 34 | */ | |
| 35 | public static Key key( final Key parent, final String name ) { | |
| 36 | assert name != null && !name.isEmpty(); | |
| 37 | return new Key( parent, name ); | |
| 38 | } | |
| 39 | ||
| 40 | private Key parent() { | |
| 41 | return mParent; | |
| 42 | } | |
| 43 | ||
| 44 | private String name() { | |
| 45 | return mName; | |
| 46 | } | |
| 47 | ||
| 48 | /** | |
| 49 | * Returns a dot-separated path representing the key's name. | |
| 50 | * | |
| 51 | * @return The recursively derived dot-separated key name. | |
| 52 | */ | |
| 53 | @Override | |
| 54 | public String toString() { | |
| 55 | return parent() == null ? name() : parent().toString() + '.' + name(); | |
| 56 | } | |
| 57 | } | |
| 1 | 58 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.preferences; | |
| 3 | ||
| 4 | import javafx.beans.property.SimpleObjectProperty; | |
| 5 | import javafx.collections.ObservableList; | |
| 1 | 6 | |
| 7 | impo/** | |
| 8 | * Responsible for providing a list of locales from which the user may pick. | |
| 9 | */// If the language is "und"efined then use the default locale. |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.preferences; | |
| 3 | ||
| 4 | import java.util.Collections; | |
| 5 | import java.util.HashMap; | |
| 6 | import java.util.Locale; | |
| 7 | import java.util.Map; | |
| 8 | ||
| 9 | import static java.util.Arrays.asList; | |
| 10 | ||
| 11 | /** | |
| 12 | * Responsible for adding an ISO 15924 alpha-4 script code to {@link Locale} | |
| 13 | * instances. This allows all {@link Locale} objects to produce language tags | |
| 14 | * using the same format. | |
| 15 | */ | |
| 16 | public final class LocaleScripts { | |
| 17 | /** | |
| 18 | * ISO 15924 alpha-4 script code to represent Latin scripts. | |
| 19 | */ | |
| 20 | private static final String SCRIPT_LATIN = "Latn"; | |
| 21 | ||
| 22 | /** | |
| 23 | * This value is returned when a script hasn't been mapped for an instance of | |
| 24 | * {@link Locale}. | |
| 25 | */ | |
| 26 | private static final Map<String, String> SCRIPT_DEFAULT = m( SCRIPT_LATIN ); | |
| 27 | ||
| 28 | private static final Map<String, Map<String, String>> SCRIPTS = | |
| 29 | new HashMap<>(); | |
| 30 | ||
| 31 | static { | |
| 32 | put( "en", m( "Latn" ) ); | |
| 33 | put( "jp", m( "Jpan" ) ); | |
| 34 | put( "ko", m( "Kore" ) ); | |
| 35 | put( "zh", m( "Hant" ), m( "Hans", "CN", "MN", "MY", "SG" ) ); | |
| 36 | } | |
| 37 | ||
| 38 | /** | |
| 39 | * Adds a script to a given {@link Locale} object. If the given {@link Locale} | |
| 40 | * already has a script, then it is returned unchanged. | |
| 41 | * | |
| 42 | * @param locale The {@link Locale} to update with its associated script. | |
| 43 | * @return The given {@link Locale} with a script included. | |
| 44 | */ | |
| 45 | public static Locale withScript( Locale locale ) { | |
| 46 | assert locale != null; | |
| 47 | ||
| 48 | final var script = locale.getScript(); | |
| 49 | ||
| 50 | if( script == null || script.isBlank() ) { | |
| 51 | final var builder = new Locale.Builder(); | |
| 52 | builder.setLocale( locale ); | |
| 53 | builder.setScript( getScript( locale ) ); | |
| 54 | locale = builder.build(); | |
| 55 | } | |
| 56 | ||
| 57 | return locale; | |
| 58 | } | |
| 59 | ||
| 60 | @SafeVarargs | |
| 61 | private static void put( | |
| 62 | final String language, final Map<String, String>... scripts ) { | |
| 63 | final var merged = new HashMap<String, String>(); | |
| 64 | asList( scripts ).forEach( merged::putAll ); | |
| 65 | SCRIPTS.put( language, merged ); | |
| 66 | } | |
| 67 | ||
| 68 | /** | |
| 69 | * Returns the ISO 15924 alpha-4 script code for the given {@link Locale}. | |
| 70 | * | |
| 71 | * @param locale Language and country are used to find the script code. | |
| 72 | * @return The ISO code for the given locale, or {@link #SCRIPT_LATIN} if | |
| 73 | * no code has been mapped yet. | |
| 74 | */ | |
| 75 | private static String getScript( final Locale locale ) { | |
| 76 | return SCRIPTS.getOrDefault( locale.getLanguage(), SCRIPT_DEFAULT ) | |
| 77 | .getOrDefault( locale.getCountry(), SCRIPT_LATIN ); | |
| 78 | } | |
| 79 | ||
| 80 | /** | |
| 81 | * Helper method to instantiate a new {@link Map} having all keys referencing | |
| 82 | * the same value. | |
| 83 | * | |
| 84 | * @param v The value to associate with each key. | |
| 85 | * @param k The keys to associate with the given value. | |
| 86 | * @return A new {@link Map} with all keys referencing the same value. | |
| 87 | */ | |
| 88 | private static Map<String, String> m( final String v, final String... k ) { | |
| 89 | final var map = new HashMap<String, String>(); | |
| 90 | asList( k ).forEach( ( key ) -> map.put( key, v ) ); | |
| 91 | return Collections.unmodifiableMap( map ); | |
| 92 | } | |
| 93 | ||
| 94 | /** | |
| 95 | * Helper method to instantiate a new {@link Map} having an empty key | |
| 96 | * referencing the given value. This provides a default value so that | |
| 97 | * an unmapped country code can return a valid script code. | |
| 98 | * | |
| 99 | * @param v The value to associate with an empty key. | |
| 100 | * @return A new {@link Map} with the empty key referencing the given value. | |
| 101 | */ | |
| 102 | private static Map<String, String> m( final String v ) { | |
| 103 | return m( v, "" ); | |
| 104 | } | |
| 105 | } | |
| 1 | 106 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.preferences; | |
| 1 | 3 | |
| 4 | import com.dlsc.formsfx.model.structure.StringField; | |
| 5 | import com.dlsc.preferencesfx.PreferencesFx; | |
| 6 | import com.dlsc.preferencesfx.CUSTOMUI_THEME_CUSTOMCUSTOMUI_THEME_CUSTOM ), false |
| 1 | /* Copyright 2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.preferences; | |
| 1 | 3 | |
| 4 | import com.dlsc.formsfx.model.structure.StringField; | |
| 5 | import com.dlsc.preferencesfx.formsfx.view.controls.SimpleControl; | |
| 6 | import javafx.beans.propertevents.StatusEvent |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.preferences; | |
| 3 | ||
| 4 | import com.keenwrite.Constants; | |
| 5 | import javafx.beans.property.SimpleObjectProperty; | |
| 6 | import javafx.collections.ObservableList; | |
| 1 | 7 | |
| 8 | importCount DarculaSolarized Dark |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.preferences; | |
| 1 | 3 | |
| 4 | import com.keenwrite.Constants; | |
| 5 | import com.keenwrite.sigils.Tokens; | |
| 6 | import javafx.application.Platform; | |
| 7 | import javafx.beans.property | |
| 8 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.preferences; | |
| 3 | ||
| 4 | import static com.keenwrite.preferences.Key.key; | |
| 1 | 5 | |
| 6 | /** | |
| 7 | * Responsible for defining constants used throughout the application that | |
| 8 | * represent |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.preferences; | |
| 3 | ||
| 4 | import com.dlsc.preferencesfx.PreferencesFx; | |
| 5 | import com.dlsc.preferencesfx.util.StorageHandler; | |
| 6 | import javafx.collections.ObservableList; | |
| 1 | 7 | |
| 8 | impfinal |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved.final |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.preview; | |
| 3 | ||
| 4 | import org.jsoup.helper.W3CDom; | |
| 5 | import org.jsoup.nodeOMImplementationx.xml.parsers.DocumentBuilder; | |
| 6 | import javax.xml.parsers.DocumentBuilderFactory;events.StatusEvent.cluefinal class Domnew LinkedHashMap<>(); | |
| 7 | ||
| 8 | static { | |
| 9 | LIGATURES.put( "ffi", "\uFB03" ); | |
| 10 | LIGATURES.put( "ffl", "\uFB04" ); | |
| 11 | LIGATURES.put( "ff", "\uFB00" ); | |
| 12 | LIGATURES.put( "fi", "\uFB01" ); | |
| 13 | LIGATURES.put( "fl", "\uFB02" ); | |
| 14 | } | |
| 15 | T | |
| 16 | if( !("pre) ) { | |
| 17 | // Calling getWholeText()final var textNode = (TextNode) node; | |
| 18 | } | |
| 19 | }; | |
| 20 | DocumentBuilderFactory DOCUMENT_FACTORY; | |
| 21 | private static DocumentBuilder DOCUMENT_BUILDER; | |
| 22 | private static DOMImplementation DOM_IMPL; | |
| 23 | ||
| 24 | static { | |
| 25 | DOCUMENT_FACTORY = DocumentBuilderFactory.newInstance(); | |
| 26 | DOCUMENT_FACTORY.setNamespaceAware( true ); | |
| 27 | ||
| 28 | try { | |
| 29 | DOCUMENT_BUILDER = DOCUMENT_FACTORY.newDocumentBuilder(); | |
| 30 | DOM_IMPL = DOCUMENT_BUILDER.getDOMImplementation(); | |
| 31 | } catch( final Exception ex ) { | |
| 32 | clue( ex ); | |
| 33 | } | |
| 34 | } | |
| 35 | ||
| 36 | @Override | |
| 37 | public assert DOCUMENT_BUILDER != null; | |
| 38 | assert DOM_IMPLOCUMENT_BUILDER.newDocument(); | |
| 39 | final org.jsoup.nodeTypeDOM_IMPL} | |
| 1 | 40 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.preview; | |
| 1 | 3 | |
| 4 | import com.keenwrite.ui.adapters.DocumentAdapter; | |
| 5 | impor |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.preview; | |
| 1 | 3 | |
| 4 | import com.keenwrite.LocaleProperty; | |
| 5 | import com.keetoPixels( getFontSize() |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved.events.StatusEvent |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwritefinal |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved.ignored |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.preview; | |
| 1 | 3 | |
| 4 | import com.keenwrite.io.HttpMediaType; | |
| 5 | import; | |
| 6 | import com.keenwrite.ui.adapters.ReplacedElementAdapter; | |
| 7 | import org.w3c.dom.Element; | |
| 8 | import org.xhtevents.StatusEvent |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors; | |
| 3 | ||
| 4 | import java.util.Map; | |
| 5 | ||
| 6 | import static com.keenwrite.processors.text.TextReplacementFactory.replace; | |
| 7 | ||
| 8 | /** | |
| 9 | * Processes interpolated string definitions in the document and inserts | |
| 10 | * their values into the post-processed text. The default variable syntax is | |
| 11 | * {@code $variable$}. | |
| 12 | */ | |
| 13 | public class DefinitionProcessor extends ExecutorProcessor<String> { | |
| 14 | ||
| 15 | private final Map<String, String> mDefinitions; | |
| 16 | ||
| 17 | /** | |
| 18 | * Constructs a processor capable of interpolating string definitions. | |
| 19 | * | |
| 20 | * @param successor Subsequent link in the processing chain. | |
| 21 | * @param context Contains resolved definitions map. | |
| 22 | */ | |
| 23 | public DefinitionProcessor( | |
| 24 | final Processor<String> successor, | |
| 25 | final ProcessorContext context ) { | |
| 26 | super( successor ); | |
| 27 | mDefinitions = context.getResolvedMap(); | |
| 28 | } | |
| 29 | ||
| 30 | /** | |
| 31 | * Processes the given text document by replacing variables with their values. | |
| 32 | * | |
| 33 | * @param text The document text that includes variables that should be | |
| 34 | * replaced with values when rendered as HTML. | |
| 35 | * @return The text with all variables replaced. | |
| 36 | */ | |
| 37 | @Override | |
| 38 | public String apply( final String text ) { | |
| 39 | return replace( text, getDefinitions() ); | |
| 40 | } | |
| 41 | ||
| 42 | /** | |
| 43 | * Returns the map to use for variable substitution. | |
| 44 | * | |
| 45 | * @return A map of variable names to values. | |
| 46 | */ | |
| 47 | protected Map<String, String> getDefinitions() { | |
| 48 | return mDefinitions; | |
| 49 | } | |
| 50 | } | |
| 1 | 51 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors; | |
| 3 | ||
| 4 | import java.util.Optional; | |
| 5 | import java.util.concurrent.atomic.AtomicReference; | |
| 6 | ||
| 7 | import static com.keenwrite.events.StatusEvent.clue; | |
| 8 | ||
| 9 | /** | |
| 10 | * Responsible for transforming data through a variety of ctry { | |
| 11 | } catch( final Exception ex ) { | |
| 12 | clue( ex ); | |
| 13 | } | |
| 1 | 14 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors; | |
| 3 | ||
| 4 | import com.keenwrite.preview.HtmlPreview; | |
| 1 | 5 | |
| 6 | /** | |
| 7 | * Responsible for notifying the HTMLPreviewPane when the succession chain has | |
| 8 | * updated. This |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors; | |
| 3 | ||
| 4 | /** | |
| 5 | * Responsible for transforming a string into itself. This is used at the | |
| 6 | * end of a processing chain when no more processing is required. | |
| 7 | */ | |
| 8 | public final class IdentityProcessor extends ExecutorProcessor<String> { | |
| 9 | public static final IdentityProcessor IDENTITY = new IdentityProcessor(); | |
| 10 | ||
| 11 | /** | |
| 12 | * Constructs a new instance having no successor (the default successor is | |
| 13 | * {@code null}). | |
| 14 | */ | |
| 15 | private IdentityProcessor() { | |
| 16 | } | |
| 17 | ||
| 18 | /** | |
| 19 | * Returns the given string without modification. | |
| 20 | * | |
| 21 | * @param s The string to return. | |
| 22 | * @return The value of s. | |
| 23 | */ | |
| 24 | @Override | |
| 25 | public String apply( final String s ) { | |
| 26 | return s; | |
| 27 | } | |
| 28 | } | |
| 1 | 29 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors; | |
| 1 | 3 | |
| 4 | /** | |
| 5 | * This is the default processor used when an unknown file name extension is | |
| 6 | * encountered. It processes the text by enclosing it in an HTfinal |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved.ioferences.Workspacefinal |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved.ferences.Workspaceprocessor the file | |
| 2 | * |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwriteConfigurationom.IgnorableSpaceStrippingRulecom.keenwrite.events.StatusEvent.clue; | |
| 3 | import static.newInstance;final class XmlProcessor extends ExecutorProcessor<String> | |
| 4 | XMLInputFactory mXmlInputFactory = newInstance(); | |
| 5 | private final Configuration mConfiguration = new Configuration(); | |
| 6 | privatemTransformerFactory = | |
| 7 | mConfiguration); mTfinal Path mPsuccontext Contains | |
| 8 | final Processor<String> successor, | |
| 9 | final ProcessorContext context ) { | |
| 10 | super( successor ); | |
| 11 | mPath = context.getDocumentPathmTransformerF final var options = mConfiguration.getParseOptions(); | |
| 12 | options.setSpaceStrippingRule( IgnorableSpaceStrippingRule.getInstance()applyclue( ex );try( | |
| 13 | final vafinal va final var final var // TODO: Use FileWatchService// mSnitchTransformer that transforms XML documents using saidInstantiate transformer failed. | |
| 14 | */mTmTmTfinal varvar xmlDirectory = m varvafinal var reader = createXmlEventReader( sr ); | |
| 15 | varvar count = 0varvar pi = (varmlmXmlInputFactorymTclueclueforclue( ex ); | |
| 16 | } | |
| 17 | } | |
| 1 | 18 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors.markdown; | |
| 1 | 3 | |
| 4 | import com.keenwrite.processors.ExecutorProcessor; | |
| 5 | import com.keenwrite.processors.Processor; | |
| 6 | import com.keenwrite.processors.Processo |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors.markdown; | |
| 1 | 3 | |
| 4 | import com.keenwrite.io.MediaType; | |
| 5 | import com.keenwrite.processors.DefinitionProcessor; | |
| 6 | import com.keenwrite.processors.Processor; | |
| 7 | imp* |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved..extensions; | |
| 2 | ||
| 3 | import com.keenwrite.Caret; | |
| 4 | import; | |
| 5 | import com.keenwrite.processors.Processoext.tables.TableBlock.extensions.EmptyNode.EMPTY_NODEBuilderextends HtmlRendererAdapter { | |
| 6 | ||
| 7 | private final CaretProcessomCaret = context.getCaret(Processoontext ) mCaret; | |
| 8 | private boolean mAdded final Caret// Optimization: if a caret is inserted, don't try to find another. | |
| 9 | if( mAdded ) { | |
| 10 | return; | |
| 11 | } | |
| 12 | ||
| 13 | // If a table block has been earmarked with an empty node, it means | |
| 14 | // another extension has generated code from an external source. The | |
| 15 | // Markdown processor won't be able to determine the caret position | |
| 16 | // with any semblance of accuracy, so skip the element. This usually | |
| 17 | // happens with tables, but in theory any Markdown generated from an | |
| 18 | // external source (e.g., an R script) could produce text that has no | |
| 19 | // caret position that can be calculated. | |
| 20 | var table = curr; | |
| 21 | ||
| 22 | if( !(curr instanceof TableBlock) ) { | |
| 23 | table = curr.getAncestorOfType( TableBlock.class ); | |
| 24 | } | |
| 25 | ||
| 26 | // The table was generated outside the document | |
| 27 | if( table != null && table.getLastChild() == EMPTY_NODE ) { | |
| 28 | return; | |
| 29 | } | |
| 30 | ||
| 31 | final var outside = mCaret.isAfterText() ? 1 : 0; + outside // This line empowerthe | |
| 32 | // We're done until the user moves the caret (micro-optimization) | |
| 33 | mAdded = true; | |
| 34 | } | |
| 35 | } | |
| 36 | } | |
| 37 | } | |
| 1 | 38 |
| 1 | package com.keenwrite.processors.markdown.extensions; | |
| 2 | ||
| 3 | import com.keenwrite.processors.Processor; | |
| 4 | import com.vladsch.flexmark.ast.Heading; | |
| 5 | import com.vladsch.flexmark.parser.Parser.Builder; | |
| 6 | import com.vladsch.flexmark.parser.Parser.ParserExtension; | |
| 7 | import com.vladsch.flexmark.parser.block.NodePostProcessor; | |
| 8 | import com.vladsch.flexmark.parser.block.NodePostProcessorFactory; | |
| 9 | import com.vladsch.flexmark.util.ast.Document; | |
| 10 | import com.vladsch.flexmark.util.ast.Node; | |
| 11 | import com.vladsch.flexmark.util.ast.NodeTracker; | |
| 12 | import com.vladsch.flexmark.util.data.MutableDataHolder; | |
| 13 | import org.jetbrains.annotations.NotNull; | |
| 14 | ||
| 15 | import java.util.regex.Pattern; | |
| 16 | ||
| 17 | import static com.keenwrite.events.ParseHeadingEvent.fireNewHeadingEvent; | |
| 18 | import static com.keenwrite.events.ParseHeadingEvent.fireNewOutlineEvent; | |
| 19 | ||
| 20 | public final class DocumentOutlineExtension implements ParserExtension { | |
| 21 | private static final Pattern sRegex = Pattern.compile( "^(#+)" ); | |
| 22 | ||
| 23 | private final Processor<String> mProcessor; | |
| 24 | ||
| 25 | private DocumentOutlineExtension( final Processor<String> processor ) { | |
| 26 | mProcessor = processor; | |
| 27 | } | |
| 28 | ||
| 29 | @Override | |
| 30 | public void parserOptions( final MutableDataHolder options ) {} | |
| 31 | ||
| 32 | @Override | |
| 33 | public void extend( final Builder builder ) { | |
| 34 | builder.postProcessorFactory( new Factory() ); | |
| 35 | } | |
| 36 | ||
| 37 | public static DocumentOutlineExtension create( | |
| 38 | final Processor<String> processor ) { | |
| 39 | return new DocumentOutlineExtension( processor ); | |
| 40 | } | |
| 41 | ||
| 42 | private class HeadingNodePostProcessor extends NodePostProcessor { | |
| 43 | @Override | |
| 44 | public void process( | |
| 45 | @NotNull final NodeTracker state, @NotNull final Node node ) { | |
| 46 | final var heading = mProcessor.apply( node.getChars().toString() ); | |
| 47 | final var matcher = sRegex.matcher( heading ); | |
| 48 | ||
| 49 | if( matcher.find() ) { | |
| 50 | final var level = matcher.group().length(); | |
| 51 | final var text = heading.substring( level ); | |
| 52 | final var offset = node.getStartOffset(); | |
| 53 | fireNewHeadingEvent( level, text, offset ); | |
| 54 | } | |
| 55 | } | |
| 56 | } | |
| 57 | ||
| 58 | public class Factory extends NodePostProcessorFactory { | |
| 59 | public Factory() { | |
| 60 | super( false ); | |
| 61 | addNodes( Heading.class ); | |
| 62 | } | |
| 63 | ||
| 64 | @NotNull | |
| 65 | @Override | |
| 66 | public NodePostProcessor apply( @NotNull final Document document ) { | |
| 67 | fireNewOutlineEvent(); | |
| 68 | return new HeadingNodePostProcessor(); | |
| 69 | } | |
| 70 | } | |
| 71 | } | |
| 1 | 72 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors.markdown.extensions; | |
| 1 | 3 | |
| 4 | import com.vladsch.flexmark.util.ast.Node; | |
| 5 | import com.vladsch.flexmark.util.sequence.BasedSequence; | |
| 6 | import org.jetbrains. |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors.markdown.extensions; | |
| 3 | DefinitioProcessor |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors.markdown.extensions; | |
| 3 | ||
| 4 | import com.vladsch.flexmark.util.data.MutableDataHolder; | |
| 5 | import org.jetbrains.annotations.NotNull; | |
| 1 | 6 | |
| 7 | import static co |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors.markdown.extensions; | |
| 3 | ||
| 4 | import com.keenwrite.ExportFormat; | |
| 5 | import com.keenwrite.exceptions.MissingFileException; | |
| 6 | import com.keenwrite.preferences.Workspace; | |
| 7 | import com.keenwrite.processorsProcessorContext; | |
| 8 | import com.ExportFormat.NONEpreferences.WorkspaceKeys.KEY_IMAGES_DIRpreferences.WorkspaceKeys.KEY_IMAGES_ORDERimport static org.renjin.repackaged.guava.base.Splitter.onath mBaseDir; | |
| 9 | private final Workspace mWorkspace; | |
| 10 | private final ExportFormat mExportFormamBaseDir = cmWorkspace = context.getWorkspace(); | |
| 11 | mExportFormat = context.getExportFormat() ) { | |
| 12 | var uri = getProtocol( uri ); | |
| 13 | ||
| 14 | if( protocol.isRemote() ) { | |
| 15 | uri ); | |
| 16 | } | |
| 17 | // Determine the fully-qualified file name (fqfn). | |
| 18 | final var fqfn = Path.of( baseDir.toString(), uri ).toFile(); | |
| 19 | ||
| 20 | if( fqfn.isFile() && fqfn.canRead() ) { | |
| 21 | uri ); | |
| 22 | } | |
| 23 | ||
| 24 | if( mExportFormat != NONE ) { | |
| 25 | uri ); | |
| 26 | }UserImagesDir(); | |
| 27 | Dir = imagesDir.toString().isEmpty() | |
| 28 | ? imagesDir : baseDir.relativizFile = Path.of( | |
| 29 | baseDir.toString(), relativeDir.toString(), uri ); | |
| 30 | ||
| 31 | Extensions() ) { | |
| 32 | var file = new File( imageFile if( file.exists() && file.canRead() ) { | |
| 33 | uri = file.toURI().toString(); | |
| 34 | uri ); | |
| 35 | } | |
| 36 | } | |
| 37 | ||
| 38 | throw new MissingFileException( imageFile + ".*"UserImagesWorkspace.toFile( KEY_IMAGES_DIR ).toPath(Extensions() { | |
| 39 | return on( ' ' ).split( mWorkspace.toString( KEY_IMAGES_ORDER )BaseDir; | |
| 40 | } | |
| 41 | } | |
| 42 | } | |
| 1 | 43 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors.markdown.extensions.r; | |
| 1 | 3 | |
| 4 | import com.keenwrite.processors.Processor; | |
| 5 | import com.keenwrite.processors.ProcessorContext; | |
| 6 | import com.keenwrite.process |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors.markdown.extensions.r; | |
| 3 | ||
| 4 | import com.keenwrite.processors.ExecutorProcessor; | |
| 5 | import com.keenwrite.processors.r.InlineRProcessor; | |
| 6 | import com.keenwrite.processors.markdown.MarkdownProcessor; | |
| 7 | import com.keenwrite.processors.markdown.extensions.tex.TeXExtension; | |
| 8 | import com.vladsch.flexmark.ast.Paragraph; | |
| 9 | import com.vladsch.flexmark.ast.Text; | |
| 10 | import com.vladsch.flexmark.html.HtmlRenderer; | |
| 11 | import com.vladsch.flexmark.parser.Parser; | |
| 12 | import com.vladsch.flexmark.util.ast.IParse; | |
| 13 | import com.vladsch.flexmark.util.ast.IRender; | |
| 14 | ||
| 15 | /** | |
| 16 | * Responsible for parsing the output from an R eval statement. This class | |
| 17 | * is used to avoid an circular dependency whereby the {@link InlineRProcessor} | |
| 18 | * must treat the output from an R function call as Markdown, which would | |
| 19 | * otherwise require a {@link MarkdownProcessor} instance; however, the | |
| 20 | * {@link MarkdownProcessor} class gives precedence to its extensions, which | |
| 21 | * means the {@link TeXExtension} will be executed <em>before</em> the | |
| 22 | * {@link InlineRProcessor}, thereby being exposed to backticks in a TeX | |
| 23 | * macro---a syntax error. To break the cycle, the {@link InlineRProcessor} | |
| 24 | * uses this class instead of {@link MarkdownProcessor}. | |
| 25 | */ | |
| 26 | public class ROutputProcessor extends ExecutorProcessor<String> { | |
| 27 | private final IParse mParser = Parser.builder().build(); | |
| 28 | private final IRender mRenderer = HtmlRenderer.builder().build(); | |
| 29 | ||
| 30 | @Override | |
| 31 | public String apply( final String markdown ) { | |
| 32 | var node = mParser.parse( markdown ).getFirstChild(); | |
| 33 | ||
| 34 | if( node == null ) { | |
| 35 | node = new Text(); | |
| 36 | } | |
| 37 | else if( node.isOrDescendantOfType( Paragraph.class ) ) { | |
| 38 | node = new Text( node.getChars() ); | |
| 39 | } | |
| 40 | ||
| 41 | // Trimming prevents displaced commas and unwanted newlines. | |
| 42 | return mRenderer.render( node ).trim(); | |
| 43 | } | |
| 44 | } | |
| 1 | 45 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors.markdown.extensions.tex; | |
| 3 | ||
| 4 | import com.keenwrite.ExportFormat; | |
| 5 | import com.keenwrite.processors.Processor; | |
| 6 | import com.keenwrite.processors.ProcessorContext; | |
| 7 | import com.keenwrite.processors.markdown.extensions.HtmlRendererAdapter; | |
| 8 | import com.keenwrite.processors.markdown.extensions.tex.TexNodeRenderer.Factory; | |
| 9 | import com.vladsch.flexmark.html.HtmlRenderer; | |
| 10 | import com.vladsch.flexmark.parser.Parser; | |
| 11 | import com.vladsch.flexmark.util.data.MutableDataHolder; | |
| 12 | import org.jetbrains.annotations.NotNull; | |
| 13 | ||
| 14 | import static com.vladsch.flexmark.parser.Parser.ParserExtension; | |
| 15 | ||
| 16 | /** | |
| 17 | * Responsible for wrapping delimited TeX code in Markdown into an XML element | |
| 18 | * that the HTML renderer can handle. For example, {@code $E=mc^2$} becomes | |
| 19 | * {@code <tex>E=mc^2</tex>} when passed to HTML renderer. The HTML renderer | |
| 20 | * is responsible for converting the TeX code for display. This avoids inserting | |
| 21 | * SVG code into the Markdown document, which the parser would then have to | |
| 22 | * iterate---a <em>very</em> wasteful operation that impacts front-end | |
| 23 | * performance. | |
| 24 | */ | |
| 25 | public class TeXExtension extends HtmlRendererAdapter | |
| 26 | implements ParserExtension { | |
| 27 | ||
| 28 | /** | |
| 29 | * Responsible for pre-parsing the input. | |
| 30 | */ | |
| 31 | private final Processor<String> mProcessor; | |
| 32 | ||
| 33 | /** | |
| 34 | * Controls how the node renderer produces TeX code within HTML output. | |
| 35 | */ | |
| 36 | private final ExportFormat mExportFormat; | |
| 37 | ||
| 38 | private TeXExtension( | |
| 39 | final Processor<String> processor, final ProcessorContext context ) { | |
| 40 | mProcessor = processor; | |
| 41 | mExportFormat = context.getExportFormat(); | |
| 42 | } | |
| 43 | ||
| 44 | /** | |
| 45 | * Creates an extension capable of handling delimited TeX code in Markdown. | |
| 46 | * | |
| 47 | * @return The new {@link TeXExtension}, never {@code null}. | |
| 48 | */ | |
| 49 | public static TeXExtension create( | |
| 50 | final Processor<String> processor, final ProcessorContext context ) { | |
| 51 | return new TeXExtension( processor, context ); | |
| 52 | } | |
| 53 | ||
| 54 | /** | |
| 55 | * Adds the TeX extension for HTML document export types. | |
| 56 | * | |
| 57 | * @param builder The document builder. | |
| 58 | * @param rendererType Indicates the document type to be built. | |
| 59 | */ | |
| 60 | @Override | |
| 61 | public void extend( @NotNull final HtmlRenderer.Builder builder, | |
| 62 | @NotNull final String rendererType ) { | |
| 63 | if( "HTML".equalsIgnoreCase( rendererType ) ) { | |
| 64 | builder.nodeRendererFactory( new Factory( mExportFormat, mProcessor ) ); | |
| 65 | } | |
| 66 | } | |
| 67 | ||
| 68 | @Override | |
| 69 | public void extend( final Parser.Builder builder ) { | |
| 70 | builder.customDelimiterProcessor( new TeXInlineDelimiterProcessor() ); | |
| 71 | } | |
| 72 | ||
| 73 | @Override | |
| 74 | public void parserOptions( final MutableDataHolder options ) { | |
| 75 | } | |
| 76 | } | |
| 1 | 77 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors.markdown.extensions.tex; | |
| 1 | 3 | |
| 4 | import com.vladsch.flexmark.parser.InlineParser; | |
| 5 | import com.vladsch.flexmark.parser.core.delimiter.Delimiter; | |
| 6 | import com.vladsch.flexmark.parser.delimiter.DelimiterProcessor; | |
| 7 | import com.vladsch.flexmark.parx node, closer |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors.markdown.extensions.tex; | |
| 3 | ||
| 4 | import com.vladsch.flexmark.ast.DelimitedNodeImpl; | |
| 1 | 5 | |
| 6 | public |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved.extensionsr.RProcessorProcessor<String>Processor<String>Processor<String>Processor<String> |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors.r; | |
| 1 | 3 | |
| 4 | import com.keenwrite.preferences.Workspace; | |
| 5 | import com.keenwrite.processors.DefinitionProcessor; | |
| 6 | import com.keenwrite.processors.Processor; | |
| 7 | ievents.StatusEvent |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors.r; | |
| 3 | ||
| 4 | import com.keenwrite.processors.ExecutorProcessor; | |
| 5 | import com.keenwrite.processors.Processor; | |
| 6 | import com.keenwrite.processors.ProcessorContex | |
| 7 | privat} | |
| 1 | 8 |
| 1 | /* Copyright 2020-2021 -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors.r; | |
| 3 | ||
| 4 | import com.keenwrite.preferences.Workspace; | |
| 5 | import com.keenwrite.processors.DefinitionProcessor; | |
| 6 | import com.keenwrite.processors.ProcessorContext; | |
| 7 | import com.keenwrite.sigils.RSigilOperator; | |
| 8 | import com.keenwrite.sigils.SigilOperator; | |
| 9 | import com.keenwrite.sigils.YamlSigilOperatorimport static com.keenwrite.preferences.WorkspaceKeys.*/ | |
| 10 | public finalrivate final SigilOperator mSigilOperator;final InlineRProcessor irp, final ProcessorContext context ) { | |
| 11 | super( irp, context ); | |
| 12 | mSigilOperator = createSigilOperator( context.getWorkspace()entokenentoken(var rMap = new HashvarmSigilOperator.entoken( key ), escap "SameParameterValue" vaigilOperator createSigilOperator( final Workspace workspace ) { | |
| 13 | final var tokens = workspace.toTokens( | |
| 14 | KEY_R_DELIM_BEGAN, KEY_R_DELIM_ENDED ); | |
| 15 | final var antecedent = createDefinitionOperator( workspace ); | |
| 16 | return new RSigilOperator( tokens, antecedent igilOperator createDefinitionOperator( final Workspace workspace ) { | |
| 17 | final var tokens = workspace.toTokens( | |
| 18 | KEY_DEF_DELIM_BEGAN, KEY_DEF_DELIM_ENDED ); | |
| 19 | return new YamlSigilOperator( tokens ); | |
| 20 | } | |
| 21 | } | |
| 1 | 22 |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. |
| 1 | ||
| 1 | /* Copyright 2020-2021 | |
| 2 | * All rights reserved. | |
| 3 | * -- All rights reserved. |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwritestatic finalstatic finalslower | |
| 3 | //algorithm implementation. |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.processors.text; | |
| 3 | ||
| 4 | import java.util.Map; | |
| 5 | ||
| 6 | /** | |
| 7 | * Defines the ability to replace text given a set of keys and values. | |
| 8 | */ | |
| 9 | public interface TextReplacer { | |
| 10 | ||
| 11 | /** | |
| 12 | * Searches through the given text for any of the keys given in the map and | |
| 13 | * replaces the keys that appear in the text with the key's corresponding | |
| 14 | * value. | |
| 15 | * | |
| 16 | * @param text The text that contains zero or more keys. | |
| 17 | * @param map The set of keys mapped to replacement values. | |
| 18 | * @return The given text with all keys replaced with corresponding values. | |
| 19 | */ | |
| 20 | String replace( String text, Map<String, String> map ); | |
| 21 | } | |
| 1 | 22 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.search; | |
| 1 | 3 | |
| 4 | import com.keenwrite.util.CyclicIterator; | |
| 5 | import javafx.beans.property.ObjectProperty; | |
| 6 | import javafx.beans.property.SimpleObjectProperty; | |
| 7 | import jafinal |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. |
| 1 | ||
| 1 | /* Copyright 2020-2021 | |
| 2 | * All rights reserved. | |
| 3 | * -- All rights reserved. |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. |
| 1 | /* Copyright 2020-2021 -- All rights reserved. */ | |
| 2 | package com.keenwritenio.file.PathPath path, | |
| 3 | String titleKey, | |
| 4 | Path path, | |
| 5 | String title, | |
| 1 | 6 |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved.import javafx.stage.Stag |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.service.events.impl; | |
| 3 | ||
| 4 | import com.keenwrite.service.events.Notification; | |
| 5 | ||
| 6 | import java.text.MessageFormat; | |
| 7 | ||
| 8 | /** | |
| 9 | * Responsible for alerting the user to prominent information. | |
| 10 | */ | |
| 11 | public class DefaultNotification implements Notification { | |
| 12 | ||
| 13 | private final String title; | |
| 14 | private final String content; | |
| 15 | ||
| 16 | /** | |
| 17 | * Constructs default message text for a notification. | |
| 18 | * | |
| 19 | * @param title The message title. | |
| 20 | * @param message The message content (needs formatting). | |
| 21 | * @param args The arguments to the message content that must be formatted. | |
| 22 | */ | |
| 23 | public DefaultNotification( | |
| 24 | final String title, | |
| 25 | final String message, | |
| 26 | final Object... args ) { | |
| 27 | this.title = title; | |
| 28 | this.content = MessageFormat.format( message, args ); | |
| 29 | } | |
| 30 | ||
| 31 | @Override | |
| 32 | public String getTitle() { | |
| 33 | return this.title; | |
| 34 | } | |
| 35 | ||
| 36 | @Override | |
| 37 | public String getContent() { | |
| 38 | return this.content; | |
| 39 | } | |
| 40 | ||
| 41 | } | |
| 1 | 42 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.service.events.impl; | |
| 1 | 3 | |
| 4 | import com.keenwrite.service.events.Notification; | |
| 5 | import com.keenwrite.service.events.Notifier; | |
| 6 | import javafx.scene.control.Alert; | |
| 7 | impButtonType.* |
| 1 | ||
| 1 | /* Copyright 2020-2021 | |
| 2 | * All rights reserved. | |
| 3 | * -- All rights reserved. |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.sigils; | |
| 3 | ||
| 4 | import static com.keenwrite.sigils.YamlSigilOperator.KEY_SEPARATOR_DEF; | |
| 5 | ||
| 6 | /** | |
| 7 | * Brackets variable names between {@link #PREFIX} and {@link #SUFFIX} sigils. | |
| 8 | */ | |
| 9 | public final class RSigilOperator extends SigilOperator { | |
| 10 | private static final char KEY_SEPARATOR_R = '$'; | |
| 11 | ||
| 12 | public static final String PREFIX = "`r#"; | |
| 13 | public static final char SUFFIX = '`'; | |
| 14 | ||
| 15 | /** | |
| 16 | * Definition variables are inserted into the document before R variables, | |
| 17 | * so this is required to reformat the definition variable suitable for R. | |
| 18 | */ | |
| 19 | private final SigilOperator mAntecedent; | |
| 20 | ||
| 21 | /** | |
| 22 | * Constructs a new {@link RSigilOperator} capable of wrapping tokens around | |
| 23 | * variable names (keys). | |
| 24 | * | |
| 25 | * @param tokens The starting and ending tokens. | |
| 26 | * @param antecedent The operator to use to undo any previous entokenizing. | |
| 27 | */ | |
| 28 | public RSigilOperator( final Tokens tokens, final SigilOperator antecedent ) { | |
| 29 | super( tokens ); | |
| 30 | ||
| 31 | mAntecedent = antecedent; | |
| 32 | } | |
| 33 | ||
| 34 | /** | |
| 35 | * Returns the given string with backticks prepended and appended. The | |
| 36 | * | |
| 37 | * @param key The string to adorn with R token delimiters. | |
| 38 | * @return PREFIX + delimiterBegan + variableName + delimiterEnded + SUFFIX. | |
| 39 | */ | |
| 40 | @Override | |
| 41 | public String apply( final String key ) { | |
| 42 | assert key != null; | |
| 43 | return PREFIX + getBegan() + key + getEnded() + SUFFIX; | |
| 44 | } | |
| 45 | ||
| 46 | /** | |
| 47 | * Transforms a definition key (bracketed by token delimiters) into the | |
| 48 | * expected format for an R variable key name. | |
| 49 | * <p> | |
| 50 | * The algorithm to entoken a definition name is faster than | |
| 51 | * {@link String#replace(char, char)}. Faster still would be to cache the | |
| 52 | * values, but that would mean managing the cache when the user changes | |
| 53 | * the beginning and ending of the R delimiters. This code gives about a | |
| 54 | * 2% performance boost when scrolling using cursor keys. After the JIT | |
| 55 | * warms up, this super-minor bottleneck vanishes. | |
| 56 | * </p> | |
| 57 | * | |
| 58 | * @param key The variable name to transform, can be empty but not null. | |
| 59 | * @return The transformed variable name. | |
| 60 | */ | |
| 61 | public String entoken( final String key ) { | |
| 62 | final var detokened = new StringBuilder( key.length() ); | |
| 63 | detokened.append( "v$" ); | |
| 64 | detokened.append( mAntecedent.detoken( key ) ); | |
| 65 | ||
| 66 | // The 3 is for "v$X" where X cannot be a period. | |
| 67 | for( int i = detokened.length() - 1; i >= 3; i-- ) { | |
| 68 | if( detokened.charAt( i ) == KEY_SEPARATOR_DEF ) { | |
| 69 | detokened.setCharAt( i, KEY_SEPARATOR_R ); | |
| 70 | } | |
| 71 | } | |
| 72 | ||
| 73 | return detokened.toString(); | |
| 74 | } | |
| 75 | } | |
| 1 | 76 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.sigils; | |
| 3 | ||
| 4 | import java.util.function.UnaryOperator; | |
| 5 | ||
| 6 | /** | |
| 7 | * Responsible for updating definition keys to use a machine-readable format | |
| 8 | * corresponding to the type of file being edited. This changes a definition | |
| 9 | * key name based on some criteria determined by the factory that creates | |
| 10 | * implementations of this interface. | |
| 11 | */ | |
| 12 | public abstract class SigilOperator implements UnaryOperator<String> { | |
| 13 | private final Tokens mTokens; | |
| 14 | ||
| 15 | SigilOperator( final Tokens tokens ) { | |
| 16 | mTokens = tokens; | |
| 17 | } | |
| 18 | ||
| 19 | /** | |
| 20 | * Removes start and stop definition key delimiters from the given key. This | |
| 21 | * method does not check for delimiters, only that there are sufficient | |
| 22 | * characters to remove from either end of the given key. | |
| 23 | * | |
| 24 | * @param key The key adorned with start and stop tokens. | |
| 25 | * @return The given key with the delimiters removed. | |
| 26 | */ | |
| 27 | String detoken( final String key ) { | |
| 28 | return key; | |
| 29 | } | |
| 30 | ||
| 31 | String getBegan() { | |
| 32 | return mTokens.getBegan(); | |
| 33 | } | |
| 34 | ||
| 35 | String getEnded() { | |
| 36 | return mTokens.getEnded(); | |
| 37 | } | |
| 38 | ||
| 39 | /** | |
| 40 | * Wraps the given key in the began and ended tokens. This may perform any | |
| 41 | * preprocessing necessary to ensure the transformation happens. | |
| 42 | * | |
| 43 | * @param key The variable name to transform. | |
| 44 | * @return The given key with tokens to delimit it (from the edited text). | |
| 45 | */ | |
| 46 | public abstract String entoken( final String key ); | |
| 47 | } | |
| 1 | 48 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.sigils; | |
| 3 | ||
| 4 | import javafx.beans.property.StringProperty; | |
| 5 | ||
| 6 | import java.util.AbstractMap.SimpleImmutableEntry; | |
| 1 | 7 | |
| 8 | /** | |
| 9 | * Convenience class for pairing a start and an |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.sigilsfinalthat may have start and stopvar began = getBegan(); | |
| 3 | final var ended = getEnded(); | |
| 4 | final int bLength = began.length(); | |
| 5 | final int eLength = ended.length(); | |
| 6 | final var bIndex = key.indexOf( began ); | |
| 7 | final var eIndex = key.indexOf( ended, bIndex ); | |
| 8 | final var kLength = key.length(); | |
| 9 | ||
| 10 | return key.substring( | |
| 11 | bIndex == -1 ? 0 : bLength, eIndex == -1 ? kLength : kLength - eLength ); | |
| 12 | } | |
| 13 | } | |
| 1 | 14 |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | ||
| 3 | /** | |
| 4 | * This package contains interfaces for spell checking implementations. | |
| 5 | */ | |
| 6 | package com.keenwrite.spelling.api; | |
| 1 | 7 |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved.final |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwritekeenwrite.exceptions.MissingFileException; | |
| 3 | import com.keenwrite.spelling.api.SpellCheckListener; | |
| 4 | import com.keenwrite.spelling. |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.spelling.impl; | |
| 3 | ||
| 4 | import com.keenwrite.spelling.api.SpellCheckListener; | |
| 5 | import com.keenwrite.spelling.api.SpellChecker; | |
| 6 | import com.vladsch.flexmark.parser.Parser; | |
| 7 | import com.vladsch.flexmark.util.ast.NodeVisitor; | |
| 8 | import com.vladsch.flexmark.util.ast.VisitHandler; | |
| 9 | import org.fxmisc.richtext.StyleClassedTextArea; | |
| 10 | import org.fxmisc.richtext.model.StyleSpansBuilder; | |
| 11 | ||
| 12 | import java.util.Collection; | |
| 13 | import java.util.concurrent.atomic.AtomicInteger; | |
| 14 | ||
| 15 | import static com.keenwrite.spelling.impl.SymSpellSpeller.forLexicon; | |
| 16 | import static java.util.Collections.emptyList; | |
| 17 | import static java.util.Collections.singleton; | |
| 18 | import static org.fxmisc.richtext.model.TwoDimensional.Bias.Forward; | |
| 19 | ||
| 20 | /** | |
| 21 | * Responsible for checking the spelling of a document being edited. | |
| 22 | */ | |
| 23 | public final class TextEditorSpeller { | |
| 24 | /** | |
| 25 | * Only load the dictionary into memory once, because it's huge. | |
| 26 | */ | |
| 27 | private static final SpellChecker sSpellChecker = forLexicon( "en.txt" ); | |
| 28 | ||
| 29 | public TextEditorSpeller() { | |
| 30 | } | |
| 31 | ||
| 32 | /** | |
| 33 | * Delegates to {@link #spellcheck(StyleClassedTextArea, String, int)}. | |
| 34 | * call to spell check the entire document. | |
| 35 | */ | |
| 36 | public void checkDocument( final StyleClassedTextArea editor ) { | |
| 37 | spellcheck( editor, editor.getText(), -1 ); | |
| 38 | } | |
| 39 | ||
| 40 | /** | |
| 41 | * Listen for changes to the any particular paragraph and perform a quick | |
| 42 | * spell check upon it. The style classes in the editor will be changed to | |
| 43 | * mark any spelling mistakes in the paragraph. The user may then interact | |
| 44 | * with any misspelled word (i.e., any piece of text that is marked) to | |
| 45 | * revise the spelling. | |
| 46 | * | |
| 47 | * @param editor The text area containing paragraphs to spellcheck. | |
| 48 | */ | |
| 49 | public void checkParagraphs( final StyleClassedTextArea editor ) { | |
| 50 | // Use the plain text changes so that notifications of style changes | |
| 51 | // are suppressed. Checking against the identity ensures that only | |
| 52 | // new text additions or deletions trigger proofreading. | |
| 53 | editor.plainTextChanges() | |
| 54 | .filter( p -> !p.isIdentity() ).subscribe( change -> { | |
| 55 | ||
| 56 | // Check current paragraph; the whole document was checked upon opening. | |
| 57 | final var offset = change.getPosition(); | |
| 58 | final var position = editor.offsetToPosition( offset, Forward ); | |
| 59 | final var paraId = position.getMajor(); | |
| 60 | final var paragraph = editor.getParagraph( paraId ); | |
| 61 | final var text = paragraph.getText(); | |
| 62 | ||
| 63 | // Prevent doubling-up styles. | |
| 64 | editor.clearStyle( paraId ); | |
| 65 | ||
| 66 | spellcheck( editor, text, paraId ); | |
| 67 | } ); | |
| 68 | } | |
| 69 | ||
| 70 | /** | |
| 71 | * Spellchecks a subset of the entire document. | |
| 72 | * | |
| 73 | * @param text Look up words for this text in the lexicon. | |
| 74 | * @param paraId Set to -1 to apply resulting style spans to the entire | |
| 75 | * text. | |
| 76 | */ | |
| 77 | private void spellcheck( | |
| 78 | final StyleClassedTextArea editor, final String text, final int paraId ) { | |
| 79 | final var builder = new StyleSpansBuilder<Collection<String>>(); | |
| 80 | final var runningIndex = new AtomicInteger( 0 ); | |
| 81 | ||
| 82 | // The text nodes must be relayed through a contextual "visitor" that | |
| 83 | // can return text in chunks with correlative offsets into the string. | |
| 84 | // This allows Markdown, R Markdown, XML, and R XML documents to return | |
| 85 | // sets of words to check. | |
| 86 | ||
| 87 | final var node = mParser.parse( text ); | |
| 88 | final var visitor = new TextVisitor( ( visited, bIndex, eIndex ) -> { | |
| 89 | // Treat hyphenated compound words as individual words. | |
| 90 | final var check = visited.replace( '-', ' ' ); | |
| 91 | ||
| 92 | sSpellChecker.proofread( check, ( misspelled, prevIndex, currIndex ) -> { | |
| 93 | prevIndex += bIndex; | |
| 94 | currIndex += bIndex; | |
| 95 | ||
| 96 | // Clear styling between lexiconically absent words. | |
| 97 | builder.add( emptyList(), prevIndex - runningIndex.get() ); | |
| 98 | builder.add( singleton( "spelling" ), currIndex - prevIndex ); | |
| 99 | runningIndex.set( currIndex ); | |
| 100 | } ); | |
| 101 | } ); | |
| 102 | ||
| 103 | visitor.visit( node ); | |
| 104 | ||
| 105 | // If the running index was set, at least one word triggered the listener. | |
| 106 | if( runningIndex.get() > 0 ) { | |
| 107 | // Clear styling after the last lexiconically absent word. | |
| 108 | builder.add( emptyList(), text.length() - runningIndex.get() ); | |
| 109 | ||
| 110 | final var spans = builder.create(); | |
| 111 | ||
| 112 | if( paraId >= 0 ) { | |
| 113 | editor.setStyleSpans( paraId, 0, spans ); | |
| 114 | } | |
| 115 | else { | |
| 116 | editor.setStyleSpans( 0, spans ); | |
| 117 | } | |
| 118 | } | |
| 119 | } | |
| 120 | ||
| 121 | /** | |
| 122 | * TODO: #59 -- Replace using Markdown processor instantiated for Markdown | |
| 123 | * files. | |
| 124 | */ | |
| 125 | private final Parser mParser = Parser.builder().build(); | |
| 126 | ||
| 127 | /** | |
| 128 | * TODO: #59 -- Replace with generic interface; provide Markdown/XML | |
| 129 | * implementations. | |
| 130 | */ | |
| 131 | private static final class TextVisitor { | |
| 132 | private final NodeVisitor mVisitor = new NodeVisitor( new VisitHandler<>( | |
| 133 | com.vladsch.flexmark.ast.Text.class, this::visit ) | |
| 134 | ); | |
| 135 | ||
| 136 | private final SpellCheckListener mConsumer; | |
| 137 | ||
| 138 | public TextVisitor( final SpellCheckListener consumer ) { | |
| 139 | mConsumer = consumer; | |
| 140 | } | |
| 141 | ||
| 142 | private void visit( final com.vladsch.flexmark.util.ast.Node node ) { | |
| 143 | if( node instanceof com.vladsch.flexmark.ast.Text ) { | |
| 144 | mConsumer.accept( node.getChars().toString(), | |
| 145 | node.getStartOffset(), | |
| 146 | node.getEndOffset() ); | |
| 147 | } | |
| 148 | ||
| 149 | mVisitor.visitChildren( node ); | |
| 150 | } | |
| 151 | } | |
| 152 | } | |
| 1 | 153 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | ||
| 3 | /** | |
| 4 | * This package contains classes for spell checking implementations. | |
| 5 | */ | |
| 6 | package com.keenwrite.spelling.impl; | |
| 1 | 7 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.ui.actions; | |
| 3 | ||
| 4 | import com.keenwrite.Constants; | |
| 5 | import com.keenwrite.Messages; | |
| 6 | import com.keenwrite.util.GenericBuilder; | |
| 7 | import de.jensd.fx.glyphs.GlyphIcons; | |
| 8 | import de.jensd.fx.glyphs.fontawesomecom.keenwrite.Constants.ACTION_PREFIX;finalfinal String text, | |
| 9 | Constants.ICON_SIZE_DEFAULTACTION_PREFIX/? this | |
| 1 | 10 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.ui.actions; | |
| 3 | ||
| 4 | import com.keenwrite.ExportFormat; | |
| 5 | import com.keenwrite.MainPane; | |
| 6 | import com.keenwrite.MainScene; | |
| 7 | import com.keenwrite.editors.TextDefinition; | |
| 1 | 8 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.ui.actions; | |
| 1 | 3 | |
| 4 | import com.keenwrite.ui.controls.EventedStatusBar; | |
| 5 | import javafx.event.ActionEvent; | |
| 6 | import javafx.event.EventHandler; | |
| 7 | import javafx.scene.Node; |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.ui.actions; | |
| 3 | ||
| 4 | import com.keenwrite.Messages; | |
| 5 | import com.keenwrite.io.FileType; | |
| 6 | import com.keenwrite.service.Settings; | |
| 7 | import javafx.beans.property.Property; | |
| 8 | import javafx.stage.FileChooser; | |
| 9 | import javafx.stage.FileChooser.ExtensionFilter; | |
| 10 | import javafx.stage.Window; | |
| 11 | ||
| 12 | import java.io.File; | |
| 13 | import java.util.ArrayList; | |
| 14 | import java.util.List; | |
| 15 | import java.util.Optional; | |
| 16 | ||
| 17 | import static com.keenwrite.Constants.*; | |
| 18 | import static com.keenwrite.Messages.get; | |
| 19 | import static com.keenwrite.io.FileType.*; | |
| 20 | import static java.lang.String.format; | |
| 21 | ||
| 22 | /** | |
| 23 | * Responsible for opening a dialog that provides users with the ability to | |
| 24 | * select files. | |
| 25 | */ | |
| 26 | public final class FileChooserCommand { | |
| 27 | private static final String FILTER_EXTENSION_TITLES = | |
| 28 | "Dialog.file.choose.filter"; | |
| 29 | ||
| 30 | /** | |
| 31 | * Dialog owner. | |
| 32 | */ | |
| 33 | private final Window mParent; | |
| 34 | ||
| 35 | /** | |
| 36 | * Set to the directory of most recently selected file. | |
| 37 | */ | |
| 38 | private final Property<File> mDirectory; | |
| 39 | ||
| 40 | /** | |
| 41 | * Constructs a new {@link FileChooserCommand} that will attach to a given | |
| 42 | * parent window and update the given property upon a successful selection. | |
| 43 | * | |
| 44 | * @param parent The parent window that will own the dialog. | |
| 45 | * @param directory The most recently opened file's directory property. | |
| 46 | */ | |
| 47 | public FileChooserCommand( | |
| 48 | final Window parent, final Property<File> directory ) { | |
| 49 | mParent = parent; | |
| 50 | mDirectory = directory; | |
| 51 | } | |
| 52 | ||
| 53 | /** | |
| 54 | * Returns a list of files to be opened. | |
| 55 | * | |
| 56 | * @return A non-null, possibly empty list of files to open. | |
| 57 | */ | |
| 58 | public List<File> openFiles() { | |
| 59 | final var dialog = createFileChooser( | |
| 60 | "Dialog.file.choose.open.title" ); | |
| 61 | final var list = dialog.showOpenMultipleDialog( mParent ); | |
| 62 | final List<File> selected = list == null ? List.of() : list; | |
| 63 | final var files = new ArrayList<File>( selected.size() ); | |
| 64 | ||
| 65 | files.addAll( selected ); | |
| 66 | ||
| 67 | if( !files.isEmpty() ) { | |
| 68 | setRecentDirectory( files.get( 0 ) ); | |
| 69 | } | |
| 70 | ||
| 71 | return files; | |
| 72 | } | |
| 73 | ||
| 74 | /** | |
| 75 | * Allows saving the document under a new file name. | |
| 76 | * | |
| 77 | * @return The new file name. | |
| 78 | */ | |
| 79 | public Optional<File> saveAs() { | |
| 80 | final var dialog = createFileChooser( "Dialog.file.choose.save.title" ); | |
| 81 | return saveOrExportAs( dialog ); | |
| 82 | } | |
| 83 | ||
| 84 | /** | |
| 85 | * Allows exporting the document to a new file format. | |
| 86 | * | |
| 87 | * @return The file name for exporting into. | |
| 88 | */ | |
| 89 | public Optional<File> exportAs( final File filename ) { | |
| 90 | final var dialog = createFileChooser( "Dialog.file.choose.export.title" ); | |
| 91 | dialog.setInitialFileName( filename.getName() ); | |
| 92 | return saveOrExportAs( dialog ); | |
| 93 | } | |
| 94 | ||
| 95 | /** | |
| 96 | * Helper method called when saving or exporting. | |
| 97 | * | |
| 98 | * @param dialog The {@link FileChooser} to display. | |
| 99 | * @return The file selected by the user. | |
| 100 | */ | |
| 101 | private Optional<File> saveOrExportAs( final FileChooser dialog ) { | |
| 102 | final var file = dialog.showSaveDialog( mParent ); | |
| 103 | ||
| 104 | setRecentDirectory( file ); | |
| 105 | ||
| 106 | return Optional.ofNullable( file ); | |
| 107 | } | |
| 108 | ||
| 109 | /** | |
| 110 | * Opens a new {@link FileChooser} at the previously selected directory. | |
| 111 | * If the initial directory is missing, this will attempt to default to | |
| 112 | * the user's home directory. If the home directory is missing, this will | |
| 113 | * use whatever JavaFX chooses for the initial directory. Without such an | |
| 114 | * intervention, an {@link IllegalArgumentException} would be thrown. | |
| 115 | * | |
| 116 | * @param key Message key from resource bundle. | |
| 117 | * @return {@link FileChooser} GUI allowing the user to pick a file. | |
| 118 | */ | |
| 119 | private FileChooser createFileChooser( final String key ) { | |
| 120 | final var prefDir = mDirectory.getValue(); | |
| 121 | final var openDir = prefDir.isDirectory() ? prefDir : USER_DIRECTORY; | |
| 122 | final var chooser = new FileChooser(); | |
| 123 | ||
| 124 | chooser.setTitle( get( key ) ); | |
| 125 | chooser.getExtensionFilters().addAll( createExtensionFilters() ); | |
| 126 | chooser.setInitialDirectory( openDir.isDirectory() ? openDir : null ); | |
| 127 | ||
| 128 | return chooser; | |
| 129 | } | |
| 130 | ||
| 131 | private List<ExtensionFilter> createExtensionFilters() { | |
| 132 | final List<ExtensionFilter> list = new ArrayList<>(); | |
| 133 | ||
| 134 | // TODO: Return a list of all properties that match the filter prefix. | |
| 135 | // This will allow dynamic filters to be added and removed just by | |
| 136 | // updating the properties file. | |
| 137 | list.add( createExtensionFilter( ALL ) ); | |
| 138 | list.add( createExtensionFilter( SOURCE ) ); | |
| 139 | list.add( createExtensionFilter( DEFINITION ) ); | |
| 140 | list.add( createExtensionFilter( XML ) ); | |
| 141 | ||
| 142 | return list; | |
| 143 | } | |
| 144 | ||
| 145 | /** | |
| 146 | * Returns a filter for file name extensions recognized by the application | |
| 147 | * that can be opened by the user. | |
| 148 | * | |
| 149 | * @param filetype Used to find the globbing pattern for extensions. | |
| 150 | * @return A file name filter suitable for use by a FileDialog instance. | |
| 151 | */ | |
| 152 | private ExtensionFilter createExtensionFilter( | |
| 153 | final FileType filetype ) { | |
| 154 | final var tKey = format( "%s.title.%s", FILTER_EXTENSION_TITLES, filetype ); | |
| 155 | final var eKey = format( "%s.%s", GLOB_PREFIX_FILE, filetype ); | |
| 156 | ||
| 157 | return new ExtensionFilter( Messages.get( tKey ), getExtensions( eKey ) ); | |
| 158 | } | |
| 159 | ||
| 160 | /** | |
| 161 | * Sets the value for the most recent directly selected. This will get the | |
| 162 | * parent location from the given file. If the parent is a readable directory | |
| 163 | * then this will update the most recent directory property. | |
| 164 | * | |
| 165 | * @param file A file contained in a directory. | |
| 166 | */ | |
| 167 | private void setRecentDirectory( final File file ) { | |
| 168 | if( file != null ) { | |
| 169 | final var parent = file.getParentFile(); | |
| 170 | final var dir = parent == null ? USER_DIRECTORY : parent; | |
| 171 | ||
| 172 | if( dir.isDirectory() && dir.canRead() ) { | |
| 173 | mDirectory.setValue( dir ); | |
| 174 | } | |
| 175 | } | |
| 176 | } | |
| 177 | ||
| 178 | private List<String> getExtensions( final String key ) { | |
| 179 | return getSettings().getStringSettingList( key ); | |
| 180 | } | |
| 181 | ||
| 182 | private static Settings getSettings() { | |
| 183 | return sSettings; | |
| 184 | } | |
| 185 | } | |
| 1 | 186 |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.ui.actions; | |
| 3 | ||
| 4 | import javafx.scene.Node; | |
| 5 | import javafx.scene.control.*; | |
| 1 | 6 | |
| 7 | /** | |
| 8 | * Represents a {@link MenuBar} or {@link ToolBar} action that has no | |
| 9 | * operatiofinal |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | ||
| 3 | /** | |
| 4 | * This package contains classes that define commands as executable actions. | |
| 5 | */ | |
| 6 | package com.keenwrite.ui.actions; | |
| 1 | 7 |
| 1 | ||
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved.events.StatusEvent |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.ui.adapters; | |
| 3 | ||
| 4 | import org.w3c.dom.Element; | |
| 5 | import org.xhtmlrenderer.extend.ReplacedElementFactory; | |
| 6 | import org.xhtmlrenderer.simple.extend.FormSubmissionListener; | |
| 7 | ||
| 8 | /** | |
| 9 | * Allows subclasses to implement only specific events of interest. | |
| 10 | */ | |
| 11 | public abstract class ReplacedElementAdapter implements ReplacedElementFactory { | |
| 12 | @Override | |
| 13 | public void reset() { | |
| 14 | } | |
| 15 | ||
| 16 | @Override | |
| 17 | public void remove( final Element e ) { | |
| 18 | } | |
| 19 | ||
| 20 | @Override | |
| 21 | public void setFormSubmissionListener( | |
| 22 | final FormSubmissionListener listener ) { | |
| 23 | } | |
| 24 | } | |
| 1 | 25 |
| 1 | ||
| 1 | /* | |
| 2 | * Copyright 2015 Karl Tauber <karl at jformdesigner dot com> | |
| 3 | * All rights reserved. | |
| 4 | * | |
| 5 | * Redistribution and use in source and binary forms, with or without | |
| 6 | * modification, are permitted provided that the following conditions are met: | |
| 7 | * | |
| 8 | * o Rfinal |
| 1 | ||
| 1 | /* | |
| 2 | * Copyright 2020 Karl Tauber and White Magic Software, Ltd. | |
| 3 | * All rights reserved. | |
| 4 | * | |
| 5 | * Redistribution and use in source and binary forms, with or without | |
| 6 | * modification, are permitted provided that the following conditions are met: | |
| 7 | * | |
| 8 | * o RedistM |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.ui.controls; | |
| 3 | ||
| 4 | import com.keenwrite.events.StatusEvent; | |
| 5 | import org.controlsfx.control.StatusBar; | |
| 6 | import org.greenrobot.eventbus.Subscribe; | |
| 7 | ||
| 8 | import static comrunLater( | |
| 9 | () -> { | |
| 10 | } | |
| 11 | ); | |
| 12 | } | |
| 13 | } | |
| 14 | } | |
| 1 | 15 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.ui.controls; | |
| 1 | 3 | |
| 4 | import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon; | |
| 5 | import de.jensd.fx.glyphs.fontawesome.utils.FontAwesomeIconFactory; | |
| 6 | import javafx.beans*Label mMatches = new Label |
| 1 | ||
| 1 | /* Copyright 2017-2021 White Magic Software, Ltd. -- All rights reserved.Stagevar |
| 1 | ||
| 1 | /* | |
| 2 | * Copyright 2015 Karl Tauber <karl at jformdesigner dot com> | |
| 3 | * All rights reserved. | |
| 4 | * | |
| 5 | * Redistribution and use in source and binary forms, with or without | |
| 6 | * modification, are permitted provided that the following conditions are met: | |
| 7 | * | |
| 8 | * o RM |
| 1 | JFDML JFormDesigner: "9.9.9.9.9999" Java: "1.8.0_66" encoding: "UTF-8" | |
| 1 | 2 | |
| 3 | new FormModel { | |
| 4 | "i18n.bundlePackage": "com.scrivendor" | |
| 5 | "i18n.bundleName": "messages" | |
| 6 | "i18n.autoExternalize": true | |
| 7 | "i18n.keyPrefix": "ImageDialog" | |
| 8 | contentType: "form/javafx" | |
| 9 | root:ImageImage2 1Image2 1Image2 |
| 1 | ||
| 1 | /* | |
| 2 | * Copyright 2016 Karl Tauber and White Magic Software, Ltd. | |
| 3 | * | |
| 4 | * All rights reserved. | |
| 5 | * | |
| 6 | * Redistribution and use in source and binary forms, with or without | |
| 7 | * modification, are permitted provided that the following conditions are met: | |
| 8 | * | |
| 9 | * o RM |
| 1 | JFDML JFormDesigner: "9.9.9.9.9999" Java: "1.8.0_66" encoding: "UTF-8" | |
| 2 | ||
| 3 | new FormModel { | |
| 4 | "i18n.bundlePackage": "com.scrivendor" | |
| 5 | "i18n.bundleName": "messages" | |
| 6 | "i18n.autoExternalize": true | |
| 7 | "i18n.keyPrefix": "LinkDialog" | |
| 8 | contentType: "form/javafx" | |
| 9 | root: new FormRoot { | |
| 10 | add( new FormContainer( "org.tbee.javafx.scene.layout.fxml.MigPane", new FormLayoutManager( class org.tbee.javafx.scene.layout.fxml.MigPane ) { | |
| 11 | "$layoutConstraints": "" | |
| 12 | "$columnConstraints": "[shrink 0,fill][300,grow,fill][fill][fill]" | |
| 13 | "$rowConstraints": "[][][][]" | |
| 14 | } ) { | |
| 15 | name: "pane" | |
| 16 | add( new FormComponent( "javafx.scene.control.Label" ) { | |
| 17 | name: "urlLabel" | |
| 18 | "text": new FormMessage( null, "LinkDialog.urlLabel.text" ) | |
| 19 | auxiliary() { | |
| 20 | "JavaCodeGenerator.variableLocal": true | |
| 21 | } | |
| 22 | }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { | |
| 23 | "value": "cell 0 0" | |
| 24 | } ) | |
| 25 | add( new FormComponent( "com.scrivendor.controls.EscapeTextField" ) { | |
| 26 | name: "urlField" | |
| 27 | "escapeCharacters": "()" | |
| 28 | "text": "http://yourlink.com" | |
| 29 | "promptText": "http://yourlink.com" | |
| 30 | }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { | |
| 31 | "value": "cell 1 0" | |
| 32 | } ) | |
| 33 | add( new FormComponent( "com.scrivendor.controls.BrowseDirectoryButton" ) { | |
| 34 | name: "linkBrowseDirectoyButton" | |
| 35 | }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { | |
| 36 | "value": "cell 2 0" | |
| 37 | } ) | |
| 38 | add( new FormComponent( "com.scrivendor.controls.BrowseFileButton" ) { | |
| 39 | name: "linkBrowseFileButton" | |
| 40 | }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { | |
| 41 | "value": "cell 3 0" | |
| 42 | } ) | |
| 43 | add( new FormComponent( "javafx.scene.control.Label" ) { | |
| 44 | name: "textLabel" | |
| 45 | "text": new FormMessage( null, "LinkDialog.textLabel.text" ) | |
| 46 | auxiliary() { | |
| 47 | "JavaCodeGenerator.variableLocal": true | |
| 48 | } | |
| 49 | }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { | |
| 50 | "value": "cell 0 1" | |
| 51 | } ) | |
| 52 | add( new FormComponent( "com.scrivendor.controls.EscapeTextField" ) { | |
| 53 | name: "textField" | |
| 54 | "escapeCharacters": "[]" | |
| 55 | }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { | |
| 56 | "value": "cell 1 1 3 1" | |
| 57 | } ) | |
| 58 | add( new FormComponent( "javafx.scene.control.Label" ) { | |
| 59 | name: "titleLabel" | |
| 60 | "text": new FormMessage( null, "LinkDialog.titleLabel.text" ) | |
| 61 | auxiliary() { | |
| 62 | "JavaCodeGenerator.variableLocal": true | |
| 63 | } | |
| 64 | }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { | |
| 65 | "value": "cell 0 2" | |
| 66 | } ) | |
| 67 | add( new FormComponent( "com.scrivendor.controls.EscapeTextField" ) { | |
| 68 | name: "titleField" | |
| 69 | }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { | |
| 70 | "value": "cell 1 2 3 1" | |
| 71 | } ) | |
| 72 | add( new FormComponent( "javafx.scene.control.Label" ) { | |
| 73 | name: "previewLabel" | |
| 74 | "text": new FormMessage( null, "LinkDialog.previewLabel.text" ) | |
| 75 | auxiliary() { | |
| 76 | "JavaCodeGenerator.variableLocal": true | |
| 77 | } | |
| 78 | }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { | |
| 79 | "value": "cell 0 3" | |
| 80 | } ) | |
| 81 | add( new FormComponent( "javafx.scene.control.Label" ) { | |
| 82 | name: "previewField" | |
| 83 | }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { | |
| 84 | "value": "cell 1 3 3 1" | |
| 85 | } ) | |
| 86 | }, new FormLayoutConstraints( null ) { | |
| 87 | "location": new javafx.geometry.Point2D( 0.0, 0.0 ) | |
| 88 | "size": new javafx.geometry.Dimension2D( 500.0, 300.0 ) | |
| 89 | } ) | |
| 90 | } | |
| 91 | } | |
| 1 | 92 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.ui.heuristics; | |
| 3 | ||
| 4 | import com.keenwrite.events.DocumentChangedEvent; | |
| 5 | import com.keenwrite.preferences.Workspace; | |
| 6 | import com.keenwrite.preview.HtmlPanel; | |
| 7 | import com.keenwrite.util.MurmurHash; | |
| 8 | import com.whitemagicsoftware.wordcount.Tokenizer; | |
| 9 | import com.whitemagicsoftware.wordcount.TokenizerException; | |
| 10 | import com.whitemagicsoftware.wordcount.TokenizerFactory; | |
| 11 | import javafx.beans.property.IntegerProperty; | |
| 12 | import javafx.beans.property.SimpleIntegerProperty; | |
| 13 | import javafx.beans.property.SimpleStringProperty; | |
| 14 | import javafx.beans.property.StringProperty; | |
| 15 | import javafx.collections.ObservableList; | |
| 16 | import javafx.collections.transformation.SortedList; | |
| 17 | import javafx.scene.control.TableColumn; | |
| 18 | import javafx.scene.control.TableView; | |
| 19 | import org.greenrobot.eventbus.Subscribe; | |
| 20 | import org.jsoup.Jsoup; | |
| 21 | ||
| 22 | import java.util.Locale; | |
| 23 | ||
| 24 | import static com.keenwrite.events.Bus.register; | |
| 25 | import static com.keenwrite.events.StatusEvent.clue; | |
| 26 | import static com.keenwrite.events.WordCountEvent.fireWordCountEvent; | |
| 27 | import static com.keenwrite.preferences.WorkspaceKeys.KEY_LANGUAGE_LOCALE; | |
| 28 | import static com.keenwrite.preferences.WorkspaceKeys.KEY_UI_FONT_EDITOR_NAME; | |
| 29 | import static java.lang.String.format; | |
| 30 | import static java.util.Locale.ENGLISH; | |
| 31 | import static javafx.application.Platform.runLater; | |
| 32 | import static javafx.collections.FXCollections.observableArrayList; | |
| 33 | ||
| 34 | /** | |
| 35 | * Responsible for displaying document statistics, such as word count and | |
| 36 | * word frequency. | |
| 37 | */ | |
| 38 | public final class DocumentStatistics | |
| 39 | extends TableView<DocumentStatistics.StatEntry> { | |
| 40 | /** | |
| 41 | * Parses documents into word counts. | |
| 42 | */ | |
| 43 | private static Tokenizer sTokenizer = createTokenizer( ENGLISH ); | |
| 44 | ||
| 45 | private final ObservableList<StatEntry> mItems = observableArrayList(); | |
| 46 | ||
| 47 | /** | |
| 48 | * Creates a new observer of document change events that will gather and | |
| 49 | * display document statistics (e.g., word counts). | |
| 50 | * | |
| 51 | * @param workspace Settings used to configure the statistics engine. | |
| 52 | */ | |
| 53 | public DocumentStatistics( final Workspace workspace ) { | |
| 54 | final var sortedItems = new SortedList<>( mItems ); | |
| 55 | sortedItems.comparatorProperty().bind( comparatorProperty() ); | |
| 56 | setItems( sortedItems ); | |
| 57 | ||
| 58 | initView(); | |
| 59 | initListeners( workspace ); | |
| 60 | register( this ); | |
| 61 | ||
| 62 | final var fontName = workspace.stringProperty( KEY_UI_FONT_EDITOR_NAME ); | |
| 63 | ||
| 64 | fontName.addListener( | |
| 65 | ( c, o, n ) -> { | |
| 66 | if( n != null ) { | |
| 67 | setFontFamily( n ); | |
| 68 | } | |
| 69 | } | |
| 70 | ); | |
| 71 | ||
| 72 | setFontFamily( fontName.getValue() ); | |
| 73 | } | |
| 74 | ||
| 75 | /** | |
| 76 | * Called when the hashcode for the current document changes. This happens | |
| 77 | * when non-collapsable-whitespace is added to the document. When the | |
| 78 | * document is sent to {@link HtmlPanel} for rendering, the parsed | |
| 79 | * {@link Jsoup} document is converted to text. If that text differs | |
| 80 | * (using {@link MurmurHash}), then this method is called. The implication | |
| 81 | * is that all variables and executable statements have been replaced. | |
| 82 | * An event bus subscriber is used so that text processing occurs outside | |
| 83 | * of the UI processing threads. | |
| 84 | * | |
| 85 | * @param event Container for the document text that has changed. | |
| 86 | */ | |
| 87 | @Subscribe | |
| 88 | public void handle( final DocumentChangedEvent event ) { | |
| 89 | try { | |
| 90 | final var tokens = sTokenizer.tokenize( event.getDocument() ); | |
| 91 | final var sum = new int[]{0}; | |
| 92 | ||
| 93 | runLater( () -> { | |
| 94 | mItems.clear(); | |
| 95 | tokens.forEach( ( k, v ) -> { | |
| 96 | final var count = v[ 0 ]; | |
| 97 | if( count > 2 ) { | |
| 98 | mItems.add( new StatEntry( k, count ) ); | |
| 99 | } | |
| 100 | sum[ 0 ] += count; | |
| 101 | } ); | |
| 102 | ||
| 103 | fireWordCountEvent( sum[ 0 ] ); | |
| 104 | } ); | |
| 105 | ||
| 106 | } catch( final TokenizerException ex ) { | |
| 107 | clue( ex ); | |
| 108 | } | |
| 109 | } | |
| 110 | ||
| 111 | @SuppressWarnings( "unchecked" ) | |
| 112 | private void initView() { | |
| 113 | final TableColumn<StatEntry, String> colWord = createColumn( "Word" ); | |
| 114 | final TableColumn<StatEntry, Number> colCount = createColumn( "Count" ); | |
| 115 | ||
| 116 | colWord.setCellValueFactory( stat -> stat.getValue().wordProperty() ); | |
| 117 | colCount.setCellValueFactory( stat -> stat.getValue().tallyProperty() ); | |
| 118 | colCount.setComparator( colCount.getComparator().reversed() ); | |
| 119 | ||
| 120 | final var columns = getColumns(); | |
| 121 | columns.add( colWord ); | |
| 122 | columns.add( colCount ); | |
| 123 | ||
| 124 | setMaxWidth( Double.MAX_VALUE ); | |
| 125 | setPrefWidth( 128 ); | |
| 126 | setColumnResizePolicy( CONSTRAINED_RESIZE_POLICY ); | |
| 127 | getSortOrder().setAll( colCount, colWord ); | |
| 128 | ||
| 129 | getStyleClass().add( "" ); | |
| 130 | } | |
| 131 | ||
| 132 | private void initListeners( final Workspace workspace ) { | |
| 133 | final var property = workspace.localeProperty( KEY_LANGUAGE_LOCALE ); | |
| 134 | property.addListener( | |
| 135 | ( c, o, n ) -> sTokenizer = createTokenizer( property.toLocale() ) | |
| 136 | ); | |
| 137 | } | |
| 138 | ||
| 139 | /** | |
| 140 | * Creates a tokenizer for English text (can handle most Latin languages). | |
| 141 | * | |
| 142 | * @return An English-based tokenizer for counting words. | |
| 143 | */ | |
| 144 | private static Tokenizer createTokenizer( final Locale language ) { | |
| 145 | return TokenizerFactory.create( language ); | |
| 146 | } | |
| 147 | ||
| 148 | private <E, T> TableColumn<E, T> createColumn( final String key ) { | |
| 149 | return new TableColumn<>( key ); | |
| 150 | } | |
| 151 | ||
| 152 | private void setFontFamily( final String value ) { | |
| 153 | runLater( () -> setStyle( format( "-fx-font-family:'%s';", value ) ) ); | |
| 154 | } | |
| 155 | ||
| 156 | /** | |
| 157 | * Represents the number of times a word appears in a document. | |
| 158 | */ | |
| 159 | protected static final class StatEntry { | |
| 160 | private final StringProperty mWord; | |
| 161 | private final IntegerProperty mTally; | |
| 162 | ||
| 163 | public StatEntry( final String word, final int tally ) { | |
| 164 | mWord = new SimpleStringProperty( word ); | |
| 165 | mTally = new SimpleIntegerProperty( tally ); | |
| 166 | } | |
| 167 | ||
| 168 | private StringProperty wordProperty() { | |
| 169 | return mWord; | |
| 170 | } | |
| 171 | ||
| 172 | private IntegerProperty tallyProperty() { | |
| 173 | return mTally; | |
| 174 | } | |
| 175 | } | |
| 176 | } | |
| 1 | 177 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.ui.listeners; | |
| 3 | ||
| 4 | import com.keenwrite.Caret; | |
| 5 | import com.keenwrite.editors.TextEditor; | |
| 6 | import com.keenwrite.events.WordCountEvent; | |
| 7 | import javafx.beans.property.ReadOnlyObjectProperty; | |
| 8 | import javafx.beans.value.ChangeListener; | |
| 9 | import javafx.beans.value.ObservableValue; | |
| 10 | import javafx.scene.control.Label; | |
| 11 | import javafx.scene.layout.VBox; | |
| 12 | import org.greenrobot.eventbus.Subscribe; | |
| 13 | ||
| 14 | import static com.keenwrite.events.Bus.register; | |
| 15 | import static javafx.application.Platform.runLater; | |
| 16 | import static javafx.geometry.Pos.BASELINE_CENTER; | |
| 17 | ||
| 18 | /** | |
| 19 | * Responsible for updating the UI whenever the caret changes position. | |
| 20 | * Only one instance of {@link CaretListener} is allowed, which prevents | |
| 21 | * duplicate adds to the observable property. | |
| 22 | */ | |
| 23 | public class CaretListener extends VBox implements ChangeListener<Integer> { | |
| 24 | ||
| 25 | /** | |
| 26 | * Use an instance of {@link Label} for its built-in CSS style class. | |
| 27 | */ | |
| 28 | private final Label mLineNumberText = new Label(); | |
| 29 | private volatile Caret mCaret; | |
| 30 | ||
| 31 | /** | |
| 32 | * Approximate number of words in the document. | |
| 33 | */ | |
| 34 | private volatile int mCount; | |
| 35 | ||
| 36 | public CaretListener( final ReadOnlyObjectProperty<TextEditor> editor ) { | |
| 37 | assert editor != null; | |
| 38 | ||
| 39 | setAlignment( BASELINE_CENTER ); | |
| 40 | getChildren().add( mLineNumberText ); | |
| 41 | ||
| 42 | editor.addListener( ( c, o, n ) -> { | |
| 43 | if( n != null ) { | |
| 44 | updateListener( n.getCaret() ); | |
| 45 | } | |
| 46 | } ); | |
| 47 | ||
| 48 | updateListener( editor.get().getCaret() ); | |
| 49 | register( this ); | |
| 50 | } | |
| 51 | ||
| 52 | /** | |
| 53 | * Called whenever the caret position changes. | |
| 54 | * | |
| 55 | * @param c The caret position property. | |
| 56 | * @param o The old caret position offset. | |
| 57 | * @param n The new caret position offset. | |
| 58 | */ | |
| 59 | @Override | |
| 60 | public void changed( | |
| 61 | final ObservableValue<? extends Integer> c, | |
| 62 | final Integer o, final Integer n ) { | |
| 63 | updateLineNumber(); | |
| 64 | } | |
| 65 | ||
| 66 | @Subscribe | |
| 67 | public void handle( final WordCountEvent event ) { | |
| 68 | mCount = event.getCount(); | |
| 69 | updateLineNumber(); | |
| 70 | } | |
| 71 | ||
| 72 | private void updateListener( final Caret caret ) { | |
| 73 | assert caret != null; | |
| 74 | ||
| 75 | final var property = caret.textOffsetProperty(); | |
| 76 | ||
| 77 | property.removeListener( this ); | |
| 78 | mCaret = caret; | |
| 79 | property.addListener( this ); | |
| 80 | updateLineNumber(); | |
| 81 | } | |
| 82 | ||
| 83 | private void updateLineNumber() { | |
| 84 | runLater( | |
| 85 | () -> mLineNumberText.setText( mCaret.toString() + " | " + mCount ) | |
| 86 | ); | |
| 87 | } | |
| 88 | } | |
| 1 | 89 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.ui.logging; | |
| 1 | 3 | |
| 4 | import com.keenwrite.events.StatusEvent; | |
| 5 | import javafx.beans.property.SimpleStringProperty; | |
| 6 | import javafx.beans.property.StringProperty; | |
| 7 | importDate |
| 1 | package com.keenwrite.ui.outline; | |
| 2 | ||
| 3 | import com.keenwrite.events.Bus; | |
| 4 | import com.keenwrite.events.ParseHeadingEvent; | |
| 5 | import javafx.control.TreeCell; | |
| 6 | i} | |
| 1 | 7 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.ui.tree; | |
| 3 | ||
| 4 | import javafx.beans.property.Property; | |
| 5 | import javafx.beans.property.SimpleStringProperty; | |
| 6 | import javafx.beans.value.ChangeListener; | |
| 7 | import javafx.beans.value.ObservableValue; | |
| 8 | import javafx.event.EventHandler; | |
| 9 | import javafx.scene.control.TextField; | |
| 10 | import javafx.scene.control.cell.TextFieldTreeCell; | |
| 11 | import javafx.scene.input.KeyEvent; | |
| 12 | import javafx.util.StringConverter; | |
| 13 | ||
| 14 | import static javafx.application.Platform.runLater; | |
| 15 | import static javafx.scene.input.KeyCode.ENTER; | |
| 16 | import static javafx.scene.input.KeyCode.TAB; | |
| 17 | import static javafx.scene.input.KeyEvent.KEY_RELEASED; | |
| 18 | ||
| 19 | /** | |
| 20 | * Responsible for enhancing the existing cell behaviour with fairly common | |
| 21 | * functionality, including commit on focus loss and Enter to commit. | |
| 22 | * | |
| 23 | * @param <T> The type of data stored by the tree. | |
| 24 | */ | |
| 25 | public class AltTreeCell<T> extends TextFieldTreeCell<T> { | |
| 26 | private final KeyHandler mKeyHandler = new KeyHandler(); | |
| 27 | private final Property<String> mInputText = new SimpleStringProperty(); | |
| 28 | private FocusListener mFocusListener; | |
| 29 | ||
| 30 | public AltTreeCell( final StringConverter<T> converter ) { | |
| 31 | super( converter ); | |
| 32 | assert converter != null; | |
| 33 | ||
| 34 | // When the text field is added as the graphics context, we hook into | |
| 35 | // the changed value to get a handle on the text field. From there it is | |
| 36 | // possible to add change the keyboard and focus behaviours. | |
| 37 | graphicProperty().addListener( ( c, o, n ) -> { | |
| 38 | if( o instanceof TextField ) { | |
| 39 | o.removeEventHandler( KEY_RELEASED, mKeyHandler ); | |
| 40 | o.focusedProperty().removeListener( mFocusListener ); | |
| 41 | } | |
| 42 | ||
| 43 | if( n instanceof TextField ) { | |
| 44 | n.addEventFilter( KEY_RELEASED, mKeyHandler ); | |
| 45 | final var input = (TextField) n; | |
| 46 | mInputText.bind( input.textProperty() ); | |
| 47 | mFocusListener = new FocusListener( input ); | |
| 48 | n.focusedProperty().addListener( mFocusListener ); | |
| 49 | } | |
| 50 | } ); | |
| 51 | } | |
| 52 | ||
| 53 | private void commitEdit() { | |
| 54 | commitEdit( getConverter().fromString( mInputText.getValue() ) ); | |
| 55 | } | |
| 56 | ||
| 57 | /** | |
| 58 | * Responsible for accepting the text when users press the Enter or Tab key. | |
| 59 | */ | |
| 60 | private class KeyHandler implements EventHandler<KeyEvent> { | |
| 61 | @Override | |
| 62 | public void handle( final KeyEvent event ) { | |
| 63 | if( event.getCode() == ENTER || event.getCode() == TAB ) { | |
| 64 | commitEdit(); | |
| 65 | event.consume(); | |
| 66 | } | |
| 67 | } | |
| 68 | } | |
| 69 | ||
| 70 | /** | |
| 71 | * Responsible for committing edits when focus is lost. This will also | |
| 72 | * deselect the input field when focus is gained so that typing text won't | |
| 73 | * overwrite the entire existing text. | |
| 74 | */ | |
| 75 | private class FocusListener implements ChangeListener<Boolean> { | |
| 76 | private final TextField mInput; | |
| 77 | ||
| 78 | private FocusListener( final TextField input ) { | |
| 79 | mInput = input; | |
| 80 | } | |
| 81 | ||
| 82 | @Override | |
| 83 | public void changed( | |
| 84 | final ObservableValue<? extends Boolean> c, | |
| 85 | final Boolean endedFocus, final Boolean beganFocus ) { | |
| 86 | ||
| 87 | if( beganFocus ) { | |
| 88 | runLater( mInput::deselect ); | |
| 89 | } | |
| 90 | else if( endedFocus ) { | |
| 91 | commitEdit(); | |
| 92 | } | |
| 93 | } | |
| 94 | } | |
| 95 | } | |
| 1 | 96 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.ui.tree; | |
| 3 | // <p> | |
| 4 | * TODO: #22 -- Upon refactoring variable functionality, re-instate drag & drop. | |
| 5 | * </p>} | |
| 1 | 6 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.ui.tree; | |
| 3 | ||
| 4 | import javafx.scene.control.TreeItem; | |
| 5 | import javafx.scene.control.TreeView; | |
| 6 | import javafx.util.StringConverter; | |
| 7 | ||
| 8 | /** | |
| 9 | * Responsible for allowing users to edit items in the tree as well as | |
| 10 | * drag and drop. The goal is to be a drop-in replacement for the regular | |
| 11 | * JavaFX {@link TreeView}, which does not offer editing and moving {@link | |
| 12 | * TreeItem} instances. | |
| 13 | * | |
| 14 | * @param <T> The type of data to edit. | |
| 15 | */ | |
| 16 | public class AltTreeView<T> extends TreeView<T> { | |
| 17 | public AltTreeView( | |
| 18 | final TreeItem<T> root, final StringConverter<T> converter ) { | |
| 19 | super( root ); | |
| 20 | ||
| 21 | setEditable( true ); | |
| 22 | setCellFactory( new AltTreeCellFactory<>( converter ) ); | |
| 23 | setShowRoot( false ); | |
| 24 | ||
| 25 | // When focus is lost, clear the selected item only when not editing. | |
| 26 | focusedProperty().addListener( ( c, o, n ) -> { | |
| 27 | if( o && getEditingItem() == null ) { | |
| 28 | getSelectionModel().clearSelection(); | |
| 29 | } | |
| 30 | } ); | |
| 31 | } | |
| 32 | } | |
| 1 | 33 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.ui.tree; | |
| 3 | ||
| 4 | import javafx.util.StringConverter; | |
| 5 | ||
| 6 | /** | |
| 7 | * Responsible for converting objects to and from string instances. The | |
| 8 | * tree items contain only strings, so this effectively is a string-to-string | |
| 9 | * converter, which allows the implementation to retain its generics. | |
| 10 | */ | |
| 11 | public class TreeItemConverter extends StringConverter<String> { | |
| 12 | ||
| 13 | @Override | |
| 14 | public String toString( final String object ) { | |
| 15 | return sanitize( object ); | |
| 16 | } | |
| 17 | ||
| 18 | @Override | |
| 19 | public String fromString( final String string ) { | |
| 20 | return sanitize( string ); | |
| 21 | } | |
| 22 | ||
| 23 | private String sanitize( final String string ) { | |
| 24 | return string == null ? "" : string; | |
| 25 | } | |
| 26 | } | |
| 1 | 27 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.util; | |
| 3 | ||
| 4 | import java.util.LinkedHashMap; | |
| 5 | import java.util.Map; | |
| 1 | 6 | |
| 7 | /** | |
| 8 | * A map that removes the oldest entry once its capacity (cache size) has | |
| 9 | * been reached. |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.util; | |
| 3 | ||
| 4 | import java.util.List; | |
| 5 | import java.util.ListIterator; | |
| 6 | import java.util.NoSuchElementException; | |
| 7 | ||
| 8 | /** | |
| 9 | * Responsible for iterating over a list either forwards or backwards. When | |
| 10 | * the iterator reaches the last element in the list, the next element will | |
| 11 | * be the first. When the iterator reaches the first element in the list, | |
| 12 | * the previous element will be the last. | |
| 13 | * <p> | |
| 14 | * Due to the ability to move forwards and backwards through the list, rather | |
| 15 | * than force client classes to track the list index independently, this | |
| 16 | * iterator provides an accessor to the index. The index is zero-based. | |
| 17 | * </p> | |
| 18 | * | |
| 19 | * @param <T> The type of list to be cycled. | |
| 20 | */ | |
| 21 | public final class CyclicIterator<T> implements ListIterator<T> { | |
| 22 | private final List<T> mList; | |
| 23 | ||
| 24 | /** | |
| 25 | * Initialize to an invalid index so that the first calls to either | |
| 26 | * {@link #previous()} or {@link #next()} will return the starting or ending | |
| 27 | * element. | |
| 28 | */ | |
| 29 | private int mIndex = -1; | |
| 30 | ||
| 31 | /** | |
| 32 | * Creates an iterator that cycles indefinitely through the given list. | |
| 33 | * | |
| 34 | * @param list The list to cycle through indefinitely. | |
| 35 | */ | |
| 36 | public CyclicIterator( final List<T> list ) { | |
| 37 | mList = list; | |
| 38 | } | |
| 39 | ||
| 40 | /** | |
| 41 | * @return {@code true} if there is at least one element. | |
| 42 | */ | |
| 43 | @Override | |
| 44 | public boolean hasNext() { | |
| 45 | return !mList.isEmpty(); | |
| 46 | } | |
| 47 | ||
| 48 | /** | |
| 49 | * @return {@code true} if there is at least one element. | |
| 50 | */ | |
| 51 | @Override | |
| 52 | public boolean hasPrevious() { | |
| 53 | return !mList.isEmpty(); | |
| 54 | } | |
| 55 | ||
| 56 | @Override | |
| 57 | public int nextIndex() { | |
| 58 | return computeIndex( +1 ); | |
| 59 | } | |
| 60 | ||
| 61 | @Override | |
| 62 | public int previousIndex() { | |
| 63 | return computeIndex( -1 ); | |
| 64 | } | |
| 65 | ||
| 66 | @Override | |
| 67 | public void remove() { | |
| 68 | mList.remove( mIndex ); | |
| 69 | } | |
| 70 | ||
| 71 | @Override | |
| 72 | public void set( final T t ) { | |
| 73 | mList.set( mIndex, t ); | |
| 74 | } | |
| 75 | ||
| 76 | @Override | |
| 77 | public void add( final T t ) { | |
| 78 | mList.add( mIndex, t ); | |
| 79 | } | |
| 80 | ||
| 81 | /** | |
| 82 | * Returns the next item in the list, which will cycle to the first | |
| 83 | * item as necessary. | |
| 84 | * | |
| 85 | * @return The next item in the list, cycling to the start if needed. | |
| 86 | */ | |
| 87 | @Override | |
| 88 | public T next() { | |
| 89 | return cycle( +1 ); | |
| 90 | } | |
| 91 | ||
| 92 | /** | |
| 93 | * Returns the previous item in the list, which will cycle to the last | |
| 94 | * item as necessary. | |
| 95 | * | |
| 96 | * @return The previous item in the list, cycling to the end if needed. | |
| 97 | */ | |
| 98 | @Override | |
| 99 | public T previous() { | |
| 100 | return cycle( -1 ); | |
| 101 | } | |
| 102 | ||
| 103 | /** | |
| 104 | * Cycles to the next or previous element, depending on the direction value. | |
| 105 | * | |
| 106 | * @param direction Use -1 for previous, +1 for next. | |
| 107 | * @return The next or previous item in the list. | |
| 108 | */ | |
| 109 | private T cycle( final int direction ) { | |
| 110 | try { | |
| 111 | return mList.get( mIndex = computeIndex( direction ) ); | |
| 112 | } catch( final Exception ex ) { | |
| 113 | throw new NoSuchElementException( ex ); | |
| 114 | } | |
| 115 | } | |
| 116 | ||
| 117 | /** | |
| 118 | * Returns the index of the value retrieved from the most recent call to | |
| 119 | * either {@link #previous()} or {@link #next()}. | |
| 120 | * | |
| 121 | * @return The list item index or -1 if no calls have been made to retrieve | |
| 122 | * an item from the list. | |
| 123 | */ | |
| 124 | public int getIndex() { | |
| 125 | return mIndex; | |
| 126 | } | |
| 127 | ||
| 128 | private int computeIndex( final int direction ) { | |
| 129 | final var i = mIndex + direction; | |
| 130 | final var size = mList.size(); | |
| 131 | final var result = i < 0 | |
| 132 | ? size - 1 | |
| 133 | : size == 0 ? 0 : i % size; | |
| 134 | ||
| 135 | // Ensure the invariant holds. | |
| 136 | assert 0 <= result && result < size || size == 0 && result <= 0; | |
| 137 | ||
| 138 | return result; | |
| 139 | } | |
| 140 | } | |
| 1 | 141 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.util; | |
| 3 | ||
| 4 | import com.keenwrite.preview.HtmlPreview; | |
| 1 | 5 | |
| 6 | import java.awt.*; | |
| 7 | import java.awt.font.TextAttribute; | |
| 8 | import java.io.FileInputStream; | |
| 9 | import java.io.IOExevents.StatusEvent |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.util; | |
| 3 | ||
| 4 | import java.util.ArrayList; | |
| 5 | import java.util.List; | |
| 6 | import java.util.function.BiConsumer; | |
| 7 | import java.util.function.Consumer; | |
| 8 | import java.util.function.Function; | |
| 9 | import java.util.function.Supplier; | |
| 10 | ||
| 11 | /** | |
| 12 | * Responsible for constructing objects that would otherwise require | |
| 13 | * a long list of constructor parameters. | |
| 14 | * <p> | |
| 15 | * See <a href="https://stackoverflow.com/a/31754787/59087">source</a> for | |
| 16 | * details. | |
| 17 | * </p> | |
| 18 | * | |
| 19 | * @param <MT> The mutable definition for the type of object to build. | |
| 20 | * @param <IT> The immutable definition for the type of object to build. | |
| 21 | */ | |
| 22 | public class GenericBuilder<MT, IT> { | |
| 23 | /** | |
| 24 | * Provides the methods to use for setting object properties. | |
| 25 | */ | |
| 26 | private final Supplier<MT> mMutable; | |
| 27 | ||
| 28 | /** | |
| 29 | * Calling {@link #build()} will instantiate the immutable instance using | |
| 30 | * the mutator. | |
| 31 | */ | |
| 32 | private final Function<MT, IT> mImmutable; | |
| 33 | ||
| 34 | /** | |
| 35 | * Adds a modifier to call when building an instance. | |
| 36 | */ | |
| 37 | private final List<Consumer<MT>> mModifiers = new ArrayList<>(); | |
| 38 | ||
| 39 | /** | |
| 40 | * Constructs a new builder instance that is capable of populating values for | |
| 41 | * any type of object. | |
| 42 | * | |
| 43 | * @param mutator Provides methods to use for setting object properties. | |
| 44 | */ | |
| 45 | protected GenericBuilder( | |
| 46 | final Supplier<MT> mutator, final Function<MT, IT> immutable ) { | |
| 47 | assert mutator != null; | |
| 48 | assert immutable != null; | |
| 49 | ||
| 50 | mMutable = mutator; | |
| 51 | mImmutable = immutable; | |
| 52 | } | |
| 53 | ||
| 54 | /** | |
| 55 | * Starting point for building an instance of a particular class. | |
| 56 | * | |
| 57 | * @param supplier Returns the instance to build. | |
| 58 | * @param <MT> The type of class to build. | |
| 59 | * @return A new {@link GenericBuilder} capable of populating data for an | |
| 60 | * instance of the class provided by the {@link Supplier}. | |
| 61 | */ | |
| 62 | public static <MT, IT> GenericBuilder<MT, IT> of( | |
| 63 | final Supplier<MT> supplier, final Function<MT, IT> immutable ) { | |
| 64 | return new GenericBuilder<>( supplier, immutable ); | |
| 65 | } | |
| 66 | ||
| 67 | /** | |
| 68 | * Registers a new value with the builder. | |
| 69 | * | |
| 70 | * @param consumer Accepts a value to be set upon the built object. | |
| 71 | * @param value The value to use when building. | |
| 72 | * @param <V> The type of value used when building. | |
| 73 | * @return This {@link GenericBuilder} instance. | |
| 74 | */ | |
| 75 | public <V> GenericBuilder<MT, IT> with( | |
| 76 | final BiConsumer<MT, V> consumer, final V value ) { | |
| 77 | mModifiers.add( instance -> consumer.accept( instance, value ) ); | |
| 78 | return this; | |
| 79 | } | |
| 80 | ||
| 81 | /** | |
| 82 | * Instantiates then populates the immutable object to build. | |
| 83 | * | |
| 84 | * @return The newly built object. | |
| 85 | */ | |
| 86 | public IT build() { | |
| 87 | final var value = mMutable.get(); | |
| 88 | mModifiers.forEach( modifier -> modifier.accept( value ) ); | |
| 89 | mModifiers.clear(); | |
| 90 | return mImmutable.apply( value ); | |
| 91 | } | |
| 92 | } | |
| 1 | 93 |
| 1 | package com.keenwrite.util; | |
| 2 | ||
| 3 | /** | |
| 4 | * The MurmurHash3 algorithm was created by Austin Appleby and placed in the | |
| 5 | * public domain. This Java port was authored by Yonik Seeley and also placed | |
| 6 | * into the public domain. The author hereby disclaims copyright to this | |
| 7 | * source code. | |
| 8 | * <p> | |
| 9 | * This produces exactly the same hash values as the final C++ version and is | |
| 10 | * thus suitable for producing the same hash values across platforms. | |
| 11 | * <p> | |
| 12 | * The 32-bit x86 version of this hash should be the fastest variant for | |
| 13 | * relatively short keys like ids. Using {@link #hash32} is a | |
| 14 | * good choice for longer strings or returning more than 32 hashed bits. | |
| 15 | * <p> | |
| 16 | * The x86 and x64 versions do not produce the same results because | |
| 17 | * algorithms are optimized for their respective platforms. | |
| 18 | * <p> | |
| 19 | * Code clean-up by White Magic Software, Ltd. | |
| 20 | * </p> | |
| 21 | */ | |
| 22 | public final class MurmurHash { | |
| 23 | /** | |
| 24 | * Returns the 32-bit x86-optimized hash of the UTF-8 bytes of the String | |
| 25 | * without actually encoding the string to a temporary buffer. This is over | |
| 26 | * twice as fast as hashing the result of {@link String#getBytes()}. | |
| 27 | */ | |
| 28 | @SuppressWarnings( "unused" ) | |
| 29 | public static int hash32( CharSequence data, int offset, int len, int seed ) { | |
| 30 | final int c1 = 0xcc9e2d51; | |
| 31 | final int c2 = 0x1b873593; | |
| 32 | ||
| 33 | int h1 = seed; | |
| 34 | ||
| 35 | int pos = offset; | |
| 36 | int end = offset + len; | |
| 37 | int k1 = 0; | |
| 38 | int k2; | |
| 39 | int shift = 0; | |
| 40 | int bits; | |
| 41 | int nBytes = 0; // length in UTF8 bytes | |
| 42 | ||
| 43 | while( pos < end ) { | |
| 44 | int code = data.charAt( pos++ ); | |
| 45 | if( code < 0x80 ) { | |
| 46 | k2 = code; | |
| 47 | bits = 8; | |
| 48 | } | |
| 49 | else if( code < 0x800 ) { | |
| 50 | k2 = (0xC0 | (code >> 6)) | |
| 51 | | ((0x80 | (code & 0x3F)) << 8); | |
| 52 | bits = 16; | |
| 53 | } | |
| 54 | else if( code < 0xD800 || code > 0xDFFF || pos >= end ) { | |
| 55 | // we check for pos>=end to encode an unpaired surrogate as 3 bytes. | |
| 56 | k2 = (0xE0 | (code >> 12)) | |
| 57 | | ((0x80 | ((code >> 6) & 0x3F)) << 8) | |
| 58 | | ((0x80 | (code & 0x3F)) << 16); | |
| 59 | bits = 24; | |
| 60 | } | |
| 61 | else { | |
| 62 | // surrogate pair | |
| 63 | // int utf32 = pos < end ? (int) data.charAt(pos++) : 0; | |
| 64 | int utf32 = data.charAt( pos++ ); | |
| 65 | utf32 = ((code - 0xD7C0) << 10) + (utf32 & 0x3FF); | |
| 66 | k2 = (0xff & (0xF0 | (utf32 >> 18))) | |
| 67 | | ((0x80 | ((utf32 >> 12) & 0x3F))) << 8 | |
| 68 | | ((0x80 | ((utf32 >> 6) & 0x3F))) << 16 | |
| 69 | | (0x80 | (utf32 & 0x3F)) << 24; | |
| 70 | bits = 32; | |
| 71 | } | |
| 72 | ||
| 73 | k1 |= k2 << shift; | |
| 74 | ||
| 75 | // int used_bits = 32 - shift; // how many bits of k2 were used in k1. | |
| 76 | // int unused_bits = bits - used_bits; // (bits-(32-shift)) == | |
| 77 | // bits+shift-32 == bits-newshift | |
| 78 | ||
| 79 | shift += bits; | |
| 80 | if( shift >= 32 ) { | |
| 81 | // mix after we have a complete word | |
| 82 | ||
| 83 | k1 *= c1; | |
| 84 | k1 = (k1 << 15) | (k1 >>> 17); // ROTL32(k1,15); | |
| 85 | k1 *= c2; | |
| 86 | ||
| 87 | h1 ^= k1; | |
| 88 | h1 = (h1 << 13) | (h1 >>> 19); // ROTL32(h1,13); | |
| 89 | h1 = h1 * 5 + 0xe6546b64; | |
| 90 | ||
| 91 | shift -= 32; | |
| 92 | // unfortunately, java won't let you shift 32 bits off, so we need to | |
| 93 | // check for 0 | |
| 94 | if( shift != 0 ) { | |
| 95 | k1 = k2 >>> (bits - shift); // bits used == bits - newshift | |
| 96 | } | |
| 97 | else { | |
| 98 | k1 = 0; | |
| 99 | } | |
| 100 | nBytes += 4; | |
| 101 | } | |
| 102 | ||
| 103 | } // inner | |
| 104 | ||
| 105 | // handle tail | |
| 106 | if( shift > 0 ) { | |
| 107 | nBytes += shift >> 3; | |
| 108 | k1 *= c1; | |
| 109 | k1 = (k1 << 15) | (k1 >>> 17); // ROTL32(k1,15); | |
| 110 | k1 *= c2; | |
| 111 | h1 ^= k1; | |
| 112 | } | |
| 113 | ||
| 114 | // finalization | |
| 115 | h1 ^= nBytes; | |
| 116 | ||
| 117 | // fmix(h1); | |
| 118 | h1 ^= h1 >>> 16; | |
| 119 | h1 *= 0x85ebca6b; | |
| 120 | h1 ^= h1 >>> 13; | |
| 121 | h1 *= 0xc2b2ae35; | |
| 122 | h1 ^= h1 >>> 16; | |
| 123 | ||
| 124 | return h1; | |
| 125 | } | |
| 126 | } | |
| 1 | 127 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.util; | |
| 3 | ||
| 4 | import java.io.File; | |
| 5 | import java.net.URI; | |
| 6 | import java.net.URL; | |
| 7 | ||
| 8 | import static com.keenwrite.events.StatusEvent.clue; | |
| 1 | 9 | |
| 10 | /** | |
| 11 | * Represents the type of dclue( ex ); |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.util; | |
| 1 | 3 | |
| 4 | import java.io.IOException; | |
| 5 | import java.net.URISyntaxException; | |
| 6 | import java.nio.file.FileSystem; | |
| 7 | import java.nio.file.Files; | |
| 8 | import java.nio.file.Patfinal |
| 1 | # R Scripts | |
| 1 | 2 | |
| 3 | These R scripts illustrate how R can be used within an application to perform calculations using variables. Authors are free to write their own scripts, of course. These scripts serve as an example of how to automate certain tasks while writicalculate a total for all numeric columns |
| 1 | # ######################################################################## | |
| 2 | # | |
| 3 | # Substitute R expressions in a document with their evaluated value. The | |
| 4 | # anchor variable must be set for functions that use relative dates. | |
| 5 | # | |
| 6 | # ######################################################################## | |
| 7 | ||
| 8 | # Evaluates an expression; writes s if there is no expression. | |
| 9 | x <- function( s ) { | |
| 10 | return( | |
| 11 | tryCatch({ | |
| 12 | r = eval( parse( text=s ) ) | |
| 13 | ||
| 14 | # If the result isn't primitive, then it was probably parsed into | |
| 15 | # an unprintable object (e.g., "gray" becomes a colour). In those | |
| 16 | # cases, return the original text string. Otherwise, an atomic | |
| 17 | # value means a primitive type (string, integer, etc.) that can be | |
| 18 | # written directly into the document. | |
| 19 | # | |
| 20 | # See: http://stackoverflow.com/a/19501276/59087 | |
| 21 | if( is.atomic( r ) ) { | |
| 22 | r | |
| 23 | } | |
| 24 | else { | |
| 25 | s | |
| 26 | } | |
| 27 | }, | |
| 28 | warning = function( w ) { | |
| 29 | s | |
| 30 | }, | |
| 31 | error = function( e ) { | |
| 32 | s | |
| 33 | }) | |
| 34 | ) | |
| 35 | } | |
| 36 | ||
| 37 | # Returns a date offset by a given number of days, relative to the given | |
| 38 | # date (d). This does not use the anchor, but is used to get the anchor's | |
| 39 | # value as a date. | |
| 40 | when <- function( d, n = 0, format = "%Y-%m-%d" ) { | |
| 41 | as.Date( d, format = format ) + x( n ) | |
| 42 | } | |
| 43 | ||
| 44 | # Full date (s) offset by an optional number of days before or after. | |
| 45 | # This will remove leading zeros (applying leading spaces instead, which | |
| 46 | # are ignored by any worthwhile typesetting engine). | |
| 47 | annal <- function( days = 0, format = "%Y-%m-%d", oformat = "%B %d, %Y" ) { | |
| 48 | format( when( anchor, days ), format = oformat ) | |
| 49 | } | |
| 50 | ||
| 51 | # Extracts the year from a date string. | |
| 52 | year <- function( days = 0, format = "%Y-%m-%d" ) { | |
| 53 | annal( days, format, "%Y" ) | |
| 54 | } | |
| 55 | ||
| 56 | # Day of the week (in days since the anchor date). | |
| 57 | weekday <- function( n ) { | |
| 58 | weekdays( when( anchor, n ) ) | |
| 59 | } | |
| 60 | ||
| 61 | # String concatenate function alias because paste0 is a terrible name. | |
| 62 | concat <- paste0 | |
| 63 | ||
| 64 | # Translates a number from digits to words using Chicago Manual of Style. | |
| 65 | # This does not translate numbers greater than one hundred. If ordinal | |
| 66 | # is TRUE, this will return the ordinal name. This will not produce ordinals | |
| 67 | # for numbers greater than 100 | |
| 68 | cms <- function( n, ordinal = FALSE ) { | |
| 69 | n <- x( n ) | |
| 70 | ||
| 71 | # We're done here. | |
| 72 | if( n == 0 ) { | |
| 73 | if( ordinal ) { | |
| 74 | return( "zeroth" ) | |
| 75 | } | |
| 76 | ||
| 77 | return( "zero" ) | |
| 78 | } | |
| 79 | ||
| 80 | # Concatenate this a little later. | |
| 81 | if( n < 0 ) { | |
| 82 | result = "negative " | |
| 83 | n = abs( n ) | |
| 84 | } | |
| 85 | ||
| 86 | # Do not spell out numbers greater than one hundred. | |
| 87 | if( n > 100 ) { | |
| 88 | # Comma-separated numbers. | |
| 89 | return( format( n, big.mark=",", trim=TRUE, scientific=FALSE ) ) | |
| 90 | } | |
| 91 | ||
| 92 | # Don't go beyond 100. | |
| 93 | if( n == 100 ) { | |
| 94 | if( ordinal ) { | |
| 95 | return( "one hundredth" ) | |
| 96 | } | |
| 97 | ||
| 98 | return( "one hundred" ) | |
| 99 | } | |
| 100 | ||
| 101 | # Samuel Langhorne Clemens noted English has too many exceptions. | |
| 102 | small = c( | |
| 103 | "one", "two", "three", "four", "five", | |
| 104 | "six", "seven", "eight", "nine", "ten", | |
| 105 | "eleven", "twelve", "thirteen", "fourteen", "fifteen", | |
| 106 | "sixteen", "seventeen", "eighteen", "nineteen" | |
| 107 | ) | |
| 108 | ||
| 109 | ord_small = c( | |
| 110 | "first", "second", "third", "fourth", "fifth", | |
| 111 | "sixth", "seventh", "eighth", "ninth", "tenth", | |
| 112 | "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth", | |
| 113 | "sixteenth", "seventeenth", "eighteenth", "nineteenth", "twentieth" | |
| 114 | ) | |
| 115 | ||
| 116 | # After this, the number (n) is between 20 and 99. | |
| 117 | if( n < 20 ) { | |
| 118 | if( ordinal ) { | |
| 119 | return( .subset( ord_small, n %% 100 ) ) | |
| 120 | } | |
| 121 | ||
| 122 | return( .subset( small, n %% 100 ) ) | |
| 123 | } | |
| 124 | ||
| 125 | tens = c( "", | |
| 126 | "twenty", "thirty", "forty", "fifty", | |
| 127 | "sixty", "seventy", "eighty", "ninety" | |
| 128 | ) | |
| 129 | ||
| 130 | ord_tens = c( "", | |
| 131 | "twentieth", "thirtieth", "fortieth", "fiftieth", | |
| 132 | "sixtieth", "seventieth", "eightieth", "ninetieth" | |
| 133 | ) | |
| 134 | ||
| 135 | ones_index = n %% 10 | |
| 136 | n = n %/% 10 | |
| 137 | ||
| 138 | # No number in the ones column, so the number must be a multiple of ten. | |
| 139 | if( ones_index == 0 ) { | |
| 140 | if( ordinal ) { | |
| 141 | return( .subset( ord_tens, n ) ) | |
| 142 | } | |
| 143 | ||
| 144 | return( .subset( tens, n ) ) | |
| 145 | } | |
| 146 | ||
| 147 | # Find the value from the ones column. | |
| 148 | if( ordinal ) { | |
| 149 | unit_1 = .subset( ord_small, ones_index ) | |
| 150 | } | |
| 151 | else { | |
| 152 | unit_1 = .subset( small, ones_index ) | |
| 153 | } | |
| 154 | ||
| 155 | # Find the tens column. | |
| 156 | unit_10 = .subset( tens, n ) | |
| 157 | ||
| 158 | # Hyphenate the tens and the ones together. | |
| 159 | concat( unit_10, concat( "-", unit_1 ) ) | |
| 160 | } | |
| 161 | ||
| 162 | # Returns a human-readable string that provides the elapsed time between | |
| 163 | # two numbers in terms of years, months, and days. If any unit value is zero, | |
| 164 | # the unit is not included. The words (year, month, day) are pluralized | |
| 165 | # according to English grammar. The numbers are written out according to | |
| 166 | # Chicago Manual of Style. This applies the serial comma. | |
| 167 | # | |
| 168 | # Both numbers are offsets relative to the anchor date. | |
| 169 | # | |
| 170 | # If all unit values are zero, this returns s ("same day" by default). | |
| 171 | # | |
| 172 | # If the start date (began) is greater than end date (ended), the dates are | |
| 173 | # swapped before calculations are performed. This allows any two dates | |
| 174 | # to be compared and positive unit values are always returned. | |
| 175 | # | |
| 176 | elapsed <- function( began, ended, s = "same day" ) { | |
| 177 | began = when( anchor, began ) | |
| 178 | ended = when( anchor, ended ) | |
| 179 | ||
| 180 | # Swap the dates if the end date comes before the start date. | |
| 181 | if( as.integer( ended - began ) < 0 ) { | |
| 182 | tempd = began | |
| 183 | began = ended | |
| 184 | ended = tempd | |
| 185 | } | |
| 186 | ||
| 187 | # Calculate number of elapsed years. | |
| 188 | years = length( seq( from = began, to = ended, by = 'year' ) ) - 1 | |
| 189 | ||
| 190 | # Move the start date up by the number of elapsed years. | |
| 191 | if( years > 0 ) { | |
| 192 | began = seq( began, length = 2, by = concat( years, " years" ) )[2] | |
| 193 | years = pl.numeric( "year", years ) | |
| 194 | } | |
| 195 | else { | |
| 196 | # Zero years. | |
| 197 | years = "" | |
| 198 | } | |
| 199 | ||
| 200 | # Calculate number of elapsed months, excluding years. | |
| 201 | months = length( seq( from = began, to = ended, by = 'month' ) ) - 1 | |
| 202 | ||
| 203 | # Move the start date up by the number of elapsed months | |
| 204 | if( months > 0 ) { | |
| 205 | began = seq( began, length = 2, by = concat( months, " months" ) )[2] | |
| 206 | months = pl.numeric( "month", months ) | |
| 207 | } | |
| 208 | else { | |
| 209 | # Zero months | |
| 210 | months = "" | |
| 211 | } | |
| 212 | ||
| 213 | # Calculate number of elapsed days, excluding months and years. | |
| 214 | days = length( seq( from = began, to = ended, by = 'day' ) ) - 1 | |
| 215 | ||
| 216 | if( days > 0 ) { | |
| 217 | days = pl.numeric( "day", days ) | |
| 218 | } | |
| 219 | else { | |
| 220 | # Zero days | |
| 221 | days = "" | |
| 222 | } | |
| 223 | ||
| 224 | if( years <= 0 && months <= 0 && days <= 0 ) { | |
| 225 | return( s ) | |
| 226 | } | |
| 227 | ||
| 228 | # Put them all in a vector, then remove the empty values. | |
| 229 | s <- c( years, months, days ) | |
| 230 | s <- s[ s != "" ] | |
| 231 | ||
| 232 | r <- paste( s, collapse = ", " ) | |
| 233 | ||
| 234 | # If all three items are present, replace the last comma with ", and". | |
| 235 | if( length( s ) > 2 ) { | |
| 236 | return( gsub( "(.*),", "\\1, and", r ) ) | |
| 237 | } | |
| 238 | ||
| 239 | # Does nothing if no commas are present. | |
| 240 | gsub( "(.*),", "\\1 and", r ) | |
| 241 | } | |
| 242 | ||
| 243 | # Returns the number (n) in English followed by the plural or singular | |
| 244 | # form of the given string (s; resumably a noun), if applicable, according | |
| 245 | # to English grammar. That is, pl.numeric( "wolf", 5 ) will return | |
| 246 | # "five wolves". | |
| 247 | pl.numeric <- function( s, n ) { | |
| 248 | concat( cms( n ), concat( " ", pluralize( s, n ) ) ) | |
| 249 | } | |
| 250 | ||
| 251 | # Name of the season, starting with an capital letter. | |
| 252 | season <- function( n, format = "%Y-%m-%d" ) { | |
| 253 | WS <- as.Date("2016-12-15", "%Y-%m-%d") # Winter Solstice | |
| 254 | SE <- as.Date("2016-03-15", "%Y-%m-%d") # Spring Equinox | |
| 255 | SS <- as.Date("2016-06-15", "%Y-%m-%d") # Summer Solstice | |
| 256 | AE <- as.Date("2016-09-15", "%Y-%m-%d") # Autumn Equinox | |
| 257 | ||
| 258 | d <- when( anchor, n ) | |
| 259 | d <- as.Date( strftime( d, format="2016-%m-%d" ) ) | |
| 260 | ||
| 261 | ifelse( d >= WS | d < SE, "Winter", | |
| 262 | ifelse( d >= SE & d < SS, "Spring", | |
| 263 | ifelse( d >= SS & d < AE, "Summer", "Autumn" ) | |
| 264 | ) | |
| 265 | ) | |
| 266 | } | |
| 267 | ||
| 268 | # Converts the first letter in a string to lowercase | |
| 269 | lc <- function( s ) { | |
| 270 | concat( tolower( substr( s, 1, 1 ) ), substr( s, 2, nchar( s ) ) ) | |
| 271 | } | |
| 272 | ||
| 273 | # Converts the first letter in a string to uppercase | |
| 274 | uc <- function( s ) { | |
| 275 | concat( toupper( substr( s, 1, 1 ) ), substr( s, 2, nchar( s ) ) ) | |
| 276 | } | |
| 277 | ||
| 278 | # Returns the number of days between the given dates. | |
| 279 | days <- function( d1, d2, format = "%Y-%m-%d" ) { | |
| 280 | dates = c( d1, d2 ) | |
| 281 | dt = strptime( dates, format = format ) | |
| 282 | as.integer( difftime( dates[2], dates[1], units = "days" ) ) | |
| 283 | } | |
| 284 | ||
| 285 | # Returns the number of years elapsed. | |
| 286 | years <- function( began, ended ) { | |
| 287 | began = when( anchor, began ) | |
| 288 | ended = when( anchor, ended ) | |
| 289 | ||
| 290 | # Swap the dates if the end date comes before the start date. | |
| 291 | if( as.integer( ended - began ) < 0 ) { | |
| 292 | tempd = began | |
| 293 | began = ended | |
| 294 | ended = tempd | |
| 295 | } | |
| 296 | ||
| 297 | # Calculate number of elapsed years. | |
| 298 | length( seq( from = began, to = ended, by = 'year' ) ) - 1 | |
| 299 | } | |
| 300 | ||
| 301 | # Full name of the month, starting with a capital letter. | |
| 302 | month <- function( n ) { | |
| 303 | # Faster than month.name[ x( n ) ] | |
| 304 | .subset( month.name, x( n ) ) | |
| 305 | } | |
| 306 | ||
| 307 | money <- function( n ) { | |
| 308 | formatC( x( n ), format="d" ) | |
| 309 | } | |
| 1 | 310 |
| 1 | # ###################################################################### | |
| 2 | # | |
| 3 | # Copyright 2016, White Magic Software, Ltd. | |
| 4 | # | |
| 5 | # Permission is hereby granted, free of charge, to any person obtaining | |
| 6 | # a copy of this software and associated documentation files (the | |
| 7 | # "Software"), to deal in the Software without restriction, including | |
| 8 | # without limitation the rights to use, copy, modify, merge, publish, | |
| 9 | # distribute, sublicense, and/or sell copies of the Software, and to | |
| 10 | # permit persons to whom the Software is furnished to do so, subject to | |
| 11 | # the following conditions: | |
| 12 | # | |
| 13 | # The above copyright notice and this permission notice shall be | |
| 14 | # included in all copies or substantial portions of the Software. | |
| 15 | # | |
| 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
| 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
| 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
| 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
| 20 | # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
| 21 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
| 22 | # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| 23 | # | |
| 24 | # ###################################################################### | |
| 25 | ||
| 26 | # ###################################################################### | |
| 27 | # | |
| 28 | # Converts CSV to Markdown. | |
| 29 | # | |
| 30 | # ###################################################################### | |
| 31 | ||
| 32 | # Reads a CSV file and converts the contents to a Markdown table. The | |
| 33 | # file must be in the working directory as specified by setwd. | |
| 34 | # | |
| 35 | # @param f The filename to convert. | |
| 36 | # @param decimals Rounded decimal places (default 1). | |
| 37 | # @param totals Include total sums (default TRUE). | |
| 38 | # @param align Right-align numbers (default TRUE). | |
| 39 | csv2md <- function( f, decimals = 1, totals = T, align = T ) { | |
| 40 | # Read the CVS data from the file; ensure strings become characters. | |
| 41 | df <- read.table( f, sep=',', header=T, stringsAsFactors=F ) | |
| 42 | ||
| 43 | if( totals ) { | |
| 44 | # Determine what columns can be summed. | |
| 45 | number <- which( unlist( lapply( df, is.numeric ) ) ) | |
| 46 | ||
| 47 | # Use colSums when more than one summable column exists. | |
| 48 | if( length( number ) > 1 ) { | |
| 49 | f.sum <- colSums | |
| 50 | } | |
| 51 | else { | |
| 52 | f.sum <- sum | |
| 53 | } | |
| 54 | ||
| 55 | # Calculate the sum of all the summable columns and insert the | |
| 56 | # results back into the data frame. | |
| 57 | df[ (nrow( df ) + 1), number ] <- f.sum( df[, number], na.rm=TRUE ) | |
| 58 | ||
| 59 | # pluralize would be heavyweight here. | |
| 60 | if( length( number ) > 1 ) { | |
| 61 | t <- "**Totals**" | |
| 62 | } | |
| 63 | else { | |
| 64 | t <- "**Total**" | |
| 65 | } | |
| 66 | ||
| 67 | # Change the first column of the last line to "Total(s)". | |
| 68 | df[ nrow( df ), 1 ] <- t | |
| 69 | ||
| 70 | # Don't clutter the output with "NA" text. | |
| 71 | df[ is.na( df ) ] <- "" | |
| 72 | } | |
| 73 | ||
| 74 | if( align ) { | |
| 75 | is.char <- vapply( df, is.character, logical( 1 ) ) | |
| 76 | dashes <- paste( ifelse( is.char, ':---', '---:' ), collapse='|' ) | |
| 77 | } | |
| 78 | else { | |
| 79 | dashes <- paste( rep( '---', length( df ) ), collapse = '|') | |
| 80 | } | |
| 81 | ||
| 82 | # Create a Markdown version of the data frame. | |
| 83 | paste( | |
| 84 | paste( names( df ), collapse = '|'), '\n', | |
| 85 | dashes, '\n', | |
| 86 | paste( | |
| 87 | Reduce( function( x, y ) { | |
| 88 | paste( x, format( y, digits = decimals ), sep = '|' ) | |
| 89 | }, df | |
| 90 | ), | |
| 91 | collapse = '|\n', sep='' | |
| 92 | ) | |
| 93 | ) | |
| 94 | } | |
| 95 | ||
| 1 | 96 |
| 1 | # ###################################################################### | |
| 2 | # | |
| 3 | # Copyright 2016, White Magic Software, Ltd. | |
| 4 | # | |
| 5 | # Permission is hereby granted, free of charge, to any person obtaining | |
| 6 | # a copy of this software and associated documentation files (the | |
| 7 | # "Software"), to deal in the Software without restriction, including | |
| 8 | # without limitation the rights to use, copy, modify, merge, publish, | |
| 9 | # distribute, sublicense, and/or sell copies of the Software, and to | |
| 10 | # permit persons to whom the Software is furnished to do so, subject to | |
| 11 | # the following conditions: | |
| 12 | # | |
| 13 | # The above copyright notice and this permission notice shall be | |
| 14 | # included in all copies or substantial portions of the Software. | |
| 15 | # | |
| 16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
| 17 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
| 18 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |
| 19 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | |
| 20 | # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | |
| 21 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
| 22 | # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| 23 | # | |
| 24 | # ###################################################################### | |
| 25 | ||
| 26 | # ###################################################################### | |
| 27 | # | |
| 28 | # See Damian Conway's "An Algorithmic Approach to English Pluralization": | |
| 29 | # http://goo.gl/oRL4MP | |
| 30 | # See Oliver Glerke's Evo Inflector: https://github.com/atteo/evo-inflector/ | |
| 31 | # See Shevek's Pluralizer: https://github.com/shevek/linguistics/ | |
| 32 | # See also: http://www.freevectors.net/assets/files/plural.txt | |
| 33 | # | |
| 34 | # ###################################################################### | |
| 35 | ||
| 36 | pluralize <- function( s, n ) { | |
| 37 | result <- s | |
| 38 | ||
| 39 | # Partial implementation of Conway's algorithm for nouns. | |
| 40 | if( n != 1 ) { | |
| 41 | if( pl.noninflective( s ) || | |
| 42 | pl.suffix( "fish", s ) || | |
| 43 | pl.suffix( "ois", s ) || | |
| 44 | pl.suffix( "sheep", s ) || | |
| 45 | pl.suffix( "deer", s ) || | |
| 46 | pl.suffix( "pox", s ) || | |
| 47 | pl.suffix( "[A-Z].*ese", s ) || | |
| 48 | pl.suffix( "itis", s ) ) { | |
| 49 | # 1. Retain non-inflective user-mapped noun as is. | |
| 50 | # 2. Retain non-inflective plural as is. | |
| 51 | result <- s | |
| 52 | } | |
| 53 | else if( pl.is.irregular.pl( s ) ) { | |
| 54 | # 4. Change irregular plurals based on mapping. | |
| 55 | result <- pl.irregular.pl( s ) | |
| 56 | } | |
| 57 | else if( pl.is.irregular.es( s ) ) { | |
| 58 | # x. From Shevek's Pluralizer | |
| 59 | result <- pl.inflect( s, "", "es" ) | |
| 60 | } | |
| 61 | else if( pl.suffix( "man", s ) ) { | |
| 62 | # 5. For -man, change -an to -en | |
| 63 | result <- pl.inflect( s, "an", "en" ) | |
| 64 | } | |
| 65 | else if( pl.suffix( "[lm]ouse", s ) ) { | |
| 66 | # 5. For [lm]ouse, change -ouse to -ice | |
| 67 | result <- pl.inflect( s, "ouse", "ice" ) | |
| 68 | } | |
| 69 | else if( pl.suffix( "tooth", s ) ) { | |
| 70 | # 5. For -tooth, change -ooth to -eeth | |
| 71 | result <- pl.inflect( s, "ooth", "eeth" ) | |
| 72 | } | |
| 73 | else if( pl.suffix( "goose", s ) ) { | |
| 74 | # 5. For -goose, change -oose to -eese | |
| 75 | result <- pl.inflect( s, "oose", "eese" ) | |
| 76 | } | |
| 77 | else if( pl.suffix( "foot", s ) ) { | |
| 78 | # 5. For -foot, change -oot to -eet | |
| 79 | result <- pl.inflect( s, "oot", "eet" ) | |
| 80 | } | |
| 81 | else if( pl.suffix( "zoon", s ) ) { | |
| 82 | # 5. For -zoon, change -on to -a | |
| 83 | result <- pl.inflect( s, "on", "a" ) | |
| 84 | } | |
| 85 | else if( pl.suffix( "[csx]is", s ) ) { | |
| 86 | # 5. Change -cis, -sis, -xis to -es | |
| 87 | result <- pl.inflect( s, "is", "es" ) | |
| 88 | } | |
| 89 | else if( pl.suffix( "([cs]h|ss)", s ) ) { | |
| 90 | # 8. Change -ch, -sh, -ss to -es | |
| 91 | result <- pl.inflect( s, "", "es" ) | |
| 92 | } | |
| 93 | else if( pl.suffix( "([aeo]lf|[^d]eaf|arf)", s ) ) { | |
| 94 | # 9. Change -f to -ves | |
| 95 | result <- pl.inflect( s, "f", "ves" ) | |
| 96 | } | |
| 97 | else if( pl.suffix( "[nlw]ife", s ) ) { | |
| 98 | # 9. Change -fe to -ves | |
| 99 | result <- pl.inflect( s, "fe", "ves" ) | |
| 100 | } | |
| 101 | else if( pl.suffix( "([aeiou]y|[A-Z].*y)", s ) ) { | |
| 102 | # 10. Change -y to -ys. | |
| 103 | result <- pl.inflect( s, "", "s" ) | |
| 104 | } | |
| 105 | else if( pl.suffix( "y", s ) ) { | |
| 106 | # 10. Change -y to -ies. | |
| 107 | result <- pl.inflect( s, "y", "ies" ) | |
| 108 | } | |
| 109 | else { | |
| 110 | # 13. Default plural: add -s. | |
| 111 | result <- pl.inflect( s, "", "s" ) | |
| 112 | } | |
| 113 | } | |
| 114 | ||
| 115 | result | |
| 116 | } | |
| 117 | ||
| 118 | # Pluralize s if n is not equal to 1. | |
| 119 | pl <- function( s, n ) { | |
| 120 | pluralize( s, x( n ) ) | |
| 121 | } | |
| 122 | ||
| 123 | # Returns the given string (s) with its suffix replaced by r. | |
| 124 | pl.inflect <- function( s, suffix, r ) { | |
| 125 | gsub( paste( suffix, "$", sep="" ), r, s ) | |
| 126 | } | |
| 127 | ||
| 128 | # Answers whether the given string (s) has the given ending. | |
| 129 | pl.suffix <- function( ending, s ) { | |
| 130 | grepl( paste( ending, "$", sep="" ), s ) | |
| 131 | } | |
| 132 | ||
| 133 | # Answers whether the given string (s) is a noninflective noun. | |
| 134 | pl.noninflective <- function( s ) { | |
| 135 | v <- c( | |
| 136 | "aircraft", "Bhutanese", "bison", "bream", "breeches", "britches", | |
| 137 | "Burmese", "carp", "chassis", "Chinese", "clippers", "cod", "contretemps", | |
| 138 | "corps", "debris", "diabetes", "djinn", "eland", "elk", "flounder", | |
| 139 | "fracas", "gallows", "graffiti", "headquarters", "herpes", "high-jinks", | |
| 140 | "homework", "hovercraft", "innings", "jackanapes", "Japanese", | |
| 141 | "Lebanese", "mackerel", "means", "measles", "mews", "mumps", "news", | |
| 142 | "pincers", "pliers", "Portuguese", "proceedings", "rabies", "salmon", | |
| 143 | "scissors", "sea-bass", "Senegalese", "series", "shears", "Siamese", | |
| 144 | "Sinhalese", "spacecraft", "species", "swine", "trout", "tuna", | |
| 145 | "Vietnamese", "watercraft", "whiting", "wildebeest" | |
| 146 | ) | |
| 147 | ||
| 148 | is.element( s, v ) | |
| 149 | } | |
| 150 | ||
| 151 | # Answers whether the given string (s) is an irregular plural. | |
| 152 | pl.is.irregular.pl <- function( s ) { | |
| 153 | # Could be refactored with pl.irregular.pl... | |
| 154 | v <- c( | |
| 155 | "beef", "brother", "child", "cow", "ephemeris", "genie", "money", | |
| 156 | "mongoose", "mythos", "octopus", "ox", "soliloquy", "trilby" | |
| 157 | ) | |
| 158 | ||
| 159 | is.element( s, v ) | |
| 160 | } | |
| 161 | ||
| 162 | # Call to pluralize an irregular noun. Only call after confirming | |
| 163 | # the noun is irregular via pl.is.irregular.pl. | |
| 164 | pl.irregular.pl <- function( s ) { | |
| 165 | v <- list( | |
| 166 | "beef" = "beefs", | |
| 167 | "brother" = "brothers", | |
| 168 | "child" = "children", | |
| 169 | "cow" = "cows", | |
| 170 | "ephemeris" = "ephemerides", | |
| 171 | "genie" = "genies", | |
| 172 | "money" = "moneys", | |
| 173 | "mongoose" = "mongooses", | |
| 174 | "mythos" = "mythoi", | |
| 175 | "octopus" = "octopuses", | |
| 176 | "ox" = "oxen", | |
| 177 | "soliloquy" = "soliloquies", | |
| 178 | "trilby" = "trilbys" | |
| 179 | ) | |
| 180 | ||
| 181 | # Faster version of v[[ s ]] | |
| 182 | .subset2( v, s ) | |
| 183 | } | |
| 184 | ||
| 185 | # Answers whether the given string (s) pluralizes with -es. | |
| 186 | pl.is.irregular.es <- function( s ) { | |
| 187 | v <- c( | |
| 188 | "acropolis", "aegis", "alias", "asbestos", "bathos", "bias", "bronchitis", | |
| 189 | "bursitis", "caddis", "cannabis", "canvas", "chaos", "cosmos", "dais", | |
| 190 | "digitalis", "epidermis", "ethos", "eyas", "gas", "glottis", "hubris", | |
| 191 | "ibis", "lens", "mantis", "marquis", "metropolis", "pathos", "pelvis", | |
| 192 | "polis", "rhinoceros", "sassafrass", "trellis" | |
| 193 | ) | |
| 194 | ||
| 195 | is.element( s, v ) | |
| 196 | } | |
| 197 | ||
| 1 | 198 |
| 1 | ||
| 1 | com.keenwrite.service.impl.DefaultSettings |
| 1 | ||
| 1 | com.keenwrite.service.events.impl.DefaultNotifier |
| 1 | # Used by the Gradle build script and the application. | |
| 2 | application.title=KeenWrite | |
| 3 | ||
| 1 | 4 |
| 1 | app.properties | |
| 1 | 2 |
| 1 | ||
| 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
| 2 | <svg | |
| 3 | xmlns:dc="http://purl.org/dc/elements/1.1/" | |
| 4 | xmlns:cc="http://creativecommons.org/ns#" | |
| 5 | xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |
| 6 | xmlns:svg="http://www.w3.org/2000/svg" | |
| 7 | 971.53119" | |
| 8 | height="498.39355" | |
| 9 | viewBox="0 0 971.53119 498.3935app-title | |
| 10 | inkscape:export-filename="/home/jarvisd/dev/java/scrivenvar/docs/images/app-title.png" | |
| 11 | inkscape:export-xdpi="24.66" | |
| 12 | inkscape:export-ydpi="24.66 /455.5775" | |
| 13 | inkscape:cy="347.59625 | |
| 14 | fit-margin-top="0" | |
| 15 | fit-margin-left="0" | |
| 16 | fit-margin-right="0" | |
| 17 | fit-margin-bottom="033 | |
| 18 | transform="translate(-394.35834,-171.20491)"opacity:1opacity:1opacity:1fill:#000000transform="translate(-394.35834,-171.20491)" />" | |
| 19 | x="311.66693" | |
| 20 | y="402.2062766693" | |
| 21 | y="402.20627 |
| 1 | #!/bin/bash | |
| 2 | ||
| 3 | INKSCAPE="/usr/bin/inkscape" | |
| 4 | PNG_COMPRESS="optipng" | |
| 5 | PNG_COMPRESS_OPTS="-o9 *png" | |
| 6 | ICO_TOOL="icotool" | |
| 7 | ICO_TOOL_OPTS="-c -o ../../../../../icons/logo.ico logo64.png" | |
| 8 | ||
| 9 | declare -a SIZES=("16" "32" "64" "128" "256" "512") | |
| 1 | 10 | |
| 11 | for i in "${SIZES[@]}"; dw "${i}" --export-overwrite --export-type=png -o "logo${i}.png" "logo.svg" |
| 1 | /* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | ||
| 3 | .markdown { | |
| 4 | -fx-font-family: 'Noto Sans'; | |
| 5 | -fx-font-size: 11pt; | |
| 6 | -fx-padding: .25em; | |
| 7 | } | |
| 8 | ||
| 9 | /* Editor background color */ | |
| 10 | .styled-text-area { | |
| 11 | -fx-background-color: -fx-control-inner-background; | |
| 12 | } | |
| 13 | ||
| 14 | /* Text foreground colour */ | |
| 15 | .styled-text-area .text { | |
| 16 | -fx-fill: -fx-text-foreground; | |
| 17 | } | |
| 1 | 18 | |
| 19 | /* Subtly highlight the current paragraph. */ | |
| 20 | .markdown .paragraph-box:has-caret { | |
| 21 | -fx-b-fx-text-background-fx-text-selection 255, 131, 67, .7 |
| 1 | 1 |
| 1 | 1 |
| 1 | 1 |
| 1 | 1 |
| 1 | 1 |
| 1 | 1 |
| 1 | .markdown { | |
| 2 | -fx-font-family: 'Noto Sans CJK JP'; | |
| 3 | } | |
| 1 | 4 |
| 1 | .markdown { | |
| 2 | -fx-font-family: 'Noto Sans CJK KR'; | |
| 3 | } | |
| 1 | 4 |
| 1 | .markdown { | |
| 2 | -fx-font-family: 'Noto Sans CJK SC'; | |
| 3 | } | |
| 1 | 4 |
| 1 | .markdown { | |
| 2 | -fx-font-family: 'Noto Sans CJK SC'; | |
| 3 | } | |
| 1 | 4 |
| 1 | .markdown { | |
| 2 | -fx-font-family: 'Noto Sans CJK HK'; | |
| 3 | } | |
| 1 | 4 |
| 1 | .markdown { | |
| 2 | -fx-font-family: 'Noto Sans CJK TC'; | |
| 3 | } | |
| 1 | 4 |
| 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
| 2 | <svg | |
| 3 | xmlns:dc="http://purl.org/dc/elements/1.1/" | |
| 4 | xmlns:cc="http://creativecommons.org/ns#" | |
| 5 | xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |
| 6 | xmlns:svg="http://www.w3.org/2000/svg" | |
| 7 | ||
| 8 | sodipodi:docname="icon.svg" | |
| 9 | id="svg52" | |
| 10 | xml:space="preserve" | |
| 11 | viewBox="0 0 512 512" | |
| 12 | height="512" | |
| 13 | width="512" | |
| 14 | version="1.1 | |
| 15 | inkscape:cy="369.17559" | |
| 16 | inkscape:cx="343.24925objecttolerance="10bordercolor="#666666id="rect933" | |
| 17 | height="175.55823" | |
| 18 | width="470.12033" | |
| 19 | y="132.06313" | |
| 20 | x="114.92139x1="0.15235768" | |
| 21 | y1="-0.0449115712="-0.049471263"> | |
| 22 | <stop | |
| 23 | offset="0%id="stop9" /> | |
| 24 | <stop | |
| 25 | offset="100%id="stop11transform="translate(-384.01706,-164.40168)"id="path14 /><path | |
| 26 | id="path22opacity:1" /><path | |
| 27 | id="path26opacity:1" /><path | |
| 28 | id="path30" /><path | |
| 29 | id="path34" /><path | |
| 30 | id="path38" /><path | |
| 31 | id="path42opacity:1" /></g> | |
| 32 | ||
| 33 | <text | |
| 34 | style="fill:#000000id="text931" | |
| 35 | xml:space="preserve" /></svg> | |
| 1 | 36 |
| 1 | # ######################################################################## | |
| 2 | # Main Application Window | |
| 3 | # ######################################################################## | |
| 4 | ||
| 5 | # suppress inspection "UnusedProperty" for whole file | |
| 1 | 6 | |
| 7 | # ##################### |
| 1 | body,h1,h2,h3,h4,h5,h6,ol,p,ul{margin:0;padding:0}img{max-width:100%;height:auto}table{table-collapse:collapse;table-spacing:0;border-spacing:0} | |
| 2 | ||
| 3 | /* Do not use points (pt): FlyingSaucer on Debian fails to render. */ | |
| 4 | bodyBULLET LISTS ***/ | |
| 5 | ul, ol { | |
| 6 | display: block; | |
| 7 | list-style: disc outside none; | |
| 8 | margin: 1em 0; | |
| 9 | padding: 0 0 0 2em; | |
| 10 | } | |
| 11 | ||
| 12 | ol { | |
| 13 | ||
| 14 | } | |
| 15 | ||
| 16 | ul ul, ol ul, | |
| 17 | ol ol, ul ol { | |
| 18 | list-style-position: inside; | |
| 19 | margin-left: 1em; | |
| 20 | } | |
| 21 | ||
| 22 | ul ul, ol ul { | |
| 23 | ||
| 24 | } | |
| 25 | ||
| 26 | ol ol, ul ol { | |
| 27 | latin; | |
| 1 | 28 |
| 1 | body { | |
| 2 | font-family: 'Noto Serif CJK JP'; | |
| 3 | } | |
| 4 | ||
| 5 | pre, code, tt { | |
| 6 | font-family: 'Noto Sans Mono CJK JP'; | |
| 7 | } | |
| 1 | 8 |
| 1 | body { | |
| 2 | font-family: 'Noto Serif CJK KR'; | |
| 3 | } | |
| 4 | ||
| 5 | pre, code, tt { | |
| 6 | font-family: 'Noto Sans Mono CJK KR'; | |
| 7 | } | |
| 1 | 8 |
| 1 | body { | |
| 2 | font-family: 'Noto Serif CJK SC'; | |
| 3 | } | |
| 4 | ||
| 5 | pre, code, tt { | |
| 6 | font-family: 'Noto Sans Mono CJK SC'; | |
| 7 | } | |
| 1 | 8 |
| 1 | body { | |
| 2 | font-family: 'Noto Serif CJK SC'; | |
| 3 | } | |
| 4 | ||
| 5 | pre, code, tt { | |
| 6 | font-family: 'Noto Sans Mono CJK SC'; | |
| 7 | } | |
| 1 | 8 |
| 1 | body { | |
| 2 | font-family: 'Noto Serif CJK SC'; | |
| 3 | } | |
| 4 | ||
| 5 | pre, code, tt { | |
| 6 | font-family: 'Noto Sans Mono CJK HK'; | |
| 7 | } | |
| 1 | 8 |
| 1 | body { | |
| 2 | font-family: 'Noto Serif CJK TC'; | |
| 3 | } | |
| 4 | ||
| 5 | pre, code, tt { | |
| 6 | font-family: 'Noto Sans Mono CJK TC'; | |
| 7 | } | |
| 1 | 8 |
| 1 | ||
| 1 | # ######################################################################## | |
| 2 | # Applicationkeenwrite | |
| 3 | file.stylesheet.application.dirthemes | |
| 4 | file.stylesheet.application.base=${file.stylesheet.application.dir}/sceneapplication.theme=${file.stylesheet.application.dir}/{0 |
| 1 | .root { | |
| 2 | -fx-base: rgb( 43, 43, 43 ); | |
| 3 | -fx-background: -fx-base;: -fx-base; | |
| 4 | 187, 187, 187 ); | |
| 5 | -fx-mid-text-color: derive( -fx-base, 100%derive( -fx-base, 25% ); | |
| 6 | -fx-text-foreground: -fx-light-text-color; | |
| 7 | -fx-text-background7.5% ); | |
| 8 | -fx-text-selection45% ); | |
| 9 | ||
| 10 | /* Make controls ( buttons, thumb, etc. ) slightly lighter */ | |
| 11 | -fx-color: derive( -fx-base20% ); | |
| 12 | } | |
| 1 | 13 | |
| 14 | .caret { | |
| 15 | -fx-stroke: -fx-accentfx-light-text-color; | |
| 16 | -fx-fill:hover { | |
| 17 | -fx-effect: dropshadow( three-pass-box, rgba( 0, 0, 0, 0.2 ), 4, 0, 0, 0 ) -fx-light-text-color |
| 1 | /* https://stackoverflow.com/a/58441758/59087 | |
| 2 | */ | |
| 3 | .root { | |
| 4 | -fx-accent: #1e74c6; | |
| 5 | -fx-focus-color: -fx-accent; | |
| 6 | -fx-base: #373e43; | |
| 7 | -fx-control-inner-background: derive( -fx-base, 35% ); | |
| 8 | -fx-control-inner-background-alt: -fx-control-inner-background; | |
| 9 | ||
| 10 | -fx-light-text-color: derive( -fx-base, 150% ); | |
| 11 | -fx-mid-text-color: derive( -fx-base, 100% ); | |
| 12 | -fx-dark-text-color: derive( -fx-base, 25% ); | |
| 13 | -fx-text-foreground: -fx-light-text-color; | |
| 14 | -fx-text-background: derive( -fx-control-inner-background, 7.5% ); | |
| 15 | -fx-text-selection: derive( -fx-control-inner-background, 45% ); | |
| 16 | } | |
| 17 | ||
| 18 | .glyph-icon { | |
| 19 | -fx-text-fill: -fx-light-text-color; | |
| 20 | -fx-fill: -fx-light-text-color; | |
| 21 | } | |
| 22 | ||
| 23 | .glyph-icon:hover { | |
| 24 | -fx-effect: dropshadow( three-pass-box, rgba( 0, 0, 0, 0.2 ), 4, 0, 0, 0 ); | |
| 25 | } | |
| 26 | ||
| 27 | .label { | |
| 28 | -fx-text-fill: -fx-light-text-color; | |
| 29 | } | |
| 30 | ||
| 31 | .text-field { | |
| 32 | -fx-prompt-text-fill: gray; | |
| 33 | } | |
| 34 | ||
| 35 | .button { | |
| 36 | -fx-focus-traversable: false; | |
| 37 | } | |
| 38 | ||
| 39 | .button:hover { | |
| 40 | -fx-text-fill: white; | |
| 41 | } | |
| 42 | ||
| 43 | .separator *.line { | |
| 44 | -fx-background-color: #3C3C3C; | |
| 45 | -fx-border-style: solid; | |
| 46 | -fx-border-width: 1px; | |
| 47 | } | |
| 48 | ||
| 49 | .scroll-bar { | |
| 50 | -fx-background-color: derive( -fx-base, 45% ); | |
| 51 | } | |
| 52 | ||
| 53 | .button:default { | |
| 54 | -fx-base: -fx-accent; | |
| 55 | } | |
| 56 | ||
| 57 | .table-view { | |
| 58 | -fx-selection-bar-non-focused: derive( -fx-base, 50% ); | |
| 59 | } | |
| 60 | ||
| 61 | .table-view .column-header .label { | |
| 62 | -fx-alignment: CENTER_LEFT; | |
| 63 | -fx-font-weight: none; | |
| 64 | } | |
| 65 | ||
| 66 | .list-cell:even, | |
| 67 | .list-cell:odd, | |
| 68 | .table-row-cell:even, | |
| 69 | .table-row-cell:odd { | |
| 70 | -fx-control-inner-background: derive( -fx-base, 15% ); | |
| 71 | } | |
| 72 | ||
| 73 | .list-cell:empty, | |
| 74 | .table-row-cell:empty { | |
| 75 | -fx-background-color: transparent; | |
| 76 | } | |
| 77 | ||
| 78 | .list-cell, | |
| 79 | .table-row-cell { | |
| 80 | -fx-border-color: transparent; | |
| 81 | -fx-table-cell-border-color: transparent; | |
| 82 | } | |
| 83 | ||
| 84 | /* Avoid clipping text descenders in statistics table row. */ | |
| 85 | .table-row-cell { | |
| 86 | -fx-cell-size: 30px; | |
| 87 | } | |
| 1 | 88 |
| 1 | /* https://github.com/joffrey-bion/javafx-themes/blob/master/css/modena_dark.css | |
| 2 | */ | |
| 3 | .root { | |
| 4 | -fx-base: rgb( 50, 50, 50 ); | |
| 5 | -fx-background: -fx-base; | |
| 1 | 6 | |
| 7 | /* Make controls ( buttons, thumb, etc. ) slightly lighter */ | |
| 8 | -fx-color: derive( -fx-base |
| 1 | .root { | |
| 2 | -fx-text-foreground: -fx-dark-text-color; | |
| 3 | -fx-text-background: derive( -fx-accent, 124% ); | |
| 4 | -fx-text-selection: #a6d2ff; | |
| 5 | } | |
| 1 | 6 |
| 1 | ||
| 1 | /* | |
| 2 | * Copyright (c) 2015 Karl Tauber <karl at jformdesigner dot com> | |
| 3 | * All rights reserved. | |
| 4 | * | |
| 5 | * Redistribution and use in source and binary forms, with or without | |
| 6 | * modification, are permitted provided that the following conditions are met: | |
| 7 | * | |
| 8 | * o R |
| 1 | /* https://toedter.com/2011/10/26/java-fx-2-0-css-styling/ | |
| 2 | */ | |
| 3 | .root { | |
| 4 | -fx-base: rgb( 50, 50, 50 ); | |
| 5 | -fx-background: -fx-base; | |
| 6 | -fx-control-inner-background: -fx-base; | |
| 1 | 7 | |
| 8 | : derive( -fx-base, 150% ); | |
| 9 | -fx-mid-text-color: derive( -fx- |
| 1 | /* https://ethanschoonover.com/solarized | |
| 2 | */ | |
| 3 | .root { | |
| 4 | /* Solarized: base03 */ | |
| 5 | -fx-base: rgb( 0, 43, 54 ); | |
| 6 | -fx-background: -fx-base; | |
| 7 | ||
| 8 | /* Brighten controls */ | |
| 9 | -fx-40% ); | |
| 1 | 10 | |
| 11 | -fx-control-inner-background: -fx-base; | |
| 12 | , 5 |
| 1 | /* https://github.com/Col-E/Recaf/blob/master/src/main/resources/style/ui-dark.css | |
| 2 | */ | |
| 3 | .root { | |
| 4 | -fx-base: rgb( 45, 45, 46 ); | |
| 5 | -fx-background: -fx-base; | |
| 6 | ||
| 7 | /* Brighten controls */ | |
| 8 | -fx-color: derive( -fx-base, -40% ); | |
| 1 | 9 | |
| 10 | /* Control background */ | |
| 11 | /* Text colors */ | |
| 12 | /* Accent colors */ | |
| 13 | -fx-accent: rgb( 51, 51, 52 ); | |
| 14 | -item { | |
| 15 | -fx-border-insets: -1; | |
| 16 | { | |
| 17 | -fx-min-width: 80px; | |
| 18 | -fx-border-insets: -1; | |
| 19 | -fx-opacity: 1.0; | |
| 20 | -fx-padding: 2 2 1 2; | |
| 21 | -fx-border-insets: 0; | |
| 22 | 1 1; | |
| 23 | -fx-padding: 2; | |
| 24 | -fx-border-insets: 0; | |
| 25 | 6, 56, 59 ); | |
| 26 | -fx-padding: -1; | |
| 27 | -fx-padding: -1; | |
| 28 | -fx-border-insets: 0; | |
| 29 | 1 0 1; | |
| 30 | -fx-padding: 2; | |
| 31 | -fx-padding: 0; | |
| 32 | 1 0 0; | |
| 33 | hyperlink { | |
| 34 |
| 1 | .tagmark { | |
| 2 | -fx-fill: gray; | |
| 3 | } | |
| 4 | .anytag { | |
| 5 | -fx-fill: crimson; | |
| 6 | } | |
| 7 | .paren { | |
| 8 | -fx-fill: firebrick; | |
| 9 | -fx-font-weight: bold; | |
| 10 | } | |
| 11 | .attribute { | |
| 12 | -fx-fill: darkviolet; | |
| 13 | } | |
| 14 | .avalue { | |
| 15 | -fx-fill: black; | |
| 16 | } | |
| 1 | 17 | |
| 18 | .comment { | |
| 19 | -fx-fill: teal; | |
| 20 | } |
| 1 | # Building | |
| 2 | ||
| 3 | The lexicon files are retrieved from SymSpell in the parent directory: | |
| 4 | ||
| 5 | svn export \ | |
| 6 | https://github.com/wolfgarbe/SymSpell/trunk/SymSpell.FrequencyDictionary/ lexicons | |
| 7 | ||
| 8 | The lexicons and bigrams are both space-separated, but parsing a | |
| 9 | tab-delimited file is easier, so change them to tab-separated files. | |
| 1 | 10 |
| 1 | # Overview | |
| 2 | ||
| 3 | Lexicons in this directory are meant to relate to a particular subject | |
| 4 | (medicine, chemistry, math, sports, and such), extend the main lexicon, | |
| 5 | or not be in common use. | |
| 6 | ||
| 1 | 7 |
| 1 | 1 | |
| 2 | 'aight | |
| 3 | ain't | |
| 4 | amn't | |
| 5 | aren't | |
| 6 | can't | |
| 7 | 'cause | |
| 8 | couldn't | |
| 9 | couldn't've | |
| 10 | could've | |
| 11 | daren't | |
| 12 | daresn't | |
| 13 | dasn't | |
| 14 | didn't | |
| 15 | doesn't | |
| 16 | don't | |
| 17 | dunno | |
| 18 | d'ye | |
| 19 | e'er | |
| 20 | everybody's | |
| 21 | everyone's | |
| 22 | g'day | |
| 23 | gimme | |
| 24 | giv'n | |
| 25 | gonna | |
| 26 | gon't | |
| 27 | gotta | |
| 28 | hadn't | |
| 29 | had've | |
| 30 | hasn't | |
| 31 | haven't | |
| 32 | he'd | |
| 33 | he'll | |
| 34 | he's | |
| 35 | he've | |
| 36 | how'd | |
| 37 | howdy | |
| 38 | how'll | |
| 39 | how're | |
| 40 | how's | |
| 41 | how've | |
| 42 | i'd | |
| 43 | i'dn't've | |
| 44 | i'd've | |
| 45 | i'll | |
| 46 | i'm | |
| 47 | i'm'a | |
| 48 | imma | |
| 49 | innit | |
| 50 | isn't | |
| 51 | it'd | |
| 52 | it'll | |
| 53 | it's | |
| 54 | i've | |
| 55 | let's | |
| 56 | ma'am | |
| 57 | mayn't | |
| 58 | may've | |
| 59 | methinks | |
| 60 | mightn't | |
| 61 | might've | |
| 62 | mustn't | |
| 63 | mustn't've | |
| 64 | must've | |
| 65 | needn't | |
| 66 | ne'er | |
| 67 | o'clock | |
| 68 | o'er | |
| 69 | ol' | |
| 70 | oughtn't | |
| 71 | shalln't | |
| 72 | shan't | |
| 73 | she'd | |
| 74 | she'll | |
| 75 | she's | |
| 76 | shouldn't | |
| 77 | shouldn't've | |
| 78 | should've | |
| 79 | somebody's | |
| 80 | someone's | |
| 81 | something's | |
| 82 | so're | |
| 83 | that'd | |
| 84 | that'll | |
| 85 | that're | |
| 86 | that's | |
| 87 | there'd | |
| 88 | there'll | |
| 89 | there're | |
| 90 | there's | |
| 91 | these'd | |
| 92 | these'll | |
| 93 | these're | |
| 94 | these've | |
| 95 | they'd | |
| 96 | they'll | |
| 97 | they're | |
| 98 | they've | |
| 99 | this's | |
| 100 | those're | |
| 101 | those've | |
| 102 | 'tis | |
| 103 | to've | |
| 104 | 'twas | |
| 105 | 'twouldn't | |
| 106 | wanna | |
| 107 | wasn't | |
| 108 | we'd | |
| 109 | we'd've | |
| 110 | we'll | |
| 111 | we're | |
| 112 | weren't | |
| 113 | we've | |
| 114 | what'd | |
| 115 | what'll | |
| 116 | what're | |
| 117 | what's | |
| 118 | what've | |
| 119 | when'd | |
| 120 | when'll | |
| 121 | when's | |
| 122 | where'd | |
| 123 | where'll | |
| 124 | where're | |
| 125 | where's | |
| 126 | where've | |
| 127 | which'd | |
| 128 | which'll | |
| 129 | which're | |
| 130 | which's | |
| 131 | which've | |
| 132 | who'd | |
| 133 | who'd've | |
| 134 | who'll | |
| 135 | who're | |
| 136 | who's | |
| 137 | who've | |
| 138 | why'd | |
| 139 | why'll | |
| 140 | why're | |
| 141 | why's | |
| 142 | willn't | |
| 143 | won't | |
| 144 | wouldn't | |
| 145 | wouldn't've | |
| 146 | would've | |
| 147 | y'all | |
| 148 | y'all'd've | |
| 149 | y'all're | |
| 150 | you'd | |
| 151 | you'dn't've | |
| 152 | you'll | |
| 153 | you're | |
| 154 | you've | |
| 155 |
| 1 | analytics 130337 | |
| 2 | hotspot 130022 | |
| 3 | instantiation 130000 | |
| 4 | onboarding 129953 | |
| 5 | biometric 129795 | |
| 6 | anamorphic 129777 | |
| 7 | benchmarking 129772 | |
| 8 | cybersecurity 129769 | |
| 9 | barcode 129757 | |
| 10 | splitter 129755 | |
| 11 | keychain 129719 | |
| 12 | crowdfunding 129696 | |
| 13 | polymorphism 129688 | |
| 14 | automata 129666 | |
| 15 | shockwave 129658 | |
| 16 | profiler 129648 | |
| 17 | kerning 129646 | |
| 18 | nanometer 129630 | |
| 19 | meridiem 129624 | |
| 20 | influencer 129618 | |
| 21 | passcode 129617 | |
| 22 | sexting 129607 | |
| 23 | cryptology 129606 | |
| 24 | biometrics 129606 | |
| 25 | bitcoin 129599 | |
| 26 | specular 129598 | |
| 27 | accelerometer 129588 | |
| 28 | googolplex 129583 | |
| 29 | grayscale 129576 | |
| 30 | ascender 129571 | |
| 31 | pixelated 129569 | |
| 32 | rockstar 129565 | |
| 33 | ragdoll 129564 | |
| 34 | cyberattack 129564 | |
| 35 | cryptanalysis 129562 | |
| 36 | ransomware 129553 | |
| 37 | crowdsourcing 129552 | |
| 38 | hackathon 129551 | |
| 39 | audiobook 129544 | |
| 40 | degauss 129543 | |
| 41 | attenuator 129540 | |
| 42 | jetpack 129538 | |
| 43 | packrat 129536 | |
| 44 | backlight 129535 | |
| 45 | bootable 129530 | |
| 46 | octothorpe 129529 | |
| 47 | newsfeed 129525 | |
| 48 | extranet 129523 | |
| 49 | failover 129516 | |
| 50 | cyberbullying 129516 | |
| 51 | neumann 129515 | |
| 52 | capacitive 129514 | |
| 53 | backlit 129511 | |
| 54 | millimicron 129507 | |
| 55 | inductor 129505 | |
| 56 | workgroup 129502 | |
| 57 | journaling 129500 | |
| 58 | middleware 129499 | |
| 59 | spooler 129497 | |
| 60 | clamshell 129495 | |
| 61 | wireframe 129494 | |
| 62 | modularity 129493 | |
| 63 | strikethrough 129489 | |
| 64 | petabyte 129487 | |
| 65 | jughead 129482 | |
| 66 | acyclic 129482 | |
| 67 | gearhead 129478 | |
| 68 | stateful 129473 | |
| 69 | submenu 129467 | |
| 70 | pseudorandom 129463 | |
| 71 | earbuds 129461 | |
| 72 | narrowband 129460 | |
| 73 | recordable 129457 | |
| 74 | unallocated 129455 | |
| 75 | mappable 129455 | |
| 76 | chipset 129454 | |
| 77 | multicast 129447 | |
| 78 | loopback 129444 | |
| 79 | pixelate 129441 | |
| 80 | cryptographic 129441 | |
| 81 | pixelation 129438 | |
| 82 | autocorrect 129438 | |
| 83 | teraflop 129437 | |
| 84 | digitizer 129436 | |
| 85 | tunnelling 129434 | |
| 86 | deduplication 129434 | |
| 87 | subwoofer 129433 | |
| 88 | touchpad 129429 | |
| 89 | namespace 129428 | |
| 90 | microcontroller 129428 | |
| 91 | geolocation 129428 | |
| 92 | telepresence 129427 | |
| 93 | driverless 129426 | |
| 94 | photolithography 129425 | |
| 95 | multiphase 129425 | |
| 96 | verifier 129424 | |
| 97 | robocall 129424 | |
| 98 | autofocus 129424 | |
| 99 | kilobit 129422 | |
| 100 | hacktivist 129419 | |
| 101 | geocache 129415 | |
| 102 | rasterize 129412 | |
| 103 | plaintext 129411 | |
| 104 | pipelining 129411 | |
| 105 | technobabble 129409 | |
| 106 | defragment 129409 | |
| 107 | connectionless 129409 | |
| 108 | homomorphic 129407 | |
| 109 | demodulator 129406 | |
| 110 | datagram 129406 | |
| 111 | activex 129406 | |
| 112 | normalisation 129404 | |
| 113 | blackhole 129402 | |
| 114 | cyberstalker 129401 | |
| 115 | multifunction 129400 | |
| 116 | undirected 129397 | |
| 117 | ciphertext 129397 | |
| 118 | superspeed 129396 | |
| 119 | spacebar 129395 | |
| 120 | cyberwar 129395 | |
| 121 | borderless 129395 | |
| 122 | transcode 129393 | |
| 123 | cyberbully 129393 | |
| 124 | multimeter 129392 | |
| 125 | dropship 129391 | |
| 126 | yottabyte 129390 | |
| 127 | infector 129390 | |
| 128 | superclass 129389 | |
| 129 | tooltip 129388 | |
| 130 | dereference 129387 | |
| 131 | combinator 129386 | |
| 132 | milliwatt 129385 | |
| 133 | cyberstalking 129384 | |
| 134 | subfolder 129383 | |
| 135 | wideband 129382 | |
| 136 | noncontiguous 129382 | |
| 137 | ferroelectric 129382 | |
| 138 | cybersquatting 129378 | |
| 139 | autofill 129378 | |
| 140 | trackpad 129376 | |
| 141 | associatively 129376 | |
| 142 | luggable 129374 | |
| 143 | seamonkey 129373 | |
| 144 | defragmentation 129373 | |
| 145 | starcraft 129371 | |
| 146 | obliquing 129371 | |
| 147 | leadless 129371 | |
| 148 | greeking 129371 | |
| 149 | upgradeable 129370 | |
| 150 | radiosity 129370 | |
| 151 | transcoding 129369 | |
| 152 | quintillionth 129369 | |
| 153 | bitmapped 129369 | |
| 154 | subdirectory 129368 | |
| 155 | degausser 129368 | |
| 156 | curtiss 129368 | |
| 157 | scunthorpe 129367 | |
| 158 | undelete 129365 | |
| 159 | gigaflops 129365 | |
| 160 | darknet 129365 | |
| 161 | zettabyte 129364 | |
| 162 | topologies 129363 | |
| 163 | spidering 129363 | |
| 164 | photorealism 129363 | |
| 165 | multithreading 129363 | |
| 166 | deallocate 129363 | |
| 167 | mersenne 129362 | |
| 168 | machinima 129361 | |
| 169 | satisfiable 129360 | |
| 170 | laserjet 129360 | |
| 171 | multicore 129359 | |
| 172 | microblog 129359 | |
| 173 | megaflops 129359 | |
| 174 | homeomorphic 129359 | |
| 175 | microblogging 129358 | |
| 176 | kilobaud 129358 | |
| 177 | cyberwarfare 129358 | |
| 178 | microarchitecture 129357 | |
| 179 | autosave 129357 | |
| 180 | wirelessly 129356 | |
| 181 | sneakernet 129355 | |
| 182 | textbox 129354 | |
| 183 | obfuscator 129354 | |
| 184 | microkernel 129353 | |
| 185 | substring 129352 | |
| 186 | macroinstruction 129352 | |
| 187 | endianness 129352 | |
| 188 | indexable 129351 | |
| 189 | backtick 129351 | |
| 190 | unshielded 129350 | |
| 191 | cleartext 129350 | |
| 192 | autocomplete 129349 | |
| 193 | abandonware 129349 | |
| 194 | hacktivism 129348 | |
| 195 | antikythera 129348 | |
| 196 | stereolithography 129347 | |
| 197 | photorealistic 129347 | |
| 198 | macrovision 129347 | |
| 199 | greasemonkey 129347 | |
| 200 | geotagging 129347 | |
| 201 | disassembler 129346 | |
| 202 | spacewar 129345 | |
| 203 | pluggable 129345 | |
| 204 | kilobits 129345 | |
| 205 | webcomic 129344 | |
| 206 | unfollow 129344 | |
| 207 | photosensor 129344 | |
| 208 | petaflop 129344 | |
| 209 | garageband 129344 | |
| 210 | truetype 129343 | |
| 211 | subnetwork 129342 | |
| 212 | backpropagation 129342 | |
| 213 | supercomputing 129340 | |
| 214 | smartwatch 129340 | |
| 215 | unbundled 129339 | |
| 216 | smilies 129339 | |
| 217 | milliamp 129339 | |
| 218 | bytecode 129339 | |
| 219 | trackpoint 129337 | |
| 220 | slipstreaming 129337 | |
| 221 | monospace 129337 | |
| 222 | memoization 129337 | |
| 223 | scaleable 129336 | |
| 224 | respawn 129335 | |
| 225 | multicasting 129335 | |
| 226 | geocacher 129335 | |
| 227 | workgroups 129334 | |
| 228 | ferrofluid 129334 | |
| 229 | smartdrive 129333 | |
| 230 | subsampling 129332 | |
| 231 | rasterization 129332 | |
| 232 | guiltware 129332 | |
| 233 | defragger 129332 | |
| 234 | satisfiability 129331 | |
| 235 | activision 129331 | |
| 236 | subdirectories 129330 | |
| 237 | segfault 129330 | |
| 238 | flamebait 129330 | |
| 239 | framebuffer 129329 | |
| 240 | defragging 129329 | |
| 241 | decompiler 129329 | |
| 242 | unshift 129328 | |
| 243 | memristor 129328 | |
| 244 | zebibyte 129327 | |
| 245 | semiprime 129327 | |
| 246 | rotoscoping 129327 | |
| 247 | hypertransport 129327 | |
| 248 | smartmedia 129326 | |
| 249 | grayware 129326 | |
| 250 | defragmenting 129326 | |
| 251 | defragmenter 129326 | |
| 252 | repagination 129325 | |
| 253 | subnetting 129324 | |
| 254 | skeuomorphism 129324 | |
| 255 | screencast 129324 | |
| 256 | stylesheet 129323 | |
| 257 | superintelligence 129322 | |
| 258 | multitenancy 129322 | |
| 259 | datastore 129322 | |
| 260 | autoplay 129322 | |
| 261 | repaginate 129321 | |
| 262 | macbook 129321 | |
| 263 | geotagged 129321 | |
| 264 | baudrate 129321 | |
| 265 | transmeta 129320 | |
| 266 | screwless 129320 | |
| 267 | nameserver 129320 | |
| 268 | interexchange 129320 | |
| 269 | geocoding 129319 | |
| 270 | downloader 129319 | |
| 271 | autodiscovery 129319 | |
| 272 | extortion 65752 | |
| 273 | emoji 65684 | |
| 274 | googol 65618 | |
| 275 | backside 65388 | |
| 276 | fibre 65387 | |
| 277 | metre 65333 | |
| 278 | royale 65173 | |
| 279 | radix 65093 | |
| 280 | hotdog 65091 | |
| 281 | lecher 65062 | |
| 282 | uptime 65009 | |
| 283 | unbound 64979 | |
| 284 | eniac 64975 | |
| 285 | synaptic 64966 | |
| 286 | voxel 64926 | |
| 287 | selfie 64917 | |
| 288 | uplink 64887 | |
| 289 | fanboy 64857 | |
| 290 | defrag 64849 | |
| 291 | nondisclosure 64839 | |
| 292 | qubit 64828 | |
| 293 | yippie 64821 | |
| 294 | gearhead 64819 | |
| 295 | subnet 64818 | |
| 296 | endian 64798 | |
| 297 | bezier 64797 | |
| 298 | reallocation 64796 | |
| 299 | telephonic 64789 | |
| 300 | mosfet 64777 | |
| 301 | mutex 64775 | |
| 302 | inkjet 64772 | |
| 303 | gobbing 64768 | |
| 304 | shader 64766 | |
| 305 | ultralight 64755 | |
| 306 | hackers 64746 | |
| 307 | pacman 64742 | |
| 308 | unlink 64741 | |
| 309 | undock 64740 | |
| 310 | understroke 64738 | |
| 311 | beginners 64736 | |
| 312 | photoscope 64731 | |
| 313 | gantt 64725 | |
| 314 | programmers 64722 | |
| 315 | todays 64720 | |
| 316 | moores 64716 | |
| 317 | fullscreen 64715 | |
| 318 | moveless 64708 | |
| 319 | reformatted 64704 | |
| 320 | deallocate 64704 | |
| 321 | laserdisc 64702 | |
| 322 | macos 64700 | |
| 323 | nonactive 64697 | |
| 324 | nonadjacent 64696 | |
| 325 | hotfix 64695 | |
| 326 | keylogger 64694 | |
| 327 | geotag 64691 | |
| 328 | oreilly 64681 | |
| 329 | exabit 64678 | |
| 330 | jailbroken 64677 | |
| 331 | fuzzer 64676 | |
| 332 | noninteractive 64673 | |
| 333 | multifactor 64672 | |
| 334 | letterspacing 64671 | |
| 335 | preinstall 64669 | |
| 336 | multiboot 64666 | |
| 337 | runescape 64665 | |
| 338 | micropayment 64664 | |
| 339 | numpad 64663 | |
| 340 | preinstalled 64661 | |
| 341 | jailbreaking 64660 | |
| 342 | attend 2158 | |
| 343 | withstand 1809 | |
| 344 | transpire 1116 | |
| 345 | reading 1110 | |
| 346 | texture 1065 | |
| 347 | capitalize 832 | |
| 348 | calling 779 | |
| 349 | unfold 767 | |
| 350 | starboard 679 | |
| 351 | commode 625 | |
| 352 | doing 594 | |
| 353 | textbook 499 | |
| 354 | unease 378 | |
| 355 | unpack 358 | |
| 356 | keycard 231 | |
| 357 | mainspring 207 | |
| 358 | grr 180 | |
| 359 | geocaching 167 | |
| 360 | microbus 160 | |
| 361 | mp3 147 | |
| 362 | svg 139 | |
| 363 | shifted 128 | |
| 364 | texted 127 | |
| 365 | towheaded 118 | |
| 366 | mineshaft 115 | |
| 367 | nonparty 95 | |
| 368 | crossbite 80 | |
| 369 | resignedness 69 | |
| 370 | msrp 61 | |
| 371 | inbreak 53 | |
| 372 | nanocomposite 44 | |
| 373 | md5 44 | |
| 374 | neomorphic 41 | |
| 375 | superstrain 28 | |
| 376 | lifers 27 | |
| 377 | multination 26 | |
| 378 | smartwatch 22 | |
| 379 | antilibration 22 | |
| 380 | zapf 20 | |
| 381 | mp4 20 | |
| 1 | 382 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite; | |
| 3 | ||
| 4 | import javafx.embed.swing.JFXPanel; | |
| 5 | import org.junit.jupiter.api.extension.BeforeAllCallback; | |
| 6 | import org.junit.jupiter.api.extension.ExtensionContext; | |
| 7 | import org.testfx.osgi.service.TestFx; | |
| 8 | ||
| 9 | import java.util.concurrent.Semaphore; | |
| 10 | ||
| 11 | import static javafx.application.Platform.runLater; | |
| 12 | import static javax.swing.SwingUtilities.invokeLater; | |
| 13 | ||
| 14 | /** | |
| 15 | * Blocks all unit tests until JavaFX is ready. | |
| 16 | */ | |
| 17 | public class AwaitFxExtension implements BeforeAllCallback { | |
| 18 | /** | |
| 19 | * Prevent {@link RuntimeException} for internal graphics not initialized yet. | |
| 20 | * | |
| 21 | * @param context Provided by the {@link TestFx} framework. | |
| 22 | * @throws InterruptedException Could not acquire semaphore. | |
| 23 | */ | |
| 24 | @Override | |
| 25 | public void beforeAll( final ExtensionContext context ) | |
| 26 | throws InterruptedException { | |
| 27 | final var semaphore = new Semaphore( 0 ); | |
| 28 | ||
| 29 | invokeLater( () -> { | |
| 30 | // Prepare JavaFX toolkit and environment. | |
| 31 | new JFXPanel(); | |
| 32 | runLater( semaphore::release ); | |
| 33 | } ); | |
| 34 | ||
| 35 | semaphore.acquire(); | |
| 36 | } | |
| 37 | } | |
| 1 | 38 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.definition; | |
| 3 | ||
| 4 | import com.keenwrite.editors.definition.DefinitionEditor; | |
| 5 | import com.keenwrite.editors.definition.yaml.YamlTreeTransformer; | |
| 6 | import com.keenwrite.editors.markdown.MarkdownEditor; | |
| 7 | import com.keenwrite.preferences.Workspace; | |
| 8 | import com.keenwrite.preview.HtmlPreview; | |
| 9 | import com.panemu.tiwulfx.control.dock.DetachableTabPane; | |
| 10 | import javafx.application.Application; | |
| 11 | import javafx.beans.property.SimpleObjectProperty; | |
| 12 | import javafx.event.Event; | |
| 13 | import javafx.event.EventHandler; | |
| 14 | import javafx.scene.Node; | |
| 15 | import javafx.scene.Scene; | |
| 16 | import javafx.scene.control.ColorPicker; | |
| 17 | import javafx.scene.control.SplitPane; | |
| 18 | import javafx.scene.control.Tooltip; | |
| 19 | import javafx.scene.control.TreeItem; | |
| 20 | import javafx.stage.Stage; | |
| 21 | import org.testfx.framework.junit5.Start; | |
| 22 | ||
| 23 | import static com.keenwrite.util.FontLoader.initFonts; | |
| 24 | ||
| 25 | //@ExtendWith(ApplicationExtension.class) | |
| 26 | public class TreeViewTest extends Application { | |
| 27 | private final SimpleObjectProperty<Node> mTextEditor = | |
| 28 | new SimpleObjectProperty<>(); | |
| 29 | ||
| 30 | private final EventHandler<TreeItem.TreeModificationEvent<Event>> mTreeHandler = | |
| 31 | event -> refresh( mTextEditor.get() ); | |
| 32 | ||
| 33 | private void refresh( final Node node ) { | |
| 34 | throw new RuntimeException( "Derp: " + node ); | |
| 35 | } | |
| 36 | ||
| 37 | public static void main( final String[] args ) { | |
| 38 | initFonts(); | |
| 39 | launch( args ); | |
| 40 | } | |
| 41 | ||
| 42 | public void start( final Stage stage ) { | |
| 43 | onStart( stage ); | |
| 44 | } | |
| 45 | ||
| 46 | @Start | |
| 47 | private void onStart( final Stage stage ) { | |
| 48 | final var workspace = new Workspace(); | |
| 49 | final var mainPane = new SplitPane(); | |
| 50 | ||
| 51 | final var transformer = new YamlTreeTransformer(); | |
| 52 | final var editor = new DefinitionEditor( transformer ); | |
| 53 | ||
| 54 | final var tabPane1 = new DetachableTabPane(); | |
| 55 | tabPane1.addTab( "Editor", editor ); | |
| 56 | ||
| 57 | final var tabPane2 = new DetachableTabPane(); | |
| 58 | final var tab21 = tabPane2.addTab( "Picker", new ColorPicker() ); | |
| 59 | final var tab22 = tabPane2.addTab( "Editor", | |
| 60 | new MarkdownEditor( workspace ) ); | |
| 61 | tab21.setTooltip( new Tooltip( "Colour Picker" ) ); | |
| 62 | tab22.setTooltip( new Tooltip( "Text Editor" ) ); | |
| 63 | ||
| 64 | final var tabPane3 = new DetachableTabPane(); | |
| 65 | tabPane3.addTab( "Preview", new HtmlPreview( workspace ) ); | |
| 66 | ||
| 67 | editor.addTreeChangeHandler( mTreeHandler ); | |
| 68 | ||
| 69 | mainPane.getItems().addAll( tabPane1, tabPane2, tabPane3 ); | |
| 70 | ||
| 71 | final var scene = new Scene( mainPane ); | |
| 72 | stage.setScene( scene ); | |
| 73 | ||
| 74 | stage.show(); | |
| 75 | } | |
| 76 | } | |
| 1 | 77 |
| 1 | package com.keenwrite.editors.markdown; | |
| 2 | ||
| 3 | import com.keenwrite.AwaitFxExtension; | |
| 4 | import com.keenwrite.preferences.Workspace; | |
| 5 | import org.junit.jupiter.api.Test; | |
| 6 | import org.junit.jupiter.api.extension.ExtendWith; | |
| 7 | import org.testfx.framework.junit5.ApplicationExtension; | |
| 8 | ||
| 9 | import java.util.regex.Pattern; | |
| 10 | ||
| 11 | import static java.util.regex.Pattern.compile; | |
| 12 | import static javafx.application.Platform.runLater; | |
| 13 | import static org.junit.jupiter.api.Assertions.assertEquals; | |
| 14 | import static org.junit.jupiter.api.Assertions.assertTrue; | |
| 15 | ||
| 16 | @ExtendWith( {ApplicationExtension.class, AwaitFxExtension.class} ) | |
| 17 | public class MarkdownEditorTest { | |
| 18 | private static final String[] WORDS = new String[]{ | |
| 19 | "Italicize", | |
| 20 | "English's", | |
| 21 | "foreign", | |
| 22 | "words", | |
| 23 | "based", | |
| 24 | "on", | |
| 25 | "popularity,", | |
| 26 | "like", | |
| 27 | "_bête_", | |
| 28 | "_noire_", | |
| 29 | "and", | |
| 30 | "_Weltanschauung_", | |
| 31 | "but", | |
| 32 | "not", | |
| 33 | "résumé.", | |
| 34 | "Don't", | |
| 35 | "omit", | |
| 36 | "accented", | |
| 37 | "characters!", | |
| 38 | "Cœlacanthe", | |
| 39 | "L'Haÿ-les-Roses", | |
| 40 | "Mühlfeldstraße", | |
| 41 | "Da̱nx̱a̱laga̱litła̱n", | |
| 42 | }; | |
| 43 | ||
| 44 | private static final String TEXT = String.join( " ", WORDS ); | |
| 45 | ||
| 46 | private static final Pattern REGEX = compile( | |
| 47 | "[^\\p{Mn}\\p{Me}\\p{L}\\p{N}'-]+" ); | |
| 48 | ||
| 49 | /** | |
| 50 | * Test that the {@link MarkdownEditor} can retrieve a word at the caret | |
| 51 | * position, regardless of whether the caret is at the beginning, middle, or | |
| 52 | * end of the word. | |
| 53 | */ | |
| 54 | @Test | |
| 55 | public void test_CaretWord_GetISO88591Word_WordSelected() { | |
| 56 | runLater( () -> { | |
| 57 | final var editor = createMarkdownEditor(); | |
| 58 | ||
| 59 | for( int i = 0; i < WORDS.length; i++ ) { | |
| 60 | final var word = WORDS[ i ]; | |
| 61 | final var len = word.length(); | |
| 62 | final var expected = REGEX.matcher( word ).replaceAll( "" ); | |
| 63 | ||
| 64 | for( int j = 0; j < len; j++ ) { | |
| 65 | editor.moveTo( offset( i ) + j ); | |
| 66 | final var actual = editor.getCaretWordText(); | |
| 67 | assertEquals( expected, actual ); | |
| 68 | } | |
| 69 | } | |
| 70 | } ); | |
| 71 | } | |
| 72 | ||
| 73 | /** | |
| 74 | * Test that the {@link MarkdownEditor} can make a word bold. | |
| 75 | */ | |
| 76 | @Test | |
| 77 | public void test_CaretWord_SetWordBold_WordIsBold() { | |
| 78 | final var index = 20; | |
| 79 | final var editor = createMarkdownEditor(); | |
| 80 | ||
| 81 | editor.moveTo( offset( index ) ); | |
| 82 | editor.bold(); | |
| 83 | assertTrue( editor.getText().contains( "**" + WORDS[ index ] + "**" ) ); | |
| 84 | } | |
| 85 | ||
| 86 | /** | |
| 87 | * Returns the document offset for a string at the given index. | |
| 88 | */ | |
| 89 | private static int offset( final int index ) { | |
| 90 | assert 0 <= index && index < WORDS.length; | |
| 91 | int offset = 0; | |
| 92 | ||
| 93 | for( int i = 0; i < index; i++ ) { | |
| 94 | offset += WORDS[ i ].length(); | |
| 95 | } | |
| 96 | ||
| 97 | // Add the index to compensate for one space between words. | |
| 98 | return offset + index; | |
| 99 | } | |
| 100 | ||
| 101 | /** | |
| 102 | * Returns an instance of {@link MarkdownEditor} pre-populated with | |
| 103 | * {@link #TEXT}. | |
| 104 | * | |
| 105 | * @return A new {@link MarkdownEditor} instance, ready for unit tests. | |
| 106 | */ | |
| 107 | private MarkdownEditor createMarkdownEditor() { | |
| 108 | final var workspace = new Workspace(); | |
| 109 | final var editor = new MarkdownEditor( workspace ); | |
| 110 | editor.setText( TEXT ); | |
| 111 | return editor; | |
| 112 | } | |
| 113 | } | |
| 1 | 114 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.io; | |
| 3 | ||
| 4 | import org.junit.jupiter.api.Test; | |
| 5 | import org.junit.jupiter.api.Timeout; | |
| 1 | 6 | |
| 7 | import java.io.File; | |
| 8 | import java.io.IOException; | |
| 9 | import java.file.Files.write( f )write( file.toPath(), text.getBytes() |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.io; | |
| 3 | ||
| 4 | import org.junit.jupiter.api.Test; | |
| 1 | 5 | |
| 6 | import |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved.keenwrite.preferences.Workspaceences.Workspace.extensions.ImageLinkExAwaitFxExtension; | |
| 2 | import com.keenwrite.Caret;extensions.ImageLinkExtensionassertEqualsassertNotNull | |
| 3 | getResource( "workspace.xml" ) Exception ex ) { | |
| 4 | throw new RuntimeException( ex ); | |
| 5 | }} | |
| 6 | } | |
| 1 | 7 |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.r; | |
| 3 | ||
| 4 | import org.junit.jupiter.api.BeforeAll; | |
| 5 | import org.junit.jupiter.api.Test; | |
| 1 | 6 | |
| 7 | import javax.script.ScriptEngine; | |
| 8 | import javax.script.ScriptEngineManager; | |
| 9 | import |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.sigils; | |
| 3 | ||
| 4 | import javafx.beans.property.SimpleStringProperty; | |
| 5 | import javafx.beans.property.StringProperty; | |
| 6 | import org.junit.jupiter.api.Test; | |
| 7 | ||
| 8 | import static org.junit.jupiter.api.Assertions.assertEquals; | |
| 9 | ||
| 10 | /** | |
| 11 | * Responsible for simulating R variable injection. | |
| 12 | */ | |
| 13 | class RSigilOperatorTest { | |
| 14 | ||
| 15 | private final SigilOperator mOperator = createRSigilOperator(); | |
| 16 | ||
| 17 | /** | |
| 18 | * Test that a key name becomes an R variable. | |
| 19 | */ | |
| 20 | @Test | |
| 21 | void test_Entoken_KeyName_Tokenized() { | |
| 22 | final var expected = "v$a$b$c$d"; | |
| 23 | final var actual = mOperator.entoken( "{{a.b.c.d}}" ); | |
| 24 | assertEquals( expected, actual ); | |
| 25 | } | |
| 26 | ||
| 27 | /** | |
| 28 | * Test that a key name becomes a viable R expression. | |
| 29 | */ | |
| 30 | @Test | |
| 31 | void test_Apply_KeyName_Expression() { | |
| 32 | final var expected = "`r#x(v$a$b$c$d)`"; | |
| 33 | final var actual = mOperator.apply( "v$a$b$c$d" ); | |
| 34 | assertEquals( expected, actual ); | |
| 35 | } | |
| 36 | ||
| 37 | private StringProperty createToken( final String token ) { | |
| 38 | return new SimpleStringProperty( token ); | |
| 39 | } | |
| 40 | ||
| 41 | private Tokens createRTokens() { | |
| 42 | return createTokens( "x(", ")" ); | |
| 43 | } | |
| 44 | ||
| 45 | private Tokens createYamlTokens() { | |
| 46 | return createTokens( "{{", "}}" ); | |
| 47 | } | |
| 48 | ||
| 49 | private Tokens createTokens( final String began, final String ended ) { | |
| 50 | return new Tokens( createToken( began ), createToken( ended ) ); | |
| 51 | } | |
| 52 | ||
| 53 | private YamlSigilOperator createYamlSigilOperator() { | |
| 54 | return new YamlSigilOperator( createYamlTokens() ); | |
| 55 | } | |
| 56 | ||
| 57 | private RSigilOperator createRSigilOperator() { | |
| 58 | return new RSigilOperator( createRTokens(), createYamlSigilOperator() ); | |
| 59 | } | |
| 60 | } | |
| 1 | 61 |
| 1 | ||
| 1 | /* | |
| 2 | * Copyright 2020-2021 White Magic Software, Ltd. | |
| 3 | * | |
| 4 | * All rights reserved. | |
| 5 | * | |
| 6 | * Redistribution and use in source and binary forms, with or without | |
| 7 | * modification, are permitted provided that the following conditions are met: | |
| 8 | * | |
| 9 | * o Redistributions of |
| 1 | /* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */ | |
| 2 | package com.keenwrite.util; | |
| 3 | ||
| 4 | import org.junit.jupiter.api.Test; | |
| 5 | ||
| 6 | import java.util.List; | |
| 7 | import java.util.ListIterator; | |
| 8 | import java.util.NoSuchElementException; | |
| 1 | 9 | |
| 10 | import static org.juni |
| 1 | <?xml version="1.0" encoding="UTF-8"?> | |
| 2 | <keenwrite> | |
| 3 | <workspace> | |
| 4 | <images> | |
| 5 | <order>svg pdf png jpg tiff</order> | |
| 6 | <dir></dir> | |
| 7 | </images> | |
| 8 | </workspace> | |
| 9 | </keenwrite> | |
| 1 | 10 |
| 1 | *.class | |
| 1 | 2 |
| 1 | # ----------------------------------------------------------------------------- | |
| 2 | # Copyright 2020 White Magic Software, Ltd. | |
| 3 | # | |
| 4 | # Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | # copy of this software and associated documentation fiRuns all scripts | |
| 6 | import s01 | |
| 7 | import s02 | |
| 8 | import s03 | |
| 9 | import s04 | |
| 1 | 10 |
| 1 | # ----------------------------------------------------------------------------- | |
| 2 | # Copyright 2020 White Magic Software, Ltd. | |
| 3 | # | |
| 4 | # Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | # copy of this software and associated documentation fiintroduces the editor and its purpose. | |
| 6 | # Fresh start | |
| 7 | rm( app_home + "/variables.yaml" ) | |
| 8 | rm( app_home + "/untitled.md" ) | |
| 9 | rm( dir_home + "/.scrivenvar | |
| 10 | # Wait for application to launch | |
| 11 | openApp( "java -jar " + app_bin ) | |
| 12 | ||
| 13 | wait("1594187265140.png", 30) | |
| 14 | ||
| 15 | # Breathing room for video recording. | |
| 16 | wait( 4 ) | |
| 17 | ||
| 18 | # --------- | |
| 19 | # Introduc240 ) | |
| 20 | ||
| 21 | heading( "What is this application?" ) | |
| 22 | typer( "Well, this application is a text editor that supports interpolated definitions, ") | |
| 23 | typer( "a few different text formats, real-time preview, spell check ") | |
| 24 | typer( "as you tipe" ) | |
| 25 | wait( 0.5 ) | |
| 26 | recur( 3ype, and R statements." ) | |
| 27 | paragraph() | |
| 28 | wait( 1finition demo | |
| 29 | heading( "What are definitions?" ) | |
| 30 | typer( "Watch. " ) | |
| 31 | wait( .5 ) | |
| 32 | ||
| 33 | # Focus the definition editor. | |
| 34 | click_create() | |
| 35 | recur( 4, tab ) | |
| 36 | ||
| 37 | wait( .5application" ) | |
| 38 | title" ) | |
| 39 | Scrivenvar" ) | |
| 40 | ||
| 41 | # Set focus to the text editor. | |
| 42 | tab() | |
| 43 | ||
| 44 | typer( "The left-hand pane contains a nested, folder-like structure of names " ) | |
| 45 | typer( "and values that are called *definitions*. " ) | |
| 46 | wait( .5 ) | |
| 47 | typer( "Such definitions can simplify updating documents. " ) | |
| 48 | wait( 1 ) | |
| 49 | ||
| 50 | edit_find( "this application" ) | |
| 51 | typer( "$application.title$" ) | |
| 52 | ||
| 53 | edit_find_next() | |
| 54 | typer( "$application.title$" ) | |
| 55 | typer( "Tresult after having substituted definition " ) | |
| 56 | typer( "values into the document." ) | |
| 57 | Now nobody wants to type definition names all the time. Instead, type any " ) | |
| 58 | typer( "partial definition value followed by `Ctrl+Space`, such as: scr" ) | |
| 59 | wait( 0.5 ) | |
| 60 | autoinsert() | |
| 61 | wait( 1 ) | |
| 62 | typer( ". *Much* better!" ) | |
| 63 | paragraph() | |
| 64 | ||
| 65 | heading( "What is interpolation?" ) | |
| 66 | typer( "Definition values can reference definition names. " ) | |
| 67 | wait( .5 ) | |
| 68 | typer( "The definition names act as placeholders. Substituting placeholders with " ) | |
| 69 | typer( "their definition value is called *interpolation*. Let's see how it works." ) | |
| 70 | wait( 2 ) | |
| 1 | 71 |
| 1 | # ----------------------------------------------------------------------------- | |
| 2 | # Copyright 2020 White Magic Software, Ltd. | |
| 3 | # | |
| 4 | # Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | # copy of this software and associated documentation fihow to use interpolated strings.Open sample chapter.1 ) | |
| 6 | typer( Key.END1O1Edit the sample document.80 ) | |
| 7 | 2, down ) | |
| 8 | ||
| 9 | # Grey | |
| 10 | recur( 3, skip_right ) | |
| 11 | autoinsert() | |
| 12 | ||
| 13 | # 34 | |
| 14 | recur( 4, skip_right ) | |
| 15 | autoinsert() | |
| 16 | ||
| 17 | # Central | |
| 18 | recur( 10, skip_right ) | |
| 19 | autoinsert() | |
| 20 | ||
| 21 | # London | |
| 22 | skip_right() | |
| 23 | autoinsert() | |
| 24 | ||
| 25 | # Hatchery | |
| 26 | skip_right() | |
| 27 | autoinsert() | |
| 28 | ||
| 29 | # and Conditioning | |
| 30 | recur( 2, select_word_right ) | |
| 31 | delete() | |
| 32 | ||
| 33 | # Centre | |
| 34 | skip_right() | |
| 35 | autoinsert( | |
| 36 | typer( " Let's interpolate those four definitions instead!" ) | |
| 37 | wait( 4 ) | |
| 38 | recur( 13, type, Key.BACKSPACE9, backspace60 ) | |
| 39 | ||
| 40 | typer( "name$" ) | |
| 41 | wait( 2 ) | |
| 42 | ||
| 43 | # Collapse all definitions | |
| 44 | tab() | |
| 45 | recur( 8, typer, Key.LEFT ) | |
| 46 | ||
| 47 | # Expand to city | |
| 48 | recur( 4, typer, Key.RIGHT ) | |
| 49 | ||
| 50 | # Jump to name | |
| 51 | recur( 2, down ) | |
| 52 | recur( 2, typer, Key.RIGHT ) | |
| 53 | ||
| 54 | # Open the text field to show the full value | |
| 55 | typer( Key.F2 ) | |
| 56 | ||
| 57 | # Traverse the text field | |
| 58 | home() | |
| 59 | recur( 16, type, Key.RIGHT, Key.CTRL ) | |
| 60 | esc() | |
| 61 | ||
| 62 | restore_typing_speed() | |
| 63 | ||
| 64 | tab() | |
| 65 | type(_next() | |
| 66 | typertyper( "'s" ) | |
| 67 | ||
| 68 | edit_find( "Hatcheries" ) | |
| 69 | autoinsert() | |
| 70 | ||
| 71 | # and Conditioning | |
| 72 | recur( 2, select_word_right ) | |
| 73 | delete() | |
| 74 | ||
| 75 | edit_find( "Central" ) | |
| 76 | autoinsert() | |
| 77 | ||
| 78 | skip_right() | |
| 79 | autoinsert() | |
| 80 | ||
| 81 | typer( " How about a different city?" ) | |
| 82 | wait( 2 ) | |
| 83 | recur( 5, type, Key.BACKSPACE, Key.CTRL ) | |
| 84 | wait( 1 ) | |
| 85 | tab() | |
| 86 | typer( Key.F2 ) | |
| 87 | typer( "Seattle" ) | |
| 88 | enter() | |
| 89 | tab() | |
| 90 | wait( 2 ) | |
| 91 | No?" ) | |
| 92 | paragraph() | |
| 93 | ||
| 94 | tab() | |
| 95 | typer( Key.F2 ) | |
| 96 | typer( "London" ) | |
| 97 | enter() | |
| 98 | ||
| 99 | tab() | |
| 100 | typer( "Organizing definitions is left to your ") | |
| 101 | typer( "doub" ) | |
| 102 | autoinsert() | |
| 103 | typer( " Good imagination." ) | |
| 104 | tab() | |
| 105 | ||
| 106 | # Jump to "char" definition | |
| 107 | home() | |
| 108 | ||
| 109 | # Jump to "char.a.primary.name" definition | |
| 110 | recur( 6, typer, Key.RIGHT ) | |
| 111 | ||
| 112 | # Jump to "char.a.primary.caste" definition | |
| 113 | down() | |
| 114 | typer( Key.RIGHT ) | |
| 115 | ||
| 116 | # Jump to root-level "caste" definition | |
| 117 | recur( 7, down ) | |
| 118 | ||
| 119 | # Reselect "super" | |
| 120 | recur( 5, typer, Key.RIGHT ) | |
| 121 | wait( 2 ) | |
| 122 | ||
| 123 | # Close the window, no save | |
| 124 | type( "w0.5 ) | |
| 125 | tab() | |
| 126 | wait( 0.5 ) | |
| 127 | typer( Key.SPACE ) | |
| 128 | wait( 1 ) | |
| 1 | 129 |
| 1 | # ----------------------------------------------------------------------------- | |
| 2 | # Copyright 2020 White Magic Software, Ltd. | |
| 3 | # | |
| 4 | # Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | # copy of this software and associated documentation files (the | |
| 6 | # "Software"), to deal in the Software without restriction, including | |
| 7 | # without limitation the rights to use, copy, modify, merge, publish, | |
| 8 | # distribute, sublicense, and/or sell copies of the Software, and to | |
| 9 | # permit persons to whom the Software is furnished to do so, subject to | |
| 10 | # the following conditions: | |
| 11 | # | |
| 12 | # The above copyright notice and this permission notice shall be included | |
| 13 | # in all copies or substantial portions of the Software. | |
| 14 | # | |
| 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 16 | # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
| 17 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
| 18 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
| 19 | # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
| 20 | # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
| 21 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| 22 | # ----------------------------------------------------------------------------- | |
| 23 | ||
| 24 | # ----------------------------------------------------------------------------- | |
| 25 | # This script introduces images and R. | |
| 26 | # ----------------------------------------------------------------------------- | |
| 27 | from sikuli import * | |
| 28 | import sys | |
| 29 | ||
| 30 | if not "../editor.sikuli" in sys.path: | |
| 31 | sys.path.append( "../editor.sikuli" ) | |
| 32 | ||
| 33 | from editor import * | |
| 34 | ||
| 35 | set_typing_speed( 80 ) | |
| 36 | ||
| 37 | file_open() | |
| 38 | type( Key.UP, Key.ALT ) | |
| 39 | wait( 0.5 ) | |
| 40 | home() | |
| 41 | wait( 0.25 ) | |
| 42 | enter() | |
| 43 | wait( 1 ) | |
| 44 | end() | |
| 45 | wait( 0.25 ) | |
| 46 | enter() | |
| 47 | wait( 1 ) | |
| 48 | ||
| 49 | set_typing_speed( 200 ) | |
| 50 | ||
| 51 | paragraph() | |
| 52 | heading( "What text formats are supported?" ) | |
| 53 | ||
| 54 | typer( "Scr" ) | |
| 55 | autoinsert() | |
| 56 | typer( " supports Markdown, R Markdown, XML, and R XML; however, the software " ) | |
| 57 | typer( "architecture enables it to easily add new formats. The following figure " ) | |
| 58 | typer( "depicts the overall architecture: " ) | |
| 59 | paragraph() | |
| 60 | typer( "" ) | |
| 61 | paragraph() | |
| 62 | typer( "Many text editors can only open one type of plain text markup format that is " ) | |
| 63 | typer( "only output as HTML. With a little more effort, text editors could support " ) | |
| 64 | typer( "multiple input and output formats. Scr" ) | |
| 65 | autoinsert() | |
| 66 | typer( " does so and goes one step further by introducing interpolated definitions." ) | |
| 67 | paragraph() | |
| 68 | typer( "Kitten interlude:" ) | |
| 69 | paragraph() | |
| 70 | typer( "" ) | |
| 71 | paragraph() | |
| 72 | ||
| 73 | heading( "What is R?" ) | |
| 74 | typer( "R is a programming language. You might have noticed a few potential grammar " ) | |
| 75 | typer( "problems with direct substitution. Rules for possessive forms, numbers, and " ) | |
| 76 | typer( "other quirks can be tackled using R." ) | |
| 77 | ||
| 78 | # ----------------------------------------------------------------------------- | |
| 79 | # Demo bootstrapping | |
| 80 | # ----------------------------------------------------------------------------- | |
| 81 | ||
| 82 | # Jump to the end | |
| 83 | type( Key.END, Key.CTRL ) | |
| 84 | paragraph() | |
| 85 | ||
| 86 | set_typing_speed( 300 ) | |
| 87 | heading( "How is R used?" ) | |
| 88 | typer( "R must be instructed where to find script files and what ones to load. The " ) | |
| 89 | typer( "*working directory* is the full path to those R files; the *startup script* " ) | |
| 90 | typer( "defines what R files to load. Both preferences must be changed before prose " ) | |
| 91 | typer( "may be processed. Preferences can be opened using either the " ) | |
| 92 | typeln( "**Edit > Preferences** menu or by pressing `Ctrl+Alt+s`. Here goes!" ) | |
| 93 | wait( 2 ) | |
| 94 | ||
| 95 | # ----------------------------------------------------------------------------- | |
| 96 | # Select the R script directory | |
| 97 | # ----------------------------------------------------------------------------- | |
| 98 | ||
| 99 | # Change the working directory by clicking "Browse" | |
| 100 | type( "s", Key.CTRL + Key.ALT ) | |
| 101 | wait("1594592396134.png", 1) | |
| 102 | click("1594592396134.png") | |
| 103 | wait( 0.5 ) | |
| 104 | ||
| 105 | # Navigate to and select the "r" directory | |
| 106 | type( Key.UP, Key.ALT ) | |
| 107 | wait( 0.5 ) | |
| 108 | end() | |
| 109 | wait( 0.5 ) | |
| 110 | enter() | |
| 111 | wait( 0.5 ) | |
| 112 | end() | |
| 113 | wait( 0.5 ) | |
| 114 | type( Key.UP ) | |
| 115 | wait( 0.5 ) | |
| 116 | recur( 2, tab ) | |
| 117 | wait( 0.5 ) | |
| 118 | enter() | |
| 119 | wait( 1 ) | |
| 120 | ||
| 121 | # ----------------------------------------------------------------------------- | |
| 122 | # Set the R startup script instructions | |
| 123 | # ----------------------------------------------------------------------------- | |
| 124 | ||
| 125 | wait("1594593710440.png", 5) | |
| 126 | click("1594593710440.png") | |
| 127 | ||
| 128 | set_typing_speed( 440 ) | |
| 129 | ||
| 130 | typeln( "setwd( '$application.r.working.directory$' )" ) | |
| 131 | typeln( "assign( 'anchor', '$date.anchor$', envir = .GlobalEnv )" ) | |
| 132 | typeln( "source( 'pluralize.R' )" ) | |
| 133 | typeln( "source( 'possessive.R' )" ) | |
| 134 | typeln( "source( 'conversion.R' )" ) | |
| 135 | typeln( "source( 'csv.R' )" ) | |
| 136 | ||
| 137 | wait("1594593794335.png", 3) | |
| 138 | click("1594593794335.png") | |
| 139 | ||
| 140 | paragraph() | |
| 141 | set_typing_speed( 220 ) | |
| 142 | ||
| 143 | typer( "R is now configured. The startup script and other R " ) | |
| 144 | typer( "files can be found in the " ) | |
| 145 | typer( "[repository](https://github.com/DaveJarvis/scrivenvar/tree/master/R). " ) | |
| 146 | wait( 1.5 ) | |
| 147 | ||
| 148 | # Wait for the browser to appear. | |
| 149 | wait("1594594984108.png", 5) | |
| 150 | click("1594594984108.png") | |
| 151 | ||
| 152 | wait( 5 ) | |
| 153 | click("1594689573764.png") | |
| 154 | ||
| 155 | paragraph() | |
| 156 | typer( "Next, we'll see how definitions and R can work together." ) | |
| 157 | wait( 2 ) | |
| 1 | 158 |
| 1 | # ----------------------------------------------------------------------------- | |
| 2 | # Copyright 2020 White Magic Software, Ltd. | |
| 3 | # | |
| 4 | # Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | # copy of this software and associated documentation files (the | |
| 6 | # "Software"), to deal in the Software without restriction, including | |
| 7 | # without limitation the rights to use, copy, modify, merge, publish, | |
| 8 | # distribute, sublicense, and/or sell copies of the Software, and to | |
| 9 | # permit persons to whom the Software is furnished to do so, subject to | |
| 10 | # the following conditions: | |
| 11 | # | |
| 12 | # The above copyright notice and this permission notice shall be included | |
| 13 | # in all copies or substantial portions of the Software. | |
| 14 | # | |
| 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 16 | # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
| 17 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
| 18 | # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
| 19 | # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
| 20 | # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
| 21 | # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
| 22 | # ----------------------------------------------------------------------------- | |
| 23 | ||
| 24 | # ----------------------------------------------------------------------------- | |
| 25 | # This script demonstrates using R. | |
| 26 | # ----------------------------------------------------------------------------- | |
| 27 | from sikuli import * | |
| 28 | import sys | |
| 29 | ||
| 30 | if not "../editor.sikuli" in sys.path: | |
| 31 | sys.path.append( "../editor.sikuli" ) | |
| 32 | ||
| 33 | from editor import * | |
| 34 | ||
| 35 | set_typing_speed( 220 ) | |
| 36 | ||
| 37 | # ----------------------------------------------------------------------------- | |
| 38 | # Open the demo text. | |
| 39 | # ----------------------------------------------------------------------------- | |
| 40 | file_open() | |
| 41 | type( Key.UP, Key.ALT ) | |
| 42 | wait( 0.5 ) | |
| 43 | end() | |
| 44 | wait( 0.5 ) | |
| 45 | enter() | |
| 46 | wait( 0.5 ) | |
| 47 | down() | |
| 48 | wait( 0.5 ) | |
| 49 | enter() | |
| 50 | wait( 2 ) | |
| 51 | ||
| 52 | # ----------------------------------------------------------------------------- | |
| 53 | # Re-open the corresponding definition file. | |
| 54 | # ----------------------------------------------------------------------------- | |
| 55 | file_open() | |
| 56 | recur( 2, down ) | |
| 57 | wait( 1 ) | |
| 58 | enter() | |
| 59 | wait( 2 ) | |
| 60 | ||
| 61 | # ----------------------------------------------------------------------------- | |
| 62 | # Brief introduction to R | |
| 63 | # ----------------------------------------------------------------------------- | |
| 64 | type( Key.HOME, Key.CTRL ) | |
| 65 | end() | |
| 66 | paragraph() | |
| 67 | ||
| 68 | typer( "## Using R" ) | |
| 69 | paragraph() | |
| 70 | typer( "Insert R code into documents as follows: `r# 1+1`. " ) | |
| 71 | wait( 1.5 ) | |
| 72 | typer( "Notice how the right-hand pane shows the computed result. I'll wait. " ) | |
| 73 | wait( 3 ) | |
| 74 | typer( "The syntax is: open backtick, r#, *computable expression*, close " ) | |
| 75 | typer( "backtick. That expression can be any valid R statement. The status bar " ) | |
| 76 | typer( "will provide clues when an R expression cannot be computed by the " ) | |
| 77 | typer( "editor. `r# glitch`" ) | |
| 78 | wait( 4 ) | |
| 79 | recur( 11, backspace ) | |
| 80 | typer( "Let's swap 34 storeys for a definition value and replace the number " ) | |
| 81 | typer( "according to the Chicago Manual of Style (cms) rules." ) | |
| 82 | ||
| 83 | # ----------------------------------------------------------------------------- | |
| 84 | # Demo pluralization | |
| 85 | # ----------------------------------------------------------------------------- | |
| 86 | set_typing_speed( 80 ) | |
| 87 | ||
| 88 | edit_find( "34" ) | |
| 89 | autoinsert() | |
| 90 | ||
| 91 | edit_find( "x(" ) | |
| 92 | typer( "cms(" ) | |
| 93 | ||
| 94 | edit_find( "storeys." ) | |
| 95 | typer( "34." ) | |
| 96 | autoinsert() | |
| 97 | edit_find( "x(" ) | |
| 98 | typer( "pl( 'storey'," ) | |
| 99 | wait( 4 ) | |
| 100 | ||
| 101 | tab() | |
| 102 | rename_definition( "1" ) | |
| 103 | wait( 4 ) | |
| 104 | rename_definition( "142" ) | |
| 105 | wait( 4 ) | |
| 106 | rename_definition( "34" ) | |
| 107 | wait( 4 ) | |
| 108 | tab() | |
| 109 | ||
| 110 | # ----------------------------------------------------------------------------- | |
| 111 | # Demo possessives (it, her, his, Director) | |
| 112 | # ----------------------------------------------------------------------------- | |
| 113 | type( Key.HOME, Key.CTRL ) | |
| 114 | edit_find( "Director" ) | |
| 115 | autoinsert() | |
| 116 | edit_find_next() | |
| 117 | autoinsert() | |
| 118 | edit_find_next() | |
| 119 | autoinsert() | |
| 120 | type( Key.RIGHT ) | |
| 121 | recur( 2, delete ) | |
| 122 | autoinsert() | |
| 123 | home() | |
| 124 | edit_find( "x(" ) | |
| 125 | typer( "pos(" ) | |
| 126 | wait( 2 ) | |
| 127 | ||
| 128 | tab() | |
| 129 | rename_definition( "Headmistress" ) | |
| 130 | wait( 4 ) | |
| 131 | rename_definition( "Director" ) | |
| 132 | wait( 2 ) | |
| 133 | tab() | |
| 134 | ||
| 135 | type( Key.END, Key.CTRL ) | |
| 136 | paragraph() | |
| 137 | typer( "Other possessives: `r# pos( 'it' )`, `r# pos( 'her' )`, `r# pos( 'his' )`, " ) | |
| 138 | typer( "and `r# pos( 'my' )`." ) | |
| 139 | ||
| 140 | # ----------------------------------------------------------------------------- | |
| 141 | # Demo conversion, including ordinal numbers | |
| 142 | # ----------------------------------------------------------------------------- | |
| 143 | set_typing_speed( 160 ) | |
| 144 | ||
| 145 | paragraph() | |
| 146 | heading( "Date Conversions" ) | |
| 147 | typer( "Mixing R code with definitions invites endless possibilities. " ) | |
| 148 | typer( "Imagine someone racing to the " ) | |
| 149 | typer( "`r#cms( v$location$breeder$storeys, ordinal=TRUE )` floor, whereby that " ) | |
| 150 | typer( "ordinal stems from the Hatchery's storeys' definition. Or how about " ) | |
| 151 | typer( "a complex timeline where dates are expressed in days relative to one " ) | |
| 152 | typer( "point in time. Let's call this the *anchor date* and define it." ) | |
| 153 | ||
| 154 | tab() | |
| 155 | home() | |
| 156 | typer( Key.SPACE ) | |
| 157 | insert() | |
| 158 | rename_definition( "date" ) | |
| 159 | insert() | |
| 160 | rename_definition( "anchor" ) | |
| 161 | insert() | |
| 162 | rename_definition( "1969-10-29" ) | |
| 163 | tab() | |
| 164 | ||
| 165 | paragraph() | |
| 166 | typer( "Next, set an R variable named `now` to the current date" ) | |
| 167 | typer( "`r# now = format( Sys.time(), '%Y-%m-%d' ); ''`--- the empty single quotes " ) | |
| 168 | typer( "prevent the date from appearing in the output document. " ) | |
| 169 | ||
| 170 | paragraph() | |
| 171 | typer( "We set the anchor date to `r# annal()`, which was " ) | |
| 172 | typer( "`r# elapsed( 0, days( v$date$anchor, format( Sys.time(), '%Y-%m-%d' ) ) )` " ) | |
| 173 | typer( "ago from `r# format( as.Date( now ), '%B %d, %Y' )`. " ) | |
| 174 | ||
| 175 | # ----------------------------------------------------------------------------- | |
| 176 | # Demo CSV file import | |
| 177 | # ----------------------------------------------------------------------------- | |
| 178 | paragraph() | |
| 179 | heading( "Tabular Data" ) | |
| 180 | typer( "The following table shows average Canadian lifespans by birth " ) | |
| 181 | typer( "year and sex:" ) | |
| 182 | paragraph() | |
| 183 | typer( "`r# csv2md( '../data.csv', total=FALSE )`" ) | |
| 184 | paragraph() | |
| 185 | typer( "Calling `csv2md` converts the comma-separated values in the spreadsheet " ) | |
| 186 | typer( "to a table formatted using Markdown. The HTML preview pane changes the " ) | |
| 187 | typer( "appearance of the resulting table. Using `../data.csv` instructs R to " ) | |
| 188 | typer( "open `data.csv` from one directory above the *working directory*." ) | |
| 189 | ||
| 190 | # ----------------------------------------------------------------------------- | |
| 191 | # Demo HTML export | |
| 192 | # ----------------------------------------------------------------------------- | |
| 193 | paragraph() | |
| 194 | heading( "Export" ) | |
| 195 | typer( "Retrieve the output HTML by using the **Edit > Copy HTML** menu. Let's " ) | |
| 196 | typer( "peek at the output." ) | |
| 197 | wait( 2 ) | |
| 198 | ||
| 199 | type( "e", Key.ALT ) | |
| 200 | wait( 0.5 ) | |
| 201 | down() | |
| 202 | wait( 0.25 ) | |
| 203 | enter() | |
| 204 | wait( 0.25 ) | |
| 205 | ||
| 206 | type( "a", Key.CTRL ) | |
| 207 | wait( 0.25 ) | |
| 208 | type( "v", Key.CTRL ) | |
| 209 | wait( 5 ) | |
| 210 | ||
| 211 | set_typing_speed( 40 ) | |
| 212 | ||
| 213 | # Jump to page bottom (should already be there, but just in case) | |
| 214 | type( Key.END, Key.CTRL ) | |
| 215 | recur( 3, typer, Key.PAGE_UP ) | |
| 216 | type( Key.HOME, Key.CTRL ) | |
| 217 | wait( 3 ) | |
| 218 | ||
| 219 | set_typing_speed( 220 ) | |
| 220 | type( "z", Key.CTRL ) | |
| 221 | type( Key.END, Key.CTRL ) | |
| 222 | ||
| 223 | paragraph() | |
| 224 | typer( "That's all for now, thank you!" ) | |
| 225 | wait( 5 ) | |
| 226 | ||
| 227 | # Delete the anchor date. | |
| 228 | tab() | |
| 229 | end() | |
| 230 | recur( 2, type, Key.UP ) | |
| 231 | delete() | |
| 232 | tab() | |
| 1 | 233 |
| 1 | from sikuli import * | |
| 2 | ||
| 3 | import sys | |
| 4 | import os | |
| 5 | ||
| 6 | def set_class_path(): | |
| 7 | path_script = getBundlePath() | |
| 8 | dir_script = os.path.dirname( path_script ) | |
| 9 | path_lib = dir_script + "/keycast/build/libs/keycast.jar" | |
| 10 | ||
| 11 | sys.path.append( path_lib ) | |
| 12 | ||
| 13 | def launch(): | |
| 14 | from com.whitemagicsoftware.keycast import KeyCast | |
| 15 | kc = KeyCast() | |
| 16 | kc.show() | |
| 17 | ||
| 18 | def main(): | |
| 19 | set_class_path() | |
| 20 | launch() | |
| 21 | ||
| 22 | ||
| 23 | if __name__ == "__main__": | |
| 24 | main() | |
| 1 | 25 |
| 1 | ||
| 1 | # ----------------------------------------------------------------------------- | |
| 2 | # Copyright 2020 White Magic Software, Ltd. | |
| 3 | # | |
| 4 | # Permission is hereby granted, free of charge, to any person obtaining a | |
| 5 | # copy of this software and associated documentation fityping_speed = 80 | |
| 6 | *args |
| 1 | *.avi | |
| 2 | *.wav | |
| 3 | *.png | |
| 4 | *.mp4 | |
| 5 | *.mp3 | |
| 6 | ||
| 1 | 7 |
| 1 | <?xml version="1.0" encoding="UTF-8" standalone="no"?> | |
| 2 | <svg | |
| 3 | xmlns:dc="http://purl.org/dc/elements/1.1/" | |
| 4 | xmlns:cc="http://creativecommons.org/ns#" | |
| 5 | xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | |
| 6 | xmlns:svg="http://www.w3.org/2000/svg" | |
| 7 | xmlns="http://www.w3.org/2000/svg" | |
| 8 | xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" | |
| 9 | xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" | |
| 10 | width="211.87125mm" | |
| 11 | height="56.576mm" | |
| 12 | viewBox="0 0 211.87125 56.576" | |
| 13 | version="1.1" | |
| 14 | id="svg8" | |
| 15 | inkscape:version="1.0 (4035a4fb49, 2020-05-01)" | |
| 16 | sodipodi:docname="traced-text.svg"> | |
| 17 | <defs | |
| 18 | id="defs2" /> | |
| 19 | <sodipodi:namedview | |
| 20 | id="base" | |
| 21 | pagecolor="#ffffff" | |
| 22 | bordercolor="#666666" | |
| 23 | borderopacity="1.0" | |
| 24 | inkscape:pageopacity="0.0" | |
| 25 | inkscape:pageshadow="2" | |
| 26 | inkscape:zoom="1.4142136" | |
| 27 | inkscape:cx="367.6429" | |
| 28 | inkscape:cy="129.23348" | |
| 29 | inkscape:document-units="mm" | |
| 30 | inkscape:current-layer="layer1" | |
| 31 | inkscape:document-rotation="0" | |
| 32 | showgrid="false" | |
| 33 | fit-margin-top="10" | |
| 34 | fit-margin-left="10" | |
| 35 | fit-margin-right="10" | |
| 36 | fit-margin-bottom="10" /> | |
| 37 | <metadata | |
| 38 | id="metadata5"> | |
| 39 | <rdf:RDF> | |
| 40 | <cc:Work | |
| 41 | rdf:about=""> | |
| 42 | <dc:format>image/svg+xml</dc:format> | |
| 43 | <dc:type | |
| 44 | rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> | |
| 45 | <dc:title></dc:title> | |
| 46 | </cc:Work> | |
| 47 | </rdf:RDF> | |
| 48 | </metadata> | |
| 49 | <g | |
| 50 | inkscape:label="Layer 1" | |
| 51 | inkscape:groupmode="layer" | |
| 52 | id="layer1" | |
| 53 | transform="translate(-1.4263456,-106.05539)"> | |
| 54 | <text | |
| 55 | xml:space="preserve" | |
| 56 | style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:50.8px;line-height:1.25;font-family:'Alex Brush';-inkscape-font-specification:'Alex Brush, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.264583" | |
| 57 | x="12.289946" | |
| 58 | y="147.80539" | |
| 59 | id="text835"><tspan | |
| 60 | sodipodi:role="line" | |
| 61 | id="tspan833" | |
| 62 | x="12.289946" | |
| 63 | y="147.80539" | |
| 64 | style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:50.8px;font-family:'Alex Brush';-inkscape-font-specification:'Alex Brush, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583">Scrivenvar</tspan></text> | |
| 65 | <path | |
| 66 | sodipodi:nodetypes="cssssc" | |
| 67 | id="path859" | |
| 68 | d="m 47.37594,126.25759 c 5.878995,0.58684 8.108819,-2.8906 6.991897,-5.39049 -4.163299,-9.31827 -26.104298,-1.57165 -26.47428,4.67958 -0.290066,4.90098 4.329286,5.69691 9.138161,6.81221 4.75698,1.10326 9.980125,1.72503 10.138085,4.5281 0.511551,9.07772 -11.28247,13.50974 -21.577969,13.14767" | |
| 69 | style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#4eb059;stroke-width:0.132292;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> | |
| 70 | <path | |
| 71 | sodipodi:nodetypes="cssc" | |
| 72 | id="path861" | |
| 73 | d="m 61.538159,137.91416 c 8.229745,-12.05206 -9.227635,-1.22793 -10.272792,5.40306 -0.929347,5.89623 4.566953,5.63307 9.024721,2.11036 5.095939,-4.02702 8.706628,-8.11599 12.031905,-13.9409" | |
| 74 | style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#4eb059;stroke-width:0.132292;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> | |
| 75 | <path | |
| 76 | sodipodi:nodetypes="ccssc" | |
| 77 | id="path863" | |
| 78 | d="m 72.321991,131.48668 c 3.834665,-5.91801 -1.131419,0.83402 0.75311,2.48796 2.189872,1.94816 6.580549,-2.11016 5.400159,-0.72958 -0.854851,0.99983 -9.857527,10.41157 -5.126492,13.80621 2.461609,1.76627 8.936925,-2.58857 11.751532,-5.5313" | |
| 79 | style="fill:none;fill-opacity:0.8;stroke:#4eb059;stroke-width:0.132292;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> | |
| 80 | <path | |
| 81 | sodipodi:nodetypes="csssc" | |
| 82 | id="path963" | |
| 83 | d="m 85.1003,141.51997 c 0,0 6.754775,-9.24626 6.743495,-8.01563 -0.01328,1.44899 -5.040946,6.68411 -6.63123,10.08427 -0.90584,1.93677 -0.626402,4.68995 2.447111,4.25184 1.468017,-0.20926 5.212094,-2.44913 10.029682,-7.66684" | |
| 84 | style="fill:none;fill-opacity:0.8;stroke:#4eb059;stroke-width:0.132292;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> | |
| 85 | <path | |
| 86 | sodipodi:nodetypes="csccc" | |
| 87 | id="path965" | |
| 88 | d="m 97.689357,140.17361 c 0,0 3.797813,-8.42805 4.594353,-7.95573 0.58723,0.34822 -6.526154,13.32545 -5.477472,14.50806 2.435753,1.7862 19.064212,-11.51107 15.563042,-16.73913 -0.73409,-1.34256 -3.18033,-1.99148 -3.18033,-1.99148" | |
| 89 | style="fill:none;fill-opacity:0.8;stroke:#4eb059;stroke-width:0.132292;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> | |
| 90 | <path | |
| 91 | sodipodi:nodetypes="csssc" | |
| 92 | d="m 113.37707,141.34636 c 4.23091,0.29831 11.94363,-4.90618 10.94354,-7.7799 -1.29105,-3.70978 -8.05529,1.78774 -9.69006,3.68511 -4.97668,5.77609 -4.11733,10.31478 -0.92228,10.61275 3.436,0.32045 8.83724,-3.13085 13.69698,-9.62574" | |
| 93 | style="fill:none;fill-opacity:0.8;stroke:#4eb059;stroke-width:0.132292;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 94 | id="path967" /> | |
| 95 | <path | |
| 96 | style="fill:none;fill-opacity:0.8;stroke:#4eb059;stroke-width:0.132292;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 97 | d="m 146.49943,140.17361 c 0,0 3.79781,-8.42805 4.59435,-7.95573 0.58723,0.34822 -6.52616,13.32545 -5.47747,14.50806 2.43575,1.7862 19.06421,-11.51107 15.56304,-16.73913 -0.73409,-1.34256 -3.10123,-1.96263 -3.10123,-1.96263" | |
| 98 | id="path970" | |
| 99 | sodipodi:nodetypes="csccc" /> | |
| 100 | <path | |
| 101 | style="fill:none;fill-opacity:0.8;stroke:#4eb059;stroke-width:0.132292;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 102 | d="m 188.80833,131.36316 c 3.83466,-5.91801 -1.13142,0.83402 0.75311,2.48796 2.18987,1.94816 6.58055,-2.11016 5.40016,-0.72958 -0.85485,0.99983 -9.98962,10.60367 -5.12649,13.80621 2.8329,1.86556 9.63808,-2.25455 13.61435,-8.05051" | |
| 103 | id="path987" | |
| 104 | sodipodi:nodetypes="ccssc" /> | |
| 105 | <path | |
| 106 | sodipodi:nodetypes="ccsssccc" | |
| 107 | d="m 127.40525,138.23858 c 1.53961,-1.23511 5.06979,-6.4876 5.94375,-5.82833 -1.7832,2.5949 -8.95273,13.68991 -7.1105,13.94503 1.19011,0.16482 7.25976,-8.00422 10.87675,-10.901 1.83151,-1.46682 4.35069,-3.49971 5.94917,-3.73267 1.66376,-0.24247 -1.93803,2.90472 -3.80099,5.77097 -1.36327,2.14988 -4.92421,8.02816 -2.69839,9.35481 3.0826,1.21137 7.35116,-4.27566 9.93439,-6.67382" | |
| 108 | style="fill:none;fill-opacity:0.8;stroke:#4eb059;stroke-width:0.132292;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" | |
| 109 | id="path989" /> | |
| 110 | <path | |
| 111 | sodipodi:nodetypes="csscsc" | |
| 112 | id="path992" | |
| 113 | d="m 176.85645,132.78853 c -3.26879,-6.24001 -16.43513,7.99373 -16.14879,12.14556 0.1378,1.99804 2.16776,3.14653 3.8818,2.44798 4.44909,-1.8132 11.93103,-13.58278 13.4413,-14.18515 -6.97685,9.84354 -7.04537,13.29844 -4.02229,13.83262 2.49715,0.44125 8.94275,-6.11484 14.79986,-15.66638" | |
| 114 | style="fill:none;fill-opacity:0.8;stroke:#4eb059;stroke-width:0.132292;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> | |
| 115 | </g> | |
| 116 | </svg> | |
| 1 | 117 |