Simplifying testing
This commit is contained in:
+1
-1
@@ -32,4 +32,4 @@ retropikzel/pffi/*/compiled
|
||||
tmp
|
||||
dockerfiles/build
|
||||
.scheme_testrunner
|
||||
snow
|
||||
core
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
ARG SCHEME=
|
||||
FROM schemers/${SCHEME}
|
||||
RUN apt-get update && apt-get install -y git make build-essential libffi-dev
|
||||
RUN git clone https://git.sr.ht/~retropikzel/compile-r7rs && cd compile-r7rs && make install
|
||||
COPY libtest.c /
|
||||
RUN gcc -o libtest.so -shared -fPIC libtest.c && cp libtest.so /usr/local/lib/
|
||||
RUN gcc -fPIC -c libtest.c && ar rcs libtest.a libtest.o && cp libtest.a /usr/local/lib
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
To run tests on different architecture than you are using, install podman and add the docker
|
||||
registry to it's configuration. Add the line
|
||||
|
||||
unqualified-search-registries = ["docker.io"]
|
||||
|
||||
to file: /etc/containers/registries.conf
|
||||
@@ -1,6 +0,0 @@
|
||||
## Error early
|
||||
|
||||
Always load with RTLD_NOW if possible so loading happens at start of program.
|
||||
|
||||
Always to to find the function when pffi-define is run, not when the function itself is run so
|
||||
any errors will happen on the program start.
|
||||
Vendored
+117
-20
@@ -1,7 +1,7 @@
|
||||
pipeline {
|
||||
agent {
|
||||
dockerfile {
|
||||
filename 'Dockerfile.jenkins'
|
||||
filename 'dockerfiles/jenkins'
|
||||
dir '.'
|
||||
args '--privileged -v /var/run/docker.sock:/var/run/docker.sock'
|
||||
}
|
||||
@@ -12,69 +12,166 @@ pipeline {
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Chibi') {
|
||||
stage('chibi') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make test-chibi-docker-jenkins-jenkins'
|
||||
sh 'make SCHEME=chibi test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Chicken-5') {
|
||||
stage('chicken') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make test-chicken-5-docker-jenkins'
|
||||
sh 'make SCHEME=chicken test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Cyclone') {
|
||||
stage('cyclone') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make test-cyclone-docker-jenkins'
|
||||
sh 'make SCHEME=cyclone test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Gambit') {
|
||||
stage('gambit') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make test-gambit-docker-jenkins'
|
||||
sh 'make SCHEME=gambit test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Guile') {
|
||||
stage('gauche') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make test-guile-docker-jenkins'
|
||||
sh 'make SCHEME=gauche test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Sagittarius') {
|
||||
stage('gerbil') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make test-sagittarius-docker-jenkins'
|
||||
sh 'make SCHEME=gerbil test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Racket') {
|
||||
stage('guile') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make test-racket-docker-jenkins'
|
||||
sh 'make SCHEME=guile test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Kawa') {
|
||||
stage('kawa') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make test-kawa-docker-jenkins'
|
||||
sh 'make SCHEME=kawa test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('STklos') {
|
||||
stage('mosh') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make test-stklos-docker-jenkins'
|
||||
sh 'make SCHEME=mosh test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('racket') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make SCHEME=racket test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('racket-wine') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make SCHEME=racket-wine test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('sagittarius') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make SCHEME=sagittarius test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('stklos') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make SCHEME=stklos test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('skint') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make SCHEME=skint test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('tr7i') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make SCHEME=tr7i test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('ypsilon') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make SCHEME=ypsilon test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('chicken') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make SCHEME=chicken test-compile-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('cyclone') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make SCHEME=cyclone test-compile-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('gambit') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make SCHEME=gambit test-compile-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('gauche') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make SCHEME=gauche test-compile-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('gerbil') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make SCHEME=gerbil test-compile-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('kawa') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make SCHEME=kawa test-compile-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('racket') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make SCHEME=racket test-compile-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@ CC=gcc
|
||||
DOCKER=docker run -it -v ${PWD}:/workdir
|
||||
DOCKER_INIT=cd /workdir && make clean &&
|
||||
|
||||
jenkinsfile:
|
||||
gosh -r7 -I ./snow build.scm
|
||||
|
||||
libtest.so: libtest.c
|
||||
${CC} -o libtest.so -shared -fPIC libtest.c
|
||||
|
||||
@@ -13,9 +16,19 @@ libtest.a: libtest.c
|
||||
test-script: libtest.so
|
||||
SCHEME=${SCHEME} script-r7rs -I . test.scm
|
||||
|
||||
test-script-docker:
|
||||
sudo docker build -f dockerfiles/test . --build-arg SCHEME=${SCHEME} --tag=pffi-${SCHEME}
|
||||
sudo docker run -v ${PWD}:/workdir pffi-${SCHEME} bash -c "cd /workdir && make libtest.so && SCHEME=${SCHEME} script-r7rs -I . test.scm"
|
||||
|
||||
test-compile: libtest.so libtest.a
|
||||
SCHEME=${SCHEME} compile-r7rs-library retropikzel/pffi.sld
|
||||
SCHEME=${SCHEME} compile-r7rs -I . test.scm && ./test
|
||||
|
||||
test-compile-docker: libtest.so libtest.a
|
||||
sudo docker build -f dockerfiles/test . --build-arg SCHEME=${SCHEME} --tag=pffi-${SCHEME}
|
||||
sudo docker run -v ${PWD}:/workdir pffi-${SCHEME} bash -c "cd /workdir && SCHEME=${SCHEME} compile-r7rs-library retropikzel/pffi.sld"
|
||||
sudo docker run -v ${PWD}:/workdir pffi-${SCHEME} bash -c "cd /workdir && SCHEME=${SCHEME} compile-r7rs -I . test.scm && ./test"
|
||||
|
||||
CHIBI=chibi-scheme -A .
|
||||
test-chibi-docker:
|
||||
docker build -f Dockerfile --build-arg SCHEME=chibi --tag=r7rs-pffi-chibi .
|
||||
@@ -194,6 +207,7 @@ clean:
|
||||
find . -name "*.o[1-9]" -delete
|
||||
find . -name "*.so" -delete
|
||||
find . -name "*.a" -delete
|
||||
find . -name "*.class" -delete
|
||||
@rm -rf test
|
||||
@rm -rf tmp
|
||||
find . -name "core.1" -delete
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
(import (scheme base)
|
||||
(scheme write)
|
||||
(scheme file)
|
||||
(scheme process-context)
|
||||
(arvyy mustache))
|
||||
|
||||
(define slurp-loop
|
||||
(lambda (line result)
|
||||
(if (eof-object? line)
|
||||
result
|
||||
(slurp-loop (read-line) (string-append result line (string #\newline))))))
|
||||
|
||||
(define slurp
|
||||
(lambda (path)
|
||||
(with-input-from-file
|
||||
path
|
||||
(lambda ()
|
||||
(slurp-loop (read-line) "")))))
|
||||
|
||||
(define script-implementations
|
||||
(vector "chibi"
|
||||
"chicken"
|
||||
"cyclone"
|
||||
"gambit"
|
||||
"gauche"
|
||||
;"gauche-wine" TODO
|
||||
"gerbil"
|
||||
"guile"
|
||||
"kawa"
|
||||
;"meevax" TODO
|
||||
"mosh"
|
||||
"racket"
|
||||
"racket-wine"
|
||||
"sagittarius"
|
||||
;"sagittarius-wine" TODO
|
||||
"stklos"
|
||||
"skint"
|
||||
"tr7i"
|
||||
"ypsilon"))
|
||||
|
||||
(define compiler-implementations
|
||||
(vector "chicken"
|
||||
"cyclone"
|
||||
"gambit"
|
||||
"gauche"
|
||||
"gerbil"
|
||||
"kawa"
|
||||
"racket"
|
||||
;"racket-wine" TODO
|
||||
))
|
||||
|
||||
;; Jenkinsfile
|
||||
(call-with-output-file
|
||||
"Jenkinsfile"
|
||||
(lambda (out)
|
||||
(execute (compile (slurp "templates/Jenkinsfile"))
|
||||
(list (cons 'script-implementations script-implementations)
|
||||
(cons 'compiler-implementations compiler-implementations))
|
||||
out)))
|
||||
@@ -1,9 +0,0 @@
|
||||
((packager . "retropikzel")
|
||||
(name . "r7rs-pffi")
|
||||
(version . "v0-4-4")
|
||||
(type . "library")
|
||||
(description . "Portable Foreign Function Interface for R7RS schemes")
|
||||
(license . "LGPL")
|
||||
(dependencies ())
|
||||
(development-dependencies ())
|
||||
)
|
||||
@@ -1,3 +0,0 @@
|
||||
# Portable Foreign Function Interface for R7RS schemes
|
||||
|
||||
Foreign function interface that is supported on multiple R7RS Sceheme implementations.
|
||||
@@ -1,231 +0,0 @@
|
||||
# Reference
|
||||
|
||||
# Types
|
||||
|
||||
Types are given as symbols, for example 'int8 or 'pointer.
|
||||
|
||||
- int8
|
||||
- uint8
|
||||
- int16
|
||||
- uint16
|
||||
- int32
|
||||
- uint32
|
||||
- int64
|
||||
- uint64
|
||||
- char
|
||||
- unsigned-char
|
||||
- short
|
||||
- unsigned-short
|
||||
- int
|
||||
- unsigned-int
|
||||
- long
|
||||
- unsigned-long
|
||||
- float
|
||||
- double
|
||||
- pointer
|
||||
|
||||
# Procedures or macros
|
||||
|
||||
On some implementations these are procedures, on some macros.
|
||||
|
||||
The arguments are in form
|
||||
|
||||
- NAME - TYPE
|
||||
|
||||
The return value is in form
|
||||
|
||||
- TYPE
|
||||
|
||||
|
||||
## pffi-shared-object-auto-load
|
||||
|
||||
Arguments:
|
||||
|
||||
- headers - (list string ...)
|
||||
- C headers of the library
|
||||
- For example (list "curl/curl.h")
|
||||
- object-name - symbol
|
||||
- The name of the dynamic library file you want to load
|
||||
- Without the "lib" in front of it
|
||||
- Without the ".so" or ".dll" at the end
|
||||
- additional-versions - (list string...)
|
||||
- For example (list ".0" ".1")
|
||||
- additional-paths - (list string...)
|
||||
- Any additional paths you want to search for the library
|
||||
- For example (list "./mylibs")
|
||||
|
||||
Returns:
|
||||
|
||||
- object
|
||||
- Shared object, the type depends on the implementation
|
||||
|
||||
## pffi-shared-object-load
|
||||
|
||||
It is recommended to use the pffi-shared-object-auto-load instead of this
|
||||
directly.
|
||||
|
||||
Arguments:
|
||||
|
||||
- headers - (list string ...)
|
||||
- Headers that need to be included
|
||||
- Example (list "curl/curl.h")
|
||||
- path - string
|
||||
- The full path to the shared object you want to load, including any "lib" infront and .so/.dll at the end
|
||||
- Example "libcurl.so"
|
||||
|
||||
Returns:
|
||||
|
||||
- object
|
||||
- Shared object, the type depends on the implementation
|
||||
|
||||
|
||||
|
||||
## pffi-define
|
||||
|
||||
Defines new foreign procedure.
|
||||
|
||||
Arguments:
|
||||
|
||||
- scheme-name - symbol
|
||||
- The name of the procedure used on scheme side
|
||||
- shared-object - object
|
||||
- The shared object
|
||||
- Use pffi-shared-object-auto-load or pffi-shared-object-load to get this
|
||||
- c-name - symbol
|
||||
- The name of the C function
|
||||
- return-type - symbol
|
||||
- The return type of the C function
|
||||
- arguments-types - (list symbol ...)
|
||||
- The C function argument types
|
||||
- Need to be given in form (list 'type 'type)
|
||||
|
||||
## pffi-define-callback
|
||||
|
||||
Defines new callback function.
|
||||
|
||||
Arguments:
|
||||
|
||||
- scheme-name
|
||||
- The name of the function used on scheme side
|
||||
- return-type - symbol
|
||||
- The return type of the callback
|
||||
- arguments-types - (list symbol ...)
|
||||
- The callback function argument types
|
||||
- procedure - procedure
|
||||
- Procedure used as callback function
|
||||
- Argument count must match the argument-types count
|
||||
|
||||
## pffi-size-of
|
||||
|
||||
Get the size of type.
|
||||
|
||||
Arguments:
|
||||
|
||||
- type - symbol
|
||||
- The type you want the size of
|
||||
|
||||
Returns:
|
||||
|
||||
- number
|
||||
- The size of the given type
|
||||
|
||||
|
||||
## pffi-pointer-allocate
|
||||
|
||||
Allocates a pointer of given size.
|
||||
|
||||
Arguments:
|
||||
|
||||
- size - number
|
||||
- The size of the pointer you want to allocate
|
||||
|
||||
Returns:
|
||||
|
||||
- object
|
||||
- A pointer of given size
|
||||
|
||||
|
||||
## pffi-pointer-null
|
||||
|
||||
Create a null pointer.
|
||||
|
||||
Returns:
|
||||
- object
|
||||
- Null pointer
|
||||
|
||||
## pffi-string->pointer
|
||||
|
||||
Arguments:
|
||||
|
||||
- string-content - string
|
||||
- The string you want to transform into pointer
|
||||
|
||||
Returns:
|
||||
|
||||
- object
|
||||
- Pointer of the given string
|
||||
|
||||
|
||||
## pffi-pointer->string
|
||||
|
||||
Arguments:
|
||||
|
||||
- pointer - object
|
||||
- The pointer you want to transform to string
|
||||
|
||||
Returns:
|
||||
|
||||
- string
|
||||
- String from the given pointer
|
||||
|
||||
## pffi-pointer-free
|
||||
|
||||
Arguments:
|
||||
|
||||
- pointer - object
|
||||
- The pointer you want to free
|
||||
|
||||
## pffi-pointer?
|
||||
|
||||
Arguments:
|
||||
|
||||
- object - object
|
||||
- The object you want to check wether it is a pointer or not
|
||||
|
||||
Returns:
|
||||
|
||||
- boolean
|
||||
- Returns true if given object is pointer, otherwise false
|
||||
|
||||
|
||||
## pffi-pointer-set!
|
||||
|
||||
Arguments:
|
||||
|
||||
- pointer - object
|
||||
- The pointer you want to modify
|
||||
- type - symbol
|
||||
- The type of value that will be put into the pointer
|
||||
- offset -number
|
||||
- The location of the value inside the pointer
|
||||
- For example: (+ (pffi-size-of 'int) (pffi-size-of 'pointer)) or 0
|
||||
- value - object
|
||||
- The value to be placed into the object
|
||||
|
||||
## pffi-pointer-get
|
||||
|
||||
Arguments:
|
||||
|
||||
- pointer - object
|
||||
- The pointer you want to get the value from
|
||||
- type - symbol
|
||||
- The type of value you want to get
|
||||
- For example: 'int
|
||||
- offset - number
|
||||
- The location of the value inside the pointer
|
||||
- For example: (+ (pffi-size-of 'int) (pffi-size-of 'pointer)) or 0
|
||||
|
||||
Returns:
|
||||
|
||||
- object
|
||||
- The value in the poiner in the given offset as given type
|
||||
@@ -1 +0,0 @@
|
||||
(prelude: :scheme/r7rs)
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
source "$HOME/.sdkman/bin/sdkman-init.sh"
|
||||
sdk use 22.0.2-tem
|
||||
@@ -1 +0,0 @@
|
||||
site_name: r7rs-pffi
|
||||
-145
@@ -1,145 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
|
||||
|
||||
<link rel="shortcut icon" href="/img/favicon.ico">
|
||||
<title>r7rs-pffi</title>
|
||||
<link href="/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="/css/font-awesome.min.css" rel="stylesheet">
|
||||
<link href="/css/base.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css">
|
||||
|
||||
<script src="/js/jquery-1.10.2.min.js" defer></script>
|
||||
<script src="/js/bootstrap.min.js" defer></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
|
||||
<script>hljs.initHighlightingOnLoad();</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="navbar fixed-top navbar-expand-lg navbar-dark bg-primary">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="/.">r7rs-pffi</a>
|
||||
<!-- Expander button -->
|
||||
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar-collapse">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<!-- Expanded navigation -->
|
||||
<div id="navbar-collapse" class="navbar-collapse collapse">
|
||||
<!-- Main navigation -->
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="navitem">
|
||||
<a href="/." class="nav-link">Portable Foreign Function Interface for R7RS schemes</a>
|
||||
</li>
|
||||
<li class="navitem">
|
||||
<a href="/reference/" class="nav-link">Reference</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav navbar-nav ml-auto">
|
||||
<li class="nav-item">
|
||||
<a href="#" class="nav-link" data-toggle="modal" data-target="#mkdocs_search_modal">
|
||||
<i class="fa fa-search"></i> Search
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
|
||||
<div class="row-fluid">
|
||||
<div id="main-content" class="span12">
|
||||
<h1 id="404-page-not-found" style="text-align: center">404</h1>
|
||||
<p style="text-align: center"><strong>Page not found</strong></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="col-md-12">
|
||||
<hr>
|
||||
<p>Documentation built with <a href="https://www.mkdocs.org/">MkDocs</a>.</p>
|
||||
</footer>
|
||||
<script>
|
||||
var base_url = "/",
|
||||
shortcuts = {"help": 191, "next": 78, "previous": 80, "search": 83};
|
||||
</script>
|
||||
<script src="/js/base.js" defer></script>
|
||||
<script src="/search/main.js" defer></script>
|
||||
|
||||
<div class="modal" id="mkdocs_search_modal" tabindex="-1" role="dialog" aria-labelledby="searchModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title" id="searchModalLabel">Search</h4>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
From here you can search these documents. Enter
|
||||
your search terms below.
|
||||
</p>
|
||||
<form>
|
||||
<div class="form-group">
|
||||
<input type="search" class="form-control" placeholder="Search..." id="mkdocs-search-query" title="Type search term here">
|
||||
</div>
|
||||
</form>
|
||||
<div id="mkdocs-search-results"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="modal" id="mkdocs_keyboard_modal" tabindex="-1" role="dialog" aria-labelledby="keyboardModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title" id="keyboardModalLabel">Keyboard Shortcuts</h4>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 20%;">Keys</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="help shortcut"><kbd>?</kbd></td>
|
||||
<td>Open this help</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="next shortcut"><kbd>n</kbd></td>
|
||||
<td>Next page</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="prev shortcut"><kbd>p</kbd></td>
|
||||
<td>Previous page</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="search shortcut"><kbd>s</kbd></td>
|
||||
<td>Search</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,313 +0,0 @@
|
||||
html {
|
||||
/* csslint ignore:start */
|
||||
/* The nav header is 3.5rem high, plus 20px for the margin-top of the
|
||||
main container. */
|
||||
scroll-padding-top: calc(3.5rem + 20px);
|
||||
/* csslint ignore:end */
|
||||
}
|
||||
|
||||
/* Replacement for `body { background-attachment: fixed; }`, which has
|
||||
performance issues when scrolling on large displays. See #1394. */
|
||||
body::before {
|
||||
content: ' ';
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: #f8f8f8;
|
||||
background: url(../img/grid.png) repeat-x;
|
||||
will-change: transform;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
body > .container {
|
||||
margin-top: 20px;
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
.navbar.fixed-top { /* csslint allow: adjoining-classes */
|
||||
/* csslint ignore:start */
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
/* csslint ignore:end */
|
||||
}
|
||||
|
||||
.source-links {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.col-md-9 img {
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
padding: 4px;
|
||||
line-height: 1.428571429;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
margin: 20px auto 30px auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: #444;
|
||||
font-weight: 400;
|
||||
font-size: 42px;
|
||||
}
|
||||
|
||||
h2, h3, h4, h5, h6 {
|
||||
color: #444;
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
hr {
|
||||
border-top: 1px solid #aaa;
|
||||
}
|
||||
|
||||
pre, .rst-content tt {
|
||||
max-width: 100%;
|
||||
background: #fff;
|
||||
border: solid 1px #e1e4e5;
|
||||
color: #333;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
code.code-large, .rst-content tt.code-large {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
code {
|
||||
padding: 2px 5px;
|
||||
background: #fff;
|
||||
border: solid 1px #e1e4e5;
|
||||
color: #333;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
pre code {
|
||||
display: block;
|
||||
background: transparent;
|
||||
border: none;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
font-family: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
kbd {
|
||||
padding: 2px 4px;
|
||||
font-size: 90%;
|
||||
color: #fff;
|
||||
background-color: #333;
|
||||
border-radius: 3px;
|
||||
-webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);
|
||||
box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);
|
||||
}
|
||||
|
||||
a code {
|
||||
color: #2FA4E7;
|
||||
}
|
||||
|
||||
a:hover code, a:focus code {
|
||||
color: #157AB5;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 30px;
|
||||
margin-bottom: 10px;
|
||||
text-align: center;
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
.modal-dialog {
|
||||
margin-top: 60px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Side navigation
|
||||
*
|
||||
* Scrollspy and affixed enhanced navigation to highlight sections and secondary
|
||||
* sections of docs content.
|
||||
*/
|
||||
|
||||
.bs-sidebar.affix { /* csslint allow: adjoining-classes */
|
||||
/* csslint ignore:start */
|
||||
position: -webkit-sticky;
|
||||
position: sticky;
|
||||
/* csslint ignore:end */
|
||||
/* The nav header is 3.5rem high, plus 20px for the margin-top of the
|
||||
main container. */
|
||||
top: calc(3.5rem + 20px);
|
||||
}
|
||||
|
||||
.bs-sidebar.card { /* csslint allow: adjoining-classes */
|
||||
padding: 0;
|
||||
max-height: 90%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* Toggle (vertically flip) sidebar collapse icon */
|
||||
.bs-sidebar .navbar-toggler span {
|
||||
-moz-transform: scale(1, -1);
|
||||
-webkit-transform: scale(1, -1);
|
||||
-o-transform: scale(1, -1);
|
||||
-ms-transform: scale(1, -1);
|
||||
transform: scale(1, -1);
|
||||
}
|
||||
|
||||
.bs-sidebar .navbar-toggler.collapsed span { /* csslint allow: adjoining-classes */
|
||||
-moz-transform: scale(1, 1);
|
||||
-webkit-transform: scale(1, 1);
|
||||
-o-transform: scale(1, 1);
|
||||
-ms-transform: scale(1, 1);
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
|
||||
/* First level of nav */
|
||||
.bs-sidebar > .navbar-collapse > .nav {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-radius: 5px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* All levels of nav */
|
||||
.bs-sidebar .nav > li > a {
|
||||
display: block;
|
||||
padding: 5px 20px;
|
||||
z-index: 1;
|
||||
}
|
||||
.bs-sidebar .nav > li > a:hover,
|
||||
.bs-sidebar .nav > li > a:focus {
|
||||
text-decoration: none;
|
||||
border-right: 1px solid;
|
||||
}
|
||||
.bs-sidebar .nav > li > a.active,
|
||||
.bs-sidebar .nav > li > a.active:hover,
|
||||
.bs-sidebar .nav > li > a.active:focus {
|
||||
font-weight: bold;
|
||||
background-color: transparent;
|
||||
border-right: 1px solid;
|
||||
}
|
||||
|
||||
.bs-sidebar .nav .nav .nav {
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.bs-sidebar .nav > li > a {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.bs-sidebar .nav .nav > li > a {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.headerlink {
|
||||
font-family: FontAwesome;
|
||||
font-size: 14px;
|
||||
display: none;
|
||||
padding-left: .5em;
|
||||
}
|
||||
|
||||
h1:hover .headerlink, h2:hover .headerlink, h3:hover .headerlink, h4:hover .headerlink, h5:hover .headerlink, h6:hover .headerlink{
|
||||
display:inline-block;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.admonition {
|
||||
padding: 15px;
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 4px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.admonition.note { /* csslint allow: adjoining-classes */
|
||||
color: #3a87ad;
|
||||
background-color: #d9edf7;
|
||||
border-color: #bce8f1;
|
||||
}
|
||||
|
||||
.admonition.warning { /* csslint allow: adjoining-classes */
|
||||
color: #c09853;
|
||||
background-color: #fcf8e3;
|
||||
border-color: #fbeed5;
|
||||
}
|
||||
|
||||
.admonition.danger { /* csslint allow: adjoining-classes */
|
||||
color: #b94a48;
|
||||
background-color: #f2dede;
|
||||
border-color: #eed3d7;
|
||||
}
|
||||
|
||||
.admonition-title {
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@media (max-width: 991.98px) {
|
||||
.navbar-collapse.show { /* csslint allow: adjoining-classes */
|
||||
overflow-y: auto;
|
||||
max-height: calc(100vh - 3.5rem);
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-item.open { /* csslint allow: adjoining-classes */
|
||||
color: #fff;
|
||||
background-color: #2FA4E7;
|
||||
}
|
||||
|
||||
.dropdown-submenu > .dropdown-menu {
|
||||
margin: 0 0 0 1.5rem;
|
||||
padding: 0;
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.dropdown-submenu > a::after {
|
||||
display: block;
|
||||
content: " ";
|
||||
float: right;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-color: transparent;
|
||||
border-style: solid;
|
||||
border-width: 5px 0 5px 5px;
|
||||
border-left-color: #ccc;
|
||||
margin-top: 5px;
|
||||
margin-right: -10px;
|
||||
}
|
||||
|
||||
.dropdown-submenu:hover > a::after {
|
||||
border-left-color: #fff;
|
||||
}
|
||||
|
||||
@media (min-width: 992px) {
|
||||
.dropdown-menu {
|
||||
overflow-y: auto;
|
||||
max-height: calc(100vh - 3.5rem);
|
||||
}
|
||||
|
||||
.dropdown-submenu {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dropdown-submenu > .dropdown-menu {
|
||||
/* csslint ignore:start */
|
||||
position: fixed !important;
|
||||
/* csslint ignore:end */
|
||||
margin-top: -9px;
|
||||
margin-left: -2px;
|
||||
border-width: 1px;
|
||||
padding: 0.5rem 0;
|
||||
}
|
||||
|
||||
.dropdown-submenu.pull-left { /* csslint allow: adjoining-classes */
|
||||
float: none;
|
||||
}
|
||||
|
||||
.dropdown-submenu.pull-left > .dropdown-menu { /* csslint allow: adjoining-classes */
|
||||
left: -100%;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
Vendored
-8
File diff suppressed because one or more lines are too long
Vendored
-4
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 434 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 420 B |
-344
@@ -1,344 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="None">
|
||||
|
||||
|
||||
<link rel="shortcut icon" href="img/favicon.ico">
|
||||
<title>r7rs-pffi</title>
|
||||
<link href="css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="css/font-awesome.min.css" rel="stylesheet">
|
||||
<link href="css/base.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css">
|
||||
|
||||
<script src="js/jquery-1.10.2.min.js" defer></script>
|
||||
<script src="js/bootstrap.min.js" defer></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
|
||||
<script>hljs.initHighlightingOnLoad();</script>
|
||||
</head>
|
||||
|
||||
<body class="homepage">
|
||||
<div class="navbar fixed-top navbar-expand-lg navbar-dark bg-primary">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href=".">r7rs-pffi</a>
|
||||
<!-- Expander button -->
|
||||
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar-collapse">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<!-- Expanded navigation -->
|
||||
<div id="navbar-collapse" class="navbar-collapse collapse">
|
||||
<!-- Main navigation -->
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="navitem active">
|
||||
<a href="." class="nav-link">Portable Foreign Function Interface for R7RS schemes</a>
|
||||
</li>
|
||||
<li class="navitem">
|
||||
<a href="reference/" class="nav-link">Reference</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav navbar-nav ml-auto">
|
||||
<li class="nav-item">
|
||||
<a href="#" class="nav-link" data-toggle="modal" data-target="#mkdocs_search_modal">
|
||||
<i class="fa fa-search"></i> Search
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a rel="prev" class="nav-link disabled">
|
||||
<i class="fa fa-arrow-left"></i> Previous
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a rel="next" href="reference/" class="nav-link">
|
||||
Next <i class="fa fa-arrow-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-3"><div class="navbar-light navbar-expand-md bs-sidebar hidden-print affix" role="complementary">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#toc-collapse" title="Table of Contents">
|
||||
<span class="fa fa-angle-down"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="toc-collapse" class="navbar-collapse collapse card bg-light">
|
||||
<ul class="nav flex-column">
|
||||
|
||||
<li class="nav-item" data-level="1"><a href="#portable-foreign-function-interface-for-r7rs-schemes" class="nav-link">Portable Foreign Function Interface for R7RS schemes</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="nav-item" data-level="1"><a href="#goals" class="nav-link">Goals</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="nav-item" data-level="1"><a href="#non-goals" class="nav-link">Non goals</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="nav-item" data-level="1"><a href="#support-tiers" class="nav-link">Support tiers</a>
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item" data-level="2"><a href="#tier-1" class="nav-link">Tier 1</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#tier-2" class="nav-link">Tier 2</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#tier-3" class="nav-link">Tier 3</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#tier-4" class="nav-link">Tier 4</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#tier-5" class="nav-link">Tier 5</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#tier-6" class="nav-link">Tier 6</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div></div>
|
||||
<div class="col-md-9" role="main">
|
||||
|
||||
<h1 id="portable-foreign-function-interface-for-r7rs-schemes">Portable Foreign Function Interface for R7RS schemes</h1>
|
||||
<p>Foreign function interface that is supported on multiple R7RS Sceheme implementations.</p>
|
||||
<p>Note that this software is in <strong>alpha</strong> stage. That said the interface should not be changing anymore.</p>
|
||||
<p>Any help in form of constructive advice and bug reports are appreciated.</p>
|
||||
<p><a href="https://retropikzel.neocities.org/r7rs-pffi/">Documentation</a> or run mkdocs serve or see docs/.</p>
|
||||
<p><a href="https://todo.sr.ht/~retropikzel/r7rs-pffi">Issue tracker</a></p>
|
||||
<p><a href="https://sr.ht/~retropikzel/r7rs-pffi/lists">Maling lists</a></p>
|
||||
<p>For documentation see <a href="retropikzel.neocities.org/r7rs-pffi">retropikzel.neocities.org/r7rs-pffi</a>
|
||||
or run mkdocs serve or see or docs/ directory.</p>
|
||||
<h1 id="goals">Goals</h1>
|
||||
<ul>
|
||||
<li>Support only R7RS implementations</li>
|
||||
<li>Needs to have cond-expand and library support atleast (propably much more)</li>
|
||||
<li>Same interface on all implementations</li>
|
||||
<li>Some things that are procedures on one implementation are macros on other,
|
||||
but they must behave the same</li>
|
||||
</ul>
|
||||
<h1 id="non-goals">Non goals</h1>
|
||||
<ul>
|
||||
<li>To support all R7RS implementations</li>
|
||||
<li>To have every possible FFI feature</li>
|
||||
<li>Compiling of C code at any point<ul>
|
||||
<li>That is no stubs, no C code generated by the library and so on</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h1 id="support-tiers">Support tiers</h1>
|
||||
<h2 id="tier-1">Tier 1</h2>
|
||||
<ul>
|
||||
<li><a href="https://www.call-cc.org/">Chicken</a><ul>
|
||||
<li>Still needs work</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://www.gnu.org/software/guile/">Guile</a><ul>
|
||||
<li>Good support, recommended</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://www.gnu.org/software/kawa/index.html">Kawa</a><ul>
|
||||
<li>Needs at least java version 22</li>
|
||||
<li>Needs jvm flags:<ul>
|
||||
<li>--add-exports java.base/jdk.internal.foreign.abi=ALL-UNNAMED</li>
|
||||
<li>--add-exports java.base/jdk.internal.foreign.layout=ALL-UNNAMED</li>
|
||||
<li>--add-exports java.base/jdk.internal.foreign=ALL-UNNAMED</li>
|
||||
<li>--enable-native-access=ALL-UNNAMED</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Good support (otherwise), recommended</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://bitbucket.org/ktakashi/sagittarius-scheme/wiki/Home">Sagittarius</a><ul>
|
||||
<li>Good support, recommended</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://racket-lang.org/">Racket</a><ul>
|
||||
<li>Good support, recommended</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://gambitscheme.org">Gambit</a><ul>
|
||||
<li>Still needs work</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="tier-2">Tier 2</h2>
|
||||
<p>These implementations do not have callback support on their FFI. If I'm wrong please let me know!</p>
|
||||
<ul>
|
||||
<li><a href="https://stklos.net/">STKlos</a><ul>
|
||||
<li>Still needs work</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://justinethier.github.io/cyclone/">Cyclone</a><ul>
|
||||
<li>Still needs work</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="tier-3">Tier 3</h2>
|
||||
<p>Support waiting for the implementation.</p>
|
||||
<ul>
|
||||
<li><a href="https://lips.js.org/">LIPS</a><ul>
|
||||
<li>Waiting for implementation to have cond-expand and library support</li>
|
||||
<li>Will only work on nodejs</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://www.biwascheme.org/">Biwascheme</a><ul>
|
||||
<li>Waiting for implementation to have cond-expand and library support</li>
|
||||
<li>Will only work on nodejs</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="tier-4">Tier 4</h2>
|
||||
<p>Support needs to be investigated.</p>
|
||||
<ul>
|
||||
<li><a href="https://cons.io/">Gerbil</a></li>
|
||||
<li><a href="http://www.littlewingpinball.com/doc/en/ypsilon/">Ypsilon</a></li>
|
||||
<li><a href="https://larcenists.org/">Larceny</a></li>
|
||||
<li><a href="https://mosh.monaos.org">Mosh</a></li>
|
||||
<li><a href="https://github.com/false-schemers/skint">Skint</a></li>
|
||||
</ul>
|
||||
<h2 id="tier-5">Tier 5</h2>
|
||||
<p>Support maybe possible/dreaming about.</p>
|
||||
<ul>
|
||||
<li><a href="https://gitlab.com/mbabich/airship-scheme">Airship</a></li>
|
||||
<li><a href="https://gambitscheme.org/">Other gambit targets</a></li>
|
||||
<li>Gambit compiles to different targets other than C too, for example Javascript. It would be cool
|
||||
and interesting to see if this FFI could also support some of those</li>
|
||||
</ul>
|
||||
<h2 id="tier-6">Tier 6</h2>
|
||||
<p>Not supported currently, and may never be.</p>
|
||||
<ul>
|
||||
<li><a href="https://synthcode.com/scheme/chibi">Chibi</a><ul>
|
||||
<li>FFI requires C code</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://www.gnu.org/software/mit-scheme/">MIT-Scheme</a><ul>
|
||||
<li>FFI requires C code</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://gitlab.com/jobol/tr7">tr7</a><ul>
|
||||
<li>FFI requires C code</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://practical-scheme.net/gauche/">Gauche</a><ul>
|
||||
<li>FFI requires C code</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://scheme.fail://ccrma.stanford.edu/software/snd/snd/s7.html">s7</a><ul>
|
||||
<li>No library support</li>
|
||||
<li>Might have other things missing too</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="https://scheme.fail/">Loko</a><ul>
|
||||
<li>Desires no C interop, I can respect that</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="col-md-12">
|
||||
<hr>
|
||||
<p>Documentation built with <a href="https://www.mkdocs.org/">MkDocs</a>.</p>
|
||||
</footer>
|
||||
<script>
|
||||
var base_url = ".",
|
||||
shortcuts = {"help": 191, "next": 78, "previous": 80, "search": 83};
|
||||
</script>
|
||||
<script src="js/base.js" defer></script>
|
||||
<script src="search/main.js" defer></script>
|
||||
|
||||
<div class="modal" id="mkdocs_search_modal" tabindex="-1" role="dialog" aria-labelledby="searchModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title" id="searchModalLabel">Search</h4>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
From here you can search these documents. Enter
|
||||
your search terms below.
|
||||
</p>
|
||||
<form>
|
||||
<div class="form-group">
|
||||
<input type="search" class="form-control" placeholder="Search..." id="mkdocs-search-query" title="Type search term here">
|
||||
</div>
|
||||
</form>
|
||||
<div id="mkdocs-search-results"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="modal" id="mkdocs_keyboard_modal" tabindex="-1" role="dialog" aria-labelledby="keyboardModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title" id="keyboardModalLabel">Keyboard Shortcuts</h4>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 20%;">Keys</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="help shortcut"><kbd>?</kbd></td>
|
||||
<td>Open this help</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="next shortcut"><kbd>n</kbd></td>
|
||||
<td>Next page</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="prev shortcut"><kbd>p</kbd></td>
|
||||
<td>Previous page</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="search shortcut"><kbd>s</kbd></td>
|
||||
<td>Search</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<!--
|
||||
MkDocs version : 1.1.2
|
||||
Build Date UTC : 2024-09-03 12:25:23.288914+00:00
|
||||
-->
|
||||
-283
@@ -1,283 +0,0 @@
|
||||
function getSearchTerm() {
|
||||
var sPageURL = window.location.search.substring(1);
|
||||
var sURLVariables = sPageURL.split('&');
|
||||
for (var i = 0; i < sURLVariables.length; i++) {
|
||||
var sParameterName = sURLVariables[i].split('=');
|
||||
if (sParameterName[0] == 'q') {
|
||||
return sParameterName[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function applyTopPadding() {
|
||||
// Update various absolute positions to match where the main container
|
||||
// starts. This is necessary for handling multi-line nav headers, since
|
||||
// that pushes the main container down.
|
||||
var offset = $('body > .container').offset();
|
||||
$('html').css('scroll-padding-top', offset.top + 'px');
|
||||
$('.bs-sidebar.affix').css('top', offset.top + 'px');
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
applyTopPadding();
|
||||
|
||||
var search_term = getSearchTerm(),
|
||||
$search_modal = $('#mkdocs_search_modal'),
|
||||
$keyboard_modal = $('#mkdocs_keyboard_modal');
|
||||
|
||||
if (search_term) {
|
||||
$search_modal.modal();
|
||||
}
|
||||
|
||||
// make sure search input gets autofocus everytime modal opens.
|
||||
$search_modal.on('shown.bs.modal', function() {
|
||||
$search_modal.find('#mkdocs-search-query').focus();
|
||||
});
|
||||
|
||||
// Close search modal when result is selected
|
||||
// The links get added later so listen to parent
|
||||
$('#mkdocs-search-results').click(function(e) {
|
||||
if ($(e.target).is('a')) {
|
||||
$search_modal.modal('hide');
|
||||
}
|
||||
});
|
||||
|
||||
// Populate keyboard modal with proper Keys
|
||||
$keyboard_modal.find('.help.shortcut kbd')[0].innerHTML = keyCodes[shortcuts.help];
|
||||
$keyboard_modal.find('.prev.shortcut kbd')[0].innerHTML = keyCodes[shortcuts.previous];
|
||||
$keyboard_modal.find('.next.shortcut kbd')[0].innerHTML = keyCodes[shortcuts.next];
|
||||
$keyboard_modal.find('.search.shortcut kbd')[0].innerHTML = keyCodes[shortcuts.search];
|
||||
|
||||
// Keyboard navigation
|
||||
document.addEventListener("keydown", function(e) {
|
||||
if ($(e.target).is(':input')) return true;
|
||||
var key = e.which || e.keyCode || window.event && window.event.keyCode;
|
||||
var page;
|
||||
switch (key) {
|
||||
case shortcuts.next:
|
||||
page = $('.navbar a[rel="next"]:first').prop('href');
|
||||
break;
|
||||
case shortcuts.previous:
|
||||
page = $('.navbar a[rel="prev"]:first').prop('href');
|
||||
break;
|
||||
case shortcuts.search:
|
||||
e.preventDefault();
|
||||
$keyboard_modal.modal('hide');
|
||||
$search_modal.modal('show');
|
||||
$search_modal.find('#mkdocs-search-query').focus();
|
||||
break;
|
||||
case shortcuts.help:
|
||||
$search_modal.modal('hide');
|
||||
$keyboard_modal.modal('show');
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
if (page) {
|
||||
$keyboard_modal.modal('hide');
|
||||
window.location.href = page;
|
||||
}
|
||||
});
|
||||
|
||||
$('table').addClass('table table-striped table-hover');
|
||||
|
||||
// Improve the scrollspy behaviour when users click on a TOC item.
|
||||
$(".bs-sidenav a").on("click", function() {
|
||||
var clicked = this;
|
||||
setTimeout(function() {
|
||||
var active = $('.nav li.active a');
|
||||
active = active[active.length - 1];
|
||||
if (clicked !== active) {
|
||||
$(active).parent().removeClass("active");
|
||||
$(clicked).parent().addClass("active");
|
||||
}
|
||||
}, 50);
|
||||
});
|
||||
|
||||
function showInnerDropdown(item) {
|
||||
var popup = $(item).next('.dropdown-menu');
|
||||
popup.addClass('show');
|
||||
$(item).addClass('open');
|
||||
|
||||
// First, close any sibling dropdowns.
|
||||
var container = $(item).parent().parent();
|
||||
container.find('> .dropdown-submenu > a').each(function(i, el) {
|
||||
if (el !== item) {
|
||||
hideInnerDropdown(el);
|
||||
}
|
||||
});
|
||||
|
||||
var popupMargin = 10;
|
||||
var maxBottom = $(window).height() - popupMargin;
|
||||
var bounds = item.getBoundingClientRect();
|
||||
|
||||
popup.css('left', bounds.right + 'px');
|
||||
if (bounds.top + popup.height() > maxBottom &&
|
||||
bounds.top > $(window).height() / 2) {
|
||||
popup.css({
|
||||
'top': (bounds.bottom - popup.height()) + 'px',
|
||||
'max-height': (bounds.bottom - popupMargin) + 'px',
|
||||
});
|
||||
} else {
|
||||
popup.css({
|
||||
'top': bounds.top + 'px',
|
||||
'max-height': (maxBottom - bounds.top) + 'px',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function hideInnerDropdown(item) {
|
||||
var popup = $(item).next('.dropdown-menu');
|
||||
popup.removeClass('show');
|
||||
$(item).removeClass('open');
|
||||
|
||||
popup.scrollTop(0);
|
||||
popup.find('.dropdown-menu').scrollTop(0).removeClass('show');
|
||||
popup.find('.dropdown-submenu > a').removeClass('open');
|
||||
}
|
||||
|
||||
$('.dropdown-submenu > a').on('click', function(e) {
|
||||
if ($(this).next('.dropdown-menu').hasClass('show')) {
|
||||
hideInnerDropdown(this);
|
||||
} else {
|
||||
showInnerDropdown(this);
|
||||
}
|
||||
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$('.dropdown-menu').parent().on('hide.bs.dropdown', function(e) {
|
||||
$(this).find('.dropdown-menu').scrollTop(0);
|
||||
$(this).find('.dropdown-submenu > a').removeClass('open');
|
||||
$(this).find('.dropdown-menu .dropdown-menu').removeClass('show');
|
||||
});
|
||||
});
|
||||
|
||||
$(window).on('resize', applyTopPadding);
|
||||
|
||||
$('body').scrollspy({
|
||||
target: '.bs-sidebar',
|
||||
offset: 100
|
||||
});
|
||||
|
||||
/* Prevent disabled links from causing a page reload */
|
||||
$("li.disabled a").click(function() {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
// See https://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
|
||||
// We only list common keys below. Obscure keys are omitted and their use is discouraged.
|
||||
var keyCodes = {
|
||||
8: 'backspace',
|
||||
9: 'tab',
|
||||
13: 'enter',
|
||||
16: 'shift',
|
||||
17: 'ctrl',
|
||||
18: 'alt',
|
||||
19: 'pause/break',
|
||||
20: 'caps lock',
|
||||
27: 'escape',
|
||||
32: 'spacebar',
|
||||
33: 'page up',
|
||||
34: 'page down',
|
||||
35: 'end',
|
||||
36: 'home',
|
||||
37: '←',
|
||||
38: '↑',
|
||||
39: '→',
|
||||
40: '↓',
|
||||
45: 'insert',
|
||||
46: 'delete',
|
||||
48: '0',
|
||||
49: '1',
|
||||
50: '2',
|
||||
51: '3',
|
||||
52: '4',
|
||||
53: '5',
|
||||
54: '6',
|
||||
55: '7',
|
||||
56: '8',
|
||||
57: '9',
|
||||
65: 'a',
|
||||
66: 'b',
|
||||
67: 'c',
|
||||
68: 'd',
|
||||
69: 'e',
|
||||
70: 'f',
|
||||
71: 'g',
|
||||
72: 'h',
|
||||
73: 'i',
|
||||
74: 'j',
|
||||
75: 'k',
|
||||
76: 'l',
|
||||
77: 'm',
|
||||
78: 'n',
|
||||
79: 'o',
|
||||
80: 'p',
|
||||
81: 'q',
|
||||
82: 'r',
|
||||
83: 's',
|
||||
84: 't',
|
||||
85: 'u',
|
||||
86: 'v',
|
||||
87: 'w',
|
||||
88: 'x',
|
||||
89: 'y',
|
||||
90: 'z',
|
||||
91: 'Left Windows Key / Left ⌘',
|
||||
92: 'Right Windows Key',
|
||||
93: 'Windows Menu / Right ⌘',
|
||||
96: 'numpad 0',
|
||||
97: 'numpad 1',
|
||||
98: 'numpad 2',
|
||||
99: 'numpad 3',
|
||||
100: 'numpad 4',
|
||||
101: 'numpad 5',
|
||||
102: 'numpad 6',
|
||||
103: 'numpad 7',
|
||||
104: 'numpad 8',
|
||||
105: 'numpad 9',
|
||||
106: 'multiply',
|
||||
107: 'add',
|
||||
109: 'subtract',
|
||||
110: 'decimal point',
|
||||
111: 'divide',
|
||||
112: 'f1',
|
||||
113: 'f2',
|
||||
114: 'f3',
|
||||
115: 'f4',
|
||||
116: 'f5',
|
||||
117: 'f6',
|
||||
118: 'f7',
|
||||
119: 'f8',
|
||||
120: 'f9',
|
||||
121: 'f10',
|
||||
122: 'f11',
|
||||
123: 'f12',
|
||||
124: 'f13',
|
||||
125: 'f14',
|
||||
126: 'f15',
|
||||
127: 'f16',
|
||||
128: 'f17',
|
||||
129: 'f18',
|
||||
130: 'f19',
|
||||
131: 'f20',
|
||||
132: 'f21',
|
||||
133: 'f22',
|
||||
134: 'f23',
|
||||
135: 'f24',
|
||||
144: 'num lock',
|
||||
145: 'scroll lock',
|
||||
186: ';',
|
||||
187: '=',
|
||||
188: ',',
|
||||
189: '‐',
|
||||
190: '.',
|
||||
191: '?',
|
||||
192: '`',
|
||||
219: '[',
|
||||
220: '\',
|
||||
221: ']',
|
||||
222: ''',
|
||||
};
|
||||
Vendored
-378
@@ -1,378 +0,0 @@
|
||||
/*!
|
||||
* Bootstrap v4.6.0 (https://getbootstrap.com/)
|
||||
* Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap={},t.jQuery,t.Popper)}(this,function(t,e,n){"use strict";function i(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var o=/* */i(e),a=/* */i(n);function s(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function l(t,e,n){return e&&s(t.prototype,e),n&&s(t,n),t}function r(){return(r=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t}).apply(this,arguments)}
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v4.6.0): util.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Private TransitionEnd Helpers
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
var u="transitionend";function d(t){var e=this,n=!1;return o.default(this).one(c.TRANSITION_END,function(){n=!0}),setTimeout(function(){n||c.triggerTransitionEnd(e)},t),this}
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Public Util Api
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
var c={TRANSITION_END:"bsTransitionEnd",getUID:function(t){do{t+=~~(1e6*Math.random());// "~~" acts like a faster Math.floor() here
|
||||
}while(document.getElementById(t));return t},getSelectorFromElement:function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():""}try{return document.querySelector(e)?e:null}catch(t){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;// Get transition-duration of the element
|
||||
var e=o.default(t).css("transition-duration"),n=o.default(t).css("transition-delay"),i=parseFloat(e),a=parseFloat(n);// Return 0 if element or transition duration is not found
|
||||
return i||a?(// If multiple durations are defined, take the first
|
||||
e=e.split(",")[0],n=n.split(",")[0],1e3*(parseFloat(e)+parseFloat(n))):0},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(t){o.default(t).trigger(u)},supportsTransitionEnd:function(){return Boolean(u)},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)){var o=n[i],a=e[i],s=a&&c.isElement(a)?"element":null==(l=a)?""+l:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(s))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+s+'" but expected type "'+o+'".')}// Shoutout AngusCroll (https://goo.gl/pxwQGp)
|
||||
var l},findShadowRoot:function(t){if(!document.documentElement.attachShadow)return null;// Can find the shadow root otherwise it'll return the document
|
||||
if("function"==typeof t.getRootNode){var e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:// when we don't find a shadow root
|
||||
t.parentNode?c.findShadowRoot(t.parentNode):null},jQueryDetection:function(){if(void 0===o.default)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=o.default.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};c.jQueryDetection(),o.default.fn.emulateTransitionEnd=d,o.default.event.special[c.TRANSITION_END]={bindType:u,delegateType:u,handle:function(t){if(o.default(t.target).is(this))return t.handleObj.handler.apply(this,arguments);// eslint-disable-line prefer-rest-params
|
||||
}};
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
var f=o.default.fn.alert,h=/* */function(){function t(t){this._element=t}// Getters
|
||||
var e=t.prototype;
|
||||
// Public
|
||||
return e.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},e.dispose=function(){o.default.removeData(this._element,"bs.alert"),this._element=null}// Private
|
||||
,e._getRootElement=function(t){var e=c.getSelectorFromElement(t),n=!1;return e&&(n=document.querySelector(e)),n||(n=o.default(t).closest(".alert")[0]),n},e._triggerCloseEvent=function(t){var e=o.default.Event("close.bs.alert");return o.default(t).trigger(e),e},e._removeElement=function(t){var e=this;if(o.default(t).removeClass("show"),o.default(t).hasClass("fade")){var n=c.getTransitionDurationFromElement(t);o.default(t).one(c.TRANSITION_END,function(n){return e._destroyElement(t,n)}).emulateTransitionEnd(n)}else this._destroyElement(t)},e._destroyElement=function(t){o.default(t).detach().trigger("closed.bs.alert").remove()}// Static
|
||||
,t._jQueryInterface=function(e){return this.each(function(){var n=o.default(this),i=n.data("bs.alert");i||(i=new t(this),n.data("bs.alert",i)),"close"===e&&i[e](this)})},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}}]),t}();
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',h._handleDismiss(new h)),
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default.fn.alert=h._jQueryInterface,o.default.fn.alert.Constructor=h,o.default.fn.alert.noConflict=function(){return o.default.fn.alert=f,h._jQueryInterface};
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
var g=o.default.fn.button,m=/* */function(){function t(t){this._element=t,this.shouldAvoidTriggerChange=!1}// Getters
|
||||
var e=t.prototype;
|
||||
// Public
|
||||
return e.toggle=function(){var t=!0,e=!0,n=o.default(this._element).closest('[data-toggle="buttons"]')[0];if(n){var i=this._element.querySelector('input:not([type="hidden"])');if(i){if("radio"===i.type)if(i.checked&&this._element.classList.contains("active"))t=!1;else{var a=n.querySelector(".active");a&&o.default(a).removeClass("active")}t&&(
|
||||
// if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input
|
||||
"checkbox"!==i.type&&"radio"!==i.type||(i.checked=!this._element.classList.contains("active")),this.shouldAvoidTriggerChange||o.default(i).trigger("change")),i.focus(),e=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(e&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&o.default(this._element).toggleClass("active"))},e.dispose=function(){o.default.removeData(this._element,"bs.button"),this._element=null}// Static
|
||||
,t._jQueryInterface=function(e,n){return this.each(function(){var i=o.default(this),a=i.data("bs.button");a||(a=new t(this),i.data("bs.button",a)),a.shouldAvoidTriggerChange=n,"toggle"===e&&a[e]()})},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}}]),t}();
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(t){var e=t.target,n=e;if(o.default(e).hasClass("btn")||(e=o.default(e).closest(".btn")[0]),!e||e.hasAttribute("disabled")||e.classList.contains("disabled"))t.preventDefault();// work around Firefox bug #1540995
|
||||
else{var i=e.querySelector('input:not([type="hidden"])');if(i&&(i.hasAttribute("disabled")||i.classList.contains("disabled")))// work around Firefox bug #1540995
|
||||
return void t.preventDefault();"INPUT"!==n.tagName&&"LABEL"===e.tagName||m._jQueryInterface.call(o.default(e),"toggle","INPUT"===n.tagName)}}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(t){var e=o.default(t.target).closest(".btn")[0];o.default(e).toggleClass("focus",/^focus(in)?$/.test(t.type))}),o.default(window).on("load.bs.button.data-api",function(){for(
|
||||
// ensure correct active class is set to match the controls' actual values/states
|
||||
// find all checkboxes/readio buttons inside data-toggle groups
|
||||
var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e<n;e++){var i=t[e],o=i.querySelector('input:not([type="hidden"])');o.checked||o.hasAttribute("checked")?i.classList.add("active"):i.classList.remove("active")}// find all button toggles
|
||||
for(var a=0,s=(t=[].slice.call(document.querySelectorAll('[data-toggle="button"]'))).length;a<s;a++){var l=t[a];"true"===l.getAttribute("aria-pressed")?l.classList.add("active"):l.classList.remove("active")}}),
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default.fn.button=m._jQueryInterface,o.default.fn.button.Constructor=m,o.default.fn.button.noConflict=function(){return o.default.fn.button=g,m._jQueryInterface};
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
var p="carousel",_=".bs.carousel",v=o.default.fn[p],b={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},y={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},E=".carousel-indicators",w={TOUCH:"touch",PEN:"pen"},T=/* */function(){function t(t,e){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._element=t,this._indicatorsElement=this._element.querySelector(E),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}// Getters
|
||||
var e=t.prototype;
|
||||
// Public
|
||||
return e.next=function(){this._isSliding||this._slide("next")},e.nextWhenVisible=function(){var t=o.default(this._element);// Don't call next when the page isn't visible
|
||||
// or the carousel or its parent isn't visible
|
||||
!document.hidden&&t.is(":visible")&&"hidden"!==t.css("visibility")&&this.next()},e.prev=function(){this._isSliding||this._slide("prev")},e.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(c.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},e.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},e.to=function(t){var e=this;this._activeElement=this._element.querySelector(".active.carousel-item");var n=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)o.default(this._element).one("slid.bs.carousel",function(){return e.to(t)});else{if(n===t)return this.pause(),void this.cycle();var i=t>n?"next":"prev";this._slide(i,this._items[t])}},e.dispose=function(){o.default(this._element).off(_),o.default.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null}// Private
|
||||
,e._getConfig=function(t){return t=r({},b,t),c.typeCheckConfig(p,t,y),t},e._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,// swipe left
|
||||
e>0&&this.prev(),// swipe right
|
||||
e<0&&this.next()}},e._addEventListeners=function(){var t=this;this._config.keyboard&&o.default(this._element).on("keydown.bs.carousel",function(e){return t._keydown(e)}),"hover"===this._config.pause&&o.default(this._element).on("mouseenter.bs.carousel",function(e){return t.pause(e)}).on("mouseleave.bs.carousel",function(e){return t.cycle(e)}),this._config.touch&&this._addTouchEventListeners()},e._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var e=function(e){t._pointerEvent&&w[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},n=function(e){t._pointerEvent&&w[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(
|
||||
// If it's a touch-enabled device, mouseenter/leave are fired as
|
||||
// part of the mouse compatibility events on first tap - the carousel
|
||||
// would stop cycling until user tapped out of it;
|
||||
// here, we listen for touchend, explicitly pause the carousel
|
||||
// (as if it's the second time we tap on it, mouseenter compat event
|
||||
// is NOT fired) and after a timeout (to allow for mouse compatibility
|
||||
// events to fire) we explicitly restart cycling
|
||||
t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout(function(e){return t.cycle(e)},500+t._config.interval))};o.default(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",function(t){return t.preventDefault()}),this._pointerEvent?(o.default(this._element).on("pointerdown.bs.carousel",function(t){return e(t)}),o.default(this._element).on("pointerup.bs.carousel",function(t){return n(t)}),this._element.classList.add("pointer-event")):(o.default(this._element).on("touchstart.bs.carousel",function(t){return e(t)}),o.default(this._element).on("touchmove.bs.carousel",function(e){return function(e){
|
||||
// ensure swiping with one touch and not pinching
|
||||
e.originalEvent.touches&&e.originalEvent.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.originalEvent.touches[0].clientX-t.touchStartX}(e)}),o.default(this._element).on("touchend.bs.carousel",function(t){return n(t)}))}},e._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},e._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},e._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),a=this._items.length-1;if((i&&0===o||n&&o===a)&&!this._config.wrap)return e;var s=(o+("prev"===t?-1:1))%this._items.length;return-1===s?this._items[this._items.length-1]:this._items[s]},e._triggerSlideEvent=function(t,e){var n=this._getItemIndex(t),i=this._getItemIndex(this._element.querySelector(".active.carousel-item")),a=o.default.Event("slide.bs.carousel",{relatedTarget:t,direction:e,from:i,to:n});return o.default(this._element).trigger(a),a},e._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var e=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));o.default(e).removeClass("active");var n=this._indicatorsElement.children[this._getItemIndex(t)];n&&o.default(n).addClass("active")}},e._updateInterval=function(){var t=this._activeElement||this._element.querySelector(".active.carousel-item");if(t){var e=parseInt(t.getAttribute("data-interval"),10);e?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=e):this._config.interval=this._config.defaultInterval||this._config.interval}},e._slide=function(t,e){var n,i,a,s=this,l=this._element.querySelector(".active.carousel-item"),r=this._getItemIndex(l),u=e||l&&this._getItemByDirection(t,l),d=this._getItemIndex(u),f=Boolean(this._interval);if("next"===t?(n="carousel-item-left",i="carousel-item-next",a="left"):(n="carousel-item-right",i="carousel-item-prev",a="right"),u&&o.default(u).hasClass("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(u,a).isDefaultPrevented()&&l&&u){this._isSliding=!0,f&&this.pause(),this._setActiveIndicatorElement(u),this._activeElement=u;var h=o.default.Event("slid.bs.carousel",{relatedTarget:u,direction:a,from:r,to:d});if(o.default(this._element).hasClass("slide")){o.default(u).addClass(i),c.reflow(u),o.default(l).addClass(n),o.default(u).addClass(n);var g=c.getTransitionDurationFromElement(l);o.default(l).one(c.TRANSITION_END,function(){o.default(u).removeClass(n+" "+i).addClass("active"),o.default(l).removeClass("active "+i+" "+n),s._isSliding=!1,setTimeout(function(){return o.default(s._element).trigger(h)},0)}).emulateTransitionEnd(g)}else o.default(l).removeClass("active"),o.default(u).addClass("active"),this._isSliding=!1,o.default(this._element).trigger(h);f&&this.cycle()}}// Static
|
||||
,t._jQueryInterface=function(e){return this.each(function(){var n=o.default(this).data("bs.carousel"),i=r({},b,o.default(this).data());"object"==typeof e&&(i=r({},i,e));var a="string"==typeof e?e:i.slide;if(n||(n=new t(this,i),o.default(this).data("bs.carousel",n)),"number"==typeof e)n.to(e);else if("string"==typeof a){if(void 0===n[a])throw new TypeError('No method named "'+a+'"');n[a]()}else i.interval&&i.ride&&(n.pause(),n.cycle())})},t._dataApiClickHandler=function(e){var n=c.getSelectorFromElement(this);if(n){var i=o.default(n)[0];if(i&&o.default(i).hasClass("carousel")){var a=r({},o.default(i).data(),o.default(this).data()),s=this.getAttribute("data-slide-to");s&&(a.interval=!1),t._jQueryInterface.call(o.default(i),a),s&&o.default(i).data("bs.carousel").to(s),e.preventDefault()}}},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return b}}]),t}();
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",T._dataApiClickHandler),o.default(window).on("load.bs.carousel.data-api",function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),e=0,n=t.length;e<n;e++){var i=o.default(t[e]);T._jQueryInterface.call(i,i.data())}}),
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default.fn[p]=T._jQueryInterface,o.default.fn[p].Constructor=T,o.default.fn[p].noConflict=function(){return o.default.fn[p]=v,T._jQueryInterface};
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
var C="collapse",S=o.default.fn[C],N={toggle:!0,parent:""},D={toggle:"boolean",parent:"(string|element)"},k='[data-toggle="collapse"]',A=/* */function(){function t(t,e){this._isTransitioning=!1,this._element=t,this._config=this._getConfig(e),this._triggerArray=[].slice.call(document.querySelectorAll('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]'));for(var n=[].slice.call(document.querySelectorAll(k)),i=0,o=n.length;i<o;i++){var a=n[i],s=c.getSelectorFromElement(a),l=[].slice.call(document.querySelectorAll(s)).filter(function(e){return e===t});null!==s&&l.length>0&&(this._selector=s,this._triggerArray.push(a))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}// Getters
|
||||
var e=t.prototype;
|
||||
// Public
|
||||
return e.toggle=function(){o.default(this._element).hasClass("show")?this.hide():this.show()},e.show=function(){var e,n,i=this;if(!this._isTransitioning&&!o.default(this._element).hasClass("show")&&(this._parent&&0===(e=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter(function(t){return"string"==typeof i._config.parent?t.getAttribute("data-parent")===i._config.parent:t.classList.contains("collapse")})).length&&(e=null),!(e&&(n=o.default(e).not(this._selector).data("bs.collapse"))&&n._isTransitioning))){var a=o.default.Event("show.bs.collapse");if(o.default(this._element).trigger(a),!a.isDefaultPrevented()){e&&(t._jQueryInterface.call(o.default(e).not(this._selector),"hide"),n||o.default(e).data("bs.collapse",null));var s=this._getDimension();o.default(this._element).removeClass("collapse").addClass("collapsing"),this._element.style[s]=0,this._triggerArray.length&&o.default(this._triggerArray).removeClass("collapsed").attr("aria-expanded",!0),this.setTransitioning(!0);var l="scroll"+(s[0].toUpperCase()+s.slice(1)),r=c.getTransitionDurationFromElement(this._element);o.default(this._element).one(c.TRANSITION_END,function(){o.default(i._element).removeClass("collapsing").addClass("collapse show"),i._element.style[s]="",i.setTransitioning(!1),o.default(i._element).trigger("shown.bs.collapse")}).emulateTransitionEnd(r),this._element.style[s]=this._element[l]+"px"}}},e.hide=function(){var t=this;if(!this._isTransitioning&&o.default(this._element).hasClass("show")){var e=o.default.Event("hide.bs.collapse");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){var n=this._getDimension();this._element.style[n]=this._element.getBoundingClientRect()[n]+"px",c.reflow(this._element),o.default(this._element).addClass("collapsing").removeClass("collapse show");var i=this._triggerArray.length;if(i>0)for(var a=0;a<i;a++){var s=this._triggerArray[a],l=c.getSelectorFromElement(s);if(null!==l)o.default([].slice.call(document.querySelectorAll(l))).hasClass("show")||o.default(s).addClass("collapsed").attr("aria-expanded",!1)}this.setTransitioning(!0);this._element.style[n]="";var r=c.getTransitionDurationFromElement(this._element);o.default(this._element).one(c.TRANSITION_END,function(){t.setTransitioning(!1),o.default(t._element).removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")}).emulateTransitionEnd(r)}}},e.setTransitioning=function(t){this._isTransitioning=t},e.dispose=function(){o.default.removeData(this._element,"bs.collapse"),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null}// Private
|
||||
,e._getConfig=function(t){return(t=r({},N,t)).toggle=Boolean(t.toggle),// Coerce string values
|
||||
c.typeCheckConfig(C,t,D),t},e._getDimension=function(){return o.default(this._element).hasClass("width")?"width":"height"},e._getParent=function(){var e,n=this;c.isElement(this._config.parent)?(e=this._config.parent,// It's a jQuery object
|
||||
void 0!==this._config.parent.jquery&&(e=this._config.parent[0])):e=document.querySelector(this._config.parent);var i='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]',a=[].slice.call(e.querySelectorAll(i));return o.default(a).each(function(e,i){n._addAriaAndCollapsedClass(t._getTargetFromElement(i),[i])}),e},e._addAriaAndCollapsedClass=function(t,e){var n=o.default(t).hasClass("show");e.length&&o.default(e).toggleClass("collapsed",!n).attr("aria-expanded",n)}// Static
|
||||
,t._getTargetFromElement=function(t){var e=c.getSelectorFromElement(t);return e?document.querySelector(e):null},t._jQueryInterface=function(e){return this.each(function(){var n=o.default(this),i=n.data("bs.collapse"),a=r({},N,n.data(),"object"==typeof e&&e?e:{});if(!i&&a.toggle&&"string"==typeof e&&/show|hide/.test(e)&&(a.toggle=!1),i||(i=new t(this,a),n.data("bs.collapse",i)),"string"==typeof e){if(void 0===i[e])throw new TypeError('No method named "'+e+'"');i[e]()}})},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return N}}]),t}();
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default(document).on("click.bs.collapse.data-api",k,function(t){
|
||||
// preventDefault only for <a> elements (which change the URL) not inside the collapsible element
|
||||
"A"===t.currentTarget.tagName&&t.preventDefault();var e=o.default(this),n=c.getSelectorFromElement(this),i=[].slice.call(document.querySelectorAll(n));o.default(i).each(function(){var t=o.default(this),n=t.data("bs.collapse")?"toggle":e.data();A._jQueryInterface.call(t,n)})}),
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default.fn[C]=A._jQueryInterface,o.default.fn[C].Constructor=A,o.default.fn[C].noConflict=function(){return o.default.fn[C]=S,A._jQueryInterface};
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
var I="dropdown",j=o.default.fn[I],O=new RegExp("38|40|27"),x={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},P={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},R=/* */function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}// Getters
|
||||
var e=t.prototype;
|
||||
// Public
|
||||
return e.toggle=function(){if(!this._element.disabled&&!o.default(this._element).hasClass("disabled")){var e=o.default(this._menu).hasClass("show");t._clearMenus(),e||this.show(!0)}},e.show=function(e){if(void 0===e&&(e=!1),!(this._element.disabled||o.default(this._element).hasClass("disabled")||o.default(this._menu).hasClass("show"))){var n={relatedTarget:this._element},i=o.default.Event("show.bs.dropdown",n),s=t._getParentFromElement(this._element);if(o.default(s).trigger(i),!i.isDefaultPrevented()){// Totally disable Popper for Dropdowns in Navbar
|
||||
if(!this._inNavbar&&e){
|
||||
/**
|
||||
* Check for Popper dependency
|
||||
* Popper - https://popper.js.org
|
||||
*/
|
||||
if(void 0===a.default)throw new TypeError("Bootstrap's dropdowns require Popper (https://popper.js.org)");var l=this._element;"parent"===this._config.reference?l=s:c.isElement(this._config.reference)&&(l=this._config.reference,// Check if it's jQuery element
|
||||
void 0!==this._config.reference.jquery&&(l=this._config.reference[0])),// If boundary is not `scrollParent`, then set position to `static`
|
||||
// to allow the menu to "escape" the scroll parent's boundaries
|
||||
// https://github.com/twbs/bootstrap/issues/24251
|
||||
"scrollParent"!==this._config.boundary&&o.default(s).addClass("position-static"),this._popper=new a.default(l,this._menu,this._getPopperConfig())}// If this is a touch-enabled device we add extra
|
||||
// empty mouseover listeners to the body's immediate children;
|
||||
// only needed because of broken event delegation on iOS
|
||||
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
|
||||
"ontouchstart"in document.documentElement&&0===o.default(s).closest(".navbar-nav").length&&o.default(document.body).children().on("mouseover",null,o.default.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),o.default(this._menu).toggleClass("show"),o.default(s).toggleClass("show").trigger(o.default.Event("shown.bs.dropdown",n))}}},e.hide=function(){if(!this._element.disabled&&!o.default(this._element).hasClass("disabled")&&o.default(this._menu).hasClass("show")){var e={relatedTarget:this._element},n=o.default.Event("hide.bs.dropdown",e),i=t._getParentFromElement(this._element);o.default(i).trigger(n),n.isDefaultPrevented()||(this._popper&&this._popper.destroy(),o.default(this._menu).toggleClass("show"),o.default(i).toggleClass("show").trigger(o.default.Event("hidden.bs.dropdown",e)))}},e.dispose=function(){o.default.removeData(this._element,"bs.dropdown"),o.default(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},e.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()}// Private
|
||||
,e._addEventListeners=function(){var t=this;o.default(this._element).on("click.bs.dropdown",function(e){e.preventDefault(),e.stopPropagation(),t.toggle()})},e._getConfig=function(t){return t=r({},this.constructor.Default,o.default(this._element).data(),t),c.typeCheckConfig(I,t,this.constructor.DefaultType),t},e._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(".dropdown-menu"))}return this._menu},e._getPlacement=function(){var t=o.default(this._element.parentNode),e="bottom-start";// Handle dropup
|
||||
return t.hasClass("dropup")?e=o.default(this._menu).hasClass("dropdown-menu-right")?"top-end":"top-start":t.hasClass("dropright")?e="right-start":t.hasClass("dropleft")?e="left-start":o.default(this._menu).hasClass("dropdown-menu-right")&&(e="bottom-end"),e},e._detectNavbar=function(){return o.default(this._element).closest(".navbar").length>0},e._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=r({},e.offsets,t._config.offset(e.offsets,t._element)||{}),e}:e.offset=this._config.offset,e},e._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};// Disable Popper if we have a static display
|
||||
return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),r({},t,this._config.popperConfig)}// Static
|
||||
,t._jQueryInterface=function(e){return this.each(function(){var n=o.default(this).data("bs.dropdown");if(n||(n=new t(this,"object"==typeof e?e:null),o.default(this).data("bs.dropdown",n)),"string"==typeof e){if(void 0===n[e])throw new TypeError('No method named "'+e+'"');n[e]()}})},t._clearMenus=function(e){if(!e||3!==e.which&&("keyup"!==e.type||9===e.which))for(var n=[].slice.call(document.querySelectorAll('[data-toggle="dropdown"]')),i=0,a=n.length;i<a;i++){var s=t._getParentFromElement(n[i]),l=o.default(n[i]).data("bs.dropdown"),r={relatedTarget:n[i]};if(e&&"click"===e.type&&(r.clickEvent=e),l){var u=l._menu;if(o.default(s).hasClass("show")&&!(e&&("click"===e.type&&/input|textarea/i.test(e.target.tagName)||"keyup"===e.type&&9===e.which)&&o.default.contains(s,e.target))){var d=o.default.Event("hide.bs.dropdown",r);o.default(s).trigger(d),d.isDefaultPrevented()||(// If this is a touch-enabled device we remove the extra
|
||||
// empty mouseover listeners we added for iOS support
|
||||
"ontouchstart"in document.documentElement&&o.default(document.body).children().off("mouseover",null,o.default.noop),n[i].setAttribute("aria-expanded","false"),l._popper&&l._popper.destroy(),o.default(u).removeClass("show"),o.default(s).removeClass("show").trigger(o.default.Event("hidden.bs.dropdown",r)))}}}},t._getParentFromElement=function(t){var e,n=c.getSelectorFromElement(t);return n&&(e=document.querySelector(n)),e||t.parentNode}// eslint-disable-next-line complexity
|
||||
,t._dataApiKeydownHandler=function(e){
|
||||
// If not input/textarea:
|
||||
// - And not a key in REGEXP_KEYDOWN => not a dropdown command
|
||||
// If input/textarea:
|
||||
// - If space key => not a dropdown command
|
||||
// - If key is other than escape
|
||||
// - If key is not up or down => not a dropdown command
|
||||
// - If trigger inside the menu => not a dropdown command
|
||||
if((/input|textarea/i.test(e.target.tagName)?!(32===e.which||27!==e.which&&(40!==e.which&&38!==e.which||o.default(e.target).closest(".dropdown-menu").length)):O.test(e.which))&&!this.disabled&&!o.default(this).hasClass("disabled")){var n=t._getParentFromElement(this),i=o.default(n).hasClass("show");if(i||27!==e.which){if(e.preventDefault(),e.stopPropagation(),!i||27===e.which||32===e.which)return 27===e.which&&o.default(n.querySelector('[data-toggle="dropdown"]')).trigger("focus"),void o.default(this).trigger("click");var a=[].slice.call(n.querySelectorAll(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)")).filter(function(t){return o.default(t).is(":visible")});if(0!==a.length){var s=a.indexOf(e.target);38===e.which&&s>0&&
|
||||
// Up
|
||||
s--,40===e.which&&s<a.length-1&&
|
||||
// Down
|
||||
s++,s<0&&(s=0),a[s].focus()}}}},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return x}},{key:"DefaultType",get:function(){return P}}]),t}();
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default(document).on("keydown.bs.dropdown.data-api",'[data-toggle="dropdown"]',R._dataApiKeydownHandler).on("keydown.bs.dropdown.data-api",".dropdown-menu",R._dataApiKeydownHandler).on("click.bs.dropdown.data-api keyup.bs.dropdown.data-api",R._clearMenus).on("click.bs.dropdown.data-api",'[data-toggle="dropdown"]',function(t){t.preventDefault(),t.stopPropagation(),R._jQueryInterface.call(o.default(this),"toggle")}).on("click.bs.dropdown.data-api",".dropdown form",function(t){t.stopPropagation()}),
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default.fn[I]=R._jQueryInterface,o.default.fn[I].Constructor=R,o.default.fn[I].noConflict=function(){return o.default.fn[I]=j,R._jQueryInterface};
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
var L=o.default.fn.modal,q={backdrop:!0,keyboard:!0,focus:!0,show:!0},F={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},Q=".modal-dialog",B=/* */function(){function t(t,e){this._config=this._getConfig(e),this._element=t,this._dialog=t.querySelector(Q),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0}// Getters
|
||||
var e=t.prototype;
|
||||
// Public
|
||||
return e.toggle=function(t){return this._isShown?this.hide():this.show(t)},e.show=function(t){var e=this;if(!this._isShown&&!this._isTransitioning){o.default(this._element).hasClass("fade")&&(this._isTransitioning=!0);var n=o.default.Event("show.bs.modal",{relatedTarget:t});o.default(this._element).trigger(n),this._isShown||n.isDefaultPrevented()||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),o.default(this._element).on("click.dismiss.bs.modal",'[data-dismiss="modal"]',function(t){return e.hide(t)}),o.default(this._dialog).on("mousedown.dismiss.bs.modal",function(){o.default(e._element).one("mouseup.dismiss.bs.modal",function(t){o.default(t.target).is(e._element)&&(e._ignoreBackdropClick=!0)})}),this._showBackdrop(function(){return e._showElement(t)}))}},e.hide=function(t){var e=this;if(t&&t.preventDefault(),this._isShown&&!this._isTransitioning){var n=o.default.Event("hide.bs.modal");if(o.default(this._element).trigger(n),this._isShown&&!n.isDefaultPrevented()){this._isShown=!1;var i=o.default(this._element).hasClass("fade");if(i&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),o.default(document).off("focusin.bs.modal"),o.default(this._element).removeClass("show"),o.default(this._element).off("click.dismiss.bs.modal"),o.default(this._dialog).off("mousedown.dismiss.bs.modal"),i){var a=c.getTransitionDurationFromElement(this._element);o.default(this._element).one(c.TRANSITION_END,function(t){return e._hideModal(t)}).emulateTransitionEnd(a)}else this._hideModal()}}},e.dispose=function(){[window,this._element,this._dialog].forEach(function(t){return o.default(t).off(".bs.modal")}),
|
||||
/**
|
||||
* `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`
|
||||
* Do not move `document` in `htmlElements` array
|
||||
* It will remove `EVENT_CLICK_DATA_API` event that should remain
|
||||
*/
|
||||
o.default(document).off("focusin.bs.modal"),o.default.removeData(this._element,"bs.modal"),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},e.handleUpdate=function(){this._adjustDialog()}// Private
|
||||
,e._getConfig=function(t){return t=r({},q,t),c.typeCheckConfig("modal",t,F),t},e._triggerBackdropTransition=function(){var t=this,e=o.default.Event("hidePrevented.bs.modal");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){var n=this._element.scrollHeight>document.documentElement.clientHeight;n||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");var i=c.getTransitionDurationFromElement(this._dialog);o.default(this._element).off(c.TRANSITION_END),o.default(this._element).one(c.TRANSITION_END,function(){t._element.classList.remove("modal-static"),n||o.default(t._element).one(c.TRANSITION_END,function(){t._element.style.overflowY=""}).emulateTransitionEnd(t._element,i)}).emulateTransitionEnd(i),this._element.focus()}},e._showElement=function(t){var e=this,n=o.default(this._element).hasClass("fade"),i=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||
|
||||
// Don't move modal's DOM position
|
||||
document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),o.default(this._dialog).hasClass("modal-dialog-scrollable")&&i?i.scrollTop=0:this._element.scrollTop=0,n&&c.reflow(this._element),o.default(this._element).addClass("show"),this._config.focus&&this._enforceFocus();var a=o.default.Event("shown.bs.modal",{relatedTarget:t}),s=function(){e._config.focus&&e._element.focus(),e._isTransitioning=!1,o.default(e._element).trigger(a)};if(n){var l=c.getTransitionDurationFromElement(this._dialog);o.default(this._dialog).one(c.TRANSITION_END,s).emulateTransitionEnd(l)}else s()},e._enforceFocus=function(){var t=this;o.default(document).off("focusin.bs.modal").on("focusin.bs.modal",function(e){document!==e.target&&t._element!==e.target&&0===o.default(t._element).has(e.target).length&&t._element.focus()})},e._setEscapeEvent=function(){var t=this;this._isShown?o.default(this._element).on("keydown.dismiss.bs.modal",function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()}):this._isShown||o.default(this._element).off("keydown.dismiss.bs.modal")},e._setResizeEvent=function(){var t=this;this._isShown?o.default(window).on("resize.bs.modal",function(e){return t.handleUpdate(e)}):o.default(window).off("resize.bs.modal")},e._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop(function(){o.default(document.body).removeClass("modal-open"),t._resetAdjustments(),t._resetScrollbar(),o.default(t._element).trigger("hidden.bs.modal")})},e._removeBackdrop=function(){this._backdrop&&(o.default(this._backdrop).remove(),this._backdrop=null)},e._showBackdrop=function(t){var e=this,n=o.default(this._element).hasClass("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",n&&this._backdrop.classList.add(n),o.default(this._backdrop).appendTo(document.body),o.default(this._element).on("click.dismiss.bs.modal",function(t){e._ignoreBackdropClick?e._ignoreBackdropClick=!1:t.target===t.currentTarget&&("static"===e._config.backdrop?e._triggerBackdropTransition():e.hide())}),n&&c.reflow(this._backdrop),o.default(this._backdrop).addClass("show"),!t)return;if(!n)return void t();var i=c.getTransitionDurationFromElement(this._backdrop);o.default(this._backdrop).one(c.TRANSITION_END,t).emulateTransitionEnd(i)}else if(!this._isShown&&this._backdrop){o.default(this._backdrop).removeClass("show");var a=function(){e._removeBackdrop(),t&&t()};if(o.default(this._element).hasClass("fade")){var s=c.getTransitionDurationFromElement(this._backdrop);o.default(this._backdrop).one(c.TRANSITION_END,a).emulateTransitionEnd(s)}else a()}else t&&t()}// ----------------------------------------------------------------------
|
||||
// the following methods are used to handle overflowing modals
|
||||
// todo (fat): these should probably be refactored out of modal.js
|
||||
// ----------------------------------------------------------------------
|
||||
,e._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},e._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},e._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},e._setScrollbar=function(){var t=this;if(this._isBodyOverflowing){
|
||||
// Note: DOMNode.style.paddingRight returns the actual value or '' if not set
|
||||
// while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
|
||||
var e=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top")),n=[].slice.call(document.querySelectorAll(".sticky-top"));// Adjust fixed content padding
|
||||
o.default(e).each(function(e,n){var i=n.style.paddingRight,a=o.default(n).css("padding-right");o.default(n).data("padding-right",i).css("padding-right",parseFloat(a)+t._scrollbarWidth+"px")}),// Adjust sticky content margin
|
||||
o.default(n).each(function(e,n){var i=n.style.marginRight,a=o.default(n).css("margin-right");o.default(n).data("margin-right",i).css("margin-right",parseFloat(a)-t._scrollbarWidth+"px")});// Adjust body padding
|
||||
var i=document.body.style.paddingRight,a=o.default(document.body).css("padding-right");o.default(document.body).data("padding-right",i).css("padding-right",parseFloat(a)+this._scrollbarWidth+"px")}o.default(document.body).addClass("modal-open")},e._resetScrollbar=function(){
|
||||
// Restore fixed content padding
|
||||
var t=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top"));o.default(t).each(function(t,e){var n=o.default(e).data("padding-right");o.default(e).removeData("padding-right"),e.style.paddingRight=n||""});// Restore sticky content
|
||||
var e=[].slice.call(document.querySelectorAll(".sticky-top"));o.default(e).each(function(t,e){var n=o.default(e).data("margin-right");void 0!==n&&o.default(e).css("margin-right",n).removeData("margin-right")});// Restore body padding
|
||||
var n=o.default(document.body).data("padding-right");o.default(document.body).removeData("padding-right"),document.body.style.paddingRight=n||""},e._getScrollbarWidth=function(){
|
||||
// thx d.walsh
|
||||
var t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e}// Static
|
||||
,t._jQueryInterface=function(e,n){return this.each(function(){var i=o.default(this).data("bs.modal"),a=r({},q,o.default(this).data(),"object"==typeof e&&e?e:{});if(i||(i=new t(this,a),o.default(this).data("bs.modal",i)),"string"==typeof e){if(void 0===i[e])throw new TypeError('No method named "'+e+'"');i[e](n)}else a.show&&i.show(n)})},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return q}}]),t}();
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(t){var e,n=this,i=c.getSelectorFromElement(this);i&&(e=document.querySelector(i));var a=o.default(e).data("bs.modal")?"toggle":r({},o.default(e).data(),o.default(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault();var s=o.default(e).one("show.bs.modal",function(t){t.isDefaultPrevented()||s.one("hidden.bs.modal",function(){o.default(n).is(":visible")&&n.focus()})});B._jQueryInterface.call(o.default(e),a,this)}),
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default.fn.modal=B._jQueryInterface,o.default.fn.modal.Constructor=B,o.default.fn.modal.noConflict=function(){return o.default.fn.modal=L,B._jQueryInterface};
|
||||
/**
|
||||
* --------------------------------------------------------------------------
|
||||
* Bootstrap (v4.6.0): tools/sanitizer.js
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
* --------------------------------------------------------------------------
|
||||
*/
|
||||
var H=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],U={
|
||||
// Global attributes allowed on any supplied element below.
|
||||
"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},M=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi,W=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;function V(t,e,n){if(0===t.length)return t;if(n&&"function"==typeof n)return n(t);for(var i=(new window.DOMParser).parseFromString(t,"text/html"),o=Object.keys(e),a=[].slice.call(i.body.querySelectorAll("*")),s=function(t,n){var i=a[t],s=i.nodeName.toLowerCase();if(-1===o.indexOf(i.nodeName.toLowerCase()))return i.parentNode.removeChild(i),"continue";var l=[].slice.call(i.attributes),r=[].concat(e["*"]||[],e[s]||[]);l.forEach(function(t){(function(t,e){var n=t.nodeName.toLowerCase();if(-1!==e.indexOf(n))return-1===H.indexOf(n)||Boolean(t.nodeValue.match(M)||t.nodeValue.match(W));// Check if a regular expression validates the attribute.
|
||||
for(var i=e.filter(function(t){return t instanceof RegExp}),o=0,a=i.length;o<a;o++)if(n.match(i[o]))return!0;return!1})(t,r)||i.removeAttribute(t.nodeName)})},l=0,r=a.length;l<r;l++)s(l);return i.body.innerHTML}
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/var z="tooltip",K=o.default.fn.tooltip,X=new RegExp("(^|\\s)bs-tooltip\\S+","g"),Y=["sanitize","whiteList","sanitizeFn"],$={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},J={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},G={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",customClass:"",sanitize:!0,sanitizeFn:null,whiteList:U,popperConfig:null},Z={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},tt=/* */function(){function t(t,e){if(void 0===a.default)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");// private
|
||||
this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,// Protected
|
||||
this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}// Getters
|
||||
var e=t.prototype;
|
||||
// Public
|
||||
return e.enable=function(){this._isEnabled=!0},e.disable=function(){this._isEnabled=!1},e.toggleEnabled=function(){this._isEnabled=!this._isEnabled},e.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=o.default(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(o.default(this.getTipElement()).hasClass("show"))return void this._leave(null,this);this._enter(null,this)}},e.dispose=function(){clearTimeout(this._timeout),o.default.removeData(this.element,this.constructor.DATA_KEY),o.default(this.element).off(this.constructor.EVENT_KEY),o.default(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&o.default(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},e.show=function(){var t=this;if("none"===o.default(this.element).css("display"))throw new Error("Please use show on visible elements");var e=o.default.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){o.default(this.element).trigger(e);var n=c.findShadowRoot(this.element),i=o.default.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(e.isDefaultPrevented()||!i)return;var s=this.getTipElement(),l=c.getUID(this.constructor.NAME);s.setAttribute("id",l),this.element.setAttribute("aria-describedby",l),this.setContent(),this.config.animation&&o.default(s).addClass("fade");var r="function"==typeof this.config.placement?this.config.placement.call(this,s,this.element):this.config.placement,u=this._getAttachment(r);this.addAttachmentClass(u);var d=this._getContainer();o.default(s).data(this.constructor.DATA_KEY,this),o.default.contains(this.element.ownerDocument.documentElement,this.tip)||o.default(s).appendTo(d),o.default(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new a.default(this.element,s,this._getPopperConfig(u)),o.default(s).addClass("show"),o.default(s).addClass(this.config.customClass),// If this is a touch-enabled device we add extra
|
||||
// empty mouseover listeners to the body's immediate children;
|
||||
// only needed because of broken event delegation on iOS
|
||||
// https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
|
||||
"ontouchstart"in document.documentElement&&o.default(document.body).children().on("mouseover",null,o.default.noop);var f=function(){t.config.animation&&t._fixTransition();var e=t._hoverState;t._hoverState=null,o.default(t.element).trigger(t.constructor.Event.SHOWN),"out"===e&&t._leave(null,t)};if(o.default(this.tip).hasClass("fade")){var h=c.getTransitionDurationFromElement(this.tip);o.default(this.tip).one(c.TRANSITION_END,f).emulateTransitionEnd(h)}else f()}},e.hide=function(t){var e=this,n=this.getTipElement(),i=o.default.Event(this.constructor.Event.HIDE),a=function(){"show"!==e._hoverState&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),o.default(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(o.default(this.element).trigger(i),!i.isDefaultPrevented()){if(o.default(n).removeClass("show"),// If this is a touch-enabled device we remove the extra
|
||||
// empty mouseover listeners we added for iOS support
|
||||
"ontouchstart"in document.documentElement&&o.default(document.body).children().off("mouseover",null,o.default.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,o.default(this.tip).hasClass("fade")){var s=c.getTransitionDurationFromElement(n);o.default(n).one(c.TRANSITION_END,a).emulateTransitionEnd(s)}else a();this._hoverState=""}},e.update=function(){null!==this._popper&&this._popper.scheduleUpdate()}// Protected
|
||||
,e.isWithContent=function(){return Boolean(this.getTitle())},e.addAttachmentClass=function(t){o.default(this.getTipElement()).addClass("bs-tooltip-"+t)},e.getTipElement=function(){return this.tip=this.tip||o.default(this.config.template)[0],this.tip},e.setContent=function(){var t=this.getTipElement();this.setElementContent(o.default(t.querySelectorAll(".tooltip-inner")),this.getTitle()),o.default(t).removeClass("fade show")},e.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=V(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):
|
||||
// Content is a DOM node or a jQuery
|
||||
this.config.html?o.default(e).parent().is(t)||t.empty().append(e):t.text(o.default(e).text())},e.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t}// Private
|
||||
,e._getPopperConfig=function(t){var e=this;return r({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},e._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=r({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},e._getContainer=function(){return!1===this.config.container?document.body:c.isElement(this.config.container)?o.default(this.config.container):o.default(document).find(this.config.container)},e._getAttachment=function(t){return J[t.toUpperCase()]},e._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach(function(e){if("click"===e)o.default(t.element).on(t.constructor.Event.CLICK,t.config.selector,function(e){return t.toggle(e)});else if("manual"!==e){var n="hover"===e?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,i="hover"===e?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;o.default(t.element).on(n,t.config.selector,function(e){return t._enter(e)}).on(i,t.config.selector,function(e){return t._leave(e)})}}),this._hideModalHandler=function(){t.element&&t.hide()},o.default(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=r({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},e._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},e._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||o.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),o.default(e.getTipElement()).hasClass("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e.config.delay&&e.config.delay.show?e._timeout=setTimeout(function(){"show"===e._hoverState&&e.show()},e.config.delay.show):e.show())},e._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||o.default(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),o.default(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(function(){"out"===e._hoverState&&e.hide()},e.config.delay.hide):e.hide())},e._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},e._getConfig=function(t){var e=o.default(this.element).data();return Object.keys(e).forEach(function(t){-1!==Y.indexOf(t)&&delete e[t]}),"number"==typeof(t=r({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),c.typeCheckConfig(z,t,this.constructor.DefaultType),t.sanitize&&(t.template=V(t.template,t.whiteList,t.sanitizeFn)),t},e._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},e._cleanTipClass=function(){var t=o.default(this.getTipElement()),e=t.attr("class").match(X);null!==e&&e.length&&t.removeClass(e.join(""))},e._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},e._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(o.default(t).removeClass("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)}// Static
|
||||
,t._jQueryInterface=function(e){return this.each(function(){var n=o.default(this),i=n.data("bs.tooltip"),a="object"==typeof e&&e;if((i||!/dispose|hide/.test(e))&&(i||(i=new t(this,a),n.data("bs.tooltip",i)),"string"==typeof e)){if(void 0===i[e])throw new TypeError('No method named "'+e+'"');i[e]()}})},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return G}},{key:"NAME",get:function(){return z}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return Z}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return $}}]),t}();
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default.fn.tooltip=tt._jQueryInterface,o.default.fn.tooltip.Constructor=tt,o.default.fn.tooltip.noConflict=function(){return o.default.fn.tooltip=K,tt._jQueryInterface};
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
var et="popover",nt=o.default.fn.popover,it=new RegExp("(^|\\s)bs-popover\\S+","g"),ot=r({},tt.Default,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),at=r({},tt.DefaultType,{content:"(string|element|function)"}),st={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},lt=/* */function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),e.prototype.constructor=e,e.__proto__=n;var a=i.prototype;
|
||||
// Overrides
|
||||
return a.isWithContent=function(){return this.getTitle()||this._getContent()},a.addAttachmentClass=function(t){o.default(this.getTipElement()).addClass("bs-popover-"+t)},a.getTipElement=function(){return this.tip=this.tip||o.default(this.config.template)[0],this.tip},a.setContent=function(){var t=o.default(this.getTipElement());// We use append for html objects to maintain js events
|
||||
this.setElementContent(t.find(".popover-header"),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(".popover-body"),e),t.removeClass("fade show")}// Private
|
||||
,a._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},a._cleanTipClass=function(){var t=o.default(this.getTipElement()),e=t.attr("class").match(it);null!==e&&e.length>0&&t.removeClass(e.join(""))}// Static
|
||||
,i._jQueryInterface=function(t){return this.each(function(){var e=o.default(this).data("bs.popover"),n="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new i(this,n),o.default(this).data("bs.popover",e)),"string"==typeof t)){if(void 0===e[t])throw new TypeError('No method named "'+t+'"');e[t]()}})},l(i,null,[{key:"VERSION",
|
||||
// Getters
|
||||
get:function(){return"4.6.0"}},{key:"Default",get:function(){return ot}},{key:"NAME",get:function(){return et}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return st}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return at}}]),i}(tt);
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default.fn.popover=lt._jQueryInterface,o.default.fn.popover.Constructor=lt,o.default.fn.popover.noConflict=function(){return o.default.fn.popover=nt,lt._jQueryInterface};
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
var rt="scrollspy",ut=o.default.fn[rt],dt={offset:10,method:"auto",target:""},ct={offset:"number",method:"string",target:"(string|element)"},ft="scroll.bs.scrollspy",ht=".nav-link",gt=".list-group-item",mt=".dropdown-item",pt=/* */function(){function t(t,e){var n=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(e),this._selector=this._config.target+" "+ht+","+this._config.target+" "+gt+","+this._config.target+" "+mt,this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,o.default(this._scrollElement).on(ft,function(t){return n._process(t)}),this.refresh(),this._process()}// Getters
|
||||
var e=t.prototype;
|
||||
// Public
|
||||
return e.refresh=function(){var t=this,e=this._scrollElement===this._scrollElement.window?"offset":"position",n="auto"===this._config.method?e:this._config.method,i="position"===n?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map(function(t){var e,a=c.getSelectorFromElement(t);if(a&&(e=document.querySelector(a)),e){var s=e.getBoundingClientRect();if(s.width||s.height)
|
||||
// TODO (fat): remove sketch reliance on jQuery position/offset
|
||||
return[o.default(e)[n]().top+i,a]}return null}).filter(function(t){return t}).sort(function(t,e){return t[0]-e[0]}).forEach(function(e){t._offsets.push(e[0]),t._targets.push(e[1])})},e.dispose=function(){o.default.removeData(this._element,"bs.scrollspy"),o.default(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null}// Private
|
||||
,e._getConfig=function(t){if("string"!=typeof(t=r({},dt,"object"==typeof t&&t?t:{})).target&&c.isElement(t.target)){var e=o.default(t.target).attr("id");e||(e=c.getUID(rt),o.default(t.target).attr("id",e)),t.target="#"+e}return c.typeCheckConfig(rt,t,ct),t},e._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},e._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},e._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},e._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&(void 0===this._offsets[o+1]||t<this._offsets[o+1])&&this._activate(this._targets[o])}}},e._activate=function(t){this._activeTarget=t,this._clear();var e=this._selector.split(",").map(function(e){return e+'[data-target="'+t+'"],'+e+'[href="'+t+'"]'}),n=o.default([].slice.call(document.querySelectorAll(e.join(","))));n.hasClass("dropdown-item")?(n.closest(".dropdown").find(".dropdown-toggle").addClass("active"),n.addClass("active")):(
|
||||
// Set triggered link as active
|
||||
n.addClass("active"),// Set triggered links parents as active
|
||||
// With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
|
||||
n.parents(".nav, .list-group").prev(ht+", "+gt).addClass("active"),// Handle special case when .nav-link is inside .nav-item
|
||||
n.parents(".nav, .list-group").prev(".nav-item").children(ht).addClass("active")),o.default(this._scrollElement).trigger("activate.bs.scrollspy",{relatedTarget:t})},e._clear=function(){[].slice.call(document.querySelectorAll(this._selector)).filter(function(t){return t.classList.contains("active")}).forEach(function(t){return t.classList.remove("active")})}// Static
|
||||
,t._jQueryInterface=function(e){return this.each(function(){var n=o.default(this).data("bs.scrollspy");if(n||(n=new t(this,"object"==typeof e&&e),o.default(this).data("bs.scrollspy",n)),"string"==typeof e){if(void 0===n[e])throw new TypeError('No method named "'+e+'"');n[e]()}})},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"Default",get:function(){return dt}}]),t}();
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default(window).on("load.bs.scrollspy.data-api",function(){for(var t=[].slice.call(document.querySelectorAll('[data-spy="scroll"]')),e=t.length;e--;){var n=o.default(t[e]);pt._jQueryInterface.call(n,n.data())}}),
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default.fn[rt]=pt._jQueryInterface,o.default.fn[rt].Constructor=pt,o.default.fn[rt].noConflict=function(){return o.default.fn[rt]=ut,pt._jQueryInterface};
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
var _t=o.default.fn.tab,vt=/* */function(){function t(t){this._element=t}// Getters
|
||||
var e=t.prototype;
|
||||
// Public
|
||||
return e.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&o.default(this._element).hasClass("active")||o.default(this._element).hasClass("disabled"))){var e,n,i=o.default(this._element).closest(".nav, .list-group")[0],a=c.getSelectorFromElement(this._element);if(i){var s="UL"===i.nodeName||"OL"===i.nodeName?"> li > .active":".active";n=(n=o.default.makeArray(o.default(i).find(s)))[n.length-1]}var l=o.default.Event("hide.bs.tab",{relatedTarget:this._element}),r=o.default.Event("show.bs.tab",{relatedTarget:n});if(n&&o.default(n).trigger(l),o.default(this._element).trigger(r),!r.isDefaultPrevented()&&!l.isDefaultPrevented()){a&&(e=document.querySelector(a)),this._activate(this._element,i);var u=function(){var e=o.default.Event("hidden.bs.tab",{relatedTarget:t._element}),i=o.default.Event("shown.bs.tab",{relatedTarget:n});o.default(n).trigger(e),o.default(t._element).trigger(i)};e?this._activate(e,e.parentNode,u):u()}}},e.dispose=function(){o.default.removeData(this._element,"bs.tab"),this._element=null}// Private
|
||||
,e._activate=function(t,e,n){var i=this,a=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?o.default(e).children(".active"):o.default(e).find("> li > .active"))[0],s=n&&a&&o.default(a).hasClass("fade"),l=function(){return i._transitionComplete(t,a,n)};if(a&&s){var r=c.getTransitionDurationFromElement(a);o.default(a).removeClass("show").one(c.TRANSITION_END,l).emulateTransitionEnd(r)}else l()},e._transitionComplete=function(t,e,n){if(e){o.default(e).removeClass("active");var i=o.default(e.parentNode).find("> .dropdown-menu .active")[0];i&&o.default(i).removeClass("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}if(o.default(t).addClass("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),c.reflow(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&o.default(t.parentNode).hasClass("dropdown-menu")){var a=o.default(t).closest(".dropdown")[0];if(a){var s=[].slice.call(a.querySelectorAll(".dropdown-toggle"));o.default(s).addClass("active")}t.setAttribute("aria-expanded",!0)}n&&n()}// Static
|
||||
,t._jQueryInterface=function(e){return this.each(function(){var n=o.default(this),i=n.data("bs.tab");if(i||(i=new t(this),n.data("bs.tab",i)),"string"==typeof e){if(void 0===i[e])throw new TypeError('No method named "'+e+'"');i[e]()}})},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}}]),t}();
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Data Api implementation
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',function(t){t.preventDefault(),vt._jQueryInterface.call(o.default(this),"show")}),
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default.fn.tab=vt._jQueryInterface,o.default.fn.tab.Constructor=vt,o.default.fn.tab.noConflict=function(){return o.default.fn.tab=_t,vt._jQueryInterface};
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* Constants
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
var bt="toast",yt=o.default.fn.toast,Et={animation:"boolean",autohide:"boolean",delay:"number"},wt={animation:!0,autohide:!0,delay:500},Tt=/* */function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}// Getters
|
||||
var e=t.prototype;
|
||||
// Public
|
||||
return e.show=function(){var t=this,e=o.default.Event("show.bs.toast");if(o.default(this._element).trigger(e),!e.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var n=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),o.default(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout(function(){t.hide()},t._config.delay))};if(this._element.classList.remove("hide"),c.reflow(this._element),this._element.classList.add("showing"),this._config.animation){var i=c.getTransitionDurationFromElement(this._element);o.default(this._element).one(c.TRANSITION_END,n).emulateTransitionEnd(i)}else n()}},e.hide=function(){if(this._element.classList.contains("show")){var t=o.default.Event("hide.bs.toast");o.default(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},e.dispose=function(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),o.default(this._element).off("click.dismiss.bs.toast"),o.default.removeData(this._element,"bs.toast"),this._element=null,this._config=null}// Private
|
||||
,e._getConfig=function(t){return t=r({},wt,o.default(this._element).data(),"object"==typeof t&&t?t:{}),c.typeCheckConfig(bt,t,this.constructor.DefaultType),t},e._setListeners=function(){var t=this;o.default(this._element).on("click.dismiss.bs.toast",'[data-dismiss="toast"]',function(){return t.hide()})},e._close=function(){var t=this,e=function(){t._element.classList.add("hide"),o.default(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var n=c.getTransitionDurationFromElement(this._element);o.default(this._element).one(c.TRANSITION_END,e).emulateTransitionEnd(n)}else e()},e._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null}// Static
|
||||
,t._jQueryInterface=function(e){return this.each(function(){var n=o.default(this),i=n.data("bs.toast");if(i||(i=new t(this,"object"==typeof e&&e),n.data("bs.toast",i)),"string"==typeof e){if(void 0===i[e])throw new TypeError('No method named "'+e+'"');i[e](this)}})},l(t,null,[{key:"VERSION",get:function(){return"4.6.0"}},{key:"DefaultType",get:function(){return Et}},{key:"Default",get:function(){return wt}}]),t}();
|
||||
/**
|
||||
* ------------------------------------------------------------------------
|
||||
* jQuery
|
||||
* ------------------------------------------------------------------------
|
||||
*/
|
||||
o.default.fn.toast=Tt._jQueryInterface,o.default.fn.toast.Constructor=Tt,o.default.fn.toast.noConflict=function(){return o.default.fn.toast=yt,Tt._jQueryInterface},t.Alert=h,t.Button=m,t.Carousel=T,t.Collapse=A,t.Dropdown=R,t.Modal=B,t.Popover=lt,t.Scrollspy=pt,t.Tab=vt,t.Toast=Tt,t.Tooltip=tt,t.Util=c,Object.defineProperty(t,"__esModule",{value:!0})});
|
||||
//# sourceMappingURL=bootstrap.js.map
|
||||
//# sourceMappingURL=bootstrap.min.js.map
|
||||
Vendored
-2
File diff suppressed because one or more lines are too long
@@ -1,521 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
|
||||
|
||||
<link rel="shortcut icon" href="../img/favicon.ico">
|
||||
<title>Reference - r7rs-pffi</title>
|
||||
<link href="../css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="../css/font-awesome.min.css" rel="stylesheet">
|
||||
<link href="../css/base.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css">
|
||||
|
||||
<script src="../js/jquery-1.10.2.min.js" defer></script>
|
||||
<script src="../js/bootstrap.min.js" defer></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
|
||||
<script>hljs.initHighlightingOnLoad();</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="navbar fixed-top navbar-expand-lg navbar-dark bg-primary">
|
||||
<div class="container">
|
||||
<a class="navbar-brand" href="..">r7rs-pffi</a>
|
||||
<!-- Expander button -->
|
||||
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar-collapse">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<!-- Expanded navigation -->
|
||||
<div id="navbar-collapse" class="navbar-collapse collapse">
|
||||
<!-- Main navigation -->
|
||||
<ul class="nav navbar-nav">
|
||||
<li class="navitem">
|
||||
<a href=".." class="nav-link">Portable Foreign Function Interface for R7RS schemes</a>
|
||||
</li>
|
||||
<li class="navitem active">
|
||||
<a href="./" class="nav-link">Reference</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="nav navbar-nav ml-auto">
|
||||
<li class="nav-item">
|
||||
<a href="#" class="nav-link" data-toggle="modal" data-target="#mkdocs_search_modal">
|
||||
<i class="fa fa-search"></i> Search
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a rel="prev" href=".." class="nav-link">
|
||||
<i class="fa fa-arrow-left"></i> Previous
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a rel="next" class="nav-link disabled">
|
||||
Next <i class="fa fa-arrow-right"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-3"><div class="navbar-light navbar-expand-md bs-sidebar hidden-print affix" role="complementary">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggler collapsed" data-toggle="collapse" data-target="#toc-collapse" title="Table of Contents">
|
||||
<span class="fa fa-angle-down"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="toc-collapse" class="navbar-collapse collapse card bg-light">
|
||||
<ul class="nav flex-column">
|
||||
|
||||
<li class="nav-item" data-level="1"><a href="#reference" class="nav-link">Reference</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="nav-item" data-level="1"><a href="#types" class="nav-link">Types</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li class="nav-item" data-level="1"><a href="#procedures-or-macros" class="nav-link">Procedures or macros</a>
|
||||
<ul class="nav flex-column">
|
||||
<li class="nav-item" data-level="2"><a href="#pffi-shared-object-auto-load" class="nav-link">pffi-shared-object-auto-load</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#pffi-shared-object-load" class="nav-link">pffi-shared-object-load</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#pffi-define" class="nav-link">pffi-define</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#pffi-define-callback" class="nav-link">pffi-define-callback</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#pffi-size-of" class="nav-link">pffi-size-of</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#pffi-pointer-allocate" class="nav-link">pffi-pointer-allocate</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#pffi-pointer-null" class="nav-link">pffi-pointer-null</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#pffi-string-pointer" class="nav-link">pffi-string->pointer</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#pffi-pointer-string" class="nav-link">pffi-pointer->string</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#pffi-pointer-free" class="nav-link">pffi-pointer-free</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#pffi-pointer" class="nav-link">pffi-pointer?</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#pffi-pointer-set" class="nav-link">pffi-pointer-set!</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#pffi-pointer-get" class="nav-link">pffi-pointer-get</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
<li class="nav-item" data-level="2"><a href="#pffi-pointer-deref" class="nav-link">pffi-pointer-deref</a>
|
||||
<ul class="nav flex-column">
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div></div>
|
||||
<div class="col-md-9" role="main">
|
||||
|
||||
<h1 id="reference">Reference</h1>
|
||||
<h1 id="types">Types</h1>
|
||||
<p>Types are given as symbols, for example 'int8 or 'pointer.</p>
|
||||
<ul>
|
||||
<li>int8</li>
|
||||
<li>uint8</li>
|
||||
<li>int16</li>
|
||||
<li>uint16</li>
|
||||
<li>int32</li>
|
||||
<li>uint32</li>
|
||||
<li>int64</li>
|
||||
<li>uint64</li>
|
||||
<li>char</li>
|
||||
<li>unsigned-char</li>
|
||||
<li>short</li>
|
||||
<li>unsigned-short</li>
|
||||
<li>int</li>
|
||||
<li>unsigned-int</li>
|
||||
<li>long</li>
|
||||
<li>unsigned-long</li>
|
||||
<li>float</li>
|
||||
<li>double</li>
|
||||
<li>string</li>
|
||||
<li>pointer</li>
|
||||
</ul>
|
||||
<h1 id="procedures-or-macros">Procedures or macros</h1>
|
||||
<p>On some implementations these are procedures, on some macros.</p>
|
||||
<p>The arguments are in form</p>
|
||||
<ul>
|
||||
<li>NAME - TYPE</li>
|
||||
</ul>
|
||||
<p>The return value is in form</p>
|
||||
<ul>
|
||||
<li>TYPE</li>
|
||||
</ul>
|
||||
<h2 id="pffi-shared-object-auto-load">pffi-shared-object-auto-load</h2>
|
||||
<p>Arguments:</p>
|
||||
<ul>
|
||||
<li>headers - (list string ...)<ul>
|
||||
<li>C headers of the library</li>
|
||||
<li>For example (list "curl/curl.h")</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>object-name - symbol<ul>
|
||||
<li>The name of the dynamic library file you want to load</li>
|
||||
<li>Without the "lib" in front of it</li>
|
||||
<li>Without the ".so" or ".dll" at the end</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>additional-versions - (list string...)<ul>
|
||||
<li>For example (list ".0" ".1")</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>additional-paths - (list string...)<ul>
|
||||
<li>Any additional paths you want to search for the library</li>
|
||||
<li>For example (list "./mylibs")</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Returns:</p>
|
||||
<ul>
|
||||
<li>object<ul>
|
||||
<li>Shared object, the type depends on the implementation</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="pffi-shared-object-load">pffi-shared-object-load</h2>
|
||||
<p>It is recommended to use the pffi-shared-object-auto-load instead of this
|
||||
directly.</p>
|
||||
<p>Arguments:</p>
|
||||
<ul>
|
||||
<li>headers - (list string ...)<ul>
|
||||
<li>Headers that need to be included</li>
|
||||
<li>Example (list "curl/curl.h")</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>path - string<ul>
|
||||
<li>The full path to the shared object you want to load, including any "lib" infront and .so/.dll at the end</li>
|
||||
<li>Example "libcurl.so"</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Returns:</p>
|
||||
<ul>
|
||||
<li>object<ul>
|
||||
<li>Shared object, the type depends on the implementation</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="pffi-define">pffi-define</h2>
|
||||
<p>Defines new foreign procedure.</p>
|
||||
<p>Arguments:</p>
|
||||
<ul>
|
||||
<li>scheme-name - symbol<ul>
|
||||
<li>The name of the procedure used on scheme side</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>shared-object - object<ul>
|
||||
<li>The shared object</li>
|
||||
<li>Use pffi-shared-object-auto-load or pffi-shared-object-load to get this</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>c-name - symbol<ul>
|
||||
<li>The name of the C function</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>return-type - symbol<ul>
|
||||
<li>The return type of the C function</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>arguments-types - (list symbol ...)<ul>
|
||||
<li>The C function argument types</li>
|
||||
<li>Need to be given in form (list 'type 'type)</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="pffi-define-callback">pffi-define-callback</h2>
|
||||
<p>Defines new callback function.</p>
|
||||
<p>Arguments:</p>
|
||||
<ul>
|
||||
<li>scheme-name<ul>
|
||||
<li>The name of the function used on scheme side</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>return-type - symbol<ul>
|
||||
<li>The return type of the callback</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>arguments-types - (list symbol ...)<ul>
|
||||
<li>The callback function argument types</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>procedure - procedure<ul>
|
||||
<li>Procedure used as callback function</li>
|
||||
<li>Argument count must match the argument-types count</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="pffi-size-of">pffi-size-of</h2>
|
||||
<p>Get the size of type.</p>
|
||||
<p>Arguments:</p>
|
||||
<ul>
|
||||
<li>type - symbol<ul>
|
||||
<li>The type you want the size of</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Returns:</p>
|
||||
<ul>
|
||||
<li>number<ul>
|
||||
<li>The size of the given type</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="pffi-pointer-allocate">pffi-pointer-allocate</h2>
|
||||
<p>Allocates a pointer of given size.</p>
|
||||
<p>Arguments:</p>
|
||||
<ul>
|
||||
<li>size - number<ul>
|
||||
<li>The size of the pointer you want to allocate</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Returns:</p>
|
||||
<ul>
|
||||
<li>object<ul>
|
||||
<li>A pointer of given size</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="pffi-pointer-null">pffi-pointer-null</h2>
|
||||
<p>Create a null pointer.</p>
|
||||
<p>Returns:
|
||||
- object
|
||||
- Null pointer</p>
|
||||
<h2 id="pffi-string-pointer">pffi-string->pointer</h2>
|
||||
<p>Arguments:</p>
|
||||
<ul>
|
||||
<li>string-content - string<ul>
|
||||
<li>The string you want to transform into pointer</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Returns:</p>
|
||||
<ul>
|
||||
<li>object<ul>
|
||||
<li>Pointer of the given string</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="pffi-pointer-string">pffi-pointer->string</h2>
|
||||
<p>Arguments:</p>
|
||||
<ul>
|
||||
<li>pointer - object<ul>
|
||||
<li>The pointer you want to transform to string</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Returns:</p>
|
||||
<ul>
|
||||
<li>string<ul>
|
||||
<li>String from the given pointer</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="pffi-pointer-free">pffi-pointer-free</h2>
|
||||
<p>Arguments:</p>
|
||||
<ul>
|
||||
<li>pointer - object<ul>
|
||||
<li>The pointer you want to free</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="pffi-pointer">pffi-pointer?</h2>
|
||||
<p>Arguments:</p>
|
||||
<ul>
|
||||
<li>object - object<ul>
|
||||
<li>The object you want to check wether it is a pointer or not</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Returns:</p>
|
||||
<ul>
|
||||
<li>boolean<ul>
|
||||
<li>Returns true if given object is pointer, otherwise false</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="pffi-pointer-set">pffi-pointer-set!</h2>
|
||||
<p>Arguments:</p>
|
||||
<ul>
|
||||
<li>pointer - object<ul>
|
||||
<li>The pointer you want to modify</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>type - symbol<ul>
|
||||
<li>The type of value that will be put into the pointer</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>offset -number<ul>
|
||||
<li>The location of the value inside the pointer</li>
|
||||
<li>For example: (+ (pffi-size-of 'int) (pffi-size-of 'pointer)) or 0</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>value - object<ul>
|
||||
<li>The value to be placed into the object</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="pffi-pointer-get">pffi-pointer-get</h2>
|
||||
<p>Arguments:</p>
|
||||
<ul>
|
||||
<li>pointer - object<ul>
|
||||
<li>The pointer you want to get the value from</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>type - symbol<ul>
|
||||
<li>The type of value you want to get</li>
|
||||
<li>For example: 'int</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>offset - number<ul>
|
||||
<li>The location of the value inside the pointer</li>
|
||||
<li>For example: (+ (pffi-size-of 'int) (pffi-size-of 'pointer)) or 0</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Returns:</p>
|
||||
<ul>
|
||||
<li>object<ul>
|
||||
<li>The value in the poiner in the given offset as given type</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="pffi-pointer-deref">pffi-pointer-deref</h2>
|
||||
<p>Arguments:</p>
|
||||
<ul>
|
||||
<li>pointer<ul>
|
||||
<li>The pointer to dereference</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Returns:</p>
|
||||
<ul>
|
||||
<li>object<ul>
|
||||
<li>Whatever the pointer holds</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="col-md-12">
|
||||
<hr>
|
||||
<p>Documentation built with <a href="https://www.mkdocs.org/">MkDocs</a>.</p>
|
||||
</footer>
|
||||
<script>
|
||||
var base_url = "..",
|
||||
shortcuts = {"help": 191, "next": 78, "previous": 80, "search": 83};
|
||||
</script>
|
||||
<script src="../js/base.js" defer></script>
|
||||
<script src="../search/main.js" defer></script>
|
||||
|
||||
<div class="modal" id="mkdocs_search_modal" tabindex="-1" role="dialog" aria-labelledby="searchModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title" id="searchModalLabel">Search</h4>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>
|
||||
From here you can search these documents. Enter
|
||||
your search terms below.
|
||||
</p>
|
||||
<form>
|
||||
<div class="form-group">
|
||||
<input type="search" class="form-control" placeholder="Search..." id="mkdocs-search-query" title="Type search term here">
|
||||
</div>
|
||||
</form>
|
||||
<div id="mkdocs-search-results"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><div class="modal" id="mkdocs_keyboard_modal" tabindex="-1" role="dialog" aria-labelledby="keyboardModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title" id="keyboardModalLabel">Keyboard Shortcuts</h4>
|
||||
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 20%;">Keys</th>
|
||||
<th>Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="help shortcut"><kbd>?</kbd></td>
|
||||
<td>Open this help</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="next shortcut"><kbd>n</kbd></td>
|
||||
<td>Next page</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="prev shortcut"><kbd>p</kbd></td>
|
||||
<td>Previous page</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="search shortcut"><kbd>s</kbd></td>
|
||||
<td>Search</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
-3475
File diff suppressed because it is too large
Load Diff
@@ -1,98 +0,0 @@
|
||||
function getSearchTermFromLocation() {
|
||||
var sPageURL = window.location.search.substring(1);
|
||||
var sURLVariables = sPageURL.split('&');
|
||||
for (var i = 0; i < sURLVariables.length; i++) {
|
||||
var sParameterName = sURLVariables[i].split('=');
|
||||
if (sParameterName[0] == 'q') {
|
||||
return decodeURIComponent(sParameterName[1].replace(/\+/g, '%20'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function joinUrl (base, path) {
|
||||
if (path.substring(0, 1) === "/") {
|
||||
// path starts with `/`. Thus it is absolute.
|
||||
return path;
|
||||
}
|
||||
if (base.substring(base.length-1) === "/") {
|
||||
// base ends with `/`
|
||||
return base + path;
|
||||
}
|
||||
return base + "/" + path;
|
||||
}
|
||||
|
||||
function formatResult (location, title, summary) {
|
||||
return '<article><h3><a href="' + joinUrl(base_url, location) + '">'+ title + '</a></h3><p>' + summary +'</p></article>';
|
||||
}
|
||||
|
||||
function displayResults (results) {
|
||||
var search_results = document.getElementById("mkdocs-search-results");
|
||||
while (search_results.firstChild) {
|
||||
search_results.removeChild(search_results.firstChild);
|
||||
}
|
||||
if (results.length > 0){
|
||||
for (var i=0; i < results.length; i++){
|
||||
var result = results[i];
|
||||
var html = formatResult(result.location, result.title, result.summary);
|
||||
search_results.insertAdjacentHTML('beforeend', html);
|
||||
}
|
||||
} else {
|
||||
search_results.insertAdjacentHTML('beforeend', "<p>No results found</p>");
|
||||
}
|
||||
}
|
||||
|
||||
function doSearch () {
|
||||
var query = document.getElementById('mkdocs-search-query').value;
|
||||
if (query.length > min_search_length) {
|
||||
if (!window.Worker) {
|
||||
displayResults(search(query));
|
||||
} else {
|
||||
searchWorker.postMessage({query: query});
|
||||
}
|
||||
} else {
|
||||
// Clear results for short queries
|
||||
displayResults([]);
|
||||
}
|
||||
}
|
||||
|
||||
function initSearch () {
|
||||
var search_input = document.getElementById('mkdocs-search-query');
|
||||
if (search_input) {
|
||||
search_input.addEventListener("keyup", doSearch);
|
||||
}
|
||||
var term = getSearchTermFromLocation();
|
||||
if (term) {
|
||||
search_input.value = term;
|
||||
doSearch();
|
||||
}
|
||||
}
|
||||
|
||||
function onWorkerMessage (e) {
|
||||
if (e.data.allowSearch) {
|
||||
initSearch();
|
||||
} else if (e.data.results) {
|
||||
var results = e.data.results;
|
||||
displayResults(results);
|
||||
} else if (e.data.config) {
|
||||
min_search_length = e.data.config.min_search_length-1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!window.Worker) {
|
||||
console.log('Web Worker API not supported');
|
||||
// load index in main thread
|
||||
$.getScript(joinUrl(base_url, "search/worker.js")).done(function () {
|
||||
console.log('Loaded worker');
|
||||
init();
|
||||
window.postMessage = function (msg) {
|
||||
onWorkerMessage({data: msg});
|
||||
};
|
||||
}).fail(function (jqxhr, settings, exception) {
|
||||
console.error('Could not load worker.js');
|
||||
});
|
||||
} else {
|
||||
// Wrap search in a web worker
|
||||
var searchWorker = new Worker(joinUrl(base_url, "search/worker.js"));
|
||||
searchWorker.postMessage({init: true});
|
||||
searchWorker.onmessage = onWorkerMessage;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -1,130 +0,0 @@
|
||||
var base_path = 'function' === typeof importScripts ? '.' : '/search/';
|
||||
var allowSearch = false;
|
||||
var index;
|
||||
var documents = {};
|
||||
var lang = ['en'];
|
||||
var data;
|
||||
|
||||
function getScript(script, callback) {
|
||||
console.log('Loading script: ' + script);
|
||||
$.getScript(base_path + script).done(function () {
|
||||
callback();
|
||||
}).fail(function (jqxhr, settings, exception) {
|
||||
console.log('Error: ' + exception);
|
||||
});
|
||||
}
|
||||
|
||||
function getScriptsInOrder(scripts, callback) {
|
||||
if (scripts.length === 0) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
getScript(scripts[0], function() {
|
||||
getScriptsInOrder(scripts.slice(1), callback);
|
||||
});
|
||||
}
|
||||
|
||||
function loadScripts(urls, callback) {
|
||||
if( 'function' === typeof importScripts ) {
|
||||
importScripts.apply(null, urls);
|
||||
callback();
|
||||
} else {
|
||||
getScriptsInOrder(urls, callback);
|
||||
}
|
||||
}
|
||||
|
||||
function onJSONLoaded () {
|
||||
data = JSON.parse(this.responseText);
|
||||
var scriptsToLoad = ['lunr.js'];
|
||||
if (data.config && data.config.lang && data.config.lang.length) {
|
||||
lang = data.config.lang;
|
||||
}
|
||||
if (lang.length > 1 || lang[0] !== "en") {
|
||||
scriptsToLoad.push('lunr.stemmer.support.js');
|
||||
if (lang.length > 1) {
|
||||
scriptsToLoad.push('lunr.multi.js');
|
||||
}
|
||||
for (var i=0; i < lang.length; i++) {
|
||||
if (lang[i] != 'en') {
|
||||
scriptsToLoad.push(['lunr', lang[i], 'js'].join('.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
loadScripts(scriptsToLoad, onScriptsLoaded);
|
||||
}
|
||||
|
||||
function onScriptsLoaded () {
|
||||
console.log('All search scripts loaded, building Lunr index...');
|
||||
if (data.config && data.config.separator && data.config.separator.length) {
|
||||
lunr.tokenizer.separator = new RegExp(data.config.separator);
|
||||
}
|
||||
|
||||
if (data.index) {
|
||||
index = lunr.Index.load(data.index);
|
||||
data.docs.forEach(function (doc) {
|
||||
documents[doc.location] = doc;
|
||||
});
|
||||
console.log('Lunr pre-built index loaded, search ready');
|
||||
} else {
|
||||
index = lunr(function () {
|
||||
if (lang.length === 1 && lang[0] !== "en" && lunr[lang[0]]) {
|
||||
this.use(lunr[lang[0]]);
|
||||
} else if (lang.length > 1) {
|
||||
this.use(lunr.multiLanguage.apply(null, lang)); // spread operator not supported in all browsers: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator#Browser_compatibility
|
||||
}
|
||||
this.field('title');
|
||||
this.field('text');
|
||||
this.ref('location');
|
||||
|
||||
for (var i=0; i < data.docs.length; i++) {
|
||||
var doc = data.docs[i];
|
||||
this.add(doc);
|
||||
documents[doc.location] = doc;
|
||||
}
|
||||
});
|
||||
console.log('Lunr index built, search ready');
|
||||
}
|
||||
allowSearch = true;
|
||||
postMessage({config: data.config});
|
||||
postMessage({allowSearch: allowSearch});
|
||||
}
|
||||
|
||||
function init () {
|
||||
var oReq = new XMLHttpRequest();
|
||||
oReq.addEventListener("load", onJSONLoaded);
|
||||
var index_path = base_path + '/search_index.json';
|
||||
if( 'function' === typeof importScripts ){
|
||||
index_path = 'search_index.json';
|
||||
}
|
||||
oReq.open("GET", index_path);
|
||||
oReq.send();
|
||||
}
|
||||
|
||||
function search (query) {
|
||||
if (!allowSearch) {
|
||||
console.error('Assets for search still loading');
|
||||
return;
|
||||
}
|
||||
|
||||
var resultDocuments = [];
|
||||
var results = index.search(query);
|
||||
for (var i=0; i < results.length; i++){
|
||||
var result = results[i];
|
||||
doc = documents[result.ref];
|
||||
doc.summary = doc.text.substring(0, 200);
|
||||
resultDocuments.push(doc);
|
||||
}
|
||||
return resultDocuments;
|
||||
}
|
||||
|
||||
if( 'function' === typeof importScripts ) {
|
||||
onmessage = function (e) {
|
||||
if (e.data.init) {
|
||||
init();
|
||||
} else if (e.data.query) {
|
||||
postMessage({ results: search(e.data.query) });
|
||||
} else {
|
||||
console.error("Worker - Unrecognized message: " + e);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><url>
|
||||
<loc>None</loc>
|
||||
<lastmod>2024-09-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url><url>
|
||||
<loc>None</loc>
|
||||
<lastmod>2024-09-03</lastmod>
|
||||
<changefreq>daily</changefreq>
|
||||
</url>
|
||||
</urlset>
|
||||
Binary file not shown.
@@ -0,0 +1,106 @@
|
||||
(define (default-writer obj out)
|
||||
(when obj
|
||||
(display obj out)))
|
||||
|
||||
(define default-lookup
|
||||
(compose-lookups
|
||||
alist-lookup))
|
||||
|
||||
(define default-collection
|
||||
(compose-collections
|
||||
vector-collection
|
||||
stream-collection))
|
||||
|
||||
(define (port->string port)
|
||||
(define str
|
||||
(let loop ((chunks '())
|
||||
(chunk (read-string 2000 port)))
|
||||
(if (eof-object? chunk)
|
||||
(apply string-append (reverse chunks))
|
||||
(loop (cons chunk chunks)
|
||||
(read-string 2000 port)))))
|
||||
(close-input-port port)
|
||||
str)
|
||||
|
||||
(define (template-get-partials template)
|
||||
(define partials
|
||||
(let loop ((template template)
|
||||
(parts '()))
|
||||
(cond
|
||||
((null? template) parts)
|
||||
(else (let ((t (car template))
|
||||
(rest (cdr template)))
|
||||
(cond
|
||||
((partial? t) (loop rest
|
||||
(cons (partial-name t) parts)))
|
||||
((section? t) (loop rest
|
||||
(append (template-get-partials (section-content t))
|
||||
parts)))
|
||||
(else (loop rest
|
||||
parts))))))))
|
||||
(delete-duplicates! partials))
|
||||
|
||||
(define compile
|
||||
(case-lambda
|
||||
((template) (compile/without-partials template))
|
||||
((root partial-locator) (compile/with-partials root partial-locator))))
|
||||
|
||||
(define (compile/without-partials template)
|
||||
(compile/with-partials #f (lambda (partial)
|
||||
(if partial
|
||||
#f
|
||||
template))))
|
||||
|
||||
(define (compile/with-partials root partial-locator)
|
||||
|
||||
;; returns 2 values: missing partials (found in part) and compiled part template
|
||||
(define (compile-part part resolved-partials)
|
||||
(define source (partial-locator part))
|
||||
(define in (cond
|
||||
((not source) "")
|
||||
((string? source) source)
|
||||
((port? source) (port->string source))
|
||||
(else (error "Partial locator returned unrecognized type"))))
|
||||
(define template (parse (read-tokens in)))
|
||||
(define partials (template-get-partials template))
|
||||
(define missing-partials (lset-difference string=? partials resolved-partials))
|
||||
(values missing-partials template))
|
||||
|
||||
(let loop ((unresolved (list root))
|
||||
(resolved-map '())
|
||||
(resolved-lst '()))
|
||||
(cond
|
||||
((null? unresolved) (cons root resolved-map))
|
||||
(else (let ((part (car unresolved)))
|
||||
(define-values (unresolved* template)
|
||||
(compile-part part resolved-lst))
|
||||
(loop (append unresolved* (cdr unresolved))
|
||||
(cons (cons part template) resolved-map)
|
||||
(cons part resolved-lst)))))))
|
||||
|
||||
(define current-lookup (make-parameter default-lookup))
|
||||
(define current-collection (make-parameter default-collection))
|
||||
(define current-writer (make-parameter default-writer))
|
||||
|
||||
(define execute
|
||||
(case-lambda
|
||||
((compilation data)
|
||||
(let ((out (open-output-string)))
|
||||
(execute compilation data out)
|
||||
(get-output-string out)))
|
||||
((compilation data out)
|
||||
(define root (car compilation))
|
||||
(define partials (cdr compilation))
|
||||
(define template (cdr (assoc root partials)))
|
||||
(define lookup (current-lookup))
|
||||
(define collection* (current-collection))
|
||||
(define writer (current-writer))
|
||||
(executor-execute template
|
||||
(list data)
|
||||
partials
|
||||
out
|
||||
lookup
|
||||
(collection-pred-proc collection*)
|
||||
(collection-empty?-proc collection*)
|
||||
(collection-for-each-proc collection*)
|
||||
writer))))
|
||||
@@ -0,0 +1,73 @@
|
||||
(define-library
|
||||
(arvyy mustache-test)
|
||||
|
||||
(import (scheme base)
|
||||
(scheme write)
|
||||
(arvyy mustache)
|
||||
(srfi 41))
|
||||
|
||||
(export run-tests)
|
||||
|
||||
(cond-expand
|
||||
(chibi
|
||||
(import (rename (except (chibi test) test-equal)
|
||||
(test test-equal))))
|
||||
((library (srfi 64))
|
||||
(import (srfi 64)))
|
||||
(else (error "No testing library found")))
|
||||
|
||||
(begin
|
||||
(define-syntax test-mustache
|
||||
(syntax-rules ()
|
||||
((_ name data template expected)
|
||||
(test-equal name expected (execute (compile "foo" (lambda args template)) data)))
|
||||
((_ name data partials template expected)
|
||||
(let* ((partials* (cons (cons "root" template) partials))
|
||||
(fn (lambda (n)
|
||||
(cond
|
||||
((assoc n partials*) => cdr)
|
||||
(else #f)))))
|
||||
(test-equal name expected (execute (compile "root" fn) data)))))))
|
||||
|
||||
(include "mustache-test/comments.scm"
|
||||
"mustache-test/delimiters.scm"
|
||||
"mustache-test/implementation-specific.scm"
|
||||
"mustache-test/interpolation.scm"
|
||||
"mustache-test/inverted.scm"
|
||||
"mustache-test/partials.scm"
|
||||
"mustache-test/sections.scm")
|
||||
|
||||
(begin
|
||||
|
||||
(define (run-tests)
|
||||
(test-begin "mustache")
|
||||
|
||||
(test-group
|
||||
"comments"
|
||||
(run-tests/comments))
|
||||
|
||||
(test-group
|
||||
"delimiters"
|
||||
(run-tests/delimiters))
|
||||
|
||||
(test-group
|
||||
"interpolation"
|
||||
(run-tests/interpolation))
|
||||
|
||||
(test-group
|
||||
"inverted"
|
||||
(run-tests/inverted))
|
||||
|
||||
(test-group
|
||||
"partials"
|
||||
(run-tests/partials))
|
||||
|
||||
(test-group
|
||||
"sections"
|
||||
(run-tests/sections))
|
||||
|
||||
(test-group
|
||||
"implementation-specific"
|
||||
(run-tests/implementation-specific))
|
||||
|
||||
(test-end))))
|
||||
@@ -0,0 +1,56 @@
|
||||
(define (run-tests/comments)
|
||||
(test-mustache "Inline"
|
||||
'()
|
||||
"12345{{! Comment Block! }}67890"
|
||||
"1234567890")
|
||||
|
||||
(test-mustache "Multiline"
|
||||
'()
|
||||
"12345{{!\n This is a\n multi-line comment...\n}}67890"
|
||||
"1234567890")
|
||||
|
||||
(test-mustache "Standalone"
|
||||
'()
|
||||
"Begin.\n{{! Comment Block! }}\nEnd."
|
||||
"Begin.\nEnd.")
|
||||
|
||||
(test-mustache "Indented Standalone"
|
||||
'()
|
||||
"Begin.\n {{! Comment Block! }}\nEnd."
|
||||
"Begin.\nEnd.")
|
||||
|
||||
(test-mustache "Standalone Line Endings"
|
||||
'()
|
||||
"\r\n{{! Standalone Comment }}\r\n"
|
||||
"\r\n")
|
||||
|
||||
(test-mustache "Standalone Without Previous Line"
|
||||
'()
|
||||
" {{! I'm Still Standalone }}\n!"
|
||||
"!")
|
||||
|
||||
(test-mustache "Standalone Without Newline"
|
||||
'()
|
||||
"!\n {{! I'm Still Standalone }}"
|
||||
"!\n")
|
||||
|
||||
(test-mustache "Multiline Standalone"
|
||||
'()
|
||||
"Begin.\n{{!\nSomething's going on here...\n}}\nEnd."
|
||||
"Begin.\nEnd.")
|
||||
|
||||
(test-mustache "Indented Multiline Standalone"
|
||||
'()
|
||||
"Begin.\n {{!\n Something's going on here...\n }}\nEnd."
|
||||
"Begin.\nEnd.")
|
||||
|
||||
(test-mustache "Indented Inline"
|
||||
'()
|
||||
" 12 {{! 34 }}\n"
|
||||
" 12 \n")
|
||||
|
||||
(test-mustache "Surrounding Whitespace"
|
||||
'()
|
||||
"12345 {{! Comment Block! }} 67890"
|
||||
"12345 67890"))
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
(define (run-tests/delimiters)
|
||||
|
||||
(test-mustache "Pair Behavior"
|
||||
'((text . "Hey!"))
|
||||
"{{=<% %>=}}(<%text%>)"
|
||||
"(Hey!)")
|
||||
|
||||
(test-mustache "Special Characters"
|
||||
'((text . "It worked!"))
|
||||
"({{=[ ]=}}[text])"
|
||||
"(It worked!)")
|
||||
|
||||
(test-mustache "Sections"
|
||||
'((section . #t)
|
||||
(data . "I got interpolated."))
|
||||
"[\n{{#section}}\n {{data}}\n |data|\n{{/section}}\n\n{{= | | =}}\n|#section|\n {{data}}\n |data|\n|/section|\n]\n"
|
||||
"[\n I got interpolated.\n |data|\n\n {{data}}\n I got interpolated.\n]\n")
|
||||
|
||||
(test-mustache "Inverted Sections"
|
||||
'((section . #f)
|
||||
(data . "I got interpolated."))
|
||||
"[\n{{^section}}\n {{data}}\n |data|\n{{/section}}\n\n{{= | | =}}\n|^section|\n {{data}}\n |data|\n|/section|\n]\n"
|
||||
"[\n I got interpolated.\n |data|\n\n {{data}}\n I got interpolated.\n]\n")
|
||||
|
||||
(test-mustache "Partial Inheritence"
|
||||
'((value . "yes"))
|
||||
'(("include" . ".{{value}}."))
|
||||
"[ {{>include}} ]\n{{= | | =}}\n[ |>include| ]\n"
|
||||
"[ .yes. ]\n[ .yes. ]\n")
|
||||
|
||||
(test-mustache "Post-Partial Behavior"
|
||||
'((value . "yes"))
|
||||
'(("include" . ".{{value}}. {{= | | =}} .|value|."))
|
||||
"[ {{>include}} ]\n[ .{{value}}. .|value|. ]\n"
|
||||
"[ .yes. .yes. ]\n[ .yes. .|value|. ]\n")
|
||||
|
||||
(test-mustache "Surrounding Whitespace"
|
||||
'()
|
||||
"| {{=@ @=}} |"
|
||||
"| |")
|
||||
|
||||
(test-mustache "Outlying Whitespace (Inline)"
|
||||
'()
|
||||
" | {{=@ @=}}\n"
|
||||
" | \n")
|
||||
|
||||
(test-mustache "Standalone Tag"
|
||||
'()
|
||||
"Begin.\n{{=@ @=}}\nEnd.\n"
|
||||
"Begin.\nEnd.\n")
|
||||
|
||||
(test-mustache "Indented Standalone Tag"
|
||||
'()
|
||||
"Begin.\n {{=@ @=}}\nEnd.\n"
|
||||
"Begin.\nEnd.\n")
|
||||
|
||||
(test-mustache "Standalone Line Endings"
|
||||
'()
|
||||
"|\r\n{{= @ @ =}}\r\n|"
|
||||
"|\r\n|")
|
||||
|
||||
(test-mustache "Standalone Without Previous Line"
|
||||
'()
|
||||
" {{=@ @=}}\n="
|
||||
"=")
|
||||
|
||||
(test-mustache "Standalone Without Newline"
|
||||
'()
|
||||
"=\n {{=@ @=}}"
|
||||
"=\n")
|
||||
|
||||
(test-mustache "Pair with Padding"
|
||||
'()
|
||||
"|{{= @ @ =}}|"
|
||||
"||"))
|
||||
@@ -0,0 +1,71 @@
|
||||
(define-record-type <foo> (foo bar) foo? (bar foo-bar))
|
||||
|
||||
(define (run-tests/implementation-specific)
|
||||
(define (foo-lookup obj name found not-found)
|
||||
(cond
|
||||
((not (foo? obj)) (not-found))
|
||||
((string=? "bar" name) (found (foo-bar obj)))
|
||||
(else (not-found))))
|
||||
|
||||
(define alist+foo (compose-lookups alist-lookup foo-lookup))
|
||||
|
||||
(define (write-foo obj out)
|
||||
(write-string "(foo " out)
|
||||
(display (foo-bar obj) out)
|
||||
(write-string ")" out))
|
||||
|
||||
(define-record-type <num-lst> (num-lst count) num-lst? (count num-lst-count))
|
||||
(define num-lst-collection
|
||||
(collection
|
||||
num-lst?
|
||||
(lambda (obj) (= 0 (num-lst-count obj)))
|
||||
(lambda (proc obj)
|
||||
(define target (num-lst-count obj))
|
||||
(let loop ((i 0))
|
||||
(when (< i target)
|
||||
(begin
|
||||
(proc i)
|
||||
(loop (+ 1 i))))))))
|
||||
|
||||
(parameterize
|
||||
((current-writer (lambda (obj out)
|
||||
(cond
|
||||
((not obj) #t)
|
||||
((foo? obj) (write-foo obj out))
|
||||
(else (display obj out))))))
|
||||
(test-mustache "Custom writer"
|
||||
`((obj . ,(foo "baz")))
|
||||
"Test {{obj}}"
|
||||
"Test (foo baz)"))
|
||||
|
||||
(parameterize
|
||||
((current-lookup alist+foo))
|
||||
(test-mustache "Custom lookup"
|
||||
`((a . ((bar . "baz1")))
|
||||
(b . ,(foo "baz2")))
|
||||
"{{a.bar}}, {{b.bar}}"
|
||||
"baz1, baz2"))
|
||||
|
||||
(parameterize
|
||||
((current-collection num-lst-collection))
|
||||
(test-mustache "Custom collection"
|
||||
`((a . ,(num-lst 3)))
|
||||
"{{#a}}{{.}};{{/a}}"
|
||||
"0;1;2;"))
|
||||
|
||||
(parameterize
|
||||
((current-collection list-collection)
|
||||
(current-lookup foo-lookup))
|
||||
(test-mustache "List collection"
|
||||
(foo '(0 1 2))
|
||||
"{{#bar}}{{.}};{{/bar}}"
|
||||
"0;1;2;"))
|
||||
|
||||
(parameterize
|
||||
((current-collection stream-collection)
|
||||
(current-lookup foo-lookup))
|
||||
(test-mustache "Stream collection"
|
||||
(foo (list->stream '(0 1 2)))
|
||||
"{{#bar}}{{.}};{{/bar}}"
|
||||
"0;1;2;")))
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
(define (run-tests/interpolation)
|
||||
|
||||
(test-mustache "No Interpolation"
|
||||
'()
|
||||
"Hello from {Mustache}!"
|
||||
"Hello from {Mustache}!")
|
||||
|
||||
(test-mustache "Basic Interpolation"
|
||||
'((subject . "world"))
|
||||
"Hello, {{subject}}!"
|
||||
"Hello, world!")
|
||||
|
||||
(test-mustache "HTML Escaping"
|
||||
'((forbidden . "& \" < >"))
|
||||
"These characters should be HTML escaped: {{forbidden}}"
|
||||
"These characters should be HTML escaped: & " < >")
|
||||
|
||||
(test-mustache "Triple Mustache"
|
||||
'((forbidden . "& \" < >"))
|
||||
"These characters should not be HTML escaped: {{{forbidden}}}"
|
||||
"These characters should not be HTML escaped: & \" < >")
|
||||
|
||||
(test-mustache "Ampersand"
|
||||
'((forbidden . "& \" < >"))
|
||||
"These characters should not be HTML escaped: {{&forbidden}}"
|
||||
"These characters should not be HTML escaped: & \" < >")
|
||||
|
||||
(test-mustache "Basic Integer Interpolation"
|
||||
'((mph . 85))
|
||||
"\"{{mph}} miles an hour!\""
|
||||
"\"85 miles an hour!\"")
|
||||
|
||||
(test-mustache "Triple Mustache Integer Interpolation"
|
||||
'((mph . 85))
|
||||
"\"{{{mph}}} miles an hour!\""
|
||||
"\"85 miles an hour!\"")
|
||||
|
||||
(test-mustache "Ampersand Mustache Integer Interpolation"
|
||||
'((mph . 85))
|
||||
"\"{{&mph}} miles an hour!\""
|
||||
"\"85 miles an hour!\"")
|
||||
|
||||
(test-mustache "Basic Decimal Interpolation"
|
||||
'((power . 1.210))
|
||||
"\"{{power}} jiggawatts!\""
|
||||
"\"1.21 jiggawatts!\"")
|
||||
|
||||
(test-mustache "Triple Mustache Decimal Interpolation"
|
||||
'((power . 1.210))
|
||||
"\"{{{power}}} jiggawatts!\""
|
||||
"\"1.21 jiggawatts!\"")
|
||||
|
||||
(test-mustache "Ampersand Mustache Decimal Interpolation"
|
||||
'((power . 1.210))
|
||||
"\"{{&power}} jiggawatts!\""
|
||||
"\"1.21 jiggawatts!\"")
|
||||
|
||||
(test-mustache "Basic Null Interpolation"
|
||||
'((cannot . #f))
|
||||
"I ({{cannot}}) be seen!"
|
||||
"I () be seen!")
|
||||
|
||||
(test-mustache "Triple Mustache Null Interpolation"
|
||||
'((cannot . #f))
|
||||
"I ({{{cannot}}}) be seen!"
|
||||
"I () be seen!")
|
||||
|
||||
(test-mustache "Ampersand Null Interpolation"
|
||||
'((cannot . #f))
|
||||
"I ({{&cannot}}) be seen!"
|
||||
"I () be seen!")
|
||||
|
||||
(test-mustache "Basic Context Miss Interpolation"
|
||||
'()
|
||||
"I ({{cannot}}) be seen!"
|
||||
"I () be seen!")
|
||||
|
||||
(test-mustache "Triple Mustache Context Miss Interpolation"
|
||||
'()
|
||||
"I ({{{cannot}}}) be seen!"
|
||||
"I () be seen!")
|
||||
|
||||
(test-mustache "Ampersand Context Miss Interpolation"
|
||||
'()
|
||||
"I ({{&cannot}}) be seen!"
|
||||
"I () be seen!")
|
||||
|
||||
(test-mustache "Dotted Names - Basic Interpolation"
|
||||
'((person . ((name . "Joe"))))
|
||||
"\"{{person.name}}\" == \"{{#person}}{{name}}{{/person}}\""
|
||||
"\"Joe\" == \"Joe\"")
|
||||
|
||||
(test-mustache "Dotted Names - Triple Mustache Interpolation"
|
||||
'((person . ((name . "Joe"))))
|
||||
"\"{{{person.name}}}\" == \"{{#person}}{{{name}}}{{/person}}\""
|
||||
"\"Joe\" == \"Joe\"")
|
||||
|
||||
(test-mustache "Dotted Names - Ampersand Interpolation"
|
||||
'((person . ((name . "Joe"))))
|
||||
"\"{{&person.name}}\" == \"{{#person}}{{&name}}{{/person}}\""
|
||||
"\"Joe\" == \"Joe\"")
|
||||
|
||||
(test-mustache "Dotted Names - Arbitrary Depth"
|
||||
'((a . ((b . ((c . ((d . ((e . ((name . "Phil"))))))))))))
|
||||
"\"{{a.b.c.d.e.name}}\" == \"Phil\""
|
||||
"\"Phil\" == \"Phil\"")
|
||||
|
||||
(test-mustache "Dotted Names - Broken Chains"
|
||||
'((a . ()))
|
||||
"\"{{a.b.c}}\" == \"\""
|
||||
"\"\" == \"\"")
|
||||
|
||||
(test-mustache "Dotted Names - Broken Chain Resolution"
|
||||
'((a . ((b . ())))
|
||||
(c . ((name . "Jim"))))
|
||||
"\"{{a.b.c.name}}\" == \"\""
|
||||
"\"\" == \"\"")
|
||||
|
||||
(test-mustache "Dotted Names - Initial Resolution"
|
||||
'((a . ((b . ((c . ((d . ((e . ((name . "Phil")))))))))))
|
||||
(b . ((c . ((d . ((e . ((name . "Wrong"))))))))))
|
||||
"\"{{#a}}{{b.c.d.e.name}}{{/a}}\" == \"Phil\""
|
||||
"\"Phil\" == \"Phil\"")
|
||||
|
||||
(test-mustache "Dotted Names - Context Precedence"
|
||||
'((a . ((b . ())))
|
||||
(b . ((c . "ERROR"))))
|
||||
"{{#a}}{{b.c}}{{/a}}"
|
||||
"")
|
||||
|
||||
(test-mustache "Implicit Iterators - Basic Interpolation"
|
||||
"world"
|
||||
"Hello, {{.}}!"
|
||||
"Hello, world!")
|
||||
|
||||
(test-mustache "Implicit Iterators - HTML Escaping"
|
||||
"& \" < >"
|
||||
"These characters should be HTML escaped: {{.}}"
|
||||
"These characters should be HTML escaped: & " < >")
|
||||
|
||||
(test-mustache "Implicit Iterators - Triple Mustache"
|
||||
"& \" < >"
|
||||
"These characters should not be HTML escaped: {{{.}}}"
|
||||
"These characters should not be HTML escaped: & \" < >")
|
||||
|
||||
(test-mustache "Implicit Iterators - Ampersand"
|
||||
"& \" < >"
|
||||
"These characters should not be HTML escaped: {{&.}}"
|
||||
"These characters should not be HTML escaped: & \" < >")
|
||||
|
||||
(test-mustache "Implicit Iterators - Basic Integer Interpolation"
|
||||
85
|
||||
"\"{{.}} miles an hour!\""
|
||||
"\"85 miles an hour!\"")
|
||||
|
||||
(test-mustache "Interpolation - Surrounding Whitespace"
|
||||
'((string . "---"))
|
||||
"| {{string}} |"
|
||||
"| --- |")
|
||||
|
||||
(test-mustache "Triple Mustache - Surrounding Whitespace"
|
||||
'((string . "---"))
|
||||
"| {{{string}}} |"
|
||||
"| --- |")
|
||||
|
||||
(test-mustache "Ampersand - Surrounding Whitespace"
|
||||
'((string . "---"))
|
||||
"| {{&string}} |"
|
||||
"| --- |")
|
||||
|
||||
(test-mustache "Interpolation - Standalone"
|
||||
'((string . "---"))
|
||||
" {{string}}\n"
|
||||
" ---\n")
|
||||
|
||||
(test-mustache "Triple Mustache - Standalone"
|
||||
'((string . "---"))
|
||||
" {{{string}}}\n"
|
||||
" ---\n")
|
||||
|
||||
(test-mustache "Ampersand - Standalone"
|
||||
'((string . "---"))
|
||||
" {{&string}}\n"
|
||||
" ---\n")
|
||||
|
||||
(test-mustache "Interpolation With Padding"
|
||||
'((string . "---"))
|
||||
"|{{ string }}|"
|
||||
"|---|")
|
||||
|
||||
(test-mustache "Triple Mustache With Padding"
|
||||
'((string . "---"))
|
||||
"|{{{ string }}}|"
|
||||
"|---|")
|
||||
|
||||
(test-mustache "Ampersand With Padding"
|
||||
'((string . "---"))
|
||||
"|{{& string }}|"
|
||||
"|---|"))
|
||||
@@ -0,0 +1,147 @@
|
||||
(define (run-tests/inverted)
|
||||
|
||||
(test-mustache "Falsey"
|
||||
'((boolean . #f))
|
||||
"\"{{^boolean}}This should be rendered.{{/boolean}}\""
|
||||
"\"This should be rendered.\"")
|
||||
|
||||
(test-mustache "Truthy"
|
||||
'((boolean . #t))
|
||||
"\"{{^boolean}}This should not be rendered.{{/boolean}}\""
|
||||
"\"\"")
|
||||
|
||||
;; "Null is falsey" test is skipped; no meaningful value for null
|
||||
|
||||
(test-mustache "Context"
|
||||
'((context . ((name . "Joe"))))
|
||||
"\"{{^context}}Hi {{name}}.{{/context}}\""
|
||||
"\"\"")
|
||||
|
||||
(test-mustache "List"
|
||||
'(list . #(((n . 1))
|
||||
((n . 2))
|
||||
((n . 3))))
|
||||
"\"{{^list}}{{n}}{{/list}}\""
|
||||
"\"\"")
|
||||
|
||||
(test-mustache "Empty List"
|
||||
'(list . #())
|
||||
"\"{{^list}}Yay lists!{{/list}}\""
|
||||
"\"Yay lists!\"")
|
||||
|
||||
(test-mustache "Doubled"
|
||||
'((bool . #f) (two . "second"))
|
||||
"
|
||||
{{^bool}}
|
||||
* first
|
||||
{{/bool}}
|
||||
* {{two}}
|
||||
{{^bool}}
|
||||
* third
|
||||
{{/bool}}
|
||||
"
|
||||
"
|
||||
* first
|
||||
* second
|
||||
* third
|
||||
")
|
||||
|
||||
(test-mustache "Nested (Falsey)"
|
||||
'((bool . #f))
|
||||
"| A {{^bool}}B {{^bool}}C{{/bool}} D{{/bool}} E |"
|
||||
"| A B C D E |")
|
||||
|
||||
(test-mustache "Nested (Truthy)"
|
||||
'((bool . #t))
|
||||
"| A {{^bool}}B {{^bool}}C{{/bool}} D{{/bool}} E |"
|
||||
"| A E |")
|
||||
|
||||
(test-mustache "Context Misses"
|
||||
'(())
|
||||
"[{{^missing}}Cannot find key 'missing'!{{/missing}}]"
|
||||
"[Cannot find key 'missing'!]")
|
||||
|
||||
(test-mustache "Dotted Names - Truthy"
|
||||
'((a . ((b . ((c . #t))))))
|
||||
"\"{{^a.b.c}}Not Here{{/a.b.c}}\" == \"\""
|
||||
"\"\" == \"\"")
|
||||
|
||||
(test-mustache "Dotted Names - Falsey"
|
||||
'((a . ((b . ((c . #f))))))
|
||||
"\"{{^a.b.c}}Not Here{{/a.b.c}}\" == \"Not Here\""
|
||||
"\"Not Here\" == \"Not Here\"")
|
||||
|
||||
(test-mustache "Dotted Names - Broken Chains"
|
||||
'((a . ()))
|
||||
"\"{{^a.b.c}}Not Here{{/a.b.c}}\" == \"Not Here\""
|
||||
"\"Not Here\" == \"Not Here\"")
|
||||
|
||||
(test-mustache "Surrounding Whitespace"
|
||||
'((boolean . #f))
|
||||
" | {{^boolean}}\t|\t{{/boolean}} | \n"
|
||||
" | \t|\t | \n")
|
||||
|
||||
(test-mustache "Internal Whitespace"
|
||||
'((boolean . #f))
|
||||
" | {{^boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n"
|
||||
" | \n | \n")
|
||||
|
||||
(test-mustache "Indented Inline Sections"
|
||||
'((boolean . #f))
|
||||
" {{^boolean}}NO{{/boolean}}\n {{^boolean}}WAY{{/boolean}}\n"
|
||||
" NO\n WAY\n")
|
||||
|
||||
(test-mustache "Standalone Lines"
|
||||
'((boolean . #f))
|
||||
"
|
||||
|
|
||||
| This Is
|
||||
{{^boolean}}
|
||||
|
|
||||
{{/boolean}}
|
||||
| A Line
|
||||
"
|
||||
"
|
||||
|
|
||||
| This Is
|
||||
|
|
||||
| A Line
|
||||
")
|
||||
|
||||
(test-mustache "Standalone Indented Lines"
|
||||
'((boolean . #f))
|
||||
"
|
||||
|
|
||||
| This Is
|
||||
{{^boolean}}
|
||||
|
|
||||
{{/boolean}}
|
||||
| A Line
|
||||
"
|
||||
"
|
||||
|
|
||||
| This Is
|
||||
|
|
||||
| A Line
|
||||
")
|
||||
|
||||
(test-mustache "Standalone Line Endings"
|
||||
'((boolean . #f))
|
||||
"|\r\n{{^boolean}}\r\n{{/boolean}}\r\n|"
|
||||
"|\r\n|")
|
||||
|
||||
(test-mustache "Standalone Without Previous Line"
|
||||
'((boolean . #f))
|
||||
" {{^boolean}}\n^{{/boolean}}\n/"
|
||||
"^\n/")
|
||||
|
||||
(test-mustache "Standalone Without Newline"
|
||||
'((boolean . #f))
|
||||
"^{{^boolean}}\n/\n {{/boolean}}"
|
||||
"^\n/\n")
|
||||
|
||||
(test-mustache "Padding"
|
||||
'((boolean . #f))
|
||||
"|{{^ boolean }}={{/ boolean }}|"
|
||||
"|=|"))
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
(define (run-tests/partials)
|
||||
|
||||
(test-mustache "Basic Behavior"
|
||||
'()
|
||||
'(("text" . "from partial"))
|
||||
"\"{{>text}}\""
|
||||
"\"from partial\"")
|
||||
|
||||
(test-mustache "Failed Lookup"
|
||||
'()
|
||||
'()
|
||||
"\"{{>text}}\""
|
||||
"\"\"")
|
||||
|
||||
(test-mustache "Context"
|
||||
'((text . "content"))
|
||||
'(("partial" . "*{{text}}*"))
|
||||
"\"{{>partial}}\""
|
||||
"\"*content*\"")
|
||||
|
||||
(test-mustache "Recursion"
|
||||
'((content . "X")
|
||||
(nodes . #(((content . "Y")
|
||||
(nodes . #())))))
|
||||
'(("node" . "{{content}}<{{#nodes}}{{>node}}{{/nodes}}>"))
|
||||
"{{>node}}"
|
||||
"X<Y<>>")
|
||||
|
||||
(test-mustache "Surrounding Whitespace"
|
||||
'()
|
||||
'(("partial" . "\t|\t"))
|
||||
"| {{>partial}} |"
|
||||
"| \t|\t |")
|
||||
|
||||
(test-mustache "Inline Indentation"
|
||||
'((data . "|"))
|
||||
'(("partial" . ">\n>"))
|
||||
" {{data}} {{> partial}}\n"
|
||||
" | >\n>\n")
|
||||
|
||||
(test-mustache "Standalone Line Endings"
|
||||
'()
|
||||
'(("partial" . ">"))
|
||||
"|\r\n{{>partial}}\r\n|"
|
||||
"|\r\n>|"))
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
(define (run-tests/sections)
|
||||
(test-mustache "Truthy"
|
||||
'((boolean . #t))
|
||||
"\"{{#boolean}}This should be rendered.{{/boolean}}\""
|
||||
"\"This should be rendered.\"")
|
||||
|
||||
(test-mustache "Falsey"
|
||||
'((boolean . #f))
|
||||
"\"{{#boolean}}This should not be rendered.{{/boolean}}\""
|
||||
"\"\"")
|
||||
|
||||
;; "Null is falsey" test is skipped; no meaningful value for null
|
||||
|
||||
(test-mustache "Context"
|
||||
'((context . ((name . "Joe"))))
|
||||
"\"{{#context}}Hi {{name}}.{{/context}}\""
|
||||
"\"Hi Joe.\"")
|
||||
|
||||
(test-mustache "Parent contexts"
|
||||
'((a . "foo")
|
||||
(b . "wrong")
|
||||
(sec . ((b . "bar")))
|
||||
(c . ((d . "baz"))))
|
||||
"\"{{#sec}}{{a}}, {{b}}, {{c.d}}{{/sec}}\""
|
||||
"\"foo, bar, baz\"")
|
||||
|
||||
(test-mustache "Variable test"
|
||||
'((foo . "bar"))
|
||||
"\"{{#foo}}{{.}} is {{foo}}{{/foo}}\""
|
||||
"\"bar is bar\"")
|
||||
|
||||
(test-mustache "List Contexts"
|
||||
'((tops . #(((tname . ((upper . "A")
|
||||
(lower . "a")))
|
||||
(middles . #(((mname . "1")
|
||||
(bottoms . #(((bname . "x"))
|
||||
((bname . "y")))))))))))
|
||||
"{{#tops}}{{#middles}}{{tname.lower}}{{mname}}.{{#bottoms}}{{tname.upper}}{{mname}}{{bname}}.{{/bottoms}}{{/middles}}{{/tops}}"
|
||||
"a1.A1x.A1y.")
|
||||
|
||||
(test-mustache "Deeply Nested Contexts"
|
||||
'((a . ((one . 1)))
|
||||
(b . ((two . 2)))
|
||||
(c . ((three . 3)
|
||||
(d . ((four . 4)
|
||||
(five . 5))))))
|
||||
"
|
||||
{{#a}}
|
||||
{{one}}
|
||||
{{#b}}
|
||||
{{one}}{{two}}{{one}}
|
||||
{{#c}}
|
||||
{{one}}{{two}}{{three}}{{two}}{{one}}
|
||||
{{#d}}
|
||||
{{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}
|
||||
{{#five}}
|
||||
{{one}}{{two}}{{three}}{{four}}{{five}}{{four}}{{three}}{{two}}{{one}}
|
||||
{{one}}{{two}}{{three}}{{four}}{{.}}6{{.}}{{four}}{{three}}{{two}}{{one}}
|
||||
{{one}}{{two}}{{three}}{{four}}{{five}}{{four}}{{three}}{{two}}{{one}}
|
||||
{{/five}}
|
||||
{{one}}{{two}}{{three}}{{four}}{{three}}{{two}}{{one}}
|
||||
{{/d}}
|
||||
{{one}}{{two}}{{three}}{{two}}{{one}}
|
||||
{{/c}}
|
||||
{{one}}{{two}}{{one}}
|
||||
{{/b}}
|
||||
{{one}}
|
||||
{{/a}}
|
||||
"
|
||||
"
|
||||
1
|
||||
121
|
||||
12321
|
||||
1234321
|
||||
123454321
|
||||
12345654321
|
||||
123454321
|
||||
1234321
|
||||
12321
|
||||
121
|
||||
1
|
||||
"
|
||||
))
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
(define-library
|
||||
(arvyy mustache)
|
||||
(import (scheme base)
|
||||
(scheme case-lambda)
|
||||
(scheme write)
|
||||
(arvyy mustache lookup)
|
||||
(arvyy mustache collection)
|
||||
(prefix (arvyy mustache executor) executor-)
|
||||
(arvyy mustache parser)
|
||||
(arvyy mustache tokenizer)
|
||||
(srfi 1))
|
||||
(export
|
||||
execute
|
||||
compile
|
||||
current-lookup
|
||||
current-collection
|
||||
current-writer
|
||||
|
||||
compose-lookups
|
||||
alist-lookup
|
||||
|
||||
collection
|
||||
compose-collections
|
||||
vector-collection
|
||||
list-collection
|
||||
stream-collection)
|
||||
(include "mustache-impl.scm"))
|
||||
@@ -0,0 +1,64 @@
|
||||
(define-library
|
||||
(arvyy mustache collection)
|
||||
(import (scheme base)
|
||||
(srfi 41))
|
||||
(export
|
||||
collection
|
||||
collection-pred-proc
|
||||
collection-empty?-proc
|
||||
collection-for-each-proc
|
||||
|
||||
compose-collections
|
||||
vector-collection
|
||||
stream-collection
|
||||
list-collection)
|
||||
(begin
|
||||
|
||||
(define-record-type <collection>
|
||||
(collection pred-proc empty?-proc for-each-proc)
|
||||
collection?
|
||||
(pred-proc collection-pred-proc)
|
||||
(empty?-proc collection-empty?-proc)
|
||||
(for-each-proc collection-for-each-proc))
|
||||
|
||||
(define vector-collection
|
||||
(collection vector?
|
||||
(lambda (v) (= 0 (vector-length v)))
|
||||
vector-for-each))
|
||||
|
||||
(define list-collection
|
||||
(collection list?
|
||||
null?
|
||||
for-each))
|
||||
|
||||
(define stream-collection
|
||||
(collection stream?
|
||||
stream-null?
|
||||
stream-for-each))
|
||||
|
||||
(define (compose-collections . collections)
|
||||
(define (find-collection object)
|
||||
(let loop ((collections collections))
|
||||
(cond
|
||||
((null? collections)
|
||||
#f)
|
||||
(((collection-pred-proc (car collections)) object)
|
||||
(car collections))
|
||||
(else (loop (cdr collections))))))
|
||||
|
||||
(collection
|
||||
;; predicate
|
||||
(lambda (object)
|
||||
(cond
|
||||
((find-collection object) #t)
|
||||
(else #f)))
|
||||
;; empty proc
|
||||
(lambda (object)
|
||||
(cond
|
||||
((find-collection object) => (lambda (c) ((collection-empty?-proc c) object)))
|
||||
(else (error "Collection not found"))))
|
||||
;; for-each proc
|
||||
(lambda (proc object)
|
||||
(cond
|
||||
((find-collection object) => (lambda (c) ((collection-for-each-proc c) proc object)))
|
||||
(else (error "Collection not found"))))))))
|
||||
@@ -0,0 +1,94 @@
|
||||
(define (html-escape writer value)
|
||||
(define str-value
|
||||
(let ((out (open-output-string)))
|
||||
(writer value out)
|
||||
(get-output-string out)))
|
||||
(define out (open-output-string))
|
||||
(string-for-each
|
||||
(lambda (char)
|
||||
(case char
|
||||
((#\&) (write-string "&" out))
|
||||
((#\<) (write-string "<" out))
|
||||
((#\>) (write-string ">" out))
|
||||
((#\") (write-string """ out))
|
||||
(else (write-char char out))))
|
||||
str-value)
|
||||
(get-output-string out))
|
||||
|
||||
(define (lookup-in-stack-single name objs-stack lookup)
|
||||
(let loop ((objs objs-stack))
|
||||
(if (null? objs)
|
||||
(values objs #f)
|
||||
(lookup (car objs)
|
||||
name
|
||||
(lambda (value) (values objs value))
|
||||
(lambda () (loop (cdr objs)))))))
|
||||
|
||||
(define (lookup-in-stack name-lst objs-stack lookup)
|
||||
(define-values (objs value)
|
||||
(lookup-in-stack-single (car name-lst) objs-stack lookup))
|
||||
(cond
|
||||
((not value) #f)
|
||||
((null? (cdr name-lst)) value)
|
||||
(else (lookup-in-stack (cdr name-lst)
|
||||
(list value)
|
||||
lookup))))
|
||||
|
||||
(define (execute template objs-stack partials out lookup collection? collection-empty? collection-for-each writer)
|
||||
(define (execute-h template indent objs-stack)
|
||||
(for-each
|
||||
(lambda (fragment)
|
||||
(cond
|
||||
((string? fragment)
|
||||
(write-string fragment out))
|
||||
((new-line? fragment)
|
||||
(begin
|
||||
(write-string (new-line-content fragment) out)
|
||||
(write-string (make-string indent #\space) out)))
|
||||
((interp? fragment)
|
||||
(let* ((name (interp-ref fragment))
|
||||
(value (if (equal? '(".") name)
|
||||
(car objs-stack)
|
||||
(lookup-in-stack name
|
||||
objs-stack
|
||||
lookup))))
|
||||
(if (interp-escape? fragment)
|
||||
(write-string (html-escape writer value) out)
|
||||
(writer value out))))
|
||||
|
||||
((section? fragment)
|
||||
(let ((value (lookup-in-stack (section-ref fragment)
|
||||
objs-stack
|
||||
lookup))
|
||||
(inner-template (section-content fragment)))
|
||||
|
||||
(cond
|
||||
((not value)
|
||||
(when (section-invert? fragment)
|
||||
(execute-h inner-template indent objs-stack)))
|
||||
((not (collection? value))
|
||||
(unless (section-invert? fragment)
|
||||
(execute-h inner-template indent (cons value objs-stack))))
|
||||
(else
|
||||
(if (section-invert? fragment)
|
||||
(when (collection-empty? value)
|
||||
(execute-h inner-template indent objs-stack))
|
||||
(collection-for-each
|
||||
(lambda (el)
|
||||
(execute-h inner-template indent (cons el objs-stack)))
|
||||
value))))))
|
||||
|
||||
((partial? fragment)
|
||||
(let ()
|
||||
(define partial-tpl
|
||||
(cond
|
||||
((assoc (partial-name fragment) partials) => cdr)
|
||||
(else #f)))
|
||||
(when partial-tpl
|
||||
(execute-h partial-tpl
|
||||
(+ indent (partial-indent fragment))
|
||||
objs-stack) )))
|
||||
|
||||
(else (error "Unknown fragment"))))
|
||||
template))
|
||||
(execute-h template 0 objs-stack))
|
||||
@@ -0,0 +1,6 @@
|
||||
(define-library
|
||||
(arvyy mustache executor)
|
||||
(import (scheme base)
|
||||
(arvyy mustache parser))
|
||||
(export execute)
|
||||
(include "executor-impl.scm"))
|
||||
@@ -0,0 +1,27 @@
|
||||
(define-library
|
||||
(arvyy mustache lookup)
|
||||
(import (scheme base))
|
||||
(export
|
||||
compose-lookups
|
||||
alist-lookup)
|
||||
(begin
|
||||
|
||||
(define (compose-lookups . lookups)
|
||||
(lambda (obj name found not-found)
|
||||
(let loop ((lookups lookups))
|
||||
(if (null? lookups)
|
||||
(not-found)
|
||||
(let ((l (car lookups)))
|
||||
(l obj name found (lambda ()
|
||||
(loop (cdr lookups)))))))))
|
||||
|
||||
(define (alist-lookup obj name found not-found)
|
||||
(define key (string->symbol name))
|
||||
(define alist? (and (list? obj)
|
||||
(or (null? obj)
|
||||
(pair? (car obj)))))
|
||||
(if alist?
|
||||
(cond
|
||||
((assoc key obj) => (lambda (pair) (found (cdr pair))))
|
||||
(else (not-found)))
|
||||
(not-found)))))
|
||||
@@ -0,0 +1,296 @@
|
||||
(define-record-type <interp>
|
||||
(interp ref escape?)
|
||||
interp?
|
||||
(ref interp-ref)
|
||||
(escape? interp-escape?) ;; should html be escaped
|
||||
)
|
||||
|
||||
(define-record-type <section>
|
||||
(section ref invert? content raw-content)
|
||||
section?
|
||||
(ref section-ref)
|
||||
(invert? section-invert?) ;; normal section if false, {{^ section if true
|
||||
(content section-content) ;; compiled inner content
|
||||
(raw-content section-raw-content) ;; uncompiled inner content as a string; used for lambdas
|
||||
)
|
||||
|
||||
(define-record-type <partial>
|
||||
(partial name indent)
|
||||
partial?
|
||||
(name partial-name)
|
||||
(indent partial-indent))
|
||||
|
||||
(define-record-type <newline>
|
||||
(new-line content)
|
||||
new-line?
|
||||
(content new-line-content))
|
||||
|
||||
(define (parse tokens)
|
||||
(let* ((tokens (replace-standalone tokens))
|
||||
(tokens (remove-non-visible tokens))
|
||||
(tokens (convert-string-tokens tokens))
|
||||
(tokens (parse-interp+sections tokens)))
|
||||
tokens))
|
||||
|
||||
(define (tpl->string tokens)
|
||||
(define (->string item out)
|
||||
(cond
|
||||
((string? item) (write-string item out))
|
||||
((new-line? item) (write-string (new-line-content item) out))
|
||||
((section? item)
|
||||
(let ((tagname (list->tagname (section-ref item))))
|
||||
(write-string (if (section-invert? item) "{{^" "{{#") out)
|
||||
(write-string tagname out)
|
||||
(write-string "}}" out)
|
||||
(for-each
|
||||
(lambda (item*)
|
||||
(->string item* out))
|
||||
(section-content item))
|
||||
(write-string "{{/" out)
|
||||
(write-string tagname out)
|
||||
(write-string "}}" out)))
|
||||
((interp? item)
|
||||
(let ((tagname (list->tagname (interp-ref item))))
|
||||
(write-string (if (interp-escape? item) "{{" "{{&") out)
|
||||
(write-string tagname out)
|
||||
(write-string "}}" out)))))
|
||||
(define out (open-output-string))
|
||||
(for-each
|
||||
(lambda (item) (->string item out))
|
||||
tokens)
|
||||
(get-output-string out))
|
||||
|
||||
;;TODO remove this
|
||||
(define (debug-tokens tokens)
|
||||
(for-each
|
||||
(lambda (t)
|
||||
(cond
|
||||
((token-str? t) (display (string-append "#<<token-str> " (token-str-content t) "> ")))
|
||||
((token-nl? t) (display "#<<token-nl>> "))
|
||||
((token-section-open? t) (display (string-append "#<<token-open> " (token-section-open-tag t) "> ")))
|
||||
((token-section-close? t) (display "#<<token-close>> "))
|
||||
((token-ws? t) (display (string-append "#<<token-ws> " (number->string (token-ws-count t)) "> ")))
|
||||
((token-interp? t) (display (string-append "#<<token-interp> " (token-interp-tag t) "> ")))
|
||||
(else (display t))))
|
||||
tokens
|
||||
)
|
||||
|
||||
)
|
||||
|
||||
(define (standalone/remove? token)
|
||||
(or (token-comment? token)
|
||||
(token-delimchager? token)))
|
||||
|
||||
(define (standalone/trim? token)
|
||||
(or (token-section-open? token)
|
||||
(token-section-close? token)))
|
||||
|
||||
(define (replace-standalone tokens)
|
||||
(let loop ((tokens tokens)
|
||||
(result/inv '())
|
||||
(first #t))
|
||||
|
||||
(cond
|
||||
((null? tokens) (reverse result/inv))
|
||||
|
||||
((and first
|
||||
(or (match-follows tokens standalone/remove? token-ws? token-nl?)
|
||||
(match-follows tokens standalone/remove? token-nl?)
|
||||
(match-follows tokens token-ws? standalone/remove? token-ws? token-nl?)
|
||||
(match-follows tokens token-ws? standalone/remove? token-nl?))) =>
|
||||
(lambda (tokens*)
|
||||
(loop tokens*
|
||||
result/inv
|
||||
#t)))
|
||||
|
||||
((and first
|
||||
(or (match-follows tokens token-ws? standalone/remove? token-ws? eof-object?)
|
||||
(match-follows tokens token-ws? standalone/remove? eof-object?)
|
||||
(match-follows tokens standalone/remove? token-ws? eof-object?)
|
||||
(match-follows tokens standalone/remove? eof-object?))) =>
|
||||
(lambda (tokens*)
|
||||
(loop '()
|
||||
result/inv
|
||||
#t)))
|
||||
|
||||
((and first
|
||||
(or (match-follows tokens token-ws? standalone/trim? token-ws? token-nl?)
|
||||
(match-follows tokens token-ws? standalone/trim? token-nl?)
|
||||
(match-follows tokens token-ws? standalone/trim? token-ws? eof-object?)
|
||||
(match-follows tokens token-ws? standalone/trim? eof-object?))) =>
|
||||
(lambda (tokens*)
|
||||
(loop tokens*
|
||||
(append (list (cadr tokens))
|
||||
result/inv)
|
||||
#t)))
|
||||
|
||||
((and first
|
||||
(or (match-follows tokens standalone/trim? token-ws? token-nl?)
|
||||
(match-follows tokens standalone/trim? token-nl?)
|
||||
(match-follows tokens standalone/trim? token-ws? eof-object?)
|
||||
(match-follows tokens standalone/trim? eof-object?))) =>
|
||||
(lambda (tokens*)
|
||||
(loop tokens*
|
||||
(append (list (car tokens))
|
||||
result/inv)
|
||||
#t)))
|
||||
|
||||
((and first
|
||||
(or (match-follows tokens token-ws? token-partial? token-ws? token-nl?)
|
||||
(match-follows tokens token-ws? token-partial? token-nl?)
|
||||
(match-follows tokens token-ws? token-partial? token-ws? eof-object?)
|
||||
(match-follows tokens token-ws? token-partial? eof-object?))) =>
|
||||
(lambda (tokens*)
|
||||
(loop tokens*
|
||||
(append (list (partial (token-partial-tag (cadr tokens))
|
||||
(token-ws-count (car tokens))))
|
||||
result/inv)
|
||||
#t)))
|
||||
|
||||
((and first
|
||||
(or (match-follows tokens token-partial? token-ws? token-nl?)
|
||||
(match-follows tokens token-partial? token-nl?)
|
||||
(match-follows tokens token-partial? token-ws? eof-object?)
|
||||
(match-follows tokens token-partial? eof-object?))) =>
|
||||
(lambda (tokens*)
|
||||
(loop tokens*
|
||||
(append (list (partial (token-partial-tag (car tokens))
|
||||
0))
|
||||
result/inv)
|
||||
#t)))
|
||||
|
||||
((match-follows tokens token-partial?) => (lambda (tokens*)
|
||||
(loop tokens*
|
||||
(cons (partial (token-partial-tag (car tokens))
|
||||
0)
|
||||
result/inv)
|
||||
#f)))
|
||||
|
||||
(else (loop (cdr tokens)
|
||||
(cons (car tokens) result/inv)
|
||||
(token-nl? (car tokens)))))))
|
||||
|
||||
(define (convert-string-tokens tokens)
|
||||
(let loop ((tokens tokens)
|
||||
(out #f)
|
||||
(result/inv '()))
|
||||
(cond
|
||||
((null? tokens)
|
||||
(let ((result-final/inv (if out
|
||||
(cons (get-output-string out)
|
||||
result/inv)
|
||||
result/inv)))
|
||||
(reverse result-final/inv)))
|
||||
((or (token-str? (car tokens))
|
||||
(token-ws? (car tokens)))
|
||||
(let* ((token (car tokens))
|
||||
(out* (if out
|
||||
out
|
||||
(open-output-string)))
|
||||
(str (if (token-str? token)
|
||||
(token-str-content token)
|
||||
(make-string (token-ws-count token) #\space))))
|
||||
(write-string str out*)
|
||||
(loop (cdr tokens)
|
||||
out*
|
||||
result/inv)))
|
||||
(else (let* ((token (car tokens))
|
||||
(value (cond
|
||||
((token-nl? token) (new-line (list->string (token-nl-chars token))))
|
||||
(else token)))
|
||||
(new-result/inv (if out
|
||||
(cons (get-output-string out)
|
||||
result/inv)
|
||||
result/inv)))
|
||||
(loop (cdr tokens)
|
||||
#f
|
||||
(cons value new-result/inv)))))))
|
||||
|
||||
(define (parse-interp+sections tokens)
|
||||
(define (parse-interp+sections* tokens expected-close-tag)
|
||||
(let loop ((tokens tokens)
|
||||
(result/inv '()))
|
||||
(cond
|
||||
((null? tokens)
|
||||
(if expected-close-tag
|
||||
(error "Unexpected eof")
|
||||
(values '() (reverse result/inv))))
|
||||
((token-section-close? (car tokens))
|
||||
(if (equal? expected-close-tag (token-section-close-tag (car tokens)))
|
||||
(values (cdr tokens) (reverse result/inv))
|
||||
(error "Closing token mismatch")))
|
||||
((token-section-open? (car tokens))
|
||||
(let* ((token (car tokens))
|
||||
(tag (token-section-open-tag token))
|
||||
(ref (tagname->list tag)))
|
||||
(define-values (tokens* result*)
|
||||
(parse-interp+sections* (cdr tokens)
|
||||
tag))
|
||||
(define value (section ref
|
||||
(token-section-open-inverted? token)
|
||||
result*
|
||||
#f))
|
||||
(loop tokens*
|
||||
(cons value result/inv))))
|
||||
((token-interp? (car tokens))
|
||||
(let* ((token (car tokens))
|
||||
(tag (token-interp-tag token))
|
||||
(ref (tagname->list tag)))
|
||||
(define value (interp ref (token-interp-escape? token)))
|
||||
(loop (cdr tokens)
|
||||
(cons value result/inv))))
|
||||
(else (loop (cdr tokens)
|
||||
(cons (car tokens)
|
||||
result/inv))))))
|
||||
(define-values (tokens* result)
|
||||
(parse-interp+sections* tokens #f))
|
||||
result)
|
||||
|
||||
(define (remove-non-visible tokens)
|
||||
(filter
|
||||
(lambda (token)
|
||||
(not (or (token-comment? token)
|
||||
(token-delimchager? token))))
|
||||
tokens))
|
||||
|
||||
(define (match-follows in . preds)
|
||||
(let loop ((in* in)
|
||||
(preds* preds))
|
||||
(cond
|
||||
((null? preds*) in*)
|
||||
((null? in*) (and (null? (cdr preds*))
|
||||
(eq? (car preds*) eof-object?)
|
||||
'()))
|
||||
(((car preds*) (car in*))
|
||||
(loop (cdr in*)
|
||||
(cdr preds*)))
|
||||
(else #f))))
|
||||
|
||||
(define (tagname->list str)
|
||||
(define (prepend-part parts part)
|
||||
(when (null? part)
|
||||
(error "Trailing period in tag name"))
|
||||
(cons (list->string (reverse part))
|
||||
parts))
|
||||
(if (equal? "." str)
|
||||
'(".")
|
||||
(let loop ((in (string->list str))
|
||||
(parts '())
|
||||
(part '()))
|
||||
(cond
|
||||
((null? in)
|
||||
(reverse (prepend-part parts part)))
|
||||
((char=? #\. (car in))
|
||||
(loop (cdr in)
|
||||
(prepend-part parts part)
|
||||
'()))
|
||||
(else (loop (cdr in)
|
||||
parts
|
||||
(cons (car in) part)))))))
|
||||
|
||||
(define (list->tagname lst)
|
||||
(apply string-append
|
||||
(cdr (apply append
|
||||
(map
|
||||
(lambda (el) (list "." el))
|
||||
lst)))))
|
||||
@@ -0,0 +1,14 @@
|
||||
(define-library
|
||||
(arvyy mustache parser)
|
||||
(import (scheme base)
|
||||
(scheme write)
|
||||
(scheme cxr)
|
||||
(arvyy mustache tokenizer)
|
||||
(srfi 1))
|
||||
(export
|
||||
parse
|
||||
interp? interp-ref interp-escape?
|
||||
section? section-ref section-invert? section-content section-raw-content
|
||||
partial? partial-name partial-indent
|
||||
new-line? new-line-content)
|
||||
(include "parser-impl.scm"))
|
||||
@@ -0,0 +1,237 @@
|
||||
(define-record-type <token-ws>
|
||||
(token-ws count)
|
||||
token-ws?
|
||||
(count token-ws-count))
|
||||
|
||||
(define-record-type <token-nl>
|
||||
(token-nl chars)
|
||||
token-nl?
|
||||
(chars token-nl-chars))
|
||||
|
||||
(define-record-type <token-comment>
|
||||
(token-comment)
|
||||
token-comment?)
|
||||
|
||||
(define-record-type <token-str>
|
||||
(token-str content)
|
||||
token-str?
|
||||
(content token-str-content))
|
||||
|
||||
(define-record-type <token-delimchanger>
|
||||
(token-delimchager open close)
|
||||
token-delimchager?
|
||||
(open token-delimchager-open)
|
||||
(close token-delimchager-close))
|
||||
|
||||
(define-record-type <token-interp>
|
||||
(token-interp tag escape?)
|
||||
token-interp?
|
||||
(tag token-interp-tag)
|
||||
(escape? token-interp-escape?))
|
||||
|
||||
(define-record-type <token-section-open>
|
||||
(token-section-open tag inverted?)
|
||||
token-section-open?
|
||||
(tag token-section-open-tag)
|
||||
(inverted? token-section-open-inverted?))
|
||||
|
||||
(define-record-type <token-section-close>
|
||||
(token-section-close tag)
|
||||
token-section-close?
|
||||
(tag token-section-close-tag))
|
||||
|
||||
(define-record-type <token-partial>
|
||||
(token-partial tag)
|
||||
token-partial?
|
||||
(tag token-partial-tag))
|
||||
|
||||
(define (read-tokens str)
|
||||
(let loop ((in (string->list str))
|
||||
(ws-count 0)
|
||||
(str-value '())
|
||||
(open-delim '(#\{ #\{))
|
||||
(close-delim '(#\} #\}))
|
||||
(result/inv '()))
|
||||
|
||||
(define (resolve-ws/str)
|
||||
(cond
|
||||
;; unflushed ws and str info
|
||||
((and (not (null? str-value))
|
||||
(> ws-count 0))
|
||||
(append (list (token-ws ws-count)
|
||||
(token-str (list->string (reverse str-value))))
|
||||
result/inv))
|
||||
|
||||
;; unflushed str info
|
||||
((not (null? str-value))
|
||||
(cons (token-str (list->string (reverse str-value)))
|
||||
result/inv))
|
||||
|
||||
;; unflushed ws info
|
||||
((> ws-count 0)
|
||||
(cons (token-ws ws-count)
|
||||
result/inv))
|
||||
|
||||
;; no unflushed info
|
||||
(else result/inv)))
|
||||
|
||||
;; handle when in is null; ie final function return
|
||||
(define (return)
|
||||
(define final-result/inv (resolve-ws/str))
|
||||
(reverse final-result/inv))
|
||||
|
||||
;; handle after tag read
|
||||
(define (continue-after-tag in token)
|
||||
(loop
|
||||
in
|
||||
0
|
||||
'()
|
||||
open-delim
|
||||
close-delim
|
||||
(cons token (resolve-ws/str))))
|
||||
|
||||
(define (process-interp in)
|
||||
(define-values (in* tag)
|
||||
(read-tag in close-delim))
|
||||
(continue-after-tag in* (token-interp tag #t)))
|
||||
|
||||
(define (process-triple-mustache in)
|
||||
(define-values (in* tag)
|
||||
(read-tag in '(#\} #\} #\})))
|
||||
(continue-after-tag in* (token-interp tag #f)))
|
||||
|
||||
(define (process-ampersand in)
|
||||
(define-values (in* tag)
|
||||
(read-tag in close-delim))
|
||||
(continue-after-tag in* (token-interp tag #f)))
|
||||
|
||||
(define (process-inverted in)
|
||||
(define-values (in* tag)
|
||||
(read-tag in close-delim))
|
||||
(continue-after-tag in* (token-section-open tag #t)))
|
||||
|
||||
(define (process-section in)
|
||||
(define-values (in* tag)
|
||||
(read-tag in close-delim))
|
||||
(continue-after-tag in* (token-section-open tag #f)))
|
||||
|
||||
(define (process-close in)
|
||||
(define-values (in* tag)
|
||||
(read-tag in close-delim))
|
||||
(continue-after-tag in* (token-section-close tag)))
|
||||
|
||||
(define (process-partial in)
|
||||
(define-values (in* tag)
|
||||
(read-tag in close-delim))
|
||||
(continue-after-tag in* (token-partial tag)))
|
||||
|
||||
(define (process-comment in)
|
||||
(let loop* ((in in))
|
||||
(cond
|
||||
((null? in) (error "Unexpected EOF"))
|
||||
((match-follows in close-delim) => (lambda (in*)
|
||||
(continue-after-tag in* (token-comment))))
|
||||
(else (loop* (cdr in))))))
|
||||
|
||||
(define (process-delim-change in)
|
||||
(let*-values (((in new-open) (read-tag in #f))
|
||||
((in new-close) (read-tag in (cons #\= close-delim))))
|
||||
(loop in
|
||||
0
|
||||
'()
|
||||
(string->list new-open)
|
||||
(string->list new-close)
|
||||
(cons (token-delimchager new-open new-close)
|
||||
(resolve-ws/str)))))
|
||||
|
||||
(define (process-open-delim in*)
|
||||
(cond
|
||||
((match-follows in* '(#\&)) => process-ampersand)
|
||||
((match-follows in* '(#\^)) => process-inverted)
|
||||
((match-follows in* '(#\#)) => process-section)
|
||||
((match-follows in* '(#\/)) => process-close)
|
||||
((match-follows in* '(#\>)) => process-partial)
|
||||
((match-follows in* '(#\=)) => process-delim-change)
|
||||
((match-follows in* '(#\!)) => process-comment)
|
||||
(else (process-interp in*))))
|
||||
|
||||
(define (process-space in*)
|
||||
(loop in*
|
||||
(+ 1 ws-count)
|
||||
str-value
|
||||
open-delim
|
||||
close-delim
|
||||
result/inv))
|
||||
|
||||
(define (process-eol in* chars)
|
||||
(loop in*
|
||||
0
|
||||
'()
|
||||
open-delim
|
||||
close-delim
|
||||
(cons (token-nl chars)
|
||||
(resolve-ws/str))))
|
||||
|
||||
(define (process-nl in*)
|
||||
(process-eol in* '(#\newline)))
|
||||
|
||||
(define (process-crnl in*)
|
||||
(process-eol in* '(#\return #\newline)))
|
||||
|
||||
(define (process-char)
|
||||
(loop (cdr in)
|
||||
0
|
||||
(append (list (car in))
|
||||
(make-list ws-count #\space)
|
||||
str-value)
|
||||
open-delim
|
||||
close-delim
|
||||
result/inv))
|
||||
|
||||
;; loop handler
|
||||
(cond
|
||||
((null? in) (return))
|
||||
((match-follows in '(#\{ #\{ #\{)) => process-triple-mustache)
|
||||
((match-follows in open-delim) => process-open-delim)
|
||||
((match-follows in '(#\space)) => process-space)
|
||||
((match-follows in '(#\newline)) => process-nl)
|
||||
((match-follows in '(#\return #\newline)) => process-crnl)
|
||||
(else (process-char)))))
|
||||
|
||||
(define (match-follows in chars)
|
||||
(let loop ((in* in)
|
||||
(chars* chars))
|
||||
(cond
|
||||
((null? chars*) in*)
|
||||
((null? in*) #f)
|
||||
((char=? (car in*) (car chars*))
|
||||
(loop (cdr in*)
|
||||
(cdr chars*)))
|
||||
(else #f))))
|
||||
|
||||
(define (skip-spaces in)
|
||||
(cond
|
||||
((null? in) '())
|
||||
((char=? (car in) #\space) (skip-spaces (cdr in)))
|
||||
(else in)))
|
||||
|
||||
(define (read-tag in close-delim)
|
||||
(define-values
|
||||
(tag in*)
|
||||
(let loop ((in (skip-spaces in))
|
||||
(result '()))
|
||||
(define (return)
|
||||
(values (list->string (reverse result))
|
||||
in))
|
||||
(cond
|
||||
((null? in) (error "Unexpected EOF"))
|
||||
((char=? (car in) #\space) (return))
|
||||
((and close-delim (match-follows in close-delim))
|
||||
(return))
|
||||
(else (loop (cdr in)
|
||||
(cons (car in) result))))))
|
||||
(cond
|
||||
((not close-delim) (values in* tag))
|
||||
((match-follows (skip-spaces in*) close-delim) => (lambda (in**)
|
||||
(values in** tag)))
|
||||
(else (error "Bad tag"))))
|
||||
@@ -0,0 +1,15 @@
|
||||
(define-library
|
||||
(arvyy mustache tokenizer)
|
||||
(import (scheme base))
|
||||
(export
|
||||
read-tokens
|
||||
token-ws? token-ws-count
|
||||
token-nl token-nl? token-nl-chars
|
||||
token-comment?
|
||||
token-str? token-str-content
|
||||
token-delimchager? token-delimchager-open token-delimchager-close
|
||||
token-interp? token-interp-tag token-interp-escape?
|
||||
token-section-open? token-section-open-tag token-section-open-inverted?
|
||||
token-section-close? token-section-close-tag
|
||||
token-partial? token-partial-tag)
|
||||
(include "tokenizer-impl.scm"))
|
||||
Vendored
+34
@@ -0,0 +1,34 @@
|
||||
pipeline {
|
||||
agent {
|
||||
dockerfile {
|
||||
filename 'dockerfiles/jenkins'
|
||||
dir '.'
|
||||
args '--privileged -v /var/run/docker.sock:/var/run/docker.sock'
|
||||
}
|
||||
}
|
||||
|
||||
options {
|
||||
buildDiscarder(logRotator(numToKeepStr: '10', artifactNumToKeepStr: '10'))
|
||||
}
|
||||
|
||||
stages {
|
||||
{{#script-implementations}}
|
||||
stage('{{.}}') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make SCHEME={{.}} test-script-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
{{/script-implementations}}
|
||||
{{#compiler-implementations}}
|
||||
stage('{{.}}') {
|
||||
steps {
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh 'make SCHEME={{.}} test-compile-docker'
|
||||
}
|
||||
}
|
||||
}
|
||||
{{/compiler-implementations}}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user