diff --git a/mkdocs.yml b/mkdocs.yml index 8882d6daa..ef316730f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -3,6 +3,7 @@ site_name: Documentation site_description: Next-generation SIP Server site_author: Pedro Sanders site_url: https://routr.io/docs +google_analytics: ['UA-71722942-3', 'routr.io'] # Repository repo_name: fonoster/routr diff --git a/site/404.html b/site/404.html new file mode 100644 index 000000000..7b3860ded --- /dev/null +++ b/site/404.html @@ -0,0 +1,953 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ +

404 - Not found

+ + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/administration/cli/index.html b/site/administration/cli/index.html new file mode 100644 index 000000000..6f786715d --- /dev/null +++ b/site/administration/cli/index.html @@ -0,0 +1,1381 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Command-Line - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Command-Line

+ +

rctl is a command line interface for running commands against a Routr server. This overview covers rctl syntax, describes the command operations and provides common examples. For details about each command, including all the supported flags and subcommands, see the rctl reference documentation. This tool is part of Routr installation.

+

Syntax

+

Use the following syntax to run rctl commands from your terminal window:

+
rctl COMMAND [REF] [flags]
+
+ +

where COMMAND, subcommand REF, and flags are:

+
    +
  • +

    COMMAND: Specifies the operation that you want to perform on one or more resources. For example: create, get, delete, locate(loc).

    +
  • +
  • +

    subcommand: Specifies the resource type. Resource types are case-sensitive and you can specify the singular, plural, or abbreviated forms. For example, the following commands produce the same output:

    +
  • +
+
  $ rctl get gateway gweef506
+  $ rctl get gateways gweef506
+  $ rctl get gw gweef506
+
+ +
    +
  • +

    REF: Specifies the reference to the resource. References are case-sensitive. If the reference is omitted, details for all resources are displayed. For example: $ rctl get agents.

    +
  • +
  • +

    flags: Specifies optional flags. For example, you can use the --filter to further reduce the output of get command.

    +
  • +
+

The --filter flag uses JsonPath to perform the filtering. The root is always '$' +so all you need to add is the path to the property and the filter operators. For example:

+
# This will return all the DIDs in Gateway 'gweef506'
+./rctl get dids --filter "@.metadata.gwRef=='gweef506'"    
+
+ +

If you need help, just run rctl --help from the terminal window.

+
$ ./rctl -h
+usage: rctl [-h] COMMAND ...
+
+rctl controls the Routr server
+
+named arguments:
+  -h, --help             show this help message and exit
+
+Basic Commands:
+  COMMAND
+    get                  display a list of resources
+    create (crea)        creates new resource(s)
+    apply                apply changes over existing resource(s)
+    delete (del)         delete an existing resource(s)
+    locate (loc)         locate sip device(s)
+    registry (reg)       shows gateways registrations
+    system (sys)         display a list of resources
+    login                sets connection info
+
+More information at https://github.com/fonoster/routr/wiki
+
+ +
+

Important: Some commands (ie.: create, delete) are not available in the default implementation of the resources modules. Only persistent implementations will allow such command.

+
+

Examples: Common operations

+

Use the following set of examples to help you familiarize yourself with running the commonly used rctl operations:

+

rctl locate or rctl loc - Locate a sip device registered on the Routr server

+
// Locate all Sip Devices registered against a Routr server
+$ rctl loc
+
+ +

rctl registry or rctl reg - Shows Gateways current registration

+
// Shows the registry
+$ rctl reg
+
+ +

rctl get - List one or more resources.

+
// List all dids
+$ rctl get dids
+
+// List all dids that belong to gateway reference gweef506
+$ rctl get dids --filter "@.metadata.ref=='gweef506'"
+
+// List did by reference
+$ rctl get dids dd50baa4
+
+// List all agents
+$ rctl get agents
+
+ +

rctl create - create a new resource.

+
// Create a new gateway(s) using a .yaml or .yml file
+$ rctl create -f new-gateway.yaml
+
+ +

rctl apply - update an existing resource(s)

+
// Update an existing resource(s) .yaml or .yml.
+$ rctl apply -f new-gateway.yaml
+
+ +

rctl delete - delete a resource.

+
// Delete all did for gateway reference gweef506
+$ rctl delete dids --filter "@.metadata.gwRef=='gweef506'"
+
+// Delete a single agent (using delete alias)
+$ rctl del agent ag3f77f6
+
+ +

Cheat Sheet

+
+

Create, delete, and update are only available in some implementations of the resources module.

+
+

Request and store token

+
# Request authentication for subsecuent commands
+$ rctl login https://127.0.0.1/api/{apiVersion} -u admin -p changeit
+
+ +

Showing the Registry

+
# Shows all the Gateways that are currently available
+$ rctl registry                                       # Shows only current registrations. You may use `reg` for short
+
+ +

Locating Sip Devices

+
# Find all sip devices available at the location service
+$ rctl locate                                         # This list will not include did-ingress-routes or domain-egress-routes
+
+ +

Creating Resources

+
# Create new peers and agents
+$ rctl create -f asterisk.yaml                        # Create Peer in file asterisk.yaml
+$ rctl create -f agents-list.yaml                     # Create Agents in file agents-list.yaml
+
+ +

Finding Resources

+
# Get DIDs
+$ rctl get dids                                          # List all available DIDs
+$ rctl get did                                           # List all available DIDs
+$ rctl get did --filter "@.metadata.ref=='dd50baa4'"     # Shows DID with reference 'DID0001'
+$ rctl get did --filter "@.metadata.gwRef=='gweef506'"   # Shows DIDs with Gateway reference 'GW1232'
+
+# Get agents
+$ rctl get agents                                        # List all Agents
+
+ +

Deleting Resources

+
# Delete command by refernce or filter
+$ rctl delete agent ag3f77f6                             # Delete Agent by reference
+$ rctl del dids --filter '@.metadata.gwRef=gweef506'     # Delete DIDs using a filter
+
+ +

Updating Resources

+
$ rctl -- apply -f asterisk.yaml                         # Create Peer in file asterisk.yaml
+$ rctl -- apply -f agents-list.yaml                      # Create Agents in file agents-list.yaml
+
+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/administration/webconsole/index.html b/site/administration/webconsole/index.html new file mode 100644 index 000000000..614c1c4ed --- /dev/null +++ b/site/administration/webconsole/index.html @@ -0,0 +1,1022 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Web Console - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Web Console

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/api/reference/index.html b/site/api/reference/index.html new file mode 100644 index 000000000..6d16bd888 --- /dev/null +++ b/site/api/reference/index.html @@ -0,0 +1,1022 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Reference - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Reference

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/api/resources/index.html b/site/api/resources/index.html new file mode 100644 index 000000000..fb0acab86 --- /dev/null +++ b/site/api/resources/index.html @@ -0,0 +1,1859 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Resources - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Resources

+ +

Routr API version is currently v1beta1. We will continue to improve the API, resource definition, and other artifacts until we reach a final version. We then will establish an update policy to ensure backward compatibility. Until then keep an eye on this document.

+

General Configuration

+
+

This file can be found at 'config/config.yaml' in the root of this project.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyDescriptionRequired
apiVersionIndicates the version of the resource (Not yet implemented)yes
metadata.userAgentSets sip header User-Agent to the desired valueNo
spec.bindAddrDefault stack IP addressNo
spec.externAddrIP address to advertiseNo
spec.localnetsLocal networks. Use in combination with spec.externAddrNo
spec.recordRouteStay within the signaling pathNo
spec.useToAsAORUse the TO header instead of Request URINo
spec.registrarIntfForce to use received & rport for registrationNo
spec.addressInfo.[*]Custom tag with the DID informationNo
spec.accessControlList.deny.[*]Deny incoming traffic from network listNo
spec.accessControlList.allow.[*]Allow incoming traffic from network listNo
spec.restService.bindAddrRestful service listening addressNo
spec.restService.portRestful service port. Defaults to 4567No
spec.restService.unsecuredDisabled https for restful calls. Default is falseNo
spec.restService.keyStorePath to keyStoreNo
spec.restService.trueStorePath to trueStoreNo
spec.restService.keyStorePasswordPassword for keyStoreNo
spec.restService.trueStorePasswordPassword for trueStoreNo
spec.transport.bindAddrOverwrites spec.bindAddr for transport entryNo
spec.transport.portTransport portYes
spec.transport.protocolValid values are: tcp, udp, tls, sctp, ws, wssYes
spec.securityContext.keyStorePath to keyStoreYes
spec.securityContext.trustStorePath to trueStoreYes
spec.securityContext.keyStorePasswordPassword for keyStoreYes
spec.securityContext.keyStoreTypeKeyStore typeYes
spec.securityContext.client.authTypeType of client authentication. Default is Disabled. See https://goo.gl/1vKbXW for more optionsNo
spec.securityContext.client.protocols.[*]Accepted tls protocols. Default is [TLSv1.2, TLSv1.1, TLSv1]No
spec.securityContext.debuggingTurns ON or OFF ssl debuging. Default is falseNo
spec.dataSource.providerDefines data provider. Defaults to files_data_providerNo
spec.dataSource.parametersParameters expecifics to data provider implementationNo
spec.logging.traceLevelVerbosity of the sip-stack logging. Default is 0No
+

Example

+
apiVersion: v1beta1
+metadata:
+  userAgent: Routr v1.0
+spec:
+  transport:
+    - protocol: udp
+      port: 5060
+  dataSource:
+    provider: redis_data_provider
+  logging:
+    traceLevel: 10
+
+ +

Data Providers

+

Routr currently implements three data providers: redis_data_provider, files_data_provider and restful_data_provider. The default data provider is the files_data_provider.

+
+

The docker version of the server uses redis_data_provider as its default

+
+

The parameters for redis_data_provider are:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterDescriptionRequired
hostRedis host. Defaults to 'localhost'No
portRedis port. The default port is 6379No
secretPassword to access databaseNo
+

The parameters for files_data_provider are:

+ + + + + + + + + + + + + + + +
ParameterDescriptionRequired
pathPath to configuration files. Defaults to 'config' folderNo
+

This implementation has the limitation that writes operations have to be performed manually on the files.

+

The parameters for restful_data_provider are:

+ + + + + + + + + + + + + + + + + + + + + + + + + +
ParameterDescriptionRequired
baseUrlEndpoint base urlyes
usernameBasic authentication usernameyes
secretBasic authentication passwordyes
+

User Resource

+
+

This file can be found at 'config/users.yaml' in the root of this project.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyDescriptionRequired
apiVersionIndicates the version of the resource (Not yet implemented)Yes
kindDefines the type of resourceYes
metadata.nameFriendly name for the User deviceYes
spec.credentials.usernameUser's credential usernameYes
spec.credentials.secretUser's credential secretYes
+

Example

+
# Users exist in Routr to perform administrative actions on the server
+- apiVersion: v1beta1
+  kind: User
+  metadata:
+    name: Administrator
+  spec:
+    credentials:
+      username: admin
+      secret: changeit
+
+ +

Agent Resource

+
+

This file can be found at 'config/agents.yaml' in the root of this project.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyDescriptionRequired
apiVersionIndicates the version of the resource (Not yet implemented)Yes
kindDefines the type of resourceYes
metadata.nameFriendly name for the SIP deviceYes
spec.credentials.usernameAgent's credential usernameYes
spec.credentials.secretAgent's credential secretYes
spec.domains[*]Context/s in which this Agent is allowed to communicate. FQDN is recommendedYes
+

Example

+
# Peers and Agents can register in Routr location service
+- apiVersion: v1beta1
+  kind: Agent
+  metadata:
+    name: John Doe
+  spec:
+    credentials:
+      username: john
+      secret: '1234'
+    domains: [sip.local]
+
+ +

Domain Resource

+
+

This file can be found at 'config/domains.yaml' in the root of this project.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyDescriptionRequired
apiVersionIndicates the version of the resource (Not yet implemented)Yes
kindDefines the type of resourceYes
metadata.nameFriendly name for the SIP domainYes
spec.context.domainUriDomain URI. FQDN is recomendedYes
spec.context.egressPolicy.ruleRegular expression indicating when a call will be routed via $spec.context.egressPolicy.didRefNo
spec.context.egressPolicy.didRefReference to the DID that will route the callNo
spec.context.accessControlList.allow[*]Traffic allow for Network in listNo
spec.context.accessControlList.deny[*]Traffic disabled for Network in listNo
+
+

Access Control List +Rules may be in CIDR, IP/Mask, or single IP format. Example +of rules are: +- 0.0.0.0/1 # all +- 192.168.1.0/255.255.255.0 +- 192.168.0.1/31

+
+

Example

+
- apiVersion: v1beta1
+  kind: Domain
+  metadata:
+    name: Local Server
+  spec:
+    context:
+      domainUri: sip.local
+      egressPolicy:
+        rule: .*
+        didRef: DID0001
+      accessControlList:
+        deny: [0.0.0.0/1]     # Deny all
+        allow: [192.168.0.1/31]
+
+ +

Gateway Resource

+
+

This file can be found at 'config/gateways.yaml' in the root of this project.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyDescriptionRequired
apiVersionIndicates the version of the resource (Not yet implemented)Yes
kindDefines the type of resourceYes
metadata.nameFriendly name for the SIP deviceYes
metadata.refReference to this resourceYes
spec.credentials.usernameGateway usernameYes
spec.credentials.secretGateway secretYes
spec.hostGateway hostYes
spec.transportTransport protocolYes
spec.registries.[*]Additional registries for ingress callsNo
+

Example

+
# Use gateway to register with a Sip Gateways or SBCs and send
+# or receive calls from the PSTN
+- apiVersion: v1beta1
+  kind: Gateway
+  metadata:
+    name: Provider, Inc
+    ref:  GW0001
+  spec:
+    host: sip.provider.com
+    transport: tcp
+    credentials:
+      username: 'user'
+      secret: changeit
+
+ +

DID Resource

+
+

This file can be found at 'config/dids.yaml' in the root of this project.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyDescriptionRequired
apiVersionIndicates the version of the resource (Not yet implemented)Yes
kindDefines the type of resourceYes
metadata.refReference to this resourceYes
metadata.gwRefReference to parent GatewayYes
metadata.geoInfo.cityCity of the DIDNo
metadata.geoInfo.countryCountry of the DIDNo
metadata.geoInfo.countryISOCodeCountry ISO code for the DID (ie.: US)No
spec.location.telUrlDID URI available in the location serverYes
spec.location.aorLinkAddress of record of SIP device for call routingYes
+

Example

+
- apiVersion: v1beta1
+  kind: DID
+  metadata:
+    ref: DID0001
+    gwRef: GW0001
+    geoInfo:
+      city: Columbus, GA
+      country: USA
+      countryISOCode: US
+  spec:
+    location:
+      telUrl: 'tel:17066041487'
+      aorLink: 'sip:john@sip.local'
+
+ +

Peer Resource

+
+

This file can be found at 'config/peers.yaml' in the root of this project.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyDescriptionRequired
apiVersionIndicates the version of the resource (Not yet implemented)Yes
kindDefines the type of resourceYes
metadata.nameFriendly name for the SIP deviceYes
spec.credentials.usernamePeer's credential usernameYes
spec.credentials.secretPeer's credential secretYes
spec.deviceWhen set it will be used by the location serviceNo
spec.contactAddrWhen set will advertise this as the contactURINo
+

Example

+
# Peers and Agents can register on Routr location service
+- apiVersion: v1beta1
+  kind: Peer
+  metadata:
+    name: Asterisk (Media Server)
+  spec:
+    credentials:
+      username: ast
+      secret: 'astsecret'
+    device: astserver      # If is not define the IP address will be use
+    contactAddr: '192.168.1.2:6060'
+
+ +

This peer can be reached using ast@astserver.

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/assets/fonts/font-awesome.css b/site/assets/fonts/font-awesome.css new file mode 100644 index 000000000..b476b53e3 --- /dev/null +++ b/site/assets/fonts/font-awesome.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url("specimen/FontAwesome.woff2") format("woff2"),url("specimen/FontAwesome.woff") format("woff"),url("specimen/FontAwesome.ttf") format("truetype")}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1,1);-ms-transform:scale(-1,1);transform:scale(-1,1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1,-1);-ms-transform:scale(1,-1);transform:scale(1,-1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} \ No newline at end of file diff --git a/site/assets/fonts/material-icons.css b/site/assets/fonts/material-icons.css new file mode 100644 index 000000000..d23d365ed --- /dev/null +++ b/site/assets/fonts/material-icons.css @@ -0,0 +1,13 @@ +/*! + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE + * DISTRIBUTED UNDER THE LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + * SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING PERMISSIONS AND + * LIMITATIONS UNDER THE LICENSE. + */@font-face{font-family:"Material Icons";font-style:normal;font-weight:400;src:local("Material Icons"),local("MaterialIcons-Regular"),url("specimen/MaterialIcons-Regular.woff2") format("woff2"),url("specimen/MaterialIcons-Regular.woff") format("woff"),url("specimen/MaterialIcons-Regular.ttf") format("truetype")} \ No newline at end of file diff --git a/site/assets/fonts/specimen/FontAwesome.ttf b/site/assets/fonts/specimen/FontAwesome.ttf new file mode 100644 index 000000000..35acda2fa Binary files /dev/null and b/site/assets/fonts/specimen/FontAwesome.ttf differ diff --git a/site/assets/fonts/specimen/FontAwesome.woff b/site/assets/fonts/specimen/FontAwesome.woff new file mode 100644 index 000000000..400014a4b Binary files /dev/null and b/site/assets/fonts/specimen/FontAwesome.woff differ diff --git a/site/assets/fonts/specimen/FontAwesome.woff2 b/site/assets/fonts/specimen/FontAwesome.woff2 new file mode 100644 index 000000000..4d13fc604 Binary files /dev/null and b/site/assets/fonts/specimen/FontAwesome.woff2 differ diff --git a/site/assets/fonts/specimen/MaterialIcons-Regular.ttf b/site/assets/fonts/specimen/MaterialIcons-Regular.ttf new file mode 100644 index 000000000..7015564ad Binary files /dev/null and b/site/assets/fonts/specimen/MaterialIcons-Regular.ttf differ diff --git a/site/assets/fonts/specimen/MaterialIcons-Regular.woff b/site/assets/fonts/specimen/MaterialIcons-Regular.woff new file mode 100644 index 000000000..b648a3eea Binary files /dev/null and b/site/assets/fonts/specimen/MaterialIcons-Regular.woff differ diff --git a/site/assets/fonts/specimen/MaterialIcons-Regular.woff2 b/site/assets/fonts/specimen/MaterialIcons-Regular.woff2 new file mode 100644 index 000000000..9fa211252 Binary files /dev/null and b/site/assets/fonts/specimen/MaterialIcons-Regular.woff2 differ diff --git a/site/assets/images/blinkpro_tls_config.png b/site/assets/images/blinkpro_tls_config.png new file mode 100644 index 000000000..59606d9f1 Binary files /dev/null and b/site/assets/images/blinkpro_tls_config.png differ diff --git a/site/assets/images/blinkpro_tls_secured.png b/site/assets/images/blinkpro_tls_secured.png new file mode 100644 index 000000000..d740ba28c Binary files /dev/null and b/site/assets/images/blinkpro_tls_secured.png differ diff --git a/site/assets/images/docusaurus.svg b/site/assets/images/docusaurus.svg new file mode 100644 index 000000000..f80b2217c --- /dev/null +++ b/site/assets/images/docusaurus.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/site/assets/images/favicon.ico b/site/assets/images/favicon.ico new file mode 100644 index 000000000..2e0ca3953 Binary files /dev/null and b/site/assets/images/favicon.ico differ diff --git a/site/assets/images/favicon.png b/site/assets/images/favicon.png new file mode 100644 index 000000000..23ccc2bac Binary files /dev/null and b/site/assets/images/favicon.png differ diff --git a/site/assets/images/favicon/favicon.ico b/site/assets/images/favicon/favicon.ico new file mode 100644 index 000000000..2e0ca3953 Binary files /dev/null and b/site/assets/images/favicon/favicon.ico differ diff --git a/site/assets/images/get_domains_and_agents.png b/site/assets/images/get_domains_and_agents.png new file mode 100644 index 000000000..bdd1779a1 Binary files /dev/null and b/site/assets/images/get_domains_and_agents.png differ diff --git a/site/assets/images/get_peers_cmd_output.png b/site/assets/images/get_peers_cmd_output.png new file mode 100644 index 000000000..da460b6d7 Binary files /dev/null and b/site/assets/images/get_peers_cmd_output.png differ diff --git a/site/assets/images/icons/bitbucket.1b09e088.svg b/site/assets/images/icons/bitbucket.1b09e088.svg new file mode 100644 index 000000000..a25435af3 --- /dev/null +++ b/site/assets/images/icons/bitbucket.1b09e088.svg @@ -0,0 +1,20 @@ + + + diff --git a/site/assets/images/icons/bitbucket.svg b/site/assets/images/icons/bitbucket.svg new file mode 100644 index 000000000..a25435af3 --- /dev/null +++ b/site/assets/images/icons/bitbucket.svg @@ -0,0 +1,20 @@ + + + diff --git a/site/assets/images/icons/github.f0b8504a.svg b/site/assets/images/icons/github.f0b8504a.svg new file mode 100644 index 000000000..c009420a7 --- /dev/null +++ b/site/assets/images/icons/github.f0b8504a.svg @@ -0,0 +1,18 @@ + + + diff --git a/site/assets/images/icons/github.svg b/site/assets/images/icons/github.svg new file mode 100644 index 000000000..c009420a7 --- /dev/null +++ b/site/assets/images/icons/github.svg @@ -0,0 +1,18 @@ + + + diff --git a/site/assets/images/icons/gitlab.6dd19c00.svg b/site/assets/images/icons/gitlab.6dd19c00.svg new file mode 100644 index 000000000..9e3d6f05b --- /dev/null +++ b/site/assets/images/icons/gitlab.6dd19c00.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/site/assets/images/icons/gitlab.svg b/site/assets/images/icons/gitlab.svg new file mode 100644 index 000000000..9e3d6f05b --- /dev/null +++ b/site/assets/images/icons/gitlab.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/site/assets/images/john_telephone_setup_advanced.png b/site/assets/images/john_telephone_setup_advanced.png new file mode 100644 index 000000000..e7a7ff37a Binary files /dev/null and b/site/assets/images/john_telephone_setup_advanced.png differ diff --git a/site/assets/images/john_telephone_setup_general.png b/site/assets/images/john_telephone_setup_general.png new file mode 100644 index 000000000..2a16fe053 Binary files /dev/null and b/site/assets/images/john_telephone_setup_general.png differ diff --git a/site/assets/images/locate_agents.png b/site/assets/images/locate_agents.png new file mode 100644 index 000000000..8782d4686 Binary files /dev/null and b/site/assets/images/locate_agents.png differ diff --git a/site/assets/images/locate_john.png b/site/assets/images/locate_john.png new file mode 100644 index 000000000..acb4f08d7 Binary files /dev/null and b/site/assets/images/locate_john.png differ diff --git a/site/assets/images/locate_john_and_ast.png b/site/assets/images/locate_john_and_ast.png new file mode 100644 index 000000000..82534b906 Binary files /dev/null and b/site/assets/images/locate_john_and_ast.png differ diff --git a/site/assets/images/logo.png b/site/assets/images/logo.png new file mode 100644 index 000000000..f6bce44e9 Binary files /dev/null and b/site/assets/images/logo.png differ diff --git a/site/assets/images/peering_ilustration.png b/site/assets/images/peering_ilustration.png new file mode 100644 index 000000000..e73ce0086 Binary files /dev/null and b/site/assets/images/peering_ilustration.png differ diff --git a/site/assets/images/routr_animation.gif b/site/assets/images/routr_animation.gif new file mode 100644 index 000000000..55940e8d8 Binary files /dev/null and b/site/assets/images/routr_animation.gif differ diff --git a/site/assets/images/secure_signaling.png b/site/assets/images/secure_signaling.png new file mode 100644 index 000000000..ae611351c Binary files /dev/null and b/site/assets/images/secure_signaling.png differ diff --git a/site/assets/images/starting_server.png b/site/assets/images/starting_server.png new file mode 100644 index 000000000..d4613d629 Binary files /dev/null and b/site/assets/images/starting_server.png differ diff --git a/site/assets/images/telephone_config_advanced.png b/site/assets/images/telephone_config_advanced.png new file mode 100644 index 000000000..0110a25e7 Binary files /dev/null and b/site/assets/images/telephone_config_advanced.png differ diff --git a/site/assets/images/telephone_config_general.png b/site/assets/images/telephone_config_general.png new file mode 100644 index 000000000..0fcc009ff Binary files /dev/null and b/site/assets/images/telephone_config_general.png differ diff --git a/site/assets/images/verify_configuration.png b/site/assets/images/verify_configuration.png new file mode 100644 index 000000000..e8f30a0a3 Binary files /dev/null and b/site/assets/images/verify_configuration.png differ diff --git a/site/assets/images/voip-setup-at-home-or-office.png b/site/assets/images/voip-setup-at-home-or-office.png new file mode 100644 index 000000000..8a445d7d3 Binary files /dev/null and b/site/assets/images/voip-setup-at-home-or-office.png differ diff --git a/site/assets/javascripts/application.9e1f3b71.js b/site/assets/javascripts/application.9e1f3b71.js new file mode 100644 index 000000000..423539028 --- /dev/null +++ b/site/assets/javascripts/application.9e1f3b71.js @@ -0,0 +1 @@ +!function(e,t){for(var n in t)e[n]=t[n]}(window,function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.l=!0,i.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=6)}([function(e,t,n){"use strict";t.__esModule=!0,t.default={createElement:function(e,t){var n=document.createElement(e);t&&Array.prototype.forEach.call(Object.keys(t),function(e){n.setAttribute(e,t[e])});for(var r=arguments.length,i=Array(r>2?r-2:0),o=2;o pre, pre > code");Array.prototype.forEach.call(n,function(t,n){var r="__code_"+n,i=e.createElement("button",{class:"md-clipboard",title:h("clipboard.copy"),"data-clipboard-target":"#"+r+" pre, #"+r+" code"},e.createElement("span",{class:"md-clipboard__message"})),o=t.parentNode;o.id=r,o.insertBefore(i,t)});new c.default(".md-clipboard").on("success",function(e){var t=e.trigger.querySelector(".md-clipboard__message");if(!(t instanceof HTMLElement))throw new ReferenceError;e.clearSelection(),t.dataset.mdTimer&&clearTimeout(parseInt(t.dataset.mdTimer,10)),t.classList.add("md-clipboard__message--active"),t.innerHTML=h("clipboard.copied"),t.dataset.mdTimer=setTimeout(function(){t.classList.remove("md-clipboard__message--active"),t.dataset.mdTimer=""},2e3).toString()})}if(!Modernizr.details){var r=document.querySelectorAll("details > summary");Array.prototype.forEach.call(r,function(e){e.addEventListener("click",function(e){var t=e.target.parentNode;t.hasAttribute("open")?t.removeAttribute("open"):t.setAttribute("open","")})})}var i=function(){if(document.location.hash){var e=document.getElementById(document.location.hash.substring(1));if(!e)return;for(var t=e.parentNode;t&&!(t instanceof HTMLDetailsElement);)t=t.parentNode;if(t&&!t.open){t.open=!0;var n=location.hash;location.hash=" ",location.hash=n}}};if(window.addEventListener("hashchange",i),i(),Modernizr.ios){var o=document.querySelectorAll("[data-md-scrollfix]");Array.prototype.forEach.call(o,function(e){e.addEventListener("touchstart",function(){var t=e.scrollTop;0===t?e.scrollTop=1:t+e.offsetHeight===e.scrollHeight&&(e.scrollTop=t-1)})})}}).listen(),new d.default.Event.Listener(window,["scroll","resize","orientationchange"],new d.default.Header.Shadow("[data-md-component=container]","[data-md-component=header]")).listen(),new d.default.Event.Listener(window,["scroll","resize","orientationchange"],new d.default.Header.Title("[data-md-component=title]",".md-typeset h1")).listen(),document.querySelector("[data-md-component=hero]")&&new d.default.Event.Listener(window,["scroll","resize","orientationchange"],new d.default.Tabs.Toggle("[data-md-component=hero]")).listen(),document.querySelector("[data-md-component=tabs]")&&new d.default.Event.Listener(window,["scroll","resize","orientationchange"],new d.default.Tabs.Toggle("[data-md-component=tabs]")).listen(),new d.default.Event.MatchMedia("(min-width: 1220px)",new d.default.Event.Listener(window,["scroll","resize","orientationchange"],new d.default.Sidebar.Position("[data-md-component=navigation]","[data-md-component=header]"))),document.querySelector("[data-md-component=toc]")&&new d.default.Event.MatchMedia("(min-width: 960px)",new d.default.Event.Listener(window,["scroll","resize","orientationchange"],new d.default.Sidebar.Position("[data-md-component=toc]","[data-md-component=header]"))),new d.default.Event.MatchMedia("(min-width: 960px)",new d.default.Event.Listener(window,"scroll",new d.default.Nav.Blur("[data-md-component=toc] [href]")));var n=document.querySelectorAll("[data-md-component=collapsible]");Array.prototype.forEach.call(n,function(e){new d.default.Event.MatchMedia("(min-width: 1220px)",new d.default.Event.Listener(e.previousElementSibling,"click",new d.default.Nav.Collapse(e)))}),new d.default.Event.MatchMedia("(max-width: 1219px)",new d.default.Event.Listener("[data-md-component=navigation] [data-md-toggle]","change",new d.default.Nav.Scrolling("[data-md-component=navigation] nav"))),document.querySelector("[data-md-component=search]")&&(new d.default.Event.MatchMedia("(max-width: 959px)",new d.default.Event.Listener("[data-md-toggle=search]","change",new d.default.Search.Lock("[data-md-toggle=search]"))),new d.default.Event.Listener("[data-md-component=query]",["focus","keyup","change"],new d.default.Search.Result("[data-md-component=result]",function(){return fetch(t.url.base+"/"+(t.version<"0.17"?"mkdocs":"search")+"/search_index.json",{credentials:"same-origin"}).then(function(e){return e.json()}).then(function(e){return e.docs.map(function(e){return e.location=t.url.base+"/"+e.location,e})})})).listen(),new d.default.Event.Listener("[data-md-component=reset]","click",function(){setTimeout(function(){var e=document.querySelector("[data-md-component=query]");if(!(e instanceof HTMLInputElement))throw new ReferenceError;e.focus()},10)}).listen(),new d.default.Event.Listener("[data-md-toggle=search]","change",function(e){setTimeout(function(e){if(!(e instanceof HTMLInputElement))throw new ReferenceError;if(e.checked){var t=document.querySelector("[data-md-component=query]");if(!(t instanceof HTMLInputElement))throw new ReferenceError;t.focus()}},400,e.target)}).listen(),new d.default.Event.MatchMedia("(min-width: 960px)",new d.default.Event.Listener("[data-md-component=query]","focus",function(){var e=document.querySelector("[data-md-toggle=search]");if(!(e instanceof HTMLInputElement))throw new ReferenceError;e.checked||(e.checked=!0,e.dispatchEvent(new CustomEvent("change")))})),new d.default.Event.Listener(window,"keydown",function(e){var t=document.querySelector("[data-md-toggle=search]");if(!(t instanceof HTMLInputElement))throw new ReferenceError;var n=document.querySelector("[data-md-component=query]");if(!(n instanceof HTMLInputElement))throw new ReferenceError;if(!e.metaKey&&!e.ctrlKey)if(t.checked){if(13===e.keyCode){if(n===document.activeElement){e.preventDefault();var r=document.querySelector("[data-md-component=search] [href][data-md-state=active]");r instanceof HTMLLinkElement&&(window.location=r.getAttribute("href"),t.checked=!1,t.dispatchEvent(new CustomEvent("change")),n.blur())}}else if(9===e.keyCode||27===e.keyCode)t.checked=!1,t.dispatchEvent(new CustomEvent("change")),n.blur();else if(-1!==[8,37,39].indexOf(e.keyCode))n!==document.activeElement&&n.focus();else if(-1!==[38,40].indexOf(e.keyCode)){var i=e.keyCode,o=Array.prototype.slice.call(document.querySelectorAll("[data-md-component=query], [data-md-component=search] [href]")),a=o.find(function(e){if(!(e instanceof HTMLElement))throw new ReferenceError;return"active"===e.dataset.mdState});a&&(a.dataset.mdState="");var s=Math.max(0,(o.indexOf(a)+o.length+(38===i?-1:1))%o.length);return o[s]&&(o[s].dataset.mdState="active",o[s].focus()),e.preventDefault(),e.stopPropagation(),!1}}else document.activeElement&&!document.activeElement.form&&(70!==e.keyCode&&83!==e.keyCode||(n.focus(),e.preventDefault()))}).listen(),new d.default.Event.Listener(window,"keypress",function(){var e=document.querySelector("[data-md-toggle=search]");if(!(e instanceof HTMLInputElement))throw new ReferenceError;if(e.checked){var t=document.querySelector("[data-md-component=query]");if(!(t instanceof HTMLInputElement))throw new ReferenceError;t!==document.activeElement&&t.focus()}}).listen()),new d.default.Event.Listener(document.body,"keydown",function(e){if(9===e.keyCode){var t=document.querySelectorAll("[data-md-component=navigation] .md-nav__link[for]:not([tabindex])");Array.prototype.forEach.call(t,function(e){e.offsetHeight&&(e.tabIndex=0)})}}).listen(),new d.default.Event.Listener(document.body,"mousedown",function(){var e=document.querySelectorAll("[data-md-component=navigation] .md-nav__link[tabindex]");Array.prototype.forEach.call(e,function(e){e.removeAttribute("tabIndex")})}).listen(),document.body.addEventListener("click",function(){"tabbing"===document.body.dataset.mdState&&(document.body.dataset.mdState="")}),new d.default.Event.MatchMedia("(max-width: 959px)",new d.default.Event.Listener("[data-md-component=navigation] [href^='#']","click",function(){var e=document.querySelector("[data-md-toggle=drawer]");if(!(e instanceof HTMLInputElement))throw new ReferenceError;e.checked&&(e.checked=!1,e.dispatchEvent(new CustomEvent("change")))})),function(){var e=document.querySelector("[data-md-source]");if(!e)return a.default.resolve([]);if(!(e instanceof HTMLAnchorElement))throw new ReferenceError;switch(e.dataset.mdSource){case"github":return new d.default.Source.Adapter.GitHub(e).fetch();default:return a.default.resolve([])}}().then(function(e){var t=document.querySelectorAll("[data-md-source]");Array.prototype.forEach.call(t,function(t){new d.default.Source.Repository(t).initialize(e)})})}t.__esModule=!0,t.app=void 0,n(7),n(8),n(9),n(10),n(11),n(12),n(13);var o=n(14),a=r(o),s=n(19),c=r(s),u=n(20),l=r(u),f=n(21),d=r(f);window.Promise=window.Promise||a.default;var h=function(e){var t=document.getElementsByName("lang:"+e)[0];if(!(t instanceof HTMLMetaElement))throw new ReferenceError;return t.content},p={initialize:i};t.app=p}).call(t,n(0))},function(e,t,n){e.exports=n.p+"assets/images/icons/bitbucket.1b09e088.svg"},function(e,t,n){e.exports=n.p+"assets/images/icons/github.f0b8504a.svg"},function(e,t,n){e.exports=n.p+"assets/images/icons/gitlab.6dd19c00.svg"},function(e,t){},function(e,t){},function(e,t){!function(){if("undefined"!=typeof window)try{var e=new window.CustomEvent("test",{cancelable:!0});if(e.preventDefault(),!0!==e.defaultPrevented)throw new Error("Could not prevent default")}catch(e){var t=function(e,t){var n,r;return t=t||{bubbles:!1,cancelable:!1,detail:void 0},n=document.createEvent("CustomEvent"),n.initCustomEvent(e,t.bubbles,t.cancelable,t.detail),r=n.preventDefault,n.preventDefault=function(){r.call(this);try{Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}})}catch(e){this.defaultPrevented=!0}},n};t.prototype=window.Event.prototype,window.CustomEvent=t}}()},function(e,t,n){window.fetch||(window.fetch=n(2).default||n(2))},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e){function r(){}function i(e,t){return function(){e.apply(t,arguments)}}function o(e){if(!(this instanceof o))throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this._deferreds=[],f(e,this)}function a(e,t){for(;3===e._state;)e=e._value;if(0===e._state)return void e._deferreds.push(t);e._handled=!0,o._immediateFn(function(){var n=1===e._state?t.onFulfilled:t.onRejected;if(null===n)return void(1===e._state?s:c)(t.promise,e._value);var r;try{r=n(e._value)}catch(e){return void c(t.promise,e)}s(t.promise,r)})}function s(e,t){try{if(t===e)throw new TypeError("A promise cannot be resolved with itself.");if(t&&("object"==typeof t||"function"==typeof t)){var n=t.then;if(t instanceof o)return e._state=3,e._value=t,void u(e);if("function"==typeof n)return void f(i(n,t),e)}e._state=1,e._value=t,u(e)}catch(t){c(e,t)}}function c(e,t){e._state=2,e._value=t,u(e)}function u(e){2===e._state&&0===e._deferreds.length&&o._immediateFn(function(){e._handled||o._unhandledRejectionFn(e._value)});for(var t=0,n=e._deferreds.length;t=0&&(e._idleTimeoutId=setTimeout(function(){e._onTimeout&&e._onTimeout()},t))},n(16),t.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==e&&e.setImmediate||this&&this.setImmediate,t.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==e&&e.clearImmediate||this&&this.clearImmediate}).call(t,n(1))},function(e,t,n){(function(e,t){!function(e,n){"use strict";function r(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),n=0;n1)for(var n=1;n0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof e.action?e.action:this.defaultAction,this.target="function"==typeof e.target?e.target:this.defaultTarget,this.text="function"==typeof e.text?e.text:this.defaultText,this.container="object"===c(e.container)?e.container:document.body}},{key:"listenClick",value:function(e){var t=this;this.listener=(0,m.default)(e,"click",function(e){return t.onClick(e)})}},{key:"onClick",value:function(e){var t=e.delegateTarget||e.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new f.default({action:this.action(t),target:this.target(t),text:this.text(t),container:this.container,trigger:t,emitter:this})}},{key:"defaultAction",value:function(e){return s("action",e)}},{key:"defaultTarget",value:function(e){var t=s("target",e);if(t)return document.querySelector(t)}},{key:"defaultText",value:function(e){return s("text",e)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],t="string"==typeof e?[e]:e,n=!!document.queryCommandSupported;return t.forEach(function(e){n=n&&!!document.queryCommandSupported(e)}),n}}]),t}(h.default);e.exports=y},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},o=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.action=e.action,this.container=e.container,this.emitter=e.emitter,this.target=e.target,this.text=e.text,this.trigger=e.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function(){var e=this,t="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return e.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[t?"right":"left"]="-9999px";var n=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=n+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,s.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=(0,s.default)(this.target),this.copyText()}},{key:"copyText",value:function(){var e=void 0;try{e=document.execCommand(this.action)}catch(t){e=!1}this.handleResult(e)}},{key:"handleResult",value:function(e){this.emitter.emit(e?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=e,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(e){if(void 0!==e){if(!e||"object"!==(void 0===e?"undefined":i(e))||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=e}},get:function(){return this._target}}]),e}();e.exports=c},function(e,t){function n(e){var t;if("SELECT"===e.nodeName)e.focus(),t=e.value;else if("INPUT"===e.nodeName||"TEXTAREA"===e.nodeName){var n=e.hasAttribute("readonly");n||e.setAttribute("readonly",""),e.select(),e.setSelectionRange(0,e.value.length),n||e.removeAttribute("readonly"),t=e.value}else{e.hasAttribute("contenteditable")&&e.focus();var r=window.getSelection(),i=document.createRange();i.selectNodeContents(e),r.removeAllRanges(),r.addRange(i),t=r.toString()}return t}e.exports=n},function(e,t){function n(){}n.prototype={on:function(e,t,n){var r=this.e||(this.e={});return(r[e]||(r[e]=[])).push({fn:t,ctx:n}),this},once:function(e,t,n){function r(){i.off(e,r),t.apply(n,arguments)}var i=this;return r._=t,this.on(e,r,n)},emit:function(e){var t=[].slice.call(arguments,1),n=((this.e||(this.e={}))[e]||[]).slice(),r=0,i=n.length;for(r;r=0,a=navigator.userAgent.indexOf("Android")>0&&!o,s=/iP(ad|hone|od)/.test(navigator.userAgent)&&!o,c=s&&/OS 4_\d(_\d)?/.test(navigator.userAgent),u=s&&/OS [6-7]_\d/.test(navigator.userAgent),l=navigator.userAgent.indexOf("BB10")>0;i.prototype.needsClick=function(e){switch(e.nodeName.toLowerCase()){case"button":case"select":case"textarea":if(e.disabled)return!0;break;case"input":if(s&&"file"===e.type||e.disabled)return!0;break;case"label":case"iframe":case"video":return!0}return/\bneedsclick\b/.test(e.className)},i.prototype.needsFocus=function(e){switch(e.nodeName.toLowerCase()){case"textarea":return!0;case"select":return!a;case"input":switch(e.type){case"button":case"checkbox":case"file":case"image":case"radio":case"submit":return!1}return!e.disabled&&!e.readOnly;default:return/\bneedsfocus\b/.test(e.className)}},i.prototype.sendClick=function(e,t){var n,r;document.activeElement&&document.activeElement!==e&&document.activeElement.blur(),r=t.changedTouches[0],n=document.createEvent("MouseEvents"),n.initMouseEvent(this.determineEventType(e),!0,!0,window,1,r.screenX,r.screenY,r.clientX,r.clientY,!1,!1,!1,!1,0,null),n.forwardedTouchEvent=!0,e.dispatchEvent(n)},i.prototype.determineEventType=function(e){return a&&"select"===e.tagName.toLowerCase()?"mousedown":"click"},i.prototype.focus=function(e){var t;s&&e.setSelectionRange&&0!==e.type.indexOf("date")&&"time"!==e.type&&"month"!==e.type?(t=e.value.length,e.setSelectionRange(t,t)):e.focus()},i.prototype.updateScrollParent=function(e){var t,n;if(!(t=e.fastClickScrollParent)||!t.contains(e)){n=e;do{if(n.scrollHeight>n.offsetHeight){t=n,e.fastClickScrollParent=n;break}n=n.parentElement}while(n)}t&&(t.fastClickLastScrollTop=t.scrollTop)},i.prototype.getTargetElementFromEventTarget=function(e){return e.nodeType===Node.TEXT_NODE?e.parentNode:e},i.prototype.onTouchStart=function(e){var t,n,r;if(e.targetTouches.length>1)return!0;if(t=this.getTargetElementFromEventTarget(e.target),n=e.targetTouches[0],s){if(r=window.getSelection(),r.rangeCount&&!r.isCollapsed)return!0;if(!c){if(n.identifier&&n.identifier===this.lastTouchIdentifier)return e.preventDefault(),!1;this.lastTouchIdentifier=n.identifier,this.updateScrollParent(t)}}return this.trackingClick=!0,this.trackingClickStart=e.timeStamp,this.targetElement=t,this.touchStartX=n.pageX,this.touchStartY=n.pageY,e.timeStamp-this.lastClickTimen||Math.abs(t.pageY-this.touchStartY)>n},i.prototype.onTouchMove=function(e){return!this.trackingClick||((this.targetElement!==this.getTargetElementFromEventTarget(e.target)||this.touchHasMoved(e))&&(this.trackingClick=!1,this.targetElement=null),!0)},i.prototype.findControl=function(e){return void 0!==e.control?e.control:e.htmlFor?document.getElementById(e.htmlFor):e.querySelector("button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea")},i.prototype.onTouchEnd=function(e){var t,n,r,i,o,l=this.targetElement;if(!this.trackingClick)return!0;if(e.timeStamp-this.lastClickTimethis.tapTimeout)return!0;if(this.cancelNextClick=!1,this.lastClickTime=e.timeStamp,n=this.trackingClickStart,this.trackingClick=!1,this.trackingClickStart=0,u&&(o=e.changedTouches[0],l=document.elementFromPoint(o.pageX-window.pageXOffset,o.pageY-window.pageYOffset)||l,l.fastClickScrollParent=this.targetElement.fastClickScrollParent),"label"===(r=l.tagName.toLowerCase())){if(t=this.findControl(l)){if(this.focus(l),a)return!1;l=t}}else if(this.needsFocus(l))return e.timeStamp-n>100||s&&window.top!==window&&"input"===r?(this.targetElement=null,!1):(this.focus(l),this.sendClick(l,e),s&&"select"===r||(this.targetElement=null,e.preventDefault()),!1);return!(!s||c||!(i=l.fastClickScrollParent)||i.fastClickLastScrollTop===i.scrollTop)||(this.needsClick(l)||(e.preventDefault(),this.sendClick(l,e)),!1)},i.prototype.onTouchCancel=function(){this.trackingClick=!1,this.targetElement=null},i.prototype.onMouse=function(e){return!this.targetElement||(!!e.forwardedTouchEvent||(!e.cancelable||(!(!this.needsClick(this.targetElement)||this.cancelNextClick)||(e.stopImmediatePropagation?e.stopImmediatePropagation():e.propagationStopped=!0,e.stopPropagation(),e.preventDefault(),!1))))},i.prototype.onClick=function(e){var t;return this.trackingClick?(this.targetElement=null,this.trackingClick=!1,!0):"submit"===e.target.type&&0===e.detail||(t=this.onMouse(e),t||(this.targetElement=null),t)},i.prototype.destroy=function(){var e=this.layer;a&&(e.removeEventListener("mouseover",this.onMouse,!0),e.removeEventListener("mousedown",this.onMouse,!0),e.removeEventListener("mouseup",this.onMouse,!0)),e.removeEventListener("click",this.onClick,!0),e.removeEventListener("touchstart",this.onTouchStart,!1),e.removeEventListener("touchmove",this.onTouchMove,!1),e.removeEventListener("touchend",this.onTouchEnd,!1),e.removeEventListener("touchcancel",this.onTouchCancel,!1)},i.notNeeded=function(e){var t,n,r;if(void 0===window.ontouchstart)return!0;if(n=+(/Chrome\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1]){if(!a)return!0;if(t=document.querySelector("meta[name=viewport]")){if(-1!==t.content.indexOf("user-scalable=no"))return!0;if(n>31&&document.documentElement.scrollWidth<=window.outerWidth)return!0}}if(l&&(r=navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/),r[1]>=10&&r[2]>=3&&(t=document.querySelector("meta[name=viewport]")))){if(-1!==t.content.indexOf("user-scalable=no"))return!0;if(document.documentElement.scrollWidth<=window.outerWidth)return!0}return"none"===e.style.msTouchAction||"manipulation"===e.style.touchAction||(!!(+(/Firefox\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1]>=27&&(t=document.querySelector("meta[name=viewport]"))&&(-1!==t.content.indexOf("user-scalable=no")||document.documentElement.scrollWidth<=window.outerWidth))||("none"===e.style.touchAction||"manipulation"===e.style.touchAction))},i.attach=function(e,t){return new i(e,t)},void 0!==(r=function(){return i}.call(t,n,t,e))&&(e.exports=r)}()},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(22),o=r(i),a=n(24),s=r(a),c=n(27),u=r(c),l=n(31),f=r(l),d=n(37),h=r(d),p=n(39),m=r(p),y=n(45),v=r(y);t.default={Event:o.default,Header:s.default,Nav:u.default,Search:f.default,Sidebar:h.default,Source:m.default,Tabs:v.default}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(3),o=r(i),a=n(23),s=r(a);t.default={Listener:o.default,MatchMedia:s.default}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=n(3),o=(function(e){e&&e.__esModule}(i),function e(t,n){r(this,e),this.handler_=function(e){e.matches?n.listen():n.unlisten()};var i=window.matchMedia(t);i.addListener(this.handler_),this.handler_(i)});t.default=o},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(25),o=r(i),a=n(26),s=r(a);t.default={Shadow:o.default,Title:s.default}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=function(){function e(t,n){r(this,e);var i="string"==typeof t?document.querySelector(t):t;if(!(i instanceof HTMLElement&&i.parentNode instanceof HTMLElement))throw new ReferenceError;if(this.el_=i.parentNode,!((i="string"==typeof n?document.querySelector(n):n)instanceof HTMLElement))throw new ReferenceError;this.header_=i,this.height_=0,this.active_=!1}return e.prototype.setup=function(){for(var e=this.el_;e=e.previousElementSibling;){if(!(e instanceof HTMLElement))throw new ReferenceError;this.height_+=e.offsetHeight}this.update()},e.prototype.update=function(e){if(!e||"resize"!==e.type&&"orientationchange"!==e.type){var t=window.pageYOffset>=this.height_;t!==this.active_&&(this.header_.dataset.mdState=(this.active_=t)?"shadow":"")}else this.height_=0,this.setup()},e.prototype.reset=function(){this.header_.dataset.mdState="",this.height_=0,this.active_=!1},e}();t.default=i},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=function(){function e(t,n){r(this,e);var i="string"==typeof t?document.querySelector(t):t;if(!(i instanceof HTMLElement))throw new ReferenceError;if(this.el_=i,!((i="string"==typeof n?document.querySelector(n):n)instanceof HTMLHeadingElement))throw new ReferenceError;this.header_=i,this.active_=!1}return e.prototype.setup=function(){var e=this;Array.prototype.forEach.call(this.el_.children,function(t){t.style.width=e.el_.offsetWidth-20+"px"})},e.prototype.update=function(e){var t=this,n=window.pageYOffset>=this.header_.offsetTop;n!==this.active_&&(this.el_.dataset.mdState=(this.active_=n)?"active":""),"resize"!==e.type&&"orientationchange"!==e.type||Array.prototype.forEach.call(this.el_.children,function(e){e.style.width=t.el_.offsetWidth-20+"px"})},e.prototype.reset=function(){this.el_.dataset.mdState="",this.el_.style.width="",this.active_=!1},e}();t.default=i},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(28),o=r(i),a=n(29),s=r(a),c=n(30),u=r(c);t.default={Blur:o.default,Collapse:s.default,Scrolling:u.default}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=function(){function e(t){r(this,e),this.els_="string"==typeof t?document.querySelectorAll(t):t,this.index_=0,this.offset_=window.pageYOffset,this.dir_=!1,this.anchors_=[].reduce.call(this.els_,function(e,t){return e.concat(document.getElementById(t.hash.substring(1))||[])},[])}return e.prototype.setup=function(){this.update()},e.prototype.update=function(){var e=window.pageYOffset,t=this.offset_-e<0;if(this.dir_!==t&&(this.index_=this.index_=t?0:this.els_.length-1),0!==this.anchors_.length){if(this.offset_<=e)for(var n=this.index_+1;n0&&(this.els_[n-1].dataset.mdState="blur"),this.index_=n;else for(var r=this.index_;r>=0;r--){if(!(this.anchors_[r].offsetTop-80>e)){this.index_=r;break}r>0&&(this.els_[r-1].dataset.mdState="")}this.offset_=e,this.dir_=t}},e.prototype.reset=function(){Array.prototype.forEach.call(this.els_,function(e){e.dataset.mdState=""}),this.index_=0,this.offset_=window.pageYOffset},e}();t.default=i},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=function(){function e(t){r(this,e);var n="string"==typeof t?document.querySelector(t):t;if(!(n instanceof HTMLElement))throw new ReferenceError;this.el_=n}return e.prototype.setup=function(){var e=this.el_.getBoundingClientRect().height;this.el_.style.display=e?"block":"none",this.el_.style.overflow=e?"visible":"hidden"},e.prototype.update=function(){var e=this,t=this.el_.getBoundingClientRect().height;if(this.el_.style.display="block",this.el_.style.overflow="",t)this.el_.style.maxHeight=t+"px",requestAnimationFrame(function(){e.el_.setAttribute("data-md-state","animate"),e.el_.style.maxHeight="0px"});else{this.el_.setAttribute("data-md-state","expand"),this.el_.style.maxHeight="";var n=this.el_.getBoundingClientRect().height;this.el_.removeAttribute("data-md-state"),this.el_.style.maxHeight="0px",requestAnimationFrame(function(){e.el_.setAttribute("data-md-state","animate"),e.el_.style.maxHeight=n+"px"})}var r=function e(n){var r=n.target;if(!(r instanceof HTMLElement))throw new ReferenceError;r.removeAttribute("data-md-state"),r.style.maxHeight="",r.style.display=t?"none":"block",r.style.overflow=t?"hidden":"visible",r.removeEventListener("transitionend",e)};this.el_.addEventListener("transitionend",r,!1)},e.prototype.reset=function(){this.el_.dataset.mdState="",this.el_.style.maxHeight="",this.el_.style.display="",this.el_.style.overflow=""},e}();t.default=i},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=function(){function e(t){r(this,e);var n="string"==typeof t?document.querySelector(t):t;if(!(n instanceof HTMLElement))throw new ReferenceError;this.el_=n}return e.prototype.setup=function(){this.el_.children[this.el_.children.length-1].style.webkitOverflowScrolling="touch";var e=this.el_.querySelectorAll("[data-md-toggle]");Array.prototype.forEach.call(e,function(e){if(!(e instanceof HTMLInputElement))throw new ReferenceError;if(e.checked){var t=e.nextElementSibling;if(!(t instanceof HTMLElement))throw new ReferenceError;for(;"NAV"!==t.tagName&&t.nextElementSibling;)t=t.nextElementSibling;if(!(e.parentNode instanceof HTMLElement&&e.parentNode.parentNode instanceof HTMLElement))throw new ReferenceError;var n=e.parentNode.parentNode,r=t.children[t.children.length-1];n.style.webkitOverflowScrolling="",r.style.webkitOverflowScrolling="touch"}})},e.prototype.update=function(e){var t=e.target;if(!(t instanceof HTMLElement))throw new ReferenceError;var n=t.nextElementSibling;if(!(n instanceof HTMLElement))throw new ReferenceError;for(;"NAV"!==n.tagName&&n.nextElementSibling;)n=n.nextElementSibling;if(!(t.parentNode instanceof HTMLElement&&t.parentNode.parentNode instanceof HTMLElement))throw new ReferenceError;var r=t.parentNode.parentNode,i=n.children[n.children.length-1];if(r.style.webkitOverflowScrolling="",i.style.webkitOverflowScrolling="",!t.checked){var o=function e(){n instanceof HTMLElement&&(r.style.webkitOverflowScrolling="touch",n.removeEventListener("transitionend",e))};n.addEventListener("transitionend",o,!1)}if(t.checked){var a=function e(){n instanceof HTMLElement&&(i.style.webkitOverflowScrolling="touch",n.removeEventListener("transitionend",e))};n.addEventListener("transitionend",a,!1)}},e.prototype.reset=function(){this.el_.children[1].style.webkitOverflowScrolling="";var e=this.el_.querySelectorAll("[data-md-toggle]");Array.prototype.forEach.call(e,function(e){if(!(e instanceof HTMLInputElement))throw new ReferenceError;if(e.checked){var t=e.nextElementSibling;if(!(t instanceof HTMLElement))throw new ReferenceError;for(;"NAV"!==t.tagName&&t.nextElementSibling;)t=t.nextElementSibling;if(!(e.parentNode instanceof HTMLElement&&e.parentNode.parentNode instanceof HTMLElement))throw new ReferenceError;var n=e.parentNode.parentNode,r=t.children[t.children.length-1];n.style.webkitOverflowScrolling="",r.style.webkitOverflowScrolling=""}})},e}();t.default=i},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(32),o=r(i),a=n(33),s=r(a);t.default={Lock:o.default,Result:s.default}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=function(){function e(t){r(this,e);var n="string"==typeof t?document.querySelector(t):t;if(!(n instanceof HTMLInputElement))throw new ReferenceError;if(this.el_=n,!document.body)throw new ReferenceError;this.lock_=document.body}return e.prototype.setup=function(){this.update()},e.prototype.update=function(){var e=this;this.el_.checked?(this.offset_=window.pageYOffset,setTimeout(function(){window.scrollTo(0,0),e.el_.checked&&(e.lock_.dataset.mdState="lock")},400)):(this.lock_.dataset.mdState="",setTimeout(function(){void 0!==e.offset_&&window.scrollTo(0,e.offset_)},100))},e.prototype.reset=function(){"lock"===this.lock_.dataset.mdState&&window.scrollTo(0,this.offset_),this.lock_.dataset.mdState=""},e}();t.default=i},function(e,t,n){"use strict";(function(e){function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var o=n(34),a=r(o),s=n(35),c=r(s),u=function(e){var t=document.createTextNode(e),n=document.createElement("p");return n.appendChild(t),n.innerHTML},l=function(e,t){var n=t;if(e.length>n){for(;" "!==e[n]&&--n>0;);return e.substring(0,n)+"..."}return e},f=function(e){var t=document.getElementsByName("lang:"+e)[0];if(!(t instanceof HTMLMetaElement))throw new ReferenceError;return t.content},d=function(){function t(e,n){i(this,t);var r="string"==typeof e?document.querySelector(e):e;if(!(r instanceof HTMLElement))throw new ReferenceError;this.el_=r;var o=Array.prototype.slice.call(this.el_.children),a=o[0],s=o[1];this.data_=n,this.meta_=a,this.list_=s,this.message_={placeholder:this.meta_.textContent,none:f("search.result.none"),one:f("search.result.one"),other:f("search.result.other")};var u=f("search.tokenizer");u.length&&(c.default.tokenizer.separator=u),this.lang_=f("search.language").split(",").filter(Boolean).map(function(e){return e.trim()})}return t.prototype.update=function(t){var n=this;if("focus"!==t.type||this.index_){if("focus"===t.type||"keyup"===t.type){var r=t.target;if(!(r instanceof HTMLInputElement))throw new ReferenceError;if(!this.index_||r.value===this.value_)return;for(;this.list_.firstChild;)this.list_.removeChild(this.list_.firstChild);if(this.value_=r.value,0===this.value_.length)return void(this.meta_.textContent=this.message_.placeholder);var i=this.index_.query(function(e){n.value_.toLowerCase().split(" ").filter(Boolean).forEach(function(t){e.term(t,{wildcard:c.default.Query.wildcard.TRAILING})})}).reduce(function(e,t){var r=n.docs_.get(t.ref);if(r.parent){var i=r.parent.location;e.set(i,(e.get(i)||[]).concat(t))}else{var o=r.location;e.set(o,e.get(o)||[])}return e},new Map),o=(0,a.default)(this.value_.trim()).replace(new RegExp(c.default.tokenizer.separator,"img"),"|"),s=new RegExp("(^|"+c.default.tokenizer.separator+")("+o+")","img"),d=function(e,t,n){return t+""+n+""};this.stack_=[],i.forEach(function(t,r){var i,o=n.docs_.get(r),a=e.createElement("li",{class:"md-search-result__item"},e.createElement("a",{href:o.location,title:o.title,class:"md-search-result__link",tabindex:"-1"},e.createElement("article",{class:"md-search-result__article md-search-result__article--document"},e.createElement("h1",{class:"md-search-result__title"},{__html:o.title.replace(s,d)}),o.text.length?e.createElement("p",{class:"md-search-result__teaser"},{__html:o.text.replace(s,d)}):{}))),c=t.map(function(t){return function(){var r=n.docs_.get(t.ref);a.appendChild(e.createElement("a",{href:r.location,title:r.title,class:"md-search-result__link","data-md-rel":"anchor",tabindex:"-1"},e.createElement("article",{class:"md-search-result__article"},e.createElement("h1",{class:"md-search-result__title"},{__html:r.title.replace(s,d)}),r.text.length?e.createElement("p",{class:"md-search-result__teaser"},{__html:l(r.text.replace(s,d),400)}):{})))}});(i=n.stack_).push.apply(i,[function(){return n.list_.appendChild(a)}].concat(c))});var h=this.el_.parentNode;if(!(h instanceof HTMLElement))throw new ReferenceError;for(;this.stack_.length&&h.offsetHeight>=h.scrollHeight-16;)this.stack_.shift()();var p=this.list_.querySelectorAll("[data-md-rel=anchor]");switch(Array.prototype.forEach.call(p,function(e){["click","keydown"].forEach(function(t){e.addEventListener(t,function(n){if("keydown"!==t||13===n.keyCode){var r=document.querySelector("[data-md-toggle=search]");if(!(r instanceof HTMLInputElement))throw new ReferenceError;r.checked&&(r.checked=!1,r.dispatchEvent(new CustomEvent("change"))),n.preventDefault(),setTimeout(function(){document.location.href=e.href},100)}})})}),i.size){case 0:this.meta_.textContent=this.message_.none;break;case 1:this.meta_.textContent=this.message_.one;break;default:this.meta_.textContent=this.message_.other.replace("#",i.size)}}}else{var m=function(e){n.docs_=e.reduce(function(e,t){var n=t.location.split("#"),r=n[0],i=n[1];return t.title=u(t.title),t.text=u(t.text),i&&(t.parent=e.get(r),t.parent&&!t.parent.done&&(t.parent.title=t.title,t.parent.text=t.text,t.parent.done=!0)),t.text=t.text.replace(/\n/g," ").replace(/\s+/g," ").replace(/\s+([,.:;!?])/g,function(e,t){return t}),t.parent&&t.parent.title===t.title||e.set(t.location,t),e},new Map);var t=n.docs_,r=n.lang_;n.stack_=[],n.index_=(0,c.default)(function(){var e,n=this,i={"search.pipeline.trimmer":c.default.trimmer,"search.pipeline.stopwords":c.default.stopWordFilter},o=Object.keys(i).reduce(function(e,t){return f(t).match(/^false$/i)||e.push(i[t]),e},[]);this.pipeline.reset(),o&&(e=this.pipeline).add.apply(e,o),1===r.length&&"en"!==r[0]&&c.default[r[0]]?this.use(c.default[r[0]]):r.length>1&&this.use(c.default.multiLanguage.apply(c.default,r)),this.field("title",{boost:10}),this.field("text"),this.ref("location"),t.forEach(function(e){return n.add(e)})});var i=n.el_.parentNode;if(!(i instanceof HTMLElement))throw new ReferenceError;i.addEventListener("scroll",function(){for(;n.stack_.length&&i.scrollTop+i.offsetHeight>=i.scrollHeight-16;)n.stack_.splice(0,10).forEach(function(e){return e()})})};setTimeout(function(){return"function"==typeof n.data_?n.data_().then(m):m(n.data_)},250)}},t}();t.default=d}).call(t,n(0))},function(e,t,n){"use strict";var r=/[|\\{}()[\]^$+*?.]/g;e.exports=function(e){if("string"!=typeof e)throw new TypeError("Expected a string");return e.replace(r,"\\$&")}},function(e,t,n){(function(t){e.exports=t.lunr=n(36)}).call(t,n(1))},function(e,t,n){var r,i;!function(){var o=function(e){var t=new o.Builder;return t.pipeline.add(o.trimmer,o.stopWordFilter,o.stemmer),t.searchPipeline.add(o.stemmer),e.call(t,t),t.build()};o.version="2.3.5",o.utils={},o.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),o.utils.asString=function(e){return void 0===e||null===e?"":e.toString()},o.utils.clone=function(e){if(null===e||void 0===e)return e;for(var t=Object.create(null),n=Object.keys(e),r=0;r0){var l=o.utils.clone(t)||{};l.position=[s,u],l.index=i.length,i.push(new o.Token(n.slice(s,a),l))}s=a+1}}return i},o.tokenizer.separator=/[\s\-]+/,o.Pipeline=function(){this._stack=[]},o.Pipeline.registeredFunctions=Object.create(null),o.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&o.utils.warn("Overwriting existing registered function: "+t),e.label=t,o.Pipeline.registeredFunctions[e.label]=e},o.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||o.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},o.Pipeline.load=function(e){var t=new o.Pipeline;return e.forEach(function(e){var n=o.Pipeline.registeredFunctions[e];if(!n)throw new Error("Cannot load unregistered function: "+e);t.add(n)}),t},o.Pipeline.prototype.add=function(){Array.prototype.slice.call(arguments).forEach(function(e){o.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},o.Pipeline.prototype.after=function(e,t){o.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");n+=1,this._stack.splice(n,0,t)},o.Pipeline.prototype.before=function(e,t){o.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");this._stack.splice(n,0,t)},o.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},o.Pipeline.prototype.run=function(e){for(var t=this._stack.length,n=0;n1&&(oe&&(n=i),o!=e);)r=n-t,i=t+Math.floor(r/2),o=this.elements[2*i];return o==e?2*i:o>e?2*i:os?u+=2:a==s&&(t+=n[c+1]*r[u+1],c+=2,u+=2);return t},o.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},o.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,n=0;t0){var a,s=i.str.charAt(0);s in i.node.edges?a=i.node.edges[s]:(a=new o.TokenSet,i.node.edges[s]=a),1==i.str.length&&(a.final=!0),r.push({node:a,editsRemaining:i.editsRemaining,str:i.str.slice(1)})}if(i.editsRemaining>0&&i.str.length>1){var c,s=i.str.charAt(1);s in i.node.edges?c=i.node.edges[s]:(c=new o.TokenSet,i.node.edges[s]=c),i.str.length<=2?c.final=!0:r.push({node:c,editsRemaining:i.editsRemaining-1,str:i.str.slice(2)})}if(i.editsRemaining>0&&1==i.str.length&&(i.node.final=!0),i.editsRemaining>0&&i.str.length>=1){if("*"in i.node.edges)var u=i.node.edges["*"];else{var u=new o.TokenSet;i.node.edges["*"]=u}1==i.str.length?u.final=!0:r.push({node:u,editsRemaining:i.editsRemaining-1,str:i.str.slice(1)})}if(i.editsRemaining>0){if("*"in i.node.edges)var l=i.node.edges["*"];else{var l=new o.TokenSet;i.node.edges["*"]=l}0==i.str.length?l.final=!0:r.push({node:l,editsRemaining:i.editsRemaining-1,str:i.str})}if(i.editsRemaining>0&&i.str.length>1){var f,d=i.str.charAt(0),h=i.str.charAt(1);h in i.node.edges?f=i.node.edges[h]:(f=new o.TokenSet,i.node.edges[h]=f),1==i.str.length?f.final=!0:r.push({node:f,editsRemaining:i.editsRemaining-1,str:d+i.str.slice(2)})}}return n},o.TokenSet.fromString=function(e){for(var t=new o.TokenSet,n=t,r=0,i=e.length;r=e;t--){var n=this.uncheckedNodes[t],r=n.child.toString();r in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[r]:(n.child._str=r,this.minimizedNodes[r]=n.child),this.uncheckedNodes.pop()}},o.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},o.Index.prototype.search=function(e){return this.query(function(t){new o.QueryParser(e,t).parse()})},o.Index.prototype.query=function(e){for(var t=new o.Query(this.fields),n=Object.create(null),r=Object.create(null),i=Object.create(null),a=Object.create(null),s=Object.create(null),c=0;c1?1:e},o.Builder.prototype.k1=function(e){this._k1=e},o.Builder.prototype.add=function(e,t){var n=e[this._ref],r=Object.keys(this._fields);this._documents[n]=t||{},this.documentCount+=1;for(var i=0;i=this.length)return o.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},o.QueryLexer.prototype.width=function(){return this.pos-this.start},o.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},o.QueryLexer.prototype.backup=function(){this.pos-=1},o.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{e=this.next(),t=e.charCodeAt(0)}while(t>47&&t<58);e!=o.QueryLexer.EOS&&this.backup()},o.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(o.QueryLexer.TERM)),e.ignore(),e.more())return o.QueryLexer.lexText},o.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(o.QueryLexer.EDIT_DISTANCE),o.QueryLexer.lexText},o.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(o.QueryLexer.BOOST),o.QueryLexer.lexText},o.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(o.QueryLexer.TERM)},o.QueryLexer.termSeparator=o.tokenizer.separator,o.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==o.QueryLexer.EOS)return o.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return o.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(o.QueryLexer.TERM),o.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(o.QueryLexer.TERM),o.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(o.QueryLexer.PRESENCE),o.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(o.QueryLexer.PRESENCE),o.QueryLexer.lexText;if(t.match(o.QueryLexer.termSeparator))return o.QueryLexer.lexTerm}else e.escapeCharacter()}},o.QueryParser=function(e,t){this.lexer=new o.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},o.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=o.QueryParser.parseClause;e;)e=e(this);return this.query},o.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},o.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},o.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},o.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(void 0!=t)switch(t.type){case o.QueryLexer.PRESENCE:return o.QueryParser.parsePresence;case o.QueryLexer.FIELD:return o.QueryParser.parseField;case o.QueryLexer.TERM:return o.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(n+=" with value '"+t.str+"'"),new o.QueryParseError(n,t.start,t.end)}},o.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(void 0!=t){switch(t.str){case"-":e.currentClause.presence=o.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=o.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+t.str+"'";throw new o.QueryParseError(n,t.start,t.end)}var r=e.peekLexeme();if(void 0==r){var n="expecting term or field, found nothing";throw new o.QueryParseError(n,t.start,t.end)}switch(r.type){case o.QueryLexer.FIELD:return o.QueryParser.parseField;case o.QueryLexer.TERM:return o.QueryParser.parseTerm;default:var n="expecting term or field, found '"+r.type+"'";throw new o.QueryParseError(n,r.start,r.end)}}},o.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(void 0!=t){if(-1==e.query.allFields.indexOf(t.str)){var n=e.query.allFields.map(function(e){return"'"+e+"'"}).join(", "),r="unrecognised field '"+t.str+"', possible fields: "+n;throw new o.QueryParseError(r,t.start,t.end)}e.currentClause.fields=[t.str];var i=e.peekLexeme();if(void 0==i){var r="expecting term, found nothing";throw new o.QueryParseError(r,t.start,t.end)}switch(i.type){case o.QueryLexer.TERM:return o.QueryParser.parseTerm;default:var r="expecting term, found '"+i.type+"'";throw new o.QueryParseError(r,i.start,i.end)}}},o.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(void 0!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(void 0==n)return void e.nextClause();switch(n.type){case o.QueryLexer.TERM:return e.nextClause(),o.QueryParser.parseTerm;case o.QueryLexer.FIELD:return e.nextClause(),o.QueryParser.parseField;case o.QueryLexer.EDIT_DISTANCE:return o.QueryParser.parseEditDistance;case o.QueryLexer.BOOST:return o.QueryParser.parseBoost;case o.QueryLexer.PRESENCE:return e.nextClause(),o.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+n.type+"'";throw new o.QueryParseError(r,n.start,n.end)}}},o.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(void 0!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="edit distance must be numeric";throw new o.QueryParseError(r,t.start,t.end)}e.currentClause.editDistance=n;var i=e.peekLexeme();if(void 0==i)return void e.nextClause();switch(i.type){case o.QueryLexer.TERM:return e.nextClause(),o.QueryParser.parseTerm;case o.QueryLexer.FIELD:return e.nextClause(),o.QueryParser.parseField;case o.QueryLexer.EDIT_DISTANCE:return o.QueryParser.parseEditDistance;case o.QueryLexer.BOOST:return o.QueryParser.parseBoost;case o.QueryLexer.PRESENCE:return e.nextClause(),o.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+i.type+"'";throw new o.QueryParseError(r,i.start,i.end)}}},o.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(void 0!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="boost must be numeric";throw new o.QueryParseError(r,t.start,t.end)}e.currentClause.boost=n;var i=e.peekLexeme();if(void 0==i)return void e.nextClause();switch(i.type){case o.QueryLexer.TERM:return e.nextClause(),o.QueryParser.parseTerm;case o.QueryLexer.FIELD:return e.nextClause(),o.QueryParser.parseField;case o.QueryLexer.EDIT_DISTANCE:return o.QueryParser.parseEditDistance;case o.QueryLexer.BOOST:return o.QueryParser.parseBoost;case o.QueryLexer.PRESENCE:return e.nextClause(),o.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+i.type+"'";throw new o.QueryParseError(r,i.start,i.end)}}},function(o,a){r=a,void 0!==(i="function"==typeof r?r.call(t,n,t,e):r)&&(e.exports=i)}(0,function(){return o})}()},function(e,t,n){"use strict";t.__esModule=!0;var r=n(38),i=function(e){return e&&e.__esModule?e:{default:e}}(r);t.default={Position:i.default}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=function(){function e(t,n){r(this,e);var i="string"==typeof t?document.querySelector(t):t;if(!(i instanceof HTMLElement&&i.parentNode instanceof HTMLElement))throw new ReferenceError;if(this.el_=i,this.parent_=i.parentNode,!((i="string"==typeof n?document.querySelector(n):n)instanceof HTMLElement))throw new ReferenceError;this.header_=i,this.height_=0,this.pad_="fixed"===window.getComputedStyle(this.header_).position}return e.prototype.setup=function(){var e=Array.prototype.reduce.call(this.parent_.children,function(e,t){return Math.max(e,t.offsetTop)},0);this.offset_=e-(this.pad_?this.header_.offsetHeight:0),this.update()},e.prototype.update=function(e){var t=window.pageYOffset,n=window.innerHeight;e&&"resize"===e.type&&this.setup();var r={top:this.pad_?this.header_.offsetHeight:0,bottom:this.parent_.offsetTop+this.parent_.offsetHeight},i=n-r.top-Math.max(0,this.offset_-t)-Math.max(0,t+n-r.bottom);i!==this.height_&&(this.el_.style.height=(this.height_=i)+"px"),t>=this.offset_?"lock"!==this.el_.dataset.mdState&&(this.el_.dataset.mdState="lock"):"lock"===this.el_.dataset.mdState&&(this.el_.dataset.mdState="")},e.prototype.reset=function(){this.el_.dataset.mdState="",this.el_.style.height="",this.height_=0},e}();t.default=i},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}t.__esModule=!0;var i=n(40),o=r(i),a=n(44),s=r(a);t.default={Adapter:o.default,Repository:s.default}},function(e,t,n){"use strict";t.__esModule=!0;var r=n(41),i=function(e){return e&&e.__esModule?e:{default:e}}(r);t.default={GitHub:i.default}},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}t.__esModule=!0;var a=n(42),s=function(e){return e&&e.__esModule?e:{default:e}}(a),c=function(e){function t(n){r(this,t);var o=i(this,e.call(this,n)),a=/^.+github\.com\/([^\/]+)\/?([^\/]+)?.*$/.exec(o.base_);if(a&&3===a.length){var s=a[1],c=a[2];o.base_="https://api.github.com/users/"+s+"/repos",o.name_=c}return o}return o(t,e),t.prototype.fetch_=function(){var e=this;return function t(){var n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;return fetch(e.base_+"?per_page=30&page="+n).then(function(e){return e.json()}).then(function(r){if(!(r instanceof Array))throw new TypeError;if(e.name_){var i=r.find(function(t){return t.name===e.name_});return i||30!==r.length?i?[e.format_(i.stargazers_count)+" Stars",e.format_(i.forks_count)+" Forks"]:[]:t(n+1)}return[r.length+" Repositories"]})}()},t}(s.default);t.default=c},function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}t.__esModule=!0;var i=n(43),o=function(e){return e&&e.__esModule?e:{default:e}}(i),a=function(){function e(t){r(this,e);var n="string"==typeof t?document.querySelector(t):t;if(!(n instanceof HTMLAnchorElement))throw new ReferenceError;this.el_=n,this.base_=this.el_.href,this.salt_=this.hash_(this.base_)}return e.prototype.fetch=function(){var e=this;return new Promise(function(t){var n=o.default.getJSON(e.salt_+".cache-source");void 0!==n?t(n):e.fetch_().then(function(n){o.default.set(e.salt_+".cache-source",n,{expires:1/96}),t(n)})})},e.prototype.fetch_=function(){throw new Error("fetch_(): Not implemented")},e.prototype.format_=function(e){return e>1e4?(e/1e3).toFixed(0)+"k":e>1e3?(e/1e3).toFixed(1)+"k":""+e},e.prototype.hash_=function(e){var t=0;if(0===e.length)return t;for(var n=0,r=e.length;n1){if(o=e({path:"/"},r.defaults,o),"number"==typeof o.expires){var s=new Date;s.setMilliseconds(s.getMilliseconds()+864e5*o.expires),o.expires=s}o.expires=o.expires?o.expires.toUTCString():"";try{a=JSON.stringify(i),/^[\{\[]/.test(a)&&(i=a)}catch(e){}i=n.write?n.write(i,t):encodeURIComponent(String(i)).replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),t=encodeURIComponent(String(t)),t=t.replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent),t=t.replace(/[\(\)]/g,escape);var c="";for(var u in o)o[u]&&(c+="; "+u,!0!==o[u]&&(c+="="+o[u]));return document.cookie=t+"="+i+c}t||(a={});for(var l=document.cookie?document.cookie.split("; "):[],f=/(%[0-9A-Z]{2})+/g,d=0;d=this.el_.children[0].offsetTop+-43;e!==this.active_&&(this.el_.dataset.mdState=(this.active_=e)?"hidden":"")},e.prototype.reset=function(){this.el_.dataset.mdState="",this.active_=!1},e}();t.default=i}])); \ No newline at end of file diff --git a/site/assets/javascripts/lunr/lunr.da.js b/site/assets/javascripts/lunr/lunr.da.js new file mode 100644 index 000000000..34910dfe5 --- /dev/null +++ b/site/assets/javascripts/lunr/lunr.da.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,m,i;e.da=function(){this.pipeline.reset(),this.pipeline.add(e.da.trimmer,e.da.stopWordFilter,e.da.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.da.stemmer))},e.da.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.da.trimmer=e.trimmerSupport.generateTrimmer(e.da.wordCharacters),e.Pipeline.registerFunction(e.da.trimmer,"trimmer-da"),e.da.stemmer=(r=e.stemmerSupport.Among,m=e.stemmerSupport.SnowballProgram,i=new function(){var i,t,n,s=[new r("hed",-1,1),new r("ethed",0,1),new r("ered",-1,1),new r("e",-1,1),new r("erede",3,1),new r("ende",3,1),new r("erende",5,1),new r("ene",3,1),new r("erne",3,1),new r("ere",3,1),new r("en",-1,1),new r("heden",10,1),new r("eren",10,1),new r("er",-1,1),new r("heder",13,1),new r("erer",13,1),new r("s",-1,2),new r("heds",16,1),new r("es",16,1),new r("endes",18,1),new r("erendes",19,1),new r("enes",18,1),new r("ernes",18,1),new r("eres",18,1),new r("ens",16,1),new r("hedens",24,1),new r("erens",24,1),new r("ers",16,1),new r("ets",16,1),new r("erets",28,1),new r("et",-1,1),new r("eret",30,1)],o=[new r("gd",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1)],a=[new r("ig",-1,1),new r("lig",0,1),new r("elig",1,1),new r("els",-1,1),new r("løst",-1,2)],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,48,0,128],u=[239,254,42,3,0,0,0,0,0,0,0,0,0,0,0,0,16],c=new m;function l(){var e,r=c.limit-c.cursor;c.cursor>=t&&(e=c.limit_backward,c.limit_backward=t,c.ket=c.cursor,c.find_among_b(o,4)?(c.bra=c.cursor,c.limit_backward=e,c.cursor=c.limit-r,c.cursor>c.limit_backward&&(c.cursor--,c.bra=c.cursor,c.slice_del())):c.limit_backward=e)}this.setCurrent=function(e){c.setCurrent(e)},this.getCurrent=function(){return c.getCurrent()},this.stem=function(){var e,r=c.cursor;return function(){var e,r=c.cursor+3;if(t=c.limit,0<=r&&r<=c.limit){for(i=r;;){if(e=c.cursor,c.in_grouping(d,97,248)){c.cursor=e;break}if((c.cursor=e)>=c.limit)return;c.cursor++}for(;!c.out_grouping(d,97,248);){if(c.cursor>=c.limit)return;c.cursor++}(t=c.cursor)=t&&(r=c.limit_backward,c.limit_backward=t,c.ket=c.cursor,e=c.find_among_b(s,32),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del();break;case 2:c.in_grouping_b(u,97,229)&&c.slice_del()}}(),c.cursor=c.limit,l(),c.cursor=c.limit,function(){var e,r,i,n=c.limit-c.cursor;if(c.ket=c.cursor,c.eq_s_b(2,"st")&&(c.bra=c.cursor,c.eq_s_b(2,"ig")&&c.slice_del()),c.cursor=c.limit-n,c.cursor>=t&&(r=c.limit_backward,c.limit_backward=t,c.ket=c.cursor,e=c.find_among_b(a,5),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del(),i=c.limit-c.cursor,l(),c.cursor=c.limit-i;break;case 2:c.slice_from("løs")}}(),c.cursor=c.limit,c.cursor>=t&&(e=c.limit_backward,c.limit_backward=t,c.ket=c.cursor,c.out_grouping_b(d,97,248)?(c.bra=c.cursor,n=c.slice_to(n),c.limit_backward=e,c.eq_v_b(n)&&c.slice_del()):c.limit_backward=e),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}),e.Pipeline.registerFunction(e.da.stemmer,"stemmer-da"),e.da.stopWordFilter=e.generateStopWordFilter("ad af alle alt anden at blev blive bliver da de dem den denne der deres det dette dig din disse dog du efter eller en end er et for fra ham han hans har havde have hende hendes her hos hun hvad hvis hvor i ikke ind jeg jer jo kunne man mange med meget men mig min mine mit mod ned noget nogle nu når og også om op os over på selv sig sin sine sit skal skulle som sådan thi til ud under var vi vil ville vor være været".split(" ")),e.Pipeline.registerFunction(e.da.stopWordFilter,"stopWordFilter-da")}}); \ No newline at end of file diff --git a/site/assets/javascripts/lunr/lunr.de.js b/site/assets/javascripts/lunr/lunr.de.js new file mode 100644 index 000000000..1529892c8 --- /dev/null +++ b/site/assets/javascripts/lunr/lunr.de.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var _,p,r;e.de=function(){this.pipeline.reset(),this.pipeline.add(e.de.trimmer,e.de.stopWordFilter,e.de.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.de.stemmer))},e.de.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.de.trimmer=e.trimmerSupport.generateTrimmer(e.de.wordCharacters),e.Pipeline.registerFunction(e.de.trimmer,"trimmer-de"),e.de.stemmer=(_=e.stemmerSupport.Among,p=e.stemmerSupport.SnowballProgram,r=new function(){var r,n,i,s=[new _("",-1,6),new _("U",0,2),new _("Y",0,1),new _("ä",0,3),new _("ö",0,4),new _("ü",0,5)],o=[new _("e",-1,2),new _("em",-1,1),new _("en",-1,2),new _("ern",-1,1),new _("er",-1,1),new _("s",-1,3),new _("es",5,2)],c=[new _("en",-1,1),new _("er",-1,1),new _("st",-1,2),new _("est",2,1)],u=[new _("ig",-1,1),new _("lich",-1,1)],a=[new _("end",-1,1),new _("ig",-1,2),new _("ung",-1,1),new _("lich",-1,3),new _("isch",-1,2),new _("ik",-1,2),new _("heit",-1,3),new _("keit",-1,4)],t=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32,8],d=[117,30,5],l=[117,30,4],m=new p;function h(e,r,n){return!(!m.eq_s(1,e)||(m.ket=m.cursor,!m.in_grouping(t,97,252)))&&(m.slice_from(r),m.cursor=n,!0)}function w(){for(;!m.in_grouping(t,97,252);){if(m.cursor>=m.limit)return!0;m.cursor++}for(;!m.out_grouping(t,97,252);){if(m.cursor>=m.limit)return!0;m.cursor++}return!1}function f(){return i<=m.cursor}function b(){return n<=m.cursor}this.setCurrent=function(e){m.setCurrent(e)},this.getCurrent=function(){return m.getCurrent()},this.stem=function(){var e=m.cursor;return function(){for(var e,r,n,i,s=m.cursor;;)if(e=m.cursor,m.bra=e,m.eq_s(1,"ß"))m.ket=m.cursor,m.slice_from("ss");else{if(e>=m.limit)break;m.cursor=e+1}for(m.cursor=s;;)for(r=m.cursor;;){if(n=m.cursor,m.in_grouping(t,97,252)){if(i=m.cursor,m.bra=i,h("u","U",n))break;if(m.cursor=i,h("y","Y",n))break}if(n>=m.limit)return m.cursor=r;m.cursor=n+1}}(),m.cursor=e,function(){i=m.limit,n=i;var e=m.cursor+3;0<=e&&e<=m.limit&&(r=e,w()||((i=m.cursor)=m.limit)return;m.cursor++}}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return r.setCurrent(e),r.stem(),r.getCurrent()}):(r.setCurrent(e),r.stem(),r.getCurrent())}),e.Pipeline.registerFunction(e.de.stemmer,"stemmer-de"),e.de.stopWordFilter=e.generateStopWordFilter("aber alle allem allen aller alles als also am an ander andere anderem anderen anderer anderes anderm andern anderr anders auch auf aus bei bin bis bist da damit dann das dasselbe dazu daß dein deine deinem deinen deiner deines dem demselben den denn denselben der derer derselbe derselben des desselben dessen dich die dies diese dieselbe dieselben diesem diesen dieser dieses dir doch dort du durch ein eine einem einen einer eines einig einige einigem einigen einiger einiges einmal er es etwas euch euer eure eurem euren eurer eures für gegen gewesen hab habe haben hat hatte hatten hier hin hinter ich ihm ihn ihnen ihr ihre ihrem ihren ihrer ihres im in indem ins ist jede jedem jeden jeder jedes jene jenem jenen jener jenes jetzt kann kein keine keinem keinen keiner keines können könnte machen man manche manchem manchen mancher manches mein meine meinem meinen meiner meines mich mir mit muss musste nach nicht nichts noch nun nur ob oder ohne sehr sein seine seinem seinen seiner seines selbst sich sie sind so solche solchem solchen solcher solches soll sollte sondern sonst um und uns unse unsem unsen unser unses unter viel vom von vor war waren warst was weg weil weiter welche welchem welchen welcher welches wenn werde werden wie wieder will wir wird wirst wo wollen wollte während würde würden zu zum zur zwar zwischen über".split(" ")),e.Pipeline.registerFunction(e.de.stopWordFilter,"stopWordFilter-de")}}); \ No newline at end of file diff --git a/site/assets/javascripts/lunr/lunr.du.js b/site/assets/javascripts/lunr/lunr.du.js new file mode 100644 index 000000000..588548a65 --- /dev/null +++ b/site/assets/javascripts/lunr/lunr.du.js @@ -0,0 +1 @@ +!function(r,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():e()(r.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var v,q,e;r.du=function(){this.pipeline.reset(),this.pipeline.add(r.du.trimmer,r.du.stopWordFilter,r.du.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(r.du.stemmer))},r.du.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.du.trimmer=r.trimmerSupport.generateTrimmer(r.du.wordCharacters),r.Pipeline.registerFunction(r.du.trimmer,"trimmer-du"),r.du.stemmer=(v=r.stemmerSupport.Among,q=r.stemmerSupport.SnowballProgram,e=new function(){var e,i,u,o=[new v("",-1,6),new v("á",0,1),new v("ä",0,1),new v("é",0,2),new v("ë",0,2),new v("í",0,3),new v("ï",0,3),new v("ó",0,4),new v("ö",0,4),new v("ú",0,5),new v("ü",0,5)],n=[new v("",-1,3),new v("I",0,2),new v("Y",0,1)],t=[new v("dd",-1,-1),new v("kk",-1,-1),new v("tt",-1,-1)],c=[new v("ene",-1,2),new v("se",-1,3),new v("en",-1,2),new v("heden",2,1),new v("s",-1,3)],a=[new v("end",-1,1),new v("ig",-1,2),new v("ing",-1,1),new v("lijk",-1,3),new v("baar",-1,4),new v("bar",-1,5)],l=[new v("aa",-1,-1),new v("ee",-1,-1),new v("oo",-1,-1),new v("uu",-1,-1)],m=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],d=[1,0,0,17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],f=[17,67,16,1,0,0,0,0,0,0,0,0,0,0,0,0,128],_=new q;function s(r){return(_.cursor=r)>=_.limit||(_.cursor++,!1)}function w(){for(;!_.in_grouping(m,97,232);){if(_.cursor>=_.limit)return!0;_.cursor++}for(;!_.out_grouping(m,97,232);){if(_.cursor>=_.limit)return!0;_.cursor++}return!1}function b(){return i<=_.cursor}function p(){return e<=_.cursor}function g(){var r=_.limit-_.cursor;_.find_among_b(t,3)&&(_.cursor=_.limit-r,_.ket=_.cursor,_.cursor>_.limit_backward&&(_.cursor--,_.bra=_.cursor,_.slice_del()))}function h(){var r;u=!1,_.ket=_.cursor,_.eq_s_b(1,"e")&&(_.bra=_.cursor,b()&&(r=_.limit-_.cursor,_.out_grouping_b(m,97,232)&&(_.cursor=_.limit-r,_.slice_del(),u=!0,g())))}function k(){var r;b()&&(r=_.limit-_.cursor,_.out_grouping_b(m,97,232)&&(_.cursor=_.limit-r,_.eq_s_b(3,"gem")||(_.cursor=_.limit-r,_.slice_del(),g())))}this.setCurrent=function(r){_.setCurrent(r)},this.getCurrent=function(){return _.getCurrent()},this.stem=function(){var r=_.cursor;return function(){for(var r,e,i,n=_.cursor;;){if(_.bra=_.cursor,r=_.find_among(o,11))switch(_.ket=_.cursor,r){case 1:_.slice_from("a");continue;case 2:_.slice_from("e");continue;case 3:_.slice_from("i");continue;case 4:_.slice_from("o");continue;case 5:_.slice_from("u");continue;case 6:if(_.cursor>=_.limit)break;_.cursor++;continue}break}for(_.cursor=n,_.bra=n,_.eq_s(1,"y")?(_.ket=_.cursor,_.slice_from("Y")):_.cursor=n;;)if(e=_.cursor,_.in_grouping(m,97,232)){if(i=_.cursor,_.bra=i,_.eq_s(1,"i"))_.ket=_.cursor,_.in_grouping(m,97,232)&&(_.slice_from("I"),_.cursor=e);else if(_.cursor=i,_.eq_s(1,"y"))_.ket=_.cursor,_.slice_from("Y"),_.cursor=e;else if(s(e))break}else if(s(e))break}(),_.cursor=r,i=_.limit,e=i,w()||((i=_.cursor)<3&&(i=3),w()||(e=_.cursor)),_.limit_backward=r,_.cursor=_.limit,function(){var r,e,i,n,o,t,s=_.limit-_.cursor;if(_.ket=_.cursor,r=_.find_among_b(c,5))switch(_.bra=_.cursor,r){case 1:b()&&_.slice_from("heid");break;case 2:k();break;case 3:b()&&_.out_grouping_b(f,97,232)&&_.slice_del()}if(_.cursor=_.limit-s,h(),_.cursor=_.limit-s,_.ket=_.cursor,_.eq_s_b(4,"heid")&&(_.bra=_.cursor,p()&&(e=_.limit-_.cursor,_.eq_s_b(1,"c")||(_.cursor=_.limit-e,_.slice_del(),_.ket=_.cursor,_.eq_s_b(2,"en")&&(_.bra=_.cursor,k())))),_.cursor=_.limit-s,_.ket=_.cursor,r=_.find_among_b(a,6))switch(_.bra=_.cursor,r){case 1:if(p()){if(_.slice_del(),i=_.limit-_.cursor,_.ket=_.cursor,_.eq_s_b(2,"ig")&&(_.bra=_.cursor,p()&&(n=_.limit-_.cursor,!_.eq_s_b(1,"e")))){_.cursor=_.limit-n,_.slice_del();break}_.cursor=_.limit-i,g()}break;case 2:p()&&(o=_.limit-_.cursor,_.eq_s_b(1,"e")||(_.cursor=_.limit-o,_.slice_del()));break;case 3:p()&&(_.slice_del(),h());break;case 4:p()&&_.slice_del();break;case 5:p()&&u&&_.slice_del()}_.cursor=_.limit-s,_.out_grouping_b(d,73,232)&&(t=_.limit-_.cursor,_.find_among_b(l,4)&&_.out_grouping_b(m,97,232)&&(_.cursor=_.limit-t,_.ket=_.cursor,_.cursor>_.limit_backward&&(_.cursor--,_.bra=_.cursor,_.slice_del())))}(),_.cursor=_.limit_backward,function(){for(var r;;)if(_.bra=_.cursor,r=_.find_among(n,3))switch(_.ket=_.cursor,r){case 1:_.slice_from("y");break;case 2:_.slice_from("i");break;case 3:if(_.cursor>=_.limit)return;_.cursor++}}(),!0}},function(r){return"function"==typeof r.update?r.update(function(r){return e.setCurrent(r),e.stem(),e.getCurrent()}):(e.setCurrent(r),e.stem(),e.getCurrent())}),r.Pipeline.registerFunction(r.du.stemmer,"stemmer-du"),r.du.stopWordFilter=r.generateStopWordFilter(" aan al alles als altijd andere ben bij daar dan dat de der deze die dit doch doen door dus een eens en er ge geen geweest haar had heb hebben heeft hem het hier hij hoe hun iemand iets ik in is ja je kan kon kunnen maar me meer men met mij mijn moet na naar niet niets nog nu of om omdat onder ons ook op over reeds te tegen toch toen tot u uit uw van veel voor want waren was wat werd wezen wie wil worden wordt zal ze zelf zich zij zijn zo zonder zou".split(" ")),r.Pipeline.registerFunction(r.du.stopWordFilter,"stopWordFilter-du")}}); \ No newline at end of file diff --git a/site/assets/javascripts/lunr/lunr.es.js b/site/assets/javascripts/lunr/lunr.es.js new file mode 100644 index 000000000..9de6c09cb --- /dev/null +++ b/site/assets/javascripts/lunr/lunr.es.js @@ -0,0 +1 @@ +!function(e,s){"function"==typeof define&&define.amd?define(s):"object"==typeof exports?module.exports=s():s()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var C,P,s;e.es=function(){this.pipeline.reset(),this.pipeline.add(e.es.trimmer,e.es.stopWordFilter,e.es.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.es.stemmer))},e.es.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.es.trimmer=e.trimmerSupport.generateTrimmer(e.es.wordCharacters),e.Pipeline.registerFunction(e.es.trimmer,"trimmer-es"),e.es.stemmer=(C=e.stemmerSupport.Among,P=e.stemmerSupport.SnowballProgram,s=new function(){var r,n,i,a=[new C("",-1,6),new C("á",0,1),new C("é",0,2),new C("í",0,3),new C("ó",0,4),new C("ú",0,5)],t=[new C("la",-1,-1),new C("sela",0,-1),new C("le",-1,-1),new C("me",-1,-1),new C("se",-1,-1),new C("lo",-1,-1),new C("selo",5,-1),new C("las",-1,-1),new C("selas",7,-1),new C("les",-1,-1),new C("los",-1,-1),new C("selos",10,-1),new C("nos",-1,-1)],o=[new C("ando",-1,6),new C("iendo",-1,6),new C("yendo",-1,7),new C("ándo",-1,2),new C("iéndo",-1,1),new C("ar",-1,6),new C("er",-1,6),new C("ir",-1,6),new C("ár",-1,3),new C("ér",-1,4),new C("ír",-1,5)],s=[new C("ic",-1,-1),new C("ad",-1,-1),new C("os",-1,-1),new C("iv",-1,1)],u=[new C("able",-1,1),new C("ible",-1,1),new C("ante",-1,1)],w=[new C("ic",-1,1),new C("abil",-1,1),new C("iv",-1,1)],c=[new C("ica",-1,1),new C("ancia",-1,2),new C("encia",-1,5),new C("adora",-1,2),new C("osa",-1,1),new C("ista",-1,1),new C("iva",-1,9),new C("anza",-1,1),new C("logía",-1,3),new C("idad",-1,8),new C("able",-1,1),new C("ible",-1,1),new C("ante",-1,2),new C("mente",-1,7),new C("amente",13,6),new C("ación",-1,2),new C("ución",-1,4),new C("ico",-1,1),new C("ismo",-1,1),new C("oso",-1,1),new C("amiento",-1,1),new C("imiento",-1,1),new C("ivo",-1,9),new C("ador",-1,2),new C("icas",-1,1),new C("ancias",-1,2),new C("encias",-1,5),new C("adoras",-1,2),new C("osas",-1,1),new C("istas",-1,1),new C("ivas",-1,9),new C("anzas",-1,1),new C("logías",-1,3),new C("idades",-1,8),new C("ables",-1,1),new C("ibles",-1,1),new C("aciones",-1,2),new C("uciones",-1,4),new C("adores",-1,2),new C("antes",-1,2),new C("icos",-1,1),new C("ismos",-1,1),new C("osos",-1,1),new C("amientos",-1,1),new C("imientos",-1,1),new C("ivos",-1,9)],m=[new C("ya",-1,1),new C("ye",-1,1),new C("yan",-1,1),new C("yen",-1,1),new C("yeron",-1,1),new C("yendo",-1,1),new C("yo",-1,1),new C("yas",-1,1),new C("yes",-1,1),new C("yais",-1,1),new C("yamos",-1,1),new C("yó",-1,1)],l=[new C("aba",-1,2),new C("ada",-1,2),new C("ida",-1,2),new C("ara",-1,2),new C("iera",-1,2),new C("ía",-1,2),new C("aría",5,2),new C("ería",5,2),new C("iría",5,2),new C("ad",-1,2),new C("ed",-1,2),new C("id",-1,2),new C("ase",-1,2),new C("iese",-1,2),new C("aste",-1,2),new C("iste",-1,2),new C("an",-1,2),new C("aban",16,2),new C("aran",16,2),new C("ieran",16,2),new C("ían",16,2),new C("arían",20,2),new C("erían",20,2),new C("irían",20,2),new C("en",-1,1),new C("asen",24,2),new C("iesen",24,2),new C("aron",-1,2),new C("ieron",-1,2),new C("arán",-1,2),new C("erán",-1,2),new C("irán",-1,2),new C("ado",-1,2),new C("ido",-1,2),new C("ando",-1,2),new C("iendo",-1,2),new C("ar",-1,2),new C("er",-1,2),new C("ir",-1,2),new C("as",-1,2),new C("abas",39,2),new C("adas",39,2),new C("idas",39,2),new C("aras",39,2),new C("ieras",39,2),new C("ías",39,2),new C("arías",45,2),new C("erías",45,2),new C("irías",45,2),new C("es",-1,1),new C("ases",49,2),new C("ieses",49,2),new C("abais",-1,2),new C("arais",-1,2),new C("ierais",-1,2),new C("íais",-1,2),new C("aríais",55,2),new C("eríais",55,2),new C("iríais",55,2),new C("aseis",-1,2),new C("ieseis",-1,2),new C("asteis",-1,2),new C("isteis",-1,2),new C("áis",-1,2),new C("éis",-1,1),new C("aréis",64,2),new C("eréis",64,2),new C("iréis",64,2),new C("ados",-1,2),new C("idos",-1,2),new C("amos",-1,2),new C("ábamos",70,2),new C("áramos",70,2),new C("iéramos",70,2),new C("íamos",70,2),new C("aríamos",74,2),new C("eríamos",74,2),new C("iríamos",74,2),new C("emos",-1,1),new C("aremos",78,2),new C("eremos",78,2),new C("iremos",78,2),new C("ásemos",78,2),new C("iésemos",78,2),new C("imos",-1,2),new C("arás",-1,2),new C("erás",-1,2),new C("irás",-1,2),new C("ís",-1,2),new C("ará",-1,2),new C("erá",-1,2),new C("irá",-1,2),new C("aré",-1,2),new C("eré",-1,2),new C("iré",-1,2),new C("ió",-1,2)],d=[new C("a",-1,1),new C("e",-1,2),new C("o",-1,1),new C("os",-1,1),new C("á",-1,1),new C("é",-1,2),new C("í",-1,1),new C("ó",-1,1)],b=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,4,10],f=new P;function _(){if(f.out_grouping(b,97,252)){for(;!f.in_grouping(b,97,252);){if(f.cursor>=f.limit)return!0;f.cursor++}return!1}return!0}function h(){var e,s=f.cursor;if(function(){if(f.in_grouping(b,97,252)){var e=f.cursor;if(_()){if(f.cursor=e,!f.in_grouping(b,97,252))return!0;for(;!f.out_grouping(b,97,252);){if(f.cursor>=f.limit)return!0;f.cursor++}}return!1}return!0}()){if(f.cursor=s,!f.out_grouping(b,97,252))return;if(e=f.cursor,_()){if(f.cursor=e,!f.in_grouping(b,97,252)||f.cursor>=f.limit)return;f.cursor++}}i=f.cursor}function v(){for(;!f.in_grouping(b,97,252);){if(f.cursor>=f.limit)return!1;f.cursor++}for(;!f.out_grouping(b,97,252);){if(f.cursor>=f.limit)return!1;f.cursor++}return!0}function p(){return i<=f.cursor}function g(){return r<=f.cursor}function k(e,s){if(!g())return!0;f.slice_del(),f.ket=f.cursor;var r=f.find_among_b(e,s);return r&&(f.bra=f.cursor,1==r&&g()&&f.slice_del()),!1}function y(e){return!g()||(f.slice_del(),f.ket=f.cursor,f.eq_s_b(2,e)&&(f.bra=f.cursor,g()&&f.slice_del()),!1)}function q(){var e;if(f.ket=f.cursor,e=f.find_among_b(c,46)){switch(f.bra=f.cursor,e){case 1:if(!g())return!1;f.slice_del();break;case 2:if(y("ic"))return!1;break;case 3:if(!g())return!1;f.slice_from("log");break;case 4:if(!g())return!1;f.slice_from("u");break;case 5:if(!g())return!1;f.slice_from("ente");break;case 6:if(!(n<=f.cursor))return!1;f.slice_del(),f.ket=f.cursor,(e=f.find_among_b(s,4))&&(f.bra=f.cursor,g()&&(f.slice_del(),1==e&&(f.ket=f.cursor,f.eq_s_b(2,"at")&&(f.bra=f.cursor,g()&&f.slice_del()))));break;case 7:if(k(u,3))return!1;break;case 8:if(k(w,3))return!1;break;case 9:if(y("at"))return!1}return!0}return!1}this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var e,s=f.cursor;return e=f.cursor,i=f.limit,r=n=i,h(),f.cursor=e,v()&&(n=f.cursor,v()&&(r=f.cursor)),f.limit_backward=s,f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,f.find_among_b(t,13)&&(f.bra=f.cursor,(e=f.find_among_b(o,11))&&p()))switch(e){case 1:f.bra=f.cursor,f.slice_from("iendo");break;case 2:f.bra=f.cursor,f.slice_from("ando");break;case 3:f.bra=f.cursor,f.slice_from("ar");break;case 4:f.bra=f.cursor,f.slice_from("er");break;case 5:f.bra=f.cursor,f.slice_from("ir");break;case 6:f.slice_del();break;case 7:f.eq_s_b(1,"u")&&f.slice_del()}}(),f.cursor=f.limit,q()||(f.cursor=f.limit,function(){var e,s;if(f.cursor>=i&&(s=f.limit_backward,f.limit_backward=i,f.ket=f.cursor,e=f.find_among_b(m,12),f.limit_backward=s,e)){if(f.bra=f.cursor,1==e){if(!f.eq_s_b(1,"u"))return!1;f.slice_del()}return!0}return!1}()||(f.cursor=f.limit,function(){var e,s,r,n;if(f.cursor>=i&&(s=f.limit_backward,f.limit_backward=i,f.ket=f.cursor,e=f.find_among_b(l,96),f.limit_backward=s,e))switch(f.bra=f.cursor,e){case 1:r=f.limit-f.cursor,f.eq_s_b(1,"u")?(n=f.limit-f.cursor,f.eq_s_b(1,"g")?f.cursor=f.limit-n:f.cursor=f.limit-r):f.cursor=f.limit-r,f.bra=f.cursor;case 2:f.slice_del()}}())),f.cursor=f.limit,function(){var e,s;if(f.ket=f.cursor,e=f.find_among_b(d,8))switch(f.bra=f.cursor,e){case 1:p()&&f.slice_del();break;case 2:p()&&(f.slice_del(),f.ket=f.cursor,f.eq_s_b(1,"u")&&(f.bra=f.cursor,s=f.limit-f.cursor,f.eq_s_b(1,"g")&&(f.cursor=f.limit-s,p()&&f.slice_del())))}}(),f.cursor=f.limit_backward,function(){for(var e;;){if(f.bra=f.cursor,e=f.find_among(a,6))switch(f.ket=f.cursor,e){case 1:f.slice_from("a");continue;case 2:f.slice_from("e");continue;case 3:f.slice_from("i");continue;case 4:f.slice_from("o");continue;case 5:f.slice_from("u");continue;case 6:if(f.cursor>=f.limit)break;f.cursor++;continue}break}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return s.setCurrent(e),s.stem(),s.getCurrent()}):(s.setCurrent(e),s.stem(),s.getCurrent())}),e.Pipeline.registerFunction(e.es.stemmer,"stemmer-es"),e.es.stopWordFilter=e.generateStopWordFilter("a al algo algunas algunos ante antes como con contra cual cuando de del desde donde durante e el ella ellas ellos en entre era erais eran eras eres es esa esas ese eso esos esta estaba estabais estaban estabas estad estada estadas estado estados estamos estando estar estaremos estará estarán estarás estaré estaréis estaría estaríais estaríamos estarían estarías estas este estemos esto estos estoy estuve estuviera estuvierais estuvieran estuvieras estuvieron estuviese estuvieseis estuviesen estuvieses estuvimos estuviste estuvisteis estuviéramos estuviésemos estuvo está estábamos estáis están estás esté estéis estén estés fue fuera fuerais fueran fueras fueron fuese fueseis fuesen fueses fui fuimos fuiste fuisteis fuéramos fuésemos ha habida habidas habido habidos habiendo habremos habrá habrán habrás habré habréis habría habríais habríamos habrían habrías habéis había habíais habíamos habían habías han has hasta hay haya hayamos hayan hayas hayáis he hemos hube hubiera hubierais hubieran hubieras hubieron hubiese hubieseis hubiesen hubieses hubimos hubiste hubisteis hubiéramos hubiésemos hubo la las le les lo los me mi mis mucho muchos muy más mí mía mías mío míos nada ni no nos nosotras nosotros nuestra nuestras nuestro nuestros o os otra otras otro otros para pero poco por porque que quien quienes qué se sea seamos sean seas seremos será serán serás seré seréis sería seríais seríamos serían serías seáis sido siendo sin sobre sois somos son soy su sus suya suyas suyo suyos sí también tanto te tendremos tendrá tendrán tendrás tendré tendréis tendría tendríais tendríamos tendrían tendrías tened tenemos tenga tengamos tengan tengas tengo tengáis tenida tenidas tenido tenidos teniendo tenéis tenía teníais teníamos tenían tenías ti tiene tienen tienes todo todos tu tus tuve tuviera tuvierais tuvieran tuvieras tuvieron tuviese tuvieseis tuviesen tuvieses tuvimos tuviste tuvisteis tuviéramos tuviésemos tuvo tuya tuyas tuyo tuyos tú un una uno unos vosotras vosotros vuestra vuestras vuestro vuestros y ya yo él éramos".split(" ")),e.Pipeline.registerFunction(e.es.stopWordFilter,"stopWordFilter-es")}}); \ No newline at end of file diff --git a/site/assets/javascripts/lunr/lunr.fi.js b/site/assets/javascripts/lunr/lunr.fi.js new file mode 100644 index 000000000..2f9bf5aeb --- /dev/null +++ b/site/assets/javascripts/lunr/lunr.fi.js @@ -0,0 +1 @@ +!function(i,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():e()(i.lunr)}(this,function(){return function(i){if(void 0===i)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===i.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var v,C,e;i.fi=function(){this.pipeline.reset(),this.pipeline.add(i.fi.trimmer,i.fi.stopWordFilter,i.fi.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(i.fi.stemmer))},i.fi.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",i.fi.trimmer=i.trimmerSupport.generateTrimmer(i.fi.wordCharacters),i.Pipeline.registerFunction(i.fi.trimmer,"trimmer-fi"),i.fi.stemmer=(v=i.stemmerSupport.Among,C=i.stemmerSupport.SnowballProgram,e=new function(){var n,t,l,o,r=[new v("pa",-1,1),new v("sti",-1,2),new v("kaan",-1,1),new v("han",-1,1),new v("kin",-1,1),new v("hän",-1,1),new v("kään",-1,1),new v("ko",-1,1),new v("pä",-1,1),new v("kö",-1,1)],s=[new v("lla",-1,-1),new v("na",-1,-1),new v("ssa",-1,-1),new v("ta",-1,-1),new v("lta",3,-1),new v("sta",3,-1)],a=[new v("llä",-1,-1),new v("nä",-1,-1),new v("ssä",-1,-1),new v("tä",-1,-1),new v("ltä",3,-1),new v("stä",3,-1)],u=[new v("lle",-1,-1),new v("ine",-1,-1)],c=[new v("nsa",-1,3),new v("mme",-1,3),new v("nne",-1,3),new v("ni",-1,2),new v("si",-1,1),new v("an",-1,4),new v("en",-1,6),new v("än",-1,5),new v("nsä",-1,3)],i=[new v("aa",-1,-1),new v("ee",-1,-1),new v("ii",-1,-1),new v("oo",-1,-1),new v("uu",-1,-1),new v("ää",-1,-1),new v("öö",-1,-1)],m=[new v("a",-1,8),new v("lla",0,-1),new v("na",0,-1),new v("ssa",0,-1),new v("ta",0,-1),new v("lta",4,-1),new v("sta",4,-1),new v("tta",4,9),new v("lle",-1,-1),new v("ine",-1,-1),new v("ksi",-1,-1),new v("n",-1,7),new v("han",11,1),new v("den",11,-1,q),new v("seen",11,-1,j),new v("hen",11,2),new v("tten",11,-1,q),new v("hin",11,3),new v("siin",11,-1,q),new v("hon",11,4),new v("hän",11,5),new v("hön",11,6),new v("ä",-1,8),new v("llä",22,-1),new v("nä",22,-1),new v("ssä",22,-1),new v("tä",22,-1),new v("ltä",26,-1),new v("stä",26,-1),new v("ttä",26,9)],w=[new v("eja",-1,-1),new v("mma",-1,1),new v("imma",1,-1),new v("mpa",-1,1),new v("impa",3,-1),new v("mmi",-1,1),new v("immi",5,-1),new v("mpi",-1,1),new v("impi",7,-1),new v("ejä",-1,-1),new v("mmä",-1,1),new v("immä",10,-1),new v("mpä",-1,1),new v("impä",12,-1)],_=[new v("i",-1,-1),new v("j",-1,-1)],k=[new v("mma",-1,1),new v("imma",0,-1)],b=[17,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8],d=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],e=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],f=[17,97,24,1,0,0,0,0,0,0,0,0,0,0,0,0,8,0,32],h=new C;function p(){for(var i;i=h.cursor,!h.in_grouping(d,97,246);){if((h.cursor=i)>=h.limit)return!0;h.cursor++}for(h.cursor=i;!h.out_grouping(d,97,246);){if(h.cursor>=h.limit)return!0;h.cursor++}return!1}function g(){var i,e;if(h.cursor>=o)if(e=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,i=h.find_among_b(r,10)){switch(h.bra=h.cursor,h.limit_backward=e,i){case 1:if(!h.in_grouping_b(f,97,246))return;break;case 2:if(!(l<=h.cursor))return}h.slice_del()}else h.limit_backward=e}function j(){return h.find_among_b(i,7)}function q(){return h.eq_s_b(1,"i")&&h.in_grouping_b(e,97,246)}this.setCurrent=function(i){h.setCurrent(i)},this.getCurrent=function(){return h.getCurrent()},this.stem=function(){var i,e=h.cursor;return o=h.limit,l=o,p()||(o=h.cursor,p()||(l=h.cursor)),n=!1,h.limit_backward=e,h.cursor=h.limit,g(),h.cursor=h.limit,function(){var i,e,r;if(h.cursor>=o)if(e=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,i=h.find_among_b(c,9))switch(h.bra=h.cursor,h.limit_backward=e,i){case 1:r=h.limit-h.cursor,h.eq_s_b(1,"k")||(h.cursor=h.limit-r,h.slice_del());break;case 2:h.slice_del(),h.ket=h.cursor,h.eq_s_b(3,"kse")&&(h.bra=h.cursor,h.slice_from("ksi"));break;case 3:h.slice_del();break;case 4:h.find_among_b(s,6)&&h.slice_del();break;case 5:h.find_among_b(a,6)&&h.slice_del();break;case 6:h.find_among_b(u,2)&&h.slice_del()}else h.limit_backward=e}(),h.cursor=h.limit,function(){var i,e,r;if(h.cursor>=o)if(e=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,i=h.find_among_b(m,30)){switch(h.bra=h.cursor,h.limit_backward=e,i){case 1:if(!h.eq_s_b(1,"a"))return;break;case 2:case 9:if(!h.eq_s_b(1,"e"))return;break;case 3:if(!h.eq_s_b(1,"i"))return;break;case 4:if(!h.eq_s_b(1,"o"))return;break;case 5:if(!h.eq_s_b(1,"ä"))return;break;case 6:if(!h.eq_s_b(1,"ö"))return;break;case 7:if(r=h.limit-h.cursor,!j()&&(h.cursor=h.limit-r,!h.eq_s_b(2,"ie"))){h.cursor=h.limit-r;break}if(h.cursor=h.limit-r,h.cursor<=h.limit_backward){h.cursor=h.limit-r;break}h.cursor--,h.bra=h.cursor;break;case 8:if(!h.in_grouping_b(d,97,246)||!h.out_grouping_b(d,97,246))return}h.slice_del(),n=!0}else h.limit_backward=e}(),h.cursor=h.limit,function(){var i,e,r;if(h.cursor>=l)if(e=h.limit_backward,h.limit_backward=l,h.ket=h.cursor,i=h.find_among_b(w,14)){if(h.bra=h.cursor,h.limit_backward=e,1==i){if(r=h.limit-h.cursor,h.eq_s_b(2,"po"))return;h.cursor=h.limit-r}h.slice_del()}else h.limit_backward=e}(),h.cursor=h.limit,h.cursor=(n?h.cursor>=o&&(i=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,h.find_among_b(_,2)?(h.bra=h.cursor,h.limit_backward=i,h.slice_del()):h.limit_backward=i):(h.cursor=h.limit,function(){var i,e,r,n,t,s;if(h.cursor>=o){if(e=h.limit_backward,h.limit_backward=o,h.ket=h.cursor,h.eq_s_b(1,"t")&&(h.bra=h.cursor,r=h.limit-h.cursor,h.in_grouping_b(d,97,246)&&(h.cursor=h.limit-r,h.slice_del(),h.limit_backward=e,n=h.limit-h.cursor,h.cursor>=l&&(h.cursor=l,t=h.limit_backward,h.limit_backward=h.cursor,h.cursor=h.limit-n,h.ket=h.cursor,i=h.find_among_b(k,2))))){if(h.bra=h.cursor,h.limit_backward=t,1==i){if(s=h.limit-h.cursor,h.eq_s_b(2,"po"))return;h.cursor=h.limit-s}return h.slice_del()}h.limit_backward=e}}()),h.limit),function(){var i,e,r,n;if(h.cursor>=o){for(i=h.limit_backward,h.limit_backward=o,e=h.limit-h.cursor,j()&&(h.cursor=h.limit-e,h.ket=h.cursor,h.cursor>h.limit_backward&&(h.cursor--,h.bra=h.cursor,h.slice_del())),h.cursor=h.limit-e,h.ket=h.cursor,h.in_grouping_b(b,97,228)&&(h.bra=h.cursor,h.out_grouping_b(d,97,246)&&h.slice_del()),h.cursor=h.limit-e,h.ket=h.cursor,h.eq_s_b(1,"j")&&(h.bra=h.cursor,r=h.limit-h.cursor,h.eq_s_b(1,"o")?h.slice_del():(h.cursor=h.limit-r,h.eq_s_b(1,"u")&&h.slice_del())),h.cursor=h.limit-e,h.ket=h.cursor,h.eq_s_b(1,"o")&&(h.bra=h.cursor,h.eq_s_b(1,"j")&&h.slice_del()),h.cursor=h.limit-e,h.limit_backward=i;;){if(n=h.limit-h.cursor,h.out_grouping_b(d,97,246)){h.cursor=h.limit-n;break}if(h.cursor=h.limit-n,h.cursor<=h.limit_backward)return;h.cursor--}h.ket=h.cursor,h.cursor>h.limit_backward&&(h.cursor--,h.bra=h.cursor,t=h.slice_to(),h.eq_v_b(t)&&h.slice_del())}}(),!0}},function(i){return"function"==typeof i.update?i.update(function(i){return e.setCurrent(i),e.stem(),e.getCurrent()}):(e.setCurrent(i),e.stem(),e.getCurrent())}),i.Pipeline.registerFunction(i.fi.stemmer,"stemmer-fi"),i.fi.stopWordFilter=i.generateStopWordFilter("ei eivät emme en et ette että he heidän heidät heihin heille heillä heiltä heissä heistä heitä hän häneen hänelle hänellä häneltä hänen hänessä hänestä hänet häntä itse ja johon joiden joihin joiksi joilla joille joilta joina joissa joista joita joka joksi jolla jolle jolta jona jonka jos jossa josta jota jotka kanssa keiden keihin keiksi keille keillä keiltä keinä keissä keistä keitä keneen keneksi kenelle kenellä keneltä kenen kenenä kenessä kenestä kenet ketkä ketkä ketä koska kuin kuka kun me meidän meidät meihin meille meillä meiltä meissä meistä meitä mihin miksi mikä mille millä miltä minkä minkä minua minulla minulle minulta minun minussa minusta minut minuun minä minä missä mistä mitkä mitä mukaan mutta ne niiden niihin niiksi niille niillä niiltä niin niin niinä niissä niistä niitä noiden noihin noiksi noilla noille noilta noin noina noissa noista noita nuo nyt näiden näihin näiksi näille näillä näiltä näinä näissä näistä näitä nämä ole olemme olen olet olette oli olimme olin olisi olisimme olisin olisit olisitte olisivat olit olitte olivat olla olleet ollut on ovat poikki se sekä sen siihen siinä siitä siksi sille sillä sillä siltä sinua sinulla sinulle sinulta sinun sinussa sinusta sinut sinuun sinä sinä sitä tai te teidän teidät teihin teille teillä teiltä teissä teistä teitä tuo tuohon tuoksi tuolla tuolle tuolta tuon tuona tuossa tuosta tuota tähän täksi tälle tällä tältä tämä tämän tänä tässä tästä tätä vaan vai vaikka yli".split(" ")),i.Pipeline.registerFunction(i.fi.stopWordFilter,"stopWordFilter-fi")}}); \ No newline at end of file diff --git a/site/assets/javascripts/lunr/lunr.fr.js b/site/assets/javascripts/lunr/lunr.fr.js new file mode 100644 index 000000000..078d0cab7 --- /dev/null +++ b/site/assets/javascripts/lunr/lunr.fr.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,y,s;e.fr=function(){this.pipeline.reset(),this.pipeline.add(e.fr.trimmer,e.fr.stopWordFilter,e.fr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.fr.stemmer))},e.fr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.fr.trimmer=e.trimmerSupport.generateTrimmer(e.fr.wordCharacters),e.Pipeline.registerFunction(e.fr.trimmer,"trimmer-fr"),e.fr.stemmer=(r=e.stemmerSupport.Among,y=e.stemmerSupport.SnowballProgram,s=new function(){var s,i,t,n=[new r("col",-1,-1),new r("par",-1,-1),new r("tap",-1,-1)],u=[new r("",-1,4),new r("I",0,1),new r("U",0,2),new r("Y",0,3)],o=[new r("iqU",-1,3),new r("abl",-1,3),new r("Ièr",-1,4),new r("ièr",-1,4),new r("eus",-1,2),new r("iv",-1,1)],c=[new r("ic",-1,2),new r("abil",-1,1),new r("iv",-1,3)],a=[new r("iqUe",-1,1),new r("atrice",-1,2),new r("ance",-1,1),new r("ence",-1,5),new r("logie",-1,3),new r("able",-1,1),new r("isme",-1,1),new r("euse",-1,11),new r("iste",-1,1),new r("ive",-1,8),new r("if",-1,8),new r("usion",-1,4),new r("ation",-1,2),new r("ution",-1,4),new r("ateur",-1,2),new r("iqUes",-1,1),new r("atrices",-1,2),new r("ances",-1,1),new r("ences",-1,5),new r("logies",-1,3),new r("ables",-1,1),new r("ismes",-1,1),new r("euses",-1,11),new r("istes",-1,1),new r("ives",-1,8),new r("ifs",-1,8),new r("usions",-1,4),new r("ations",-1,2),new r("utions",-1,4),new r("ateurs",-1,2),new r("ments",-1,15),new r("ements",30,6),new r("issements",31,12),new r("ités",-1,7),new r("ment",-1,15),new r("ement",34,6),new r("issement",35,12),new r("amment",34,13),new r("emment",34,14),new r("aux",-1,10),new r("eaux",39,9),new r("eux",-1,1),new r("ité",-1,7)],l=[new r("ira",-1,1),new r("ie",-1,1),new r("isse",-1,1),new r("issante",-1,1),new r("i",-1,1),new r("irai",4,1),new r("ir",-1,1),new r("iras",-1,1),new r("ies",-1,1),new r("îmes",-1,1),new r("isses",-1,1),new r("issantes",-1,1),new r("îtes",-1,1),new r("is",-1,1),new r("irais",13,1),new r("issais",13,1),new r("irions",-1,1),new r("issions",-1,1),new r("irons",-1,1),new r("issons",-1,1),new r("issants",-1,1),new r("it",-1,1),new r("irait",21,1),new r("issait",21,1),new r("issant",-1,1),new r("iraIent",-1,1),new r("issaIent",-1,1),new r("irent",-1,1),new r("issent",-1,1),new r("iront",-1,1),new r("ît",-1,1),new r("iriez",-1,1),new r("issiez",-1,1),new r("irez",-1,1),new r("issez",-1,1)],w=[new r("a",-1,3),new r("era",0,2),new r("asse",-1,3),new r("ante",-1,3),new r("ée",-1,2),new r("ai",-1,3),new r("erai",5,2),new r("er",-1,2),new r("as",-1,3),new r("eras",8,2),new r("âmes",-1,3),new r("asses",-1,3),new r("antes",-1,3),new r("âtes",-1,3),new r("ées",-1,2),new r("ais",-1,3),new r("erais",15,2),new r("ions",-1,1),new r("erions",17,2),new r("assions",17,3),new r("erons",-1,2),new r("ants",-1,3),new r("és",-1,2),new r("ait",-1,3),new r("erait",23,2),new r("ant",-1,3),new r("aIent",-1,3),new r("eraIent",26,2),new r("èrent",-1,2),new r("assent",-1,3),new r("eront",-1,2),new r("ât",-1,3),new r("ez",-1,2),new r("iez",32,2),new r("eriez",33,2),new r("assiez",33,3),new r("erez",32,2),new r("é",-1,2)],f=[new r("e",-1,3),new r("Ière",0,2),new r("ière",0,2),new r("ion",-1,1),new r("Ier",-1,2),new r("ier",-1,2),new r("ë",-1,4)],m=[new r("ell",-1,-1),new r("eill",-1,-1),new r("enn",-1,-1),new r("onn",-1,-1),new r("ett",-1,-1)],_=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,128,130,103,8,5],b=[1,65,20,0,0,0,0,0,0,0,0,0,0,0,0,0,128],d=new y;function k(e,r,s){return!(!d.eq_s(1,e)||(d.ket=d.cursor,!d.in_grouping(_,97,251)))&&(d.slice_from(r),d.cursor=s,!0)}function p(e,r,s){return!!d.eq_s(1,e)&&(d.ket=d.cursor,d.slice_from(r),d.cursor=s,!0)}function g(){for(;!d.in_grouping(_,97,251);){if(d.cursor>=d.limit)return!0;d.cursor++}for(;!d.out_grouping(_,97,251);){if(d.cursor>=d.limit)return!0;d.cursor++}return!1}function q(){return t<=d.cursor}function v(){return i<=d.cursor}function h(){return s<=d.cursor}function z(){if(!function(){var e,r;if(d.ket=d.cursor,e=d.find_among_b(a,43)){switch(d.bra=d.cursor,e){case 1:if(!h())return!1;d.slice_del();break;case 2:if(!h())return!1;d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,"ic")&&(d.bra=d.cursor,h()?d.slice_del():d.slice_from("iqU"));break;case 3:if(!h())return!1;d.slice_from("log");break;case 4:if(!h())return!1;d.slice_from("u");break;case 5:if(!h())return!1;d.slice_from("ent");break;case 6:if(!q())return!1;if(d.slice_del(),d.ket=d.cursor,e=d.find_among_b(o,6))switch(d.bra=d.cursor,e){case 1:h()&&(d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,"at")&&(d.bra=d.cursor,h()&&d.slice_del()));break;case 2:h()?d.slice_del():v()&&d.slice_from("eux");break;case 3:h()&&d.slice_del();break;case 4:q()&&d.slice_from("i")}break;case 7:if(!h())return!1;if(d.slice_del(),d.ket=d.cursor,e=d.find_among_b(c,3))switch(d.bra=d.cursor,e){case 1:h()?d.slice_del():d.slice_from("abl");break;case 2:h()?d.slice_del():d.slice_from("iqU");break;case 3:h()&&d.slice_del()}break;case 8:if(!h())return!1;if(d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,"at")&&(d.bra=d.cursor,h()&&(d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,"ic")))){d.bra=d.cursor,h()?d.slice_del():d.slice_from("iqU");break}break;case 9:d.slice_from("eau");break;case 10:if(!v())return!1;d.slice_from("al");break;case 11:if(h())d.slice_del();else{if(!v())return!1;d.slice_from("eux")}break;case 12:if(!v()||!d.out_grouping_b(_,97,251))return!1;d.slice_del();break;case 13:return q()&&d.slice_from("ant"),!1;case 14:return q()&&d.slice_from("ent"),!1;case 15:return r=d.limit-d.cursor,d.in_grouping_b(_,97,251)&&q()&&(d.cursor=d.limit-r,d.slice_del()),!1}return!0}return!1}()&&(d.cursor=d.limit,!function(){var e,r;if(d.cursor=t){if(s=d.limit_backward,d.limit_backward=t,d.ket=d.cursor,e=d.find_among_b(f,7))switch(d.bra=d.cursor,e){case 1:if(h()){if(i=d.limit-d.cursor,!d.eq_s_b(1,"s")&&(d.cursor=d.limit-i,!d.eq_s_b(1,"t")))break;d.slice_del()}break;case 2:d.slice_from("i");break;case 3:d.slice_del();break;case 4:d.eq_s_b(2,"gu")&&d.slice_del()}d.limit_backward=s}}();d.cursor=d.limit,d.ket=d.cursor,d.eq_s_b(1,"Y")?(d.bra=d.cursor,d.slice_from("i")):(d.cursor=d.limit,d.eq_s_b(1,"ç")&&(d.bra=d.cursor,d.slice_from("c")))}this.setCurrent=function(e){d.setCurrent(e)},this.getCurrent=function(){return d.getCurrent()},this.stem=function(){var e,r=d.cursor;return function(){for(var e,r;;){if(e=d.cursor,d.in_grouping(_,97,251)){if(d.bra=d.cursor,r=d.cursor,k("u","U",e))continue;if(d.cursor=r,k("i","I",e))continue;if(d.cursor=r,p("y","Y",e))continue}if(d.cursor=e,!k("y","Y",d.bra=e)){if(d.cursor=e,d.eq_s(1,"q")&&(d.bra=d.cursor,p("u","U",e)))continue;if((d.cursor=e)>=d.limit)return;d.cursor++}}}(),d.cursor=r,function(){var e=d.cursor;if(t=d.limit,s=i=t,d.in_grouping(_,97,251)&&d.in_grouping(_,97,251)&&d.cursor=d.limit){d.cursor=t;break}d.cursor++}while(!d.in_grouping(_,97,251))}t=d.cursor,d.cursor=e,g()||(i=d.cursor,g()||(s=d.cursor))}(),d.limit_backward=r,d.cursor=d.limit,z(),d.cursor=d.limit,e=d.limit-d.cursor,d.find_among_b(m,5)&&(d.cursor=d.limit-e,d.ket=d.cursor,d.cursor>d.limit_backward&&(d.cursor--,d.bra=d.cursor,d.slice_del())),d.cursor=d.limit,function(){for(var e,r=1;d.out_grouping_b(_,97,251);)r--;if(r<=0){if(d.ket=d.cursor,e=d.limit-d.cursor,!d.eq_s_b(1,"é")&&(d.cursor=d.limit-e,!d.eq_s_b(1,"è")))return;d.bra=d.cursor,d.slice_from("e")}}(),d.cursor=d.limit_backward,function(){for(var e,r;r=d.cursor,d.bra=r,e=d.find_among(u,4);)switch(d.ket=d.cursor,e){case 1:d.slice_from("i");break;case 2:d.slice_from("u");break;case 3:d.slice_from("y");break;case 4:if(d.cursor>=d.limit)return;d.cursor++}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return s.setCurrent(e),s.stem(),s.getCurrent()}):(s.setCurrent(e),s.stem(),s.getCurrent())}),e.Pipeline.registerFunction(e.fr.stemmer,"stemmer-fr"),e.fr.stopWordFilter=e.generateStopWordFilter("ai aie aient aies ait as au aura aurai auraient aurais aurait auras aurez auriez aurions aurons auront aux avaient avais avait avec avez aviez avions avons ayant ayez ayons c ce ceci celà ces cet cette d dans de des du elle en es est et eu eue eues eurent eus eusse eussent eusses eussiez eussions eut eux eûmes eût eûtes furent fus fusse fussent fusses fussiez fussions fut fûmes fût fûtes ici il ils j je l la le les leur leurs lui m ma mais me mes moi mon même n ne nos notre nous on ont ou par pas pour qu que quel quelle quelles quels qui s sa sans se sera serai seraient serais serait seras serez seriez serions serons seront ses soi soient sois soit sommes son sont soyez soyons suis sur t ta te tes toi ton tu un une vos votre vous y à étaient étais était étant étiez étions été étée étées étés êtes".split(" ")),e.Pipeline.registerFunction(e.fr.stopWordFilter,"stopWordFilter-fr")}}); \ No newline at end of file diff --git a/site/assets/javascripts/lunr/lunr.hu.js b/site/assets/javascripts/lunr/lunr.hu.js new file mode 100644 index 000000000..56a4b0dc1 --- /dev/null +++ b/site/assets/javascripts/lunr/lunr.hu.js @@ -0,0 +1 @@ +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var p,_,n;e.hu=function(){this.pipeline.reset(),this.pipeline.add(e.hu.trimmer,e.hu.stopWordFilter,e.hu.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.hu.stemmer))},e.hu.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.hu.trimmer=e.trimmerSupport.generateTrimmer(e.hu.wordCharacters),e.Pipeline.registerFunction(e.hu.trimmer,"trimmer-hu"),e.hu.stemmer=(p=e.stemmerSupport.Among,_=e.stemmerSupport.SnowballProgram,n=new function(){var r,i=[new p("cs",-1,-1),new p("dzs",-1,-1),new p("gy",-1,-1),new p("ly",-1,-1),new p("ny",-1,-1),new p("sz",-1,-1),new p("ty",-1,-1),new p("zs",-1,-1)],n=[new p("á",-1,1),new p("é",-1,2)],a=[new p("bb",-1,-1),new p("cc",-1,-1),new p("dd",-1,-1),new p("ff",-1,-1),new p("gg",-1,-1),new p("jj",-1,-1),new p("kk",-1,-1),new p("ll",-1,-1),new p("mm",-1,-1),new p("nn",-1,-1),new p("pp",-1,-1),new p("rr",-1,-1),new p("ccs",-1,-1),new p("ss",-1,-1),new p("zzs",-1,-1),new p("tt",-1,-1),new p("vv",-1,-1),new p("ggy",-1,-1),new p("lly",-1,-1),new p("nny",-1,-1),new p("tty",-1,-1),new p("ssz",-1,-1),new p("zz",-1,-1)],t=[new p("al",-1,1),new p("el",-1,2)],e=[new p("ba",-1,-1),new p("ra",-1,-1),new p("be",-1,-1),new p("re",-1,-1),new p("ig",-1,-1),new p("nak",-1,-1),new p("nek",-1,-1),new p("val",-1,-1),new p("vel",-1,-1),new p("ul",-1,-1),new p("nál",-1,-1),new p("nél",-1,-1),new p("ból",-1,-1),new p("ról",-1,-1),new p("tól",-1,-1),new p("bõl",-1,-1),new p("rõl",-1,-1),new p("tõl",-1,-1),new p("ül",-1,-1),new p("n",-1,-1),new p("an",19,-1),new p("ban",20,-1),new p("en",19,-1),new p("ben",22,-1),new p("képpen",22,-1),new p("on",19,-1),new p("ön",19,-1),new p("képp",-1,-1),new p("kor",-1,-1),new p("t",-1,-1),new p("at",29,-1),new p("et",29,-1),new p("ként",29,-1),new p("anként",32,-1),new p("enként",32,-1),new p("onként",32,-1),new p("ot",29,-1),new p("ért",29,-1),new p("öt",29,-1),new p("hez",-1,-1),new p("hoz",-1,-1),new p("höz",-1,-1),new p("vá",-1,-1),new p("vé",-1,-1)],s=[new p("án",-1,2),new p("én",-1,1),new p("ánként",-1,3)],c=[new p("stul",-1,2),new p("astul",0,1),new p("ástul",0,3),new p("stül",-1,2),new p("estül",3,1),new p("éstül",3,4)],w=[new p("á",-1,1),new p("é",-1,2)],o=[new p("k",-1,7),new p("ak",0,4),new p("ek",0,6),new p("ok",0,5),new p("ák",0,1),new p("ék",0,2),new p("ök",0,3)],l=[new p("éi",-1,7),new p("áéi",0,6),new p("ééi",0,5),new p("é",-1,9),new p("ké",3,4),new p("aké",4,1),new p("eké",4,1),new p("oké",4,1),new p("áké",4,3),new p("éké",4,2),new p("öké",4,1),new p("éé",3,8)],u=[new p("a",-1,18),new p("ja",0,17),new p("d",-1,16),new p("ad",2,13),new p("ed",2,13),new p("od",2,13),new p("ád",2,14),new p("éd",2,15),new p("öd",2,13),new p("e",-1,18),new p("je",9,17),new p("nk",-1,4),new p("unk",11,1),new p("ánk",11,2),new p("énk",11,3),new p("ünk",11,1),new p("uk",-1,8),new p("juk",16,7),new p("ájuk",17,5),new p("ük",-1,8),new p("jük",19,7),new p("éjük",20,6),new p("m",-1,12),new p("am",22,9),new p("em",22,9),new p("om",22,9),new p("ám",22,10),new p("ém",22,11),new p("o",-1,18),new p("á",-1,19),new p("é",-1,20)],m=[new p("id",-1,10),new p("aid",0,9),new p("jaid",1,6),new p("eid",0,9),new p("jeid",3,6),new p("áid",0,7),new p("éid",0,8),new p("i",-1,15),new p("ai",7,14),new p("jai",8,11),new p("ei",7,14),new p("jei",10,11),new p("ái",7,12),new p("éi",7,13),new p("itek",-1,24),new p("eitek",14,21),new p("jeitek",15,20),new p("éitek",14,23),new p("ik",-1,29),new p("aik",18,26),new p("jaik",19,25),new p("eik",18,26),new p("jeik",21,25),new p("áik",18,27),new p("éik",18,28),new p("ink",-1,20),new p("aink",25,17),new p("jaink",26,16),new p("eink",25,17),new p("jeink",28,16),new p("áink",25,18),new p("éink",25,19),new p("aitok",-1,21),new p("jaitok",32,20),new p("áitok",-1,22),new p("im",-1,5),new p("aim",35,4),new p("jaim",36,1),new p("eim",35,4),new p("jeim",38,1),new p("áim",35,2),new p("éim",35,3)],k=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,1,17,52,14],f=new _;function b(){return r<=f.cursor}function d(){var e=f.limit-f.cursor;return!!f.find_among_b(a,23)&&(f.cursor=f.limit-e,!0)}function g(){if(f.cursor>f.limit_backward){f.cursor--,f.ket=f.cursor;var e=f.cursor-1;f.limit_backward<=e&&e<=f.limit&&(f.cursor=e,f.bra=e,f.slice_del())}}function h(){f.ket=f.cursor,f.find_among_b(e,44)&&(f.bra=f.cursor,b()&&(f.slice_del(),function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(n,2))&&(f.bra=f.cursor,b()))switch(e){case 1:f.slice_from("a");break;case 2:f.slice_from("e")}}()))}this.setCurrent=function(e){f.setCurrent(e)},this.getCurrent=function(){return f.getCurrent()},this.stem=function(){var e=f.cursor;return function(){var e,n=f.cursor;if(r=f.limit,f.in_grouping(k,97,252))for(;;){if(e=f.cursor,f.out_grouping(k,97,252))return f.cursor=e,f.find_among(i,8)||(f.cursor=e)=f.limit)return r=e;f.cursor++}if(f.cursor=n,f.out_grouping(k,97,252)){for(;!f.in_grouping(k,97,252);){if(f.cursor>=f.limit)return;f.cursor++}r=f.cursor}}(),f.limit_backward=e,f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(t,2))&&(f.bra=f.cursor,b())){if((1==e||2==e)&&!d())return;f.slice_del(),g()}}(),f.cursor=f.limit,h(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(s,3))&&(f.bra=f.cursor,b()))switch(e){case 1:f.slice_from("e");break;case 2:case 3:f.slice_from("a")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(c,6))&&(f.bra=f.cursor,b()))switch(e){case 1:case 2:f.slice_del();break;case 3:f.slice_from("a");break;case 4:f.slice_from("e")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(w,2))&&(f.bra=f.cursor,b())){if((1==e||2==e)&&!d())return;f.slice_del(),g()}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(l,12))&&(f.bra=f.cursor,b()))switch(e){case 1:case 4:case 7:case 9:f.slice_del();break;case 2:case 5:case 8:f.slice_from("e");break;case 3:case 6:f.slice_from("a")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(u,31))&&(f.bra=f.cursor,b()))switch(e){case 1:case 4:case 7:case 8:case 9:case 12:case 13:case 16:case 17:case 18:f.slice_del();break;case 2:case 5:case 10:case 14:case 19:f.slice_from("a");break;case 3:case 6:case 11:case 15:case 20:f.slice_from("e")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(m,42))&&(f.bra=f.cursor,b()))switch(e){case 1:case 4:case 5:case 6:case 9:case 10:case 11:case 14:case 15:case 16:case 17:case 20:case 21:case 24:case 25:case 26:case 29:f.slice_del();break;case 2:case 7:case 12:case 18:case 22:case 27:f.slice_from("a");break;case 3:case 8:case 13:case 19:case 23:case 28:f.slice_from("e")}}(),f.cursor=f.limit,function(){var e;if(f.ket=f.cursor,(e=f.find_among_b(o,7))&&(f.bra=f.cursor,b()))switch(e){case 1:f.slice_from("a");break;case 2:f.slice_from("e");break;case 3:case 4:case 5:case 6:case 7:f.slice_del()}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}),e.Pipeline.registerFunction(e.hu.stemmer,"stemmer-hu"),e.hu.stopWordFilter=e.generateStopWordFilter("a abban ahhoz ahogy ahol aki akik akkor alatt amely amelyek amelyekben amelyeket amelyet amelynek ami amikor amit amolyan amíg annak arra arról az azok azon azonban azt aztán azután azzal azért be belül benne bár cikk cikkek cikkeket csak de e ebben eddig egy egyes egyetlen egyik egyre egyéb egész ehhez ekkor el ellen elsõ elég elõ elõször elõtt emilyen ennek erre ez ezek ezen ezt ezzel ezért fel felé hanem hiszen hogy hogyan igen ill ill. illetve ilyen ilyenkor ismét ison itt jobban jó jól kell kellett keressünk keresztül ki kívül között közül legalább legyen lehet lehetett lenne lenni lesz lett maga magát majd majd meg mellett mely melyek mert mi mikor milyen minden mindenki mindent mindig mint mintha mit mivel miért most már más másik még míg nagy nagyobb nagyon ne nekem neki nem nincs néha néhány nélkül olyan ott pedig persze rá s saját sem semmi sok sokat sokkal szemben szerint szinte számára talán tehát teljes tovább továbbá több ugyanis utolsó után utána vagy vagyis vagyok valaki valami valamint való van vannak vele vissza viszont volna volt voltak voltam voltunk által általában át én éppen és így õ õk õket össze úgy új újabb újra".split(" ")),e.Pipeline.registerFunction(e.hu.stopWordFilter,"stopWordFilter-hu")}}); \ No newline at end of file diff --git a/site/assets/javascripts/lunr/lunr.it.js b/site/assets/javascripts/lunr/lunr.it.js new file mode 100644 index 000000000..50dddaa04 --- /dev/null +++ b/site/assets/javascripts/lunr/lunr.it.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var z,P,r;e.it=function(){this.pipeline.reset(),this.pipeline.add(e.it.trimmer,e.it.stopWordFilter,e.it.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.it.stemmer))},e.it.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.it.trimmer=e.trimmerSupport.generateTrimmer(e.it.wordCharacters),e.Pipeline.registerFunction(e.it.trimmer,"trimmer-it"),e.it.stemmer=(z=e.stemmerSupport.Among,P=e.stemmerSupport.SnowballProgram,r=new function(){var o,t,s,a=[new z("",-1,7),new z("qu",0,6),new z("á",0,1),new z("é",0,2),new z("í",0,3),new z("ó",0,4),new z("ú",0,5)],u=[new z("",-1,3),new z("I",0,1),new z("U",0,2)],c=[new z("la",-1,-1),new z("cela",0,-1),new z("gliela",0,-1),new z("mela",0,-1),new z("tela",0,-1),new z("vela",0,-1),new z("le",-1,-1),new z("cele",6,-1),new z("gliele",6,-1),new z("mele",6,-1),new z("tele",6,-1),new z("vele",6,-1),new z("ne",-1,-1),new z("cene",12,-1),new z("gliene",12,-1),new z("mene",12,-1),new z("sene",12,-1),new z("tene",12,-1),new z("vene",12,-1),new z("ci",-1,-1),new z("li",-1,-1),new z("celi",20,-1),new z("glieli",20,-1),new z("meli",20,-1),new z("teli",20,-1),new z("veli",20,-1),new z("gli",20,-1),new z("mi",-1,-1),new z("si",-1,-1),new z("ti",-1,-1),new z("vi",-1,-1),new z("lo",-1,-1),new z("celo",31,-1),new z("glielo",31,-1),new z("melo",31,-1),new z("telo",31,-1),new z("velo",31,-1)],w=[new z("ando",-1,1),new z("endo",-1,1),new z("ar",-1,2),new z("er",-1,2),new z("ir",-1,2)],r=[new z("ic",-1,-1),new z("abil",-1,-1),new z("os",-1,-1),new z("iv",-1,1)],n=[new z("ic",-1,1),new z("abil",-1,1),new z("iv",-1,1)],i=[new z("ica",-1,1),new z("logia",-1,3),new z("osa",-1,1),new z("ista",-1,1),new z("iva",-1,9),new z("anza",-1,1),new z("enza",-1,5),new z("ice",-1,1),new z("atrice",7,1),new z("iche",-1,1),new z("logie",-1,3),new z("abile",-1,1),new z("ibile",-1,1),new z("usione",-1,4),new z("azione",-1,2),new z("uzione",-1,4),new z("atore",-1,2),new z("ose",-1,1),new z("ante",-1,1),new z("mente",-1,1),new z("amente",19,7),new z("iste",-1,1),new z("ive",-1,9),new z("anze",-1,1),new z("enze",-1,5),new z("ici",-1,1),new z("atrici",25,1),new z("ichi",-1,1),new z("abili",-1,1),new z("ibili",-1,1),new z("ismi",-1,1),new z("usioni",-1,4),new z("azioni",-1,2),new z("uzioni",-1,4),new z("atori",-1,2),new z("osi",-1,1),new z("anti",-1,1),new z("amenti",-1,6),new z("imenti",-1,6),new z("isti",-1,1),new z("ivi",-1,9),new z("ico",-1,1),new z("ismo",-1,1),new z("oso",-1,1),new z("amento",-1,6),new z("imento",-1,6),new z("ivo",-1,9),new z("ità",-1,8),new z("istà",-1,1),new z("istè",-1,1),new z("istì",-1,1)],l=[new z("isca",-1,1),new z("enda",-1,1),new z("ata",-1,1),new z("ita",-1,1),new z("uta",-1,1),new z("ava",-1,1),new z("eva",-1,1),new z("iva",-1,1),new z("erebbe",-1,1),new z("irebbe",-1,1),new z("isce",-1,1),new z("ende",-1,1),new z("are",-1,1),new z("ere",-1,1),new z("ire",-1,1),new z("asse",-1,1),new z("ate",-1,1),new z("avate",16,1),new z("evate",16,1),new z("ivate",16,1),new z("ete",-1,1),new z("erete",20,1),new z("irete",20,1),new z("ite",-1,1),new z("ereste",-1,1),new z("ireste",-1,1),new z("ute",-1,1),new z("erai",-1,1),new z("irai",-1,1),new z("isci",-1,1),new z("endi",-1,1),new z("erei",-1,1),new z("irei",-1,1),new z("assi",-1,1),new z("ati",-1,1),new z("iti",-1,1),new z("eresti",-1,1),new z("iresti",-1,1),new z("uti",-1,1),new z("avi",-1,1),new z("evi",-1,1),new z("ivi",-1,1),new z("isco",-1,1),new z("ando",-1,1),new z("endo",-1,1),new z("Yamo",-1,1),new z("iamo",-1,1),new z("avamo",-1,1),new z("evamo",-1,1),new z("ivamo",-1,1),new z("eremo",-1,1),new z("iremo",-1,1),new z("assimo",-1,1),new z("ammo",-1,1),new z("emmo",-1,1),new z("eremmo",54,1),new z("iremmo",54,1),new z("immo",-1,1),new z("ano",-1,1),new z("iscano",58,1),new z("avano",58,1),new z("evano",58,1),new z("ivano",58,1),new z("eranno",-1,1),new z("iranno",-1,1),new z("ono",-1,1),new z("iscono",65,1),new z("arono",65,1),new z("erono",65,1),new z("irono",65,1),new z("erebbero",-1,1),new z("irebbero",-1,1),new z("assero",-1,1),new z("essero",-1,1),new z("issero",-1,1),new z("ato",-1,1),new z("ito",-1,1),new z("uto",-1,1),new z("avo",-1,1),new z("evo",-1,1),new z("ivo",-1,1),new z("ar",-1,1),new z("ir",-1,1),new z("erà",-1,1),new z("irà",-1,1),new z("erò",-1,1),new z("irò",-1,1)],m=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2,1],f=[17,65,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,8,2],v=[17],b=new P;function d(e,r,n){return!(!b.eq_s(1,e)||(b.ket=b.cursor,!b.in_grouping(m,97,249)))&&(b.slice_from(r),b.cursor=n,!0)}function _(e){if(b.cursor=e,!b.in_grouping(m,97,249))return!1;for(;!b.out_grouping(m,97,249);){if(b.cursor>=b.limit)return!1;b.cursor++}return!0}function g(){var e,r=b.cursor;if(!function(){if(b.in_grouping(m,97,249)){var e=b.cursor;if(b.out_grouping(m,97,249)){for(;!b.in_grouping(m,97,249);){if(b.cursor>=b.limit)return _(e);b.cursor++}return!0}return _(e)}return!1}()){if(b.cursor=r,!b.out_grouping(m,97,249))return;if(e=b.cursor,b.out_grouping(m,97,249)){for(;!b.in_grouping(m,97,249);){if(b.cursor>=b.limit)return b.cursor=e,void(b.in_grouping(m,97,249)&&b.cursor=b.limit)return;b.cursor++}s=b.cursor}function p(){for(;!b.in_grouping(m,97,249);){if(b.cursor>=b.limit)return!1;b.cursor++}for(;!b.out_grouping(m,97,249);){if(b.cursor>=b.limit)return!1;b.cursor++}return!0}function k(){return s<=b.cursor}function h(){return o<=b.cursor}function q(){var e;if(b.ket=b.cursor,!(e=b.find_among_b(i,51)))return!1;switch(b.bra=b.cursor,e){case 1:if(!h())return!1;b.slice_del();break;case 2:if(!h())return!1;b.slice_del(),b.ket=b.cursor,b.eq_s_b(2,"ic")&&(b.bra=b.cursor,h()&&b.slice_del());break;case 3:if(!h())return!1;b.slice_from("log");break;case 4:if(!h())return!1;b.slice_from("u");break;case 5:if(!h())return!1;b.slice_from("ente");break;case 6:if(!k())return!1;b.slice_del();break;case 7:if(!(t<=b.cursor))return!1;b.slice_del(),b.ket=b.cursor,(e=b.find_among_b(r,4))&&(b.bra=b.cursor,h()&&(b.slice_del(),1==e&&(b.ket=b.cursor,b.eq_s_b(2,"at")&&(b.bra=b.cursor,h()&&b.slice_del()))));break;case 8:if(!h())return!1;b.slice_del(),b.ket=b.cursor,(e=b.find_among_b(n,3))&&(b.bra=b.cursor,1==e&&h()&&b.slice_del());break;case 9:if(!h())return!1;b.slice_del(),b.ket=b.cursor,b.eq_s_b(2,"at")&&(b.bra=b.cursor,h()&&(b.slice_del(),b.ket=b.cursor,b.eq_s_b(2,"ic")&&(b.bra=b.cursor,h()&&b.slice_del())))}return!0}function C(){var e;e=b.limit-b.cursor,b.ket=b.cursor,b.in_grouping_b(f,97,242)&&(b.bra=b.cursor,k()&&(b.slice_del(),b.ket=b.cursor,b.eq_s_b(1,"i")&&(b.bra=b.cursor,k())))?b.slice_del():b.cursor=b.limit-e,b.ket=b.cursor,b.eq_s_b(1,"h")&&(b.bra=b.cursor,b.in_grouping_b(v,99,103)&&k()&&b.slice_del())}this.setCurrent=function(e){b.setCurrent(e)},this.getCurrent=function(){return b.getCurrent()},this.stem=function(){var e,r,n,i=b.cursor;return function(){for(var e,r,n,i,o=b.cursor;;){if(b.bra=b.cursor,e=b.find_among(a,7))switch(b.ket=b.cursor,e){case 1:b.slice_from("à");continue;case 2:b.slice_from("è");continue;case 3:b.slice_from("ì");continue;case 4:b.slice_from("ò");continue;case 5:b.slice_from("ù");continue;case 6:b.slice_from("qU");continue;case 7:if(b.cursor>=b.limit)break;b.cursor++;continue}break}for(b.cursor=o;;)for(r=b.cursor;;){if(n=b.cursor,b.in_grouping(m,97,249)){if(b.bra=b.cursor,i=b.cursor,d("u","U",n))break;if(b.cursor=i,d("i","I",n))break}if(b.cursor=n,b.cursor>=b.limit)return b.cursor=r;b.cursor++}}(),b.cursor=i,e=b.cursor,s=b.limit,o=t=s,g(),b.cursor=e,p()&&(t=b.cursor,p()&&(o=b.cursor)),b.limit_backward=i,b.cursor=b.limit,function(){var e;if(b.ket=b.cursor,b.find_among_b(c,37)&&(b.bra=b.cursor,(e=b.find_among_b(w,5))&&k()))switch(e){case 1:b.slice_del();break;case 2:b.slice_from("e")}}(),b.cursor=b.limit,q()||(b.cursor=b.limit,b.cursor>=s&&(n=b.limit_backward,b.limit_backward=s,b.ket=b.cursor,(r=b.find_among_b(l,87))&&(b.bra=b.cursor,1==r&&b.slice_del()),b.limit_backward=n)),b.cursor=b.limit,C(),b.cursor=b.limit_backward,function(){for(var e;b.bra=b.cursor,e=b.find_among(u,3);)switch(b.ket=b.cursor,e){case 1:b.slice_from("i");break;case 2:b.slice_from("u");break;case 3:if(b.cursor>=b.limit)return;b.cursor++}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return r.setCurrent(e),r.stem(),r.getCurrent()}):(r.setCurrent(e),r.stem(),r.getCurrent())}),e.Pipeline.registerFunction(e.it.stemmer,"stemmer-it"),e.it.stopWordFilter=e.generateStopWordFilter("a abbia abbiamo abbiano abbiate ad agl agli ai al all alla alle allo anche avemmo avendo avesse avessero avessi avessimo aveste avesti avete aveva avevamo avevano avevate avevi avevo avrai avranno avrebbe avrebbero avrei avremmo avremo avreste avresti avrete avrà avrò avuta avute avuti avuto c che chi ci coi col come con contro cui da dagl dagli dai dal dall dalla dalle dallo degl degli dei del dell della delle dello di dov dove e ebbe ebbero ebbi ed era erano eravamo eravate eri ero essendo faccia facciamo facciano facciate faccio facemmo facendo facesse facessero facessi facessimo faceste facesti faceva facevamo facevano facevate facevi facevo fai fanno farai faranno farebbe farebbero farei faremmo faremo fareste faresti farete farà farò fece fecero feci fosse fossero fossi fossimo foste fosti fu fui fummo furono gli ha hai hanno ho i il in io l la le lei li lo loro lui ma mi mia mie miei mio ne negl negli nei nel nell nella nelle nello noi non nostra nostre nostri nostro o per perché più quale quanta quante quanti quanto quella quelle quelli quello questa queste questi questo sarai saranno sarebbe sarebbero sarei saremmo saremo sareste saresti sarete sarà sarò se sei si sia siamo siano siate siete sono sta stai stando stanno starai staranno starebbe starebbero starei staremmo staremo stareste staresti starete starà starò stava stavamo stavano stavate stavi stavo stemmo stesse stessero stessi stessimo steste stesti stette stettero stetti stia stiamo stiano stiate sto su sua sue sugl sugli sui sul sull sulla sulle sullo suo suoi ti tra tu tua tue tuo tuoi tutti tutto un una uno vi voi vostra vostre vostri vostro è".split(" ")),e.Pipeline.registerFunction(e.it.stopWordFilter,"stopWordFilter-it")}}); \ No newline at end of file diff --git a/site/assets/javascripts/lunr/lunr.jp.js b/site/assets/javascripts/lunr/lunr.jp.js new file mode 100644 index 000000000..ed2b3d258 --- /dev/null +++ b/site/assets/javascripts/lunr/lunr.jp.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(n){if(void 0===n)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===n.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var i="2"==n.version[0];n.jp=function(){this.pipeline.reset(),this.pipeline.add(n.jp.stopWordFilter,n.jp.stemmer),i?this.tokenizer=n.jp.tokenizer:(n.tokenizer&&(n.tokenizer=n.jp.tokenizer),this.tokenizerFn&&(this.tokenizerFn=n.jp.tokenizer))};var o=new n.TinySegmenter;n.jp.tokenizer=function(e){if(!arguments.length||null==e||null==e)return[];if(Array.isArray(e))return e.map(function(e){return i?new n.Token(e.toLowerCase()):e.toLowerCase()});for(var r=e.toString().toLowerCase().replace(/^\s+/,""),t=r.length-1;0<=t;t--)if(/\S/.test(r.charAt(t))){r=r.substring(0,t+1);break}return o.segment(r).filter(function(e){return!!e}).map(function(e){return i?new n.Token(e):e})},n.jp.stemmer=function(e){return e},n.Pipeline.registerFunction(n.jp.stemmer,"stemmer-jp"),n.jp.wordCharacters="一二三四五六七八九十百千万億兆一-龠々〆ヵヶぁ-んァ-ヴーア-ン゙a-zA-Za-zA-Z0-90-9",n.jp.stopWordFilter=function(e){if(-1===n.jp.stopWordFilter.stopWords.indexOf(i?e.toString():e))return e},n.jp.stopWordFilter=n.generateStopWordFilter("これ それ あれ この その あの ここ そこ あそこ こちら どこ だれ なに なん 何 私 貴方 貴方方 我々 私達 あの人 あのかた 彼女 彼 です あります おります います は が の に を で え から まで より も どの と し それで しかし".split(" ")),n.Pipeline.registerFunction(n.jp.stopWordFilter,"stopWordFilter-jp")}}); \ No newline at end of file diff --git a/site/assets/javascripts/lunr/lunr.multi.js b/site/assets/javascripts/lunr/lunr.multi.js new file mode 100644 index 000000000..8a145c911 --- /dev/null +++ b/site/assets/javascripts/lunr/lunr.multi.js @@ -0,0 +1 @@ +!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(o){o.multiLanguage=function(){for(var e=Array.prototype.slice.call(arguments),i=e.join("-"),t="",r=[],n=[],s=0;s=c.limit)return;c.cursor=e+1}for(;!c.out_grouping(u,97,248);){if(c.cursor>=c.limit)return;c.cursor++}(s=c.cursor)=s&&(r=c.limit_backward,c.limit_backward=s,c.ket=c.cursor,e=c.find_among_b(a,29),c.limit_backward=r,e))switch(c.bra=c.cursor,e){case 1:c.slice_del();break;case 2:n=c.limit-c.cursor,c.in_grouping_b(d,98,122)?c.slice_del():(c.cursor=c.limit-n,c.eq_s_b(1,"k")&&c.out_grouping_b(u,97,248)&&c.slice_del());break;case 3:c.slice_from("er")}}(),c.cursor=c.limit,r=c.limit-c.cursor,c.cursor>=s&&(e=c.limit_backward,c.limit_backward=s,c.ket=c.cursor,c.find_among_b(m,2)?(c.bra=c.cursor,c.limit_backward=e,c.cursor=c.limit-r,c.cursor>c.limit_backward&&(c.cursor--,c.bra=c.cursor,c.slice_del())):c.limit_backward=e),c.cursor=c.limit,c.cursor>=s&&(i=c.limit_backward,c.limit_backward=s,c.ket=c.cursor,(n=c.find_among_b(l,11))?(c.bra=c.cursor,c.limit_backward=i,1==n&&c.slice_del()):c.limit_backward=i),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}),e.Pipeline.registerFunction(e.no.stemmer,"stemmer-no"),e.no.stopWordFilter=e.generateStopWordFilter("alle at av bare begge ble blei bli blir blitt både båe da de deg dei deim deira deires dem den denne der dere deres det dette di din disse ditt du dykk dykkar då eg ein eit eitt eller elles en enn er et ett etter for fordi fra før ha hadde han hans har hennar henne hennes her hjå ho hoe honom hoss hossen hun hva hvem hver hvilke hvilken hvis hvor hvordan hvorfor i ikke ikkje ikkje ingen ingi inkje inn inni ja jeg kan kom korleis korso kun kunne kva kvar kvarhelst kven kvi kvifor man mange me med medan meg meget mellom men mi min mine mitt mot mykje ned no noe noen noka noko nokon nokor nokre nå når og også om opp oss over på samme seg selv si si sia sidan siden sin sine sitt sjøl skal skulle slik so som som somme somt så sånn til um upp ut uten var vart varte ved vere verte vi vil ville vore vors vort vår være være vært å".split(" ")),e.Pipeline.registerFunction(e.no.stopWordFilter,"stopWordFilter-no")}}); \ No newline at end of file diff --git a/site/assets/javascripts/lunr/lunr.pt.js b/site/assets/javascripts/lunr/lunr.pt.js new file mode 100644 index 000000000..f50fc9fa6 --- /dev/null +++ b/site/assets/javascripts/lunr/lunr.pt.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var j,C,r;e.pt=function(){this.pipeline.reset(),this.pipeline.add(e.pt.trimmer,e.pt.stopWordFilter,e.pt.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.pt.stemmer))},e.pt.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.pt.trimmer=e.trimmerSupport.generateTrimmer(e.pt.wordCharacters),e.Pipeline.registerFunction(e.pt.trimmer,"trimmer-pt"),e.pt.stemmer=(j=e.stemmerSupport.Among,C=e.stemmerSupport.SnowballProgram,r=new function(){var s,n,i,o=[new j("",-1,3),new j("ã",0,1),new j("õ",0,2)],a=[new j("",-1,3),new j("a~",0,1),new j("o~",0,2)],r=[new j("ic",-1,-1),new j("ad",-1,-1),new j("os",-1,-1),new j("iv",-1,1)],t=[new j("ante",-1,1),new j("avel",-1,1),new j("ível",-1,1)],u=[new j("ic",-1,1),new j("abil",-1,1),new j("iv",-1,1)],w=[new j("ica",-1,1),new j("ância",-1,1),new j("ência",-1,4),new j("ira",-1,9),new j("adora",-1,1),new j("osa",-1,1),new j("ista",-1,1),new j("iva",-1,8),new j("eza",-1,1),new j("logía",-1,2),new j("idade",-1,7),new j("ante",-1,1),new j("mente",-1,6),new j("amente",12,5),new j("ável",-1,1),new j("ível",-1,1),new j("ución",-1,3),new j("ico",-1,1),new j("ismo",-1,1),new j("oso",-1,1),new j("amento",-1,1),new j("imento",-1,1),new j("ivo",-1,8),new j("aça~o",-1,1),new j("ador",-1,1),new j("icas",-1,1),new j("ências",-1,4),new j("iras",-1,9),new j("adoras",-1,1),new j("osas",-1,1),new j("istas",-1,1),new j("ivas",-1,8),new j("ezas",-1,1),new j("logías",-1,2),new j("idades",-1,7),new j("uciones",-1,3),new j("adores",-1,1),new j("antes",-1,1),new j("aço~es",-1,1),new j("icos",-1,1),new j("ismos",-1,1),new j("osos",-1,1),new j("amentos",-1,1),new j("imentos",-1,1),new j("ivos",-1,8)],m=[new j("ada",-1,1),new j("ida",-1,1),new j("ia",-1,1),new j("aria",2,1),new j("eria",2,1),new j("iria",2,1),new j("ara",-1,1),new j("era",-1,1),new j("ira",-1,1),new j("ava",-1,1),new j("asse",-1,1),new j("esse",-1,1),new j("isse",-1,1),new j("aste",-1,1),new j("este",-1,1),new j("iste",-1,1),new j("ei",-1,1),new j("arei",16,1),new j("erei",16,1),new j("irei",16,1),new j("am",-1,1),new j("iam",20,1),new j("ariam",21,1),new j("eriam",21,1),new j("iriam",21,1),new j("aram",20,1),new j("eram",20,1),new j("iram",20,1),new j("avam",20,1),new j("em",-1,1),new j("arem",29,1),new j("erem",29,1),new j("irem",29,1),new j("assem",29,1),new j("essem",29,1),new j("issem",29,1),new j("ado",-1,1),new j("ido",-1,1),new j("ando",-1,1),new j("endo",-1,1),new j("indo",-1,1),new j("ara~o",-1,1),new j("era~o",-1,1),new j("ira~o",-1,1),new j("ar",-1,1),new j("er",-1,1),new j("ir",-1,1),new j("as",-1,1),new j("adas",47,1),new j("idas",47,1),new j("ias",47,1),new j("arias",50,1),new j("erias",50,1),new j("irias",50,1),new j("aras",47,1),new j("eras",47,1),new j("iras",47,1),new j("avas",47,1),new j("es",-1,1),new j("ardes",58,1),new j("erdes",58,1),new j("irdes",58,1),new j("ares",58,1),new j("eres",58,1),new j("ires",58,1),new j("asses",58,1),new j("esses",58,1),new j("isses",58,1),new j("astes",58,1),new j("estes",58,1),new j("istes",58,1),new j("is",-1,1),new j("ais",71,1),new j("eis",71,1),new j("areis",73,1),new j("ereis",73,1),new j("ireis",73,1),new j("áreis",73,1),new j("éreis",73,1),new j("íreis",73,1),new j("ásseis",73,1),new j("ésseis",73,1),new j("ísseis",73,1),new j("áveis",73,1),new j("íeis",73,1),new j("aríeis",84,1),new j("eríeis",84,1),new j("iríeis",84,1),new j("ados",-1,1),new j("idos",-1,1),new j("amos",-1,1),new j("áramos",90,1),new j("éramos",90,1),new j("íramos",90,1),new j("ávamos",90,1),new j("íamos",90,1),new j("aríamos",95,1),new j("eríamos",95,1),new j("iríamos",95,1),new j("emos",-1,1),new j("aremos",99,1),new j("eremos",99,1),new j("iremos",99,1),new j("ássemos",99,1),new j("êssemos",99,1),new j("íssemos",99,1),new j("imos",-1,1),new j("armos",-1,1),new j("ermos",-1,1),new j("irmos",-1,1),new j("ámos",-1,1),new j("arás",-1,1),new j("erás",-1,1),new j("irás",-1,1),new j("eu",-1,1),new j("iu",-1,1),new j("ou",-1,1),new j("ará",-1,1),new j("erá",-1,1),new j("irá",-1,1)],c=[new j("a",-1,1),new j("i",-1,1),new j("o",-1,1),new j("os",-1,1),new j("á",-1,1),new j("í",-1,1),new j("ó",-1,1)],l=[new j("e",-1,1),new j("ç",-1,2),new j("é",-1,1),new j("ê",-1,1)],f=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,3,19,12,2],d=new C;function v(){if(d.out_grouping(f,97,250)){for(;!d.in_grouping(f,97,250);){if(d.cursor>=d.limit)return!0;d.cursor++}return!1}return!0}function p(){var e,r,s=d.cursor;if(d.in_grouping(f,97,250))if(e=d.cursor,v()){if(d.cursor=e,function(){if(d.in_grouping(f,97,250))for(;!d.out_grouping(f,97,250);){if(d.cursor>=d.limit)return!1;d.cursor++}return i=d.cursor,!0}())return}else i=d.cursor;if(d.cursor=s,d.out_grouping(f,97,250)){if(r=d.cursor,v()){if(d.cursor=r,!d.in_grouping(f,97,250)||d.cursor>=d.limit)return;d.cursor++}i=d.cursor}}function _(){for(;!d.in_grouping(f,97,250);){if(d.cursor>=d.limit)return!1;d.cursor++}for(;!d.out_grouping(f,97,250);){if(d.cursor>=d.limit)return!1;d.cursor++}return!0}function h(){return i<=d.cursor}function b(){return s<=d.cursor}function g(){var e;if(d.ket=d.cursor,!(e=d.find_among_b(w,45)))return!1;switch(d.bra=d.cursor,e){case 1:if(!b())return!1;d.slice_del();break;case 2:if(!b())return!1;d.slice_from("log");break;case 3:if(!b())return!1;d.slice_from("u");break;case 4:if(!b())return!1;d.slice_from("ente");break;case 5:if(!(n<=d.cursor))return!1;d.slice_del(),d.ket=d.cursor,(e=d.find_among_b(r,4))&&(d.bra=d.cursor,b()&&(d.slice_del(),1==e&&(d.ket=d.cursor,d.eq_s_b(2,"at")&&(d.bra=d.cursor,b()&&d.slice_del()))));break;case 6:if(!b())return!1;d.slice_del(),d.ket=d.cursor,(e=d.find_among_b(t,3))&&(d.bra=d.cursor,1==e&&b()&&d.slice_del());break;case 7:if(!b())return!1;d.slice_del(),d.ket=d.cursor,(e=d.find_among_b(u,3))&&(d.bra=d.cursor,1==e&&b()&&d.slice_del());break;case 8:if(!b())return!1;d.slice_del(),d.ket=d.cursor,d.eq_s_b(2,"at")&&(d.bra=d.cursor,b()&&d.slice_del());break;case 9:if(!h()||!d.eq_s_b(1,"e"))return!1;d.slice_from("ir")}return!0}function k(e,r){if(d.eq_s_b(1,e)){d.bra=d.cursor;var s=d.limit-d.cursor;if(d.eq_s_b(1,r))return d.cursor=d.limit-s,h()&&d.slice_del(),!1}return!0}function q(){if(!g()&&(d.cursor=d.limit,!function(){var e,r;if(d.cursor>=i){if(r=d.limit_backward,d.limit_backward=i,d.ket=d.cursor,e=d.find_among_b(m,120))return d.bra=d.cursor,1==e&&d.slice_del(),d.limit_backward=r,!0;d.limit_backward=r}return!1}()))return d.cursor=d.limit,d.ket=d.cursor,void((e=d.find_among_b(c,7))&&(d.bra=d.cursor,1==e&&h()&&d.slice_del()));var e;d.cursor=d.limit,d.ket=d.cursor,d.eq_s_b(1,"i")&&(d.bra=d.cursor,d.eq_s_b(1,"c")&&(d.cursor=d.limit,h()&&d.slice_del()))}this.setCurrent=function(e){d.setCurrent(e)},this.getCurrent=function(){return d.getCurrent()},this.stem=function(){var e,r=d.cursor;return function(){for(var e;;){if(d.bra=d.cursor,e=d.find_among(o,3))switch(d.ket=d.cursor,e){case 1:d.slice_from("a~");continue;case 2:d.slice_from("o~");continue;case 3:if(d.cursor>=d.limit)break;d.cursor++;continue}break}}(),d.cursor=r,e=d.cursor,i=d.limit,s=n=i,p(),d.cursor=e,_()&&(n=d.cursor,_()&&(s=d.cursor)),d.limit_backward=r,d.cursor=d.limit,q(),d.cursor=d.limit,function(){var e;if(d.ket=d.cursor,e=d.find_among_b(l,4))switch(d.bra=d.cursor,e){case 1:h()&&(d.slice_del(),d.ket=d.cursor,d.limit,d.cursor,k("u","g")&&k("i","c"));break;case 2:d.slice_from("c")}}(),d.cursor=d.limit_backward,function(){for(var e;;){if(d.bra=d.cursor,e=d.find_among(a,3))switch(d.ket=d.cursor,e){case 1:d.slice_from("ã");continue;case 2:d.slice_from("õ");continue;case 3:if(d.cursor>=d.limit)break;d.cursor++;continue}break}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return r.setCurrent(e),r.stem(),r.getCurrent()}):(r.setCurrent(e),r.stem(),r.getCurrent())}),e.Pipeline.registerFunction(e.pt.stemmer,"stemmer-pt"),e.pt.stopWordFilter=e.generateStopWordFilter("a ao aos aquela aquelas aquele aqueles aquilo as até com como da das de dela delas dele deles depois do dos e ela elas ele eles em entre era eram essa essas esse esses esta estamos estas estava estavam este esteja estejam estejamos estes esteve estive estivemos estiver estivera estiveram estiverem estivermos estivesse estivessem estivéramos estivéssemos estou está estávamos estão eu foi fomos for fora foram forem formos fosse fossem fui fôramos fôssemos haja hajam hajamos havemos hei houve houvemos houver houvera houveram houverei houverem houveremos houveria houveriam houvermos houverá houverão houveríamos houvesse houvessem houvéramos houvéssemos há hão isso isto já lhe lhes mais mas me mesmo meu meus minha minhas muito na nas nem no nos nossa nossas nosso nossos num numa não nós o os ou para pela pelas pelo pelos por qual quando que quem se seja sejam sejamos sem serei seremos seria seriam será serão seríamos seu seus somos sou sua suas são só também te tem temos tenha tenham tenhamos tenho terei teremos teria teriam terá terão teríamos teu teus teve tinha tinham tive tivemos tiver tivera tiveram tiverem tivermos tivesse tivessem tivéramos tivéssemos tu tua tuas tém tínhamos um uma você vocês vos à às éramos".split(" ")),e.Pipeline.registerFunction(e.pt.stopWordFilter,"stopWordFilter-pt")}}); \ No newline at end of file diff --git a/site/assets/javascripts/lunr/lunr.ro.js b/site/assets/javascripts/lunr/lunr.ro.js new file mode 100644 index 000000000..b19627e1b --- /dev/null +++ b/site/assets/javascripts/lunr/lunr.ro.js @@ -0,0 +1 @@ +!function(e,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var h,z,i;e.ro=function(){this.pipeline.reset(),this.pipeline.add(e.ro.trimmer,e.ro.stopWordFilter,e.ro.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ro.stemmer))},e.ro.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.ro.trimmer=e.trimmerSupport.generateTrimmer(e.ro.wordCharacters),e.Pipeline.registerFunction(e.ro.trimmer,"trimmer-ro"),e.ro.stemmer=(h=e.stemmerSupport.Among,z=e.stemmerSupport.SnowballProgram,i=new function(){var r,n,t,a,o=[new h("",-1,3),new h("I",0,1),new h("U",0,2)],s=[new h("ea",-1,3),new h("aţia",-1,7),new h("aua",-1,2),new h("iua",-1,4),new h("aţie",-1,7),new h("ele",-1,3),new h("ile",-1,5),new h("iile",6,4),new h("iei",-1,4),new h("atei",-1,6),new h("ii",-1,4),new h("ului",-1,1),new h("ul",-1,1),new h("elor",-1,3),new h("ilor",-1,4),new h("iilor",14,4)],c=[new h("icala",-1,4),new h("iciva",-1,4),new h("ativa",-1,5),new h("itiva",-1,6),new h("icale",-1,4),new h("aţiune",-1,5),new h("iţiune",-1,6),new h("atoare",-1,5),new h("itoare",-1,6),new h("ătoare",-1,5),new h("icitate",-1,4),new h("abilitate",-1,1),new h("ibilitate",-1,2),new h("ivitate",-1,3),new h("icive",-1,4),new h("ative",-1,5),new h("itive",-1,6),new h("icali",-1,4),new h("atori",-1,5),new h("icatori",18,4),new h("itori",-1,6),new h("ători",-1,5),new h("icitati",-1,4),new h("abilitati",-1,1),new h("ivitati",-1,3),new h("icivi",-1,4),new h("ativi",-1,5),new h("itivi",-1,6),new h("icităi",-1,4),new h("abilităi",-1,1),new h("ivităi",-1,3),new h("icităţi",-1,4),new h("abilităţi",-1,1),new h("ivităţi",-1,3),new h("ical",-1,4),new h("ator",-1,5),new h("icator",35,4),new h("itor",-1,6),new h("ător",-1,5),new h("iciv",-1,4),new h("ativ",-1,5),new h("itiv",-1,6),new h("icală",-1,4),new h("icivă",-1,4),new h("ativă",-1,5),new h("itivă",-1,6)],u=[new h("ica",-1,1),new h("abila",-1,1),new h("ibila",-1,1),new h("oasa",-1,1),new h("ata",-1,1),new h("ita",-1,1),new h("anta",-1,1),new h("ista",-1,3),new h("uta",-1,1),new h("iva",-1,1),new h("ic",-1,1),new h("ice",-1,1),new h("abile",-1,1),new h("ibile",-1,1),new h("isme",-1,3),new h("iune",-1,2),new h("oase",-1,1),new h("ate",-1,1),new h("itate",17,1),new h("ite",-1,1),new h("ante",-1,1),new h("iste",-1,3),new h("ute",-1,1),new h("ive",-1,1),new h("ici",-1,1),new h("abili",-1,1),new h("ibili",-1,1),new h("iuni",-1,2),new h("atori",-1,1),new h("osi",-1,1),new h("ati",-1,1),new h("itati",30,1),new h("iti",-1,1),new h("anti",-1,1),new h("isti",-1,3),new h("uti",-1,1),new h("işti",-1,3),new h("ivi",-1,1),new h("ităi",-1,1),new h("oşi",-1,1),new h("ităţi",-1,1),new h("abil",-1,1),new h("ibil",-1,1),new h("ism",-1,3),new h("ator",-1,1),new h("os",-1,1),new h("at",-1,1),new h("it",-1,1),new h("ant",-1,1),new h("ist",-1,3),new h("ut",-1,1),new h("iv",-1,1),new h("ică",-1,1),new h("abilă",-1,1),new h("ibilă",-1,1),new h("oasă",-1,1),new h("ată",-1,1),new h("ită",-1,1),new h("antă",-1,1),new h("istă",-1,3),new h("ută",-1,1),new h("ivă",-1,1)],w=[new h("ea",-1,1),new h("ia",-1,1),new h("esc",-1,1),new h("ăsc",-1,1),new h("ind",-1,1),new h("ând",-1,1),new h("are",-1,1),new h("ere",-1,1),new h("ire",-1,1),new h("âre",-1,1),new h("se",-1,2),new h("ase",10,1),new h("sese",10,2),new h("ise",10,1),new h("use",10,1),new h("âse",10,1),new h("eşte",-1,1),new h("ăşte",-1,1),new h("eze",-1,1),new h("ai",-1,1),new h("eai",19,1),new h("iai",19,1),new h("sei",-1,2),new h("eşti",-1,1),new h("ăşti",-1,1),new h("ui",-1,1),new h("ezi",-1,1),new h("âi",-1,1),new h("aşi",-1,1),new h("seşi",-1,2),new h("aseşi",29,1),new h("seseşi",29,2),new h("iseşi",29,1),new h("useşi",29,1),new h("âseşi",29,1),new h("işi",-1,1),new h("uşi",-1,1),new h("âşi",-1,1),new h("aţi",-1,2),new h("eaţi",38,1),new h("iaţi",38,1),new h("eţi",-1,2),new h("iţi",-1,2),new h("âţi",-1,2),new h("arăţi",-1,1),new h("serăţi",-1,2),new h("aserăţi",45,1),new h("seserăţi",45,2),new h("iserăţi",45,1),new h("userăţi",45,1),new h("âserăţi",45,1),new h("irăţi",-1,1),new h("urăţi",-1,1),new h("ârăţi",-1,1),new h("am",-1,1),new h("eam",54,1),new h("iam",54,1),new h("em",-1,2),new h("asem",57,1),new h("sesem",57,2),new h("isem",57,1),new h("usem",57,1),new h("âsem",57,1),new h("im",-1,2),new h("âm",-1,2),new h("ăm",-1,2),new h("arăm",65,1),new h("serăm",65,2),new h("aserăm",67,1),new h("seserăm",67,2),new h("iserăm",67,1),new h("userăm",67,1),new h("âserăm",67,1),new h("irăm",65,1),new h("urăm",65,1),new h("ârăm",65,1),new h("au",-1,1),new h("eau",76,1),new h("iau",76,1),new h("indu",-1,1),new h("ându",-1,1),new h("ez",-1,1),new h("ească",-1,1),new h("ară",-1,1),new h("seră",-1,2),new h("aseră",84,1),new h("seseră",84,2),new h("iseră",84,1),new h("useră",84,1),new h("âseră",84,1),new h("iră",-1,1),new h("ură",-1,1),new h("âră",-1,1),new h("ează",-1,1)],i=[new h("a",-1,1),new h("e",-1,1),new h("ie",1,1),new h("i",-1,1),new h("ă",-1,1)],m=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,2,32,0,0,4],l=new z;function f(e,i){l.eq_s(1,e)&&(l.ket=l.cursor,l.in_grouping(m,97,259)&&l.slice_from(i))}function p(){if(l.out_grouping(m,97,259)){for(;!l.in_grouping(m,97,259);){if(l.cursor>=l.limit)return!0;l.cursor++}return!1}return!0}function d(){var e,i,r=l.cursor;if(l.in_grouping(m,97,259)){if(e=l.cursor,!p())return void(a=l.cursor);if(l.cursor=e,!function(){if(l.in_grouping(m,97,259))for(;!l.out_grouping(m,97,259);){if(l.cursor>=l.limit)return!0;l.cursor++}return!1}())return void(a=l.cursor)}l.cursor=r,l.out_grouping(m,97,259)&&(i=l.cursor,p()&&(l.cursor=i,l.in_grouping(m,97,259)&&l.cursor=l.limit)return!1;l.cursor++}for(;!l.out_grouping(m,97,259);){if(l.cursor>=l.limit)return!1;l.cursor++}return!0}function v(){return t<=l.cursor}function _(){var e,i=l.limit-l.cursor;if(l.ket=l.cursor,(e=l.find_among_b(c,46))&&(l.bra=l.cursor,v())){switch(e){case 1:l.slice_from("abil");break;case 2:l.slice_from("ibil");break;case 3:l.slice_from("iv");break;case 4:l.slice_from("ic");break;case 5:l.slice_from("at");break;case 6:l.slice_from("it")}return r=!0,l.cursor=l.limit-i,!0}return!1}function g(){var e,i;for(r=!1;;)if(i=l.limit-l.cursor,!_()){l.cursor=l.limit-i;break}if(l.ket=l.cursor,(e=l.find_among_b(u,62))&&(l.bra=l.cursor,n<=l.cursor)){switch(e){case 1:l.slice_del();break;case 2:l.eq_s_b(1,"ţ")&&(l.bra=l.cursor,l.slice_from("t"));break;case 3:l.slice_from("ist")}r=!0}}function k(){var e;l.ket=l.cursor,(e=l.find_among_b(i,5))&&(l.bra=l.cursor,a<=l.cursor&&1==e&&l.slice_del())}this.setCurrent=function(e){l.setCurrent(e)},this.getCurrent=function(){return l.getCurrent()},this.stem=function(){var e,i=l.cursor;return function(){for(var e,i;e=l.cursor,l.in_grouping(m,97,259)&&(i=l.cursor,l.bra=i,f("u","U"),l.cursor=i,f("i","I")),l.cursor=e,!(l.cursor>=l.limit);)l.cursor++}(),l.cursor=i,e=l.cursor,a=l.limit,n=t=a,d(),l.cursor=e,b()&&(t=l.cursor,b()&&(n=l.cursor)),l.limit_backward=i,l.cursor=l.limit,function(){var e,i;if(l.ket=l.cursor,(e=l.find_among_b(s,16))&&(l.bra=l.cursor,v()))switch(e){case 1:l.slice_del();break;case 2:l.slice_from("a");break;case 3:l.slice_from("e");break;case 4:l.slice_from("i");break;case 5:i=l.limit-l.cursor,l.eq_s_b(2,"ab")||(l.cursor=l.limit-i,l.slice_from("i"));break;case 6:l.slice_from("at");break;case 7:l.slice_from("aţi")}}(),l.cursor=l.limit,g(),l.cursor=l.limit,r||(l.cursor=l.limit,function(){var e,i,r;if(l.cursor>=a){if(i=l.limit_backward,l.limit_backward=a,l.ket=l.cursor,e=l.find_among_b(w,94))switch(l.bra=l.cursor,e){case 1:if(r=l.limit-l.cursor,!l.out_grouping_b(m,97,259)&&(l.cursor=l.limit-r,!l.eq_s_b(1,"u")))break;case 2:l.slice_del()}l.limit_backward=i}}(),l.cursor=l.limit),k(),l.cursor=l.limit_backward,function(){for(var e;;){if(l.bra=l.cursor,e=l.find_among(o,3))switch(l.ket=l.cursor,e){case 1:l.slice_from("i");continue;case 2:l.slice_from("u");continue;case 3:if(l.cursor>=l.limit)break;l.cursor++;continue}break}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return i.setCurrent(e),i.stem(),i.getCurrent()}):(i.setCurrent(e),i.stem(),i.getCurrent())}),e.Pipeline.registerFunction(e.ro.stemmer,"stemmer-ro"),e.ro.stopWordFilter=e.generateStopWordFilter("acea aceasta această aceea acei aceia acel acela acele acelea acest acesta aceste acestea aceşti aceştia acolo acord acum ai aia aibă aici al ale alea altceva altcineva am ar are asemenea asta astea astăzi asupra au avea avem aveţi azi aş aşadar aţi bine bucur bună ca care caut ce cel ceva chiar cinci cine cineva contra cu cum cumva curând curînd când cât câte câtva câţi cînd cît cîte cîtva cîţi că căci cărei căror cărui către da dacă dar datorită dată dau de deci deja deoarece departe deşi din dinaintea dintr- dintre doi doilea două drept după dă ea ei el ele eram este eu eşti face fata fi fie fiecare fii fim fiu fiţi frumos fără graţie halbă iar ieri la le li lor lui lângă lîngă mai mea mei mele mereu meu mi mie mine mult multă mulţi mulţumesc mâine mîine mă ne nevoie nici nicăieri nimeni nimeri nimic nişte noastre noastră noi noroc nostru nouă noştri nu opt ori oricare orice oricine oricum oricând oricât oricînd oricît oriunde patra patru patrulea pe pentru peste pic poate pot prea prima primul prin puţin puţina puţină până pînă rog sa sale sau se spate spre sub sunt suntem sunteţi sută sînt sîntem sînteţi să săi său ta tale te timp tine toate toată tot totuşi toţi trei treia treilea tu tăi tău un una unde undeva unei uneia unele uneori unii unor unora unu unui unuia unul vi voastre voastră voi vostru vouă voştri vreme vreo vreun vă zece zero zi zice îi îl îmi împotriva în înainte înaintea încotro încât încît între întrucât întrucît îţi ăla ălea ăsta ăstea ăştia şapte şase şi ştiu ţi ţie".split(" ")),e.Pipeline.registerFunction(e.ro.stopWordFilter,"stopWordFilter-ro")}}); \ No newline at end of file diff --git a/site/assets/javascripts/lunr/lunr.ru.js b/site/assets/javascripts/lunr/lunr.ru.js new file mode 100644 index 000000000..ac9924804 --- /dev/null +++ b/site/assets/javascripts/lunr/lunr.ru.js @@ -0,0 +1 @@ +!function(e,n){"function"==typeof define&&define.amd?define(n):"object"==typeof exports?module.exports=n():n()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var h,g,n;e.ru=function(){this.pipeline.reset(),this.pipeline.add(e.ru.trimmer,e.ru.stopWordFilter,e.ru.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.ru.stemmer))},e.ru.wordCharacters="Ѐ-҄҇-ԯᴫᵸⷠ-ⷿꙀ-ꚟ︮︯",e.ru.trimmer=e.trimmerSupport.generateTrimmer(e.ru.wordCharacters),e.Pipeline.registerFunction(e.ru.trimmer,"trimmer-ru"),e.ru.stemmer=(h=e.stemmerSupport.Among,g=e.stemmerSupport.SnowballProgram,n=new function(){var n,e,r=[new h("в",-1,1),new h("ив",0,2),new h("ыв",0,2),new h("вши",-1,1),new h("ивши",3,2),new h("ывши",3,2),new h("вшись",-1,1),new h("ившись",6,2),new h("ывшись",6,2)],t=[new h("ее",-1,1),new h("ие",-1,1),new h("ое",-1,1),new h("ые",-1,1),new h("ими",-1,1),new h("ыми",-1,1),new h("ей",-1,1),new h("ий",-1,1),new h("ой",-1,1),new h("ый",-1,1),new h("ем",-1,1),new h("им",-1,1),new h("ом",-1,1),new h("ым",-1,1),new h("его",-1,1),new h("ого",-1,1),new h("ему",-1,1),new h("ому",-1,1),new h("их",-1,1),new h("ых",-1,1),new h("ею",-1,1),new h("ою",-1,1),new h("ую",-1,1),new h("юю",-1,1),new h("ая",-1,1),new h("яя",-1,1)],w=[new h("ем",-1,1),new h("нн",-1,1),new h("вш",-1,1),new h("ивш",2,2),new h("ывш",2,2),new h("щ",-1,1),new h("ющ",5,1),new h("ующ",6,2)],i=[new h("сь",-1,1),new h("ся",-1,1)],u=[new h("ла",-1,1),new h("ила",0,2),new h("ыла",0,2),new h("на",-1,1),new h("ена",3,2),new h("ете",-1,1),new h("ите",-1,2),new h("йте",-1,1),new h("ейте",7,2),new h("уйте",7,2),new h("ли",-1,1),new h("или",10,2),new h("ыли",10,2),new h("й",-1,1),new h("ей",13,2),new h("уй",13,2),new h("л",-1,1),new h("ил",16,2),new h("ыл",16,2),new h("ем",-1,1),new h("им",-1,2),new h("ым",-1,2),new h("н",-1,1),new h("ен",22,2),new h("ло",-1,1),new h("ило",24,2),new h("ыло",24,2),new h("но",-1,1),new h("ено",27,2),new h("нно",27,1),new h("ет",-1,1),new h("ует",30,2),new h("ит",-1,2),new h("ыт",-1,2),new h("ют",-1,1),new h("уют",34,2),new h("ят",-1,2),new h("ны",-1,1),new h("ены",37,2),new h("ть",-1,1),new h("ить",39,2),new h("ыть",39,2),new h("ешь",-1,1),new h("ишь",-1,2),new h("ю",-1,2),new h("ую",44,2)],s=[new h("а",-1,1),new h("ев",-1,1),new h("ов",-1,1),new h("е",-1,1),new h("ие",3,1),new h("ье",3,1),new h("и",-1,1),new h("еи",6,1),new h("ии",6,1),new h("ами",6,1),new h("ями",6,1),new h("иями",10,1),new h("й",-1,1),new h("ей",12,1),new h("ией",13,1),new h("ий",12,1),new h("ой",12,1),new h("ам",-1,1),new h("ем",-1,1),new h("ием",18,1),new h("ом",-1,1),new h("ям",-1,1),new h("иям",21,1),new h("о",-1,1),new h("у",-1,1),new h("ах",-1,1),new h("ях",-1,1),new h("иях",26,1),new h("ы",-1,1),new h("ь",-1,1),new h("ю",-1,1),new h("ию",30,1),new h("ью",30,1),new h("я",-1,1),new h("ия",33,1),new h("ья",33,1)],o=[new h("ост",-1,1),new h("ость",-1,1)],c=[new h("ейше",-1,1),new h("н",-1,2),new h("ейш",-1,1),new h("ь",-1,3)],m=[33,65,8,232],l=new g;function f(){for(;!l.in_grouping(m,1072,1103);){if(l.cursor>=l.limit)return!1;l.cursor++}return!0}function a(){for(;!l.out_grouping(m,1072,1103);){if(l.cursor>=l.limit)return!1;l.cursor++}return!0}function p(e,n){var r,t;if(l.ket=l.cursor,r=l.find_among_b(e,n)){switch(l.bra=l.cursor,r){case 1:if(t=l.limit-l.cursor,!l.eq_s_b(1,"а")&&(l.cursor=l.limit-t,!l.eq_s_b(1,"я")))return!1;case 2:l.slice_del()}return!0}return!1}function d(e,n){var r;return l.ket=l.cursor,!!(r=l.find_among_b(e,n))&&(l.bra=l.cursor,1==r&&l.slice_del(),!0)}function _(){return!!d(t,26)&&(p(w,8),!0)}function b(){var e;l.ket=l.cursor,(e=l.find_among_b(o,2))&&(l.bra=l.cursor,n<=l.cursor&&1==e&&l.slice_del())}this.setCurrent=function(e){l.setCurrent(e)},this.getCurrent=function(){return l.getCurrent()},this.stem=function(){return e=l.limit,n=e,f()&&(e=l.cursor,a()&&f()&&a()&&(n=l.cursor)),l.cursor=l.limit,!(l.cursor>3]&1<<(7&s))return this.cursor++,!0}return!1},in_grouping_b:function(r,t,i){if(this.cursor>this.limit_backward){var s=b.charCodeAt(this.cursor-1);if(s<=i&&t<=s&&r[(s-=t)>>3]&1<<(7&s))return this.cursor--,!0}return!1},out_grouping:function(r,t,i){if(this.cursor>3]&1<<(7&s)))return this.cursor++,!0}return!1},out_grouping_b:function(r,t,i){if(this.cursor>this.limit_backward){var s=b.charCodeAt(this.cursor-1);if(i>3]&1<<(7&s)))return this.cursor--,!0}return!1},eq_s:function(r,t){if(this.limit-this.cursor>1),a=0,f=u=(l=r[i]).s_size){if(this.cursor=e+l.s_size,!l.method)return l.result;var m=l.method();if(this.cursor=e+l.s_size,m)return l.result}if((i=l.substring_i)<0)return 0}},find_among_b:function(r,t){for(var i=0,s=t,e=this.cursor,n=this.limit_backward,u=0,o=0,h=!1;;){for(var c=i+(s-i>>1),a=0,f=u=(_=r[i]).s_size){if(this.cursor=e-_.s_size,!_.method)return _.result;var m=_.method();if(this.cursor=e-_.s_size,m)return _.result}if((i=_.substring_i)<0)return 0}},replace_s:function(r,t,i){var s=i.length-(t-r);return b=b.substring(0,r)+i+b.substring(t),this.limit+=s,this.cursor>=t?this.cursor+=s:this.cursor>r&&(this.cursor=r),s},slice_check:function(){if(this.bra<0||this.bra>this.ket||this.ket>this.limit||this.limit>b.length)throw"faulty slice operation"},slice_from:function(r){this.slice_check(),this.replace_s(this.bra,this.ket,r)},slice_del:function(){this.slice_from("")},insert:function(r,t,i){var s=this.replace_s(r,t,i);r<=this.bra&&(this.bra+=s),r<=this.ket&&(this.ket+=s)},slice_to:function(){return this.slice_check(),b.substring(this.bra,this.ket)},eq_v_b:function(r){return this.eq_s_b(r.length,r)}}}},r.trimmerSupport={generateTrimmer:function(r){var t=new RegExp("^[^"+r+"]+"),i=new RegExp("[^"+r+"]+$");return function(r){return"function"==typeof r.update?r.update(function(r){return r.replace(t,"").replace(i,"")}):r.replace(t,"").replace(i,"")}}}}}); \ No newline at end of file diff --git a/site/assets/javascripts/lunr/lunr.sv.js b/site/assets/javascripts/lunr/lunr.sv.js new file mode 100644 index 000000000..6daf5f9d8 --- /dev/null +++ b/site/assets/javascripts/lunr/lunr.sv.js @@ -0,0 +1 @@ +!function(e,r){"function"==typeof define&&define.amd?define(r):"object"==typeof exports?module.exports=r():r()(e.lunr)}(this,function(){return function(e){if(void 0===e)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===e.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var r,l,n;e.sv=function(){this.pipeline.reset(),this.pipeline.add(e.sv.trimmer,e.sv.stopWordFilter,e.sv.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(e.sv.stemmer))},e.sv.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",e.sv.trimmer=e.trimmerSupport.generateTrimmer(e.sv.wordCharacters),e.Pipeline.registerFunction(e.sv.trimmer,"trimmer-sv"),e.sv.stemmer=(r=e.stemmerSupport.Among,l=e.stemmerSupport.SnowballProgram,n=new function(){var n,t,i=[new r("a",-1,1),new r("arna",0,1),new r("erna",0,1),new r("heterna",2,1),new r("orna",0,1),new r("ad",-1,1),new r("e",-1,1),new r("ade",6,1),new r("ande",6,1),new r("arne",6,1),new r("are",6,1),new r("aste",6,1),new r("en",-1,1),new r("anden",12,1),new r("aren",12,1),new r("heten",12,1),new r("ern",-1,1),new r("ar",-1,1),new r("er",-1,1),new r("heter",18,1),new r("or",-1,1),new r("s",-1,2),new r("as",21,1),new r("arnas",22,1),new r("ernas",22,1),new r("ornas",22,1),new r("es",21,1),new r("ades",26,1),new r("andes",26,1),new r("ens",21,1),new r("arens",29,1),new r("hetens",29,1),new r("erns",21,1),new r("at",-1,1),new r("andet",-1,1),new r("het",-1,1),new r("ast",-1,1)],s=[new r("dd",-1,-1),new r("gd",-1,-1),new r("nn",-1,-1),new r("dt",-1,-1),new r("gt",-1,-1),new r("kt",-1,-1),new r("tt",-1,-1)],a=[new r("ig",-1,1),new r("lig",0,1),new r("els",-1,1),new r("fullt",-1,3),new r("löst",-1,2)],o=[17,65,16,1,0,0,0,0,0,0,0,0,0,0,0,0,24,0,32],u=[119,127,149],m=new l;this.setCurrent=function(e){m.setCurrent(e)},this.getCurrent=function(){return m.getCurrent()},this.stem=function(){var e,r=m.cursor;return function(){var e,r=m.cursor+3;if(t=m.limit,0<=r||r<=m.limit){for(n=r;;){if(e=m.cursor,m.in_grouping(o,97,246)){m.cursor=e;break}if(m.cursor=e,m.cursor>=m.limit)return;m.cursor++}for(;!m.out_grouping(o,97,246);){if(m.cursor>=m.limit)return;m.cursor++}(t=m.cursor)=t&&(m.limit_backward=t,m.cursor=m.limit,m.ket=m.cursor,e=m.find_among_b(i,37),m.limit_backward=r,e))switch(m.bra=m.cursor,e){case 1:m.slice_del();break;case 2:m.in_grouping_b(u,98,121)&&m.slice_del()}}(),m.cursor=m.limit,e=m.limit_backward,m.cursor>=t&&(m.limit_backward=t,m.cursor=m.limit,m.find_among_b(s,7)&&(m.cursor=m.limit,m.ket=m.cursor,m.cursor>m.limit_backward&&(m.bra=--m.cursor,m.slice_del())),m.limit_backward=e),m.cursor=m.limit,function(){var e,r;if(m.cursor>=t){if(r=m.limit_backward,m.limit_backward=t,m.cursor=m.limit,m.ket=m.cursor,e=m.find_among_b(a,5))switch(m.bra=m.cursor,e){case 1:m.slice_del();break;case 2:m.slice_from("lös");break;case 3:m.slice_from("full")}m.limit_backward=r}}(),!0}},function(e){return"function"==typeof e.update?e.update(function(e){return n.setCurrent(e),n.stem(),n.getCurrent()}):(n.setCurrent(e),n.stem(),n.getCurrent())}),e.Pipeline.registerFunction(e.sv.stemmer,"stemmer-sv"),e.sv.stopWordFilter=e.generateStopWordFilter("alla allt att av blev bli blir blivit de dem den denna deras dess dessa det detta dig din dina ditt du där då efter ej eller en er era ert ett från för ha hade han hans har henne hennes hon honom hur här i icke ingen inom inte jag ju kan kunde man med mellan men mig min mina mitt mot mycket ni nu när någon något några och om oss på samma sedan sig sin sina sitta själv skulle som så sådan sådana sådant till under upp ut utan vad var vara varför varit varje vars vart vem vi vid vilka vilkas vilken vilket vår våra vårt än är åt över".split(" ")),e.Pipeline.registerFunction(e.sv.stopWordFilter,"stopWordFilter-sv")}}); \ No newline at end of file diff --git a/site/assets/javascripts/lunr/lunr.tr.js b/site/assets/javascripts/lunr/lunr.tr.js new file mode 100644 index 000000000..e8fb5a7df --- /dev/null +++ b/site/assets/javascripts/lunr/lunr.tr.js @@ -0,0 +1 @@ +!function(r,i){"function"==typeof define&&define.amd?define(i):"object"==typeof exports?module.exports=i():i()(r.lunr)}(this,function(){return function(r){if(void 0===r)throw new Error("Lunr is not present. Please include / require Lunr before this script.");if(void 0===r.stemmerSupport)throw new Error("Lunr stemmer support is not present. Please include / require Lunr stemmer support before this script.");var mr,dr,i;r.tr=function(){this.pipeline.reset(),this.pipeline.add(r.tr.trimmer,r.tr.stopWordFilter,r.tr.stemmer),this.searchPipeline&&(this.searchPipeline.reset(),this.searchPipeline.add(r.tr.stemmer))},r.tr.wordCharacters="A-Za-zªºÀ-ÖØ-öø-ʸˠ-ˤᴀ-ᴥᴬ-ᵜᵢ-ᵥᵫ-ᵷᵹ-ᶾḀ-ỿⁱⁿₐ-ₜKÅℲⅎⅠ-ↈⱠ-ⱿꜢ-ꞇꞋ-ꞭꞰ-ꞷꟷ-ꟿꬰ-ꭚꭜ-ꭤff-stA-Za-z",r.tr.trimmer=r.trimmerSupport.generateTrimmer(r.tr.wordCharacters),r.Pipeline.registerFunction(r.tr.trimmer,"trimmer-tr"),r.tr.stemmer=(mr=r.stemmerSupport.Among,dr=r.stemmerSupport.SnowballProgram,i=new function(){var t,r=[new mr("m",-1,-1),new mr("n",-1,-1),new mr("miz",-1,-1),new mr("niz",-1,-1),new mr("muz",-1,-1),new mr("nuz",-1,-1),new mr("müz",-1,-1),new mr("nüz",-1,-1),new mr("mız",-1,-1),new mr("nız",-1,-1)],i=[new mr("leri",-1,-1),new mr("ları",-1,-1)],e=[new mr("ni",-1,-1),new mr("nu",-1,-1),new mr("nü",-1,-1),new mr("nı",-1,-1)],n=[new mr("in",-1,-1),new mr("un",-1,-1),new mr("ün",-1,-1),new mr("ın",-1,-1)],u=[new mr("a",-1,-1),new mr("e",-1,-1)],o=[new mr("na",-1,-1),new mr("ne",-1,-1)],s=[new mr("da",-1,-1),new mr("ta",-1,-1),new mr("de",-1,-1),new mr("te",-1,-1)],c=[new mr("nda",-1,-1),new mr("nde",-1,-1)],l=[new mr("dan",-1,-1),new mr("tan",-1,-1),new mr("den",-1,-1),new mr("ten",-1,-1)],a=[new mr("ndan",-1,-1),new mr("nden",-1,-1)],m=[new mr("la",-1,-1),new mr("le",-1,-1)],d=[new mr("ca",-1,-1),new mr("ce",-1,-1)],f=[new mr("im",-1,-1),new mr("um",-1,-1),new mr("üm",-1,-1),new mr("ım",-1,-1)],b=[new mr("sin",-1,-1),new mr("sun",-1,-1),new mr("sün",-1,-1),new mr("sın",-1,-1)],w=[new mr("iz",-1,-1),new mr("uz",-1,-1),new mr("üz",-1,-1),new mr("ız",-1,-1)],_=[new mr("siniz",-1,-1),new mr("sunuz",-1,-1),new mr("sünüz",-1,-1),new mr("sınız",-1,-1)],k=[new mr("lar",-1,-1),new mr("ler",-1,-1)],p=[new mr("niz",-1,-1),new mr("nuz",-1,-1),new mr("nüz",-1,-1),new mr("nız",-1,-1)],g=[new mr("dir",-1,-1),new mr("tir",-1,-1),new mr("dur",-1,-1),new mr("tur",-1,-1),new mr("dür",-1,-1),new mr("tür",-1,-1),new mr("dır",-1,-1),new mr("tır",-1,-1)],y=[new mr("casına",-1,-1),new mr("cesine",-1,-1)],z=[new mr("di",-1,-1),new mr("ti",-1,-1),new mr("dik",-1,-1),new mr("tik",-1,-1),new mr("duk",-1,-1),new mr("tuk",-1,-1),new mr("dük",-1,-1),new mr("tük",-1,-1),new mr("dık",-1,-1),new mr("tık",-1,-1),new mr("dim",-1,-1),new mr("tim",-1,-1),new mr("dum",-1,-1),new mr("tum",-1,-1),new mr("düm",-1,-1),new mr("tüm",-1,-1),new mr("dım",-1,-1),new mr("tım",-1,-1),new mr("din",-1,-1),new mr("tin",-1,-1),new mr("dun",-1,-1),new mr("tun",-1,-1),new mr("dün",-1,-1),new mr("tün",-1,-1),new mr("dın",-1,-1),new mr("tın",-1,-1),new mr("du",-1,-1),new mr("tu",-1,-1),new mr("dü",-1,-1),new mr("tü",-1,-1),new mr("dı",-1,-1),new mr("tı",-1,-1)],h=[new mr("sa",-1,-1),new mr("se",-1,-1),new mr("sak",-1,-1),new mr("sek",-1,-1),new mr("sam",-1,-1),new mr("sem",-1,-1),new mr("san",-1,-1),new mr("sen",-1,-1)],v=[new mr("miş",-1,-1),new mr("muş",-1,-1),new mr("müş",-1,-1),new mr("mış",-1,-1)],q=[new mr("b",-1,1),new mr("c",-1,2),new mr("d",-1,3),new mr("ğ",-1,4)],C=[17,65,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,8,0,0,0,0,0,0,1],P=[1,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,1],F=[65],S=[65],W=[["a",[1,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],97,305],["e",[17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,130],101,252],["ı",[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],97,305],["i",[17],101,105],["o",F,111,117],["ö",S,246,252],["u",F,111,117]],L=new dr;function x(r,i,e){for(;;){var n=L.limit-L.cursor;if(L.in_grouping_b(r,i,e)){L.cursor=L.limit-n;break}if(L.cursor=L.limit-n,L.cursor<=L.limit_backward)return!1;L.cursor--}return!0}function A(){var r,i;r=L.limit-L.cursor,x(C,97,305);for(var e=0;eL.limit_backward&&(L.cursor--,e=L.limit-L.cursor,i()))?(L.cursor=L.limit-e,!0):(L.cursor=L.limit-n,r()?(L.cursor=L.limit-n,!1):(L.cursor=L.limit-n,!(L.cursor<=L.limit_backward)&&(L.cursor--,!!i()&&(L.cursor=L.limit-n,!0))))}function j(r){return E(r,function(){return L.in_grouping_b(C,97,305)})}function T(){return j(function(){return L.eq_s_b(1,"n")})}function Z(){return j(function(){return L.eq_s_b(1,"y")})}function B(){return L.find_among_b(r,10)&&E(function(){return L.in_grouping_b(P,105,305)},function(){return L.out_grouping_b(C,97,305)})}function D(){return A()&&L.in_grouping_b(P,105,305)&&j(function(){return L.eq_s_b(1,"s")})}function G(){return L.find_among_b(i,2)}function H(){return A()&&L.find_among_b(n,4)&&T()}function I(){return A()&&L.find_among_b(s,4)}function J(){return A()&&L.find_among_b(c,2)}function K(){return A()&&L.find_among_b(f,4)&&Z()}function M(){return A()&&L.find_among_b(b,4)}function N(){return A()&&L.find_among_b(w,4)&&Z()}function O(){return L.find_among_b(_,4)}function Q(){return A()&&L.find_among_b(k,2)}function R(){return A()&&L.find_among_b(g,8)}function U(){return A()&&L.find_among_b(z,32)&&Z()}function V(){return L.find_among_b(h,8)&&Z()}function X(){return A()&&L.find_among_b(v,4)&&Z()}function Y(){var r=L.limit-L.cursor;return!(X()||(L.cursor=L.limit-r,U()||(L.cursor=L.limit-r,V()||(L.cursor=L.limit-r,L.eq_s_b(3,"ken")&&Z()))))}function $(){if(L.find_among_b(y,2)){var r=L.limit-L.cursor;if(O()||(L.cursor=L.limit-r,Q()||(L.cursor=L.limit-r,K()||(L.cursor=L.limit-r,M()||(L.cursor=L.limit-r,N()||(L.cursor=L.limit-r))))),X())return!1}return!0}function rr(){if(!A()||!L.find_among_b(p,4))return!0;var r=L.limit-L.cursor;return!U()&&(L.cursor=L.limit-r,!V())}function ir(){var r,i,e,n=L.limit-L.cursor;if(L.ket=L.cursor,t=!0,Y()&&(L.cursor=L.limit-n,$()&&(L.cursor=L.limit-n,function(){if(Q()){L.bra=L.cursor,L.slice_del();var r=L.limit-L.cursor;return L.ket=L.cursor,R()||(L.cursor=L.limit-r,U()||(L.cursor=L.limit-r,V()||(L.cursor=L.limit-r,X()||(L.cursor=L.limit-r)))),t=!1}return!0}()&&(L.cursor=L.limit-n,rr()&&(L.cursor=L.limit-n,e=L.limit-L.cursor,!(O()||(L.cursor=L.limit-e,N()||(L.cursor=L.limit-e,M()||(L.cursor=L.limit-e,K()))))||(L.bra=L.cursor,L.slice_del(),i=L.limit-L.cursor,L.ket=L.cursor,X()||(L.cursor=L.limit-i),0)))))){if(L.cursor=L.limit-n,!R())return;L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,r=L.limit-L.cursor,O()||(L.cursor=L.limit-r,Q()||(L.cursor=L.limit-r,K()||(L.cursor=L.limit-r,M()||(L.cursor=L.limit-r,N()||(L.cursor=L.limit-r))))),X()||(L.cursor=L.limit-r)}L.bra=L.cursor,L.slice_del()}function er(){var r,i,e,n;if(L.ket=L.cursor,L.eq_s_b(2,"ki")){if(r=L.limit-L.cursor,I())return L.bra=L.cursor,L.slice_del(),i=L.limit-L.cursor,L.ket=L.cursor,Q()?(L.bra=L.cursor,L.slice_del(),er()):(L.cursor=L.limit-i,B()&&(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er()))),!0;if(L.cursor=L.limit-r,H()){if(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,e=L.limit-L.cursor,G())L.bra=L.cursor,L.slice_del();else{if(L.cursor=L.limit-e,L.ket=L.cursor,!B()&&(L.cursor=L.limit-e,!D()&&(L.cursor=L.limit-e,!er())))return!0;L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er())}return!0}if(L.cursor=L.limit-r,J()){if(n=L.limit-L.cursor,G())L.bra=L.cursor,L.slice_del();else if(L.cursor=L.limit-n,D())L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er());else if(L.cursor=L.limit-n,!er())return!1;return!0}}return!1}function nr(r){if(L.ket=L.cursor,!J()&&(L.cursor=L.limit-r,!A()||!L.find_among_b(o,2)))return!1;var i=L.limit-L.cursor;if(G())L.bra=L.cursor,L.slice_del();else if(L.cursor=L.limit-i,D())L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er());else if(L.cursor=L.limit-i,!er())return!1;return!0}function tr(r){if(L.ket=L.cursor,!(A()&&L.find_among_b(a,2)||(L.cursor=L.limit-r,A()&&L.find_among_b(e,4))))return!1;var i=L.limit-L.cursor;return!(!D()&&(L.cursor=L.limit-i,!G()))&&(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er()),!0)}function ur(){var r,i=L.limit-L.cursor;return L.ket=L.cursor,!!(H()||(L.cursor=L.limit-i,A()&&L.find_among_b(m,2)&&Z()))&&(L.bra=L.cursor,L.slice_del(),r=L.limit-L.cursor,L.ket=L.cursor,!(!Q()||(L.bra=L.cursor,L.slice_del(),!er()))||(L.cursor=L.limit-r,L.ket=L.cursor,(B()||(L.cursor=L.limit-r,D()||(L.cursor=L.limit-r,er())))&&(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er())),!0))}function or(){var r,i,e=L.limit-L.cursor;if(L.ket=L.cursor,!(I()||(L.cursor=L.limit-e,A()&&L.in_grouping_b(P,105,305)&&Z()||(L.cursor=L.limit-e,A()&&L.find_among_b(u,2)&&Z()))))return!1;if(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,r=L.limit-L.cursor,B())L.bra=L.cursor,L.slice_del(),i=L.limit-L.cursor,L.ket=L.cursor,Q()||(L.cursor=L.limit-i);else if(L.cursor=L.limit-r,!Q())return!0;return L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,er(),!0}function sr(){var r,i,e=L.limit-L.cursor;if(L.ket=L.cursor,Q())return L.bra=L.cursor,L.slice_del(),void er();if(L.cursor=L.limit-e,L.ket=L.cursor,A()&&L.find_among_b(d,2)&&T())if(L.bra=L.cursor,L.slice_del(),r=L.limit-L.cursor,L.ket=L.cursor,G())L.bra=L.cursor,L.slice_del();else{if(L.cursor=L.limit-r,L.ket=L.cursor,!B()&&(L.cursor=L.limit-r,!D())){if(L.cursor=L.limit-r,L.ket=L.cursor,!Q())return;if(L.bra=L.cursor,L.slice_del(),!er())return}L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er())}else if(L.cursor=L.limit-e,!nr(e)&&(L.cursor=L.limit-e,!tr(e))){if(L.cursor=L.limit-e,L.ket=L.cursor,A()&&L.find_among_b(l,4))return L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,i=L.limit-L.cursor,void(B()?(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er())):(L.cursor=L.limit-i,Q()?(L.bra=L.cursor,L.slice_del()):L.cursor=L.limit-i,er()));if(L.cursor=L.limit-e,!ur()){if(L.cursor=L.limit-e,G())return L.bra=L.cursor,void L.slice_del();L.cursor=L.limit-e,er()||(L.cursor=L.limit-e,or()||(L.cursor=L.limit-e,L.ket=L.cursor,(B()||(L.cursor=L.limit-e,D()))&&(L.bra=L.cursor,L.slice_del(),L.ket=L.cursor,Q()&&(L.bra=L.cursor,L.slice_del(),er()))))}}}function cr(r,i,e){if(L.cursor=L.limit-r,function(){for(;;){var r=L.limit-L.cursor;if(L.in_grouping_b(C,97,305)){L.cursor=L.limit-r;break}if(L.cursor=L.limit-r,L.cursor<=L.limit_backward)return!1;L.cursor--}return!0}()){var n=L.limit-L.cursor;if(!L.eq_s_b(1,i)&&(L.cursor=L.limit-n,!L.eq_s_b(1,e)))return!0;L.cursor=L.limit-r;var t=L.cursor;return L.insert(L.cursor,L.cursor,e),L.cursor=t,!1}return!0}function lr(r,i,e){for(;!L.eq_s(i,e);){if(L.cursor>=L.limit)return!0;L.cursor++}return i!=L.limit||(L.cursor=r,!1)}function ar(){var r,i,e=L.cursor;return!(!lr(r=L.cursor,2,"ad")||!lr(L.cursor=r,5,"soyad"))&&(L.limit_backward=e,L.cursor=L.limit,i=L.limit-L.cursor,(L.eq_s_b(1,"d")||(L.cursor=L.limit-i,L.eq_s_b(1,"g")))&&cr(i,"a","ı")&&cr(i,"e","i")&&cr(i,"o","u")&&cr(i,"ö","ü"),L.cursor=L.limit,function(){var r;if(L.ket=L.cursor,r=L.find_among_b(q,4))switch(L.bra=L.cursor,r){case 1:L.slice_from("p");break;case 2:L.slice_from("ç");break;case 3:L.slice_from("t");break;case 4:L.slice_from("k")}}(),!0)}this.setCurrent=function(r){L.setCurrent(r)},this.getCurrent=function(){return L.getCurrent()},this.stem=function(){return!!(function(){for(var r,i=L.cursor,e=2;;){for(r=L.cursor;!L.in_grouping(C,97,305);){if(L.cursor>=L.limit)return L.cursor=r,!(0c;c++)if(m=e[c],v=j.style[m],u(m,"-")&&(m=p(m)),j.style[m]!==n){if(i||r(o,"undefined"))return a(),"pfx"!=t||m;try{j.style[m]=o}catch(e){}if(j.style[m]!=v)return a(),"pfx"!=t||m}return a(),!1}function m(e,t){return function(){return e.apply(t,arguments)}}function v(e,t,n){var o;for(var i in e)if(e[i]in t)return!1===n?e[i]:(o=t[e[i]],r(o,"function")?m(o,n||t):o);return!1}function y(e,t,n,o,i){var s=e.charAt(0).toUpperCase()+e.slice(1),a=(e+" "+k.join(s+" ")+s).split(" ");return r(t,"string")||r(t,"undefined")?h(a,t,o,i):(a=(e+" "+A.join(s+" ")+s).split(" "),v(a,t,n))}function g(e,t,r){return y(e,n,n,t,r)}var S=[],C={_version:"3.6.0",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(e,t){var n=this;setTimeout(function(){t(n[e])},0)},addTest:function(e,t,n){S.push({name:e,fn:t,options:n})},addAsyncTest:function(e){S.push({name:null,fn:e})}},w=function(){};w.prototype=C,w=new w;var b,_=[],x=t.documentElement,T="svg"===x.nodeName.toLowerCase();!function(){var e={}.hasOwnProperty;b=r(e,"undefined")||r(e.call,"undefined")?function(e,t){return t in e&&r(e.constructor.prototype[t],"undefined")}:function(t,n){return e.call(t,n)}}(),C._l={},C.on=function(e,t){this._l[e]||(this._l[e]=[]),this._l[e].push(t),w.hasOwnProperty(e)&&setTimeout(function(){w._trigger(e,w[e])},0)},C._trigger=function(e,t){if(this._l[e]){var n=this._l[e];setTimeout(function(){var e;for(e=0;e +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Variables: typography +// ---------------------------------------------------------------------------- + +// Modular typographic scale +$ms-base: 1.6rem; +$ms-ratio: $major-third; + +// ---------------------------------------------------------------------------- +// Variables: breakpoints +// ---------------------------------------------------------------------------- + +// stylelint-disable unit-whitelist + +// Device-specific breakpoints +$break-devices: ( + mobile: ( + portrait: px2em(220px) px2em(479px), + landscape: px2em(480px) px2em(719px) + ), + tablet: ( + portrait: px2em(720px) px2em(959px), + landscape: px2em(960px) px2em(1219px) + ), + screen: ( + small: px2em(1220px) px2em(1599px), + medium: px2em(1600px) px2em(1999px), + large: px2em(2000px) + ) +); + +// stylelint-enable unit-whitelist + +// ---------------------------------------------------------------------------- +// Variables: base colors +// ---------------------------------------------------------------------------- + +// Primary and accent colors +$md-color-primary: $clr-indigo-500 !default; +$md-color-accent: $clr-indigo-a200 !default; + +// Shades of black +$md-color-black: hsla(0, 0%, 0%, 0.87) !default; +$md-color-black--light: hsla(0, 0%, 0%, 0.54) !default; +$md-color-black--lighter: hsla(0, 0%, 0%, 0.26) !default; +$md-color-black--lightest: hsla(0, 0%, 0%, 0.07) !default; +$md-color-black--transparent: hsla(0, 0%, 0%, 0) !default; + +// Shades of white +$md-color-white: hsla(0, 0%, 100%, 1) !default; +$md-color-white--light: hsla(0, 0%, 100%, 0.7) !default; +$md-color-white--lighter: hsla(0, 0%, 100%, 0.3) !default; +$md-color-white--lightest: hsla(0, 0%, 100%, 0.12) !default; +$md-color-white--transparent: hsla(0, 0%, 100%, 0) !default; + +// ---------------------------------------------------------------------------- +// Variables: sizing and spacing +// ---------------------------------------------------------------------------- + +// Icons +$md-icon-size: $ms-base * 1.5; +$md-icon-padding: $ms-base * 0.5; +$md-icon-margin: $ms-base * 0.25; + +// Code blocks +$md-code-background: hsla(0, 0%, 92.5%, 0.5); +$md-code-color: #37474F; + +// Keystrokes +$md-keyboard-background: #FCFCFC; +$md-keyboard-color: #555555; diff --git a/site/assets/stylesheets/_shame.scss b/site/assets/stylesheets/_shame.scss new file mode 100644 index 000000000..31326ac51 --- /dev/null +++ b/site/assets/stylesheets/_shame.scss @@ -0,0 +1,25 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Nothing to see here, move along +// ---------------------------------------------------------------------------- diff --git a/site/assets/stylesheets/application-palette.22915126.css b/site/assets/stylesheets/application-palette.22915126.css new file mode 100644 index 000000000..3c8766e26 --- /dev/null +++ b/site/assets/stylesheets/application-palette.22915126.css @@ -0,0 +1,1176 @@ +button[data-md-color-primary], +button[data-md-color-accent] { + width: 13rem; + margin-bottom: 0.4rem; + padding: 2.4rem 0.8rem 0.4rem; + transition: background-color 0.25s, opacity 0.25s; + border-radius: 0.2rem; + color: white; + font-size: 1.28rem; + text-align: left; + cursor: pointer; } + button[data-md-color-primary]:hover, + button[data-md-color-accent]:hover { + opacity: 0.75; } + +button[data-md-color-primary="red"] { + background-color: #ef5350; } + +[data-md-color-primary="red"] .md-typeset a { + color: #ef5350; } + +[data-md-color-primary="red"] .md-header { + background-color: #ef5350; } + +[data-md-color-primary="red"] .md-hero { + background-color: #ef5350; } + +[data-md-color-primary="red"] .md-nav__link:active, +[data-md-color-primary="red"] .md-nav__link--active { + color: #ef5350; } + +[data-md-color-primary="red"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="pink"] { + background-color: #e91e63; } + +[data-md-color-primary="pink"] .md-typeset a { + color: #e91e63; } + +[data-md-color-primary="pink"] .md-header { + background-color: #e91e63; } + +[data-md-color-primary="pink"] .md-hero { + background-color: #e91e63; } + +[data-md-color-primary="pink"] .md-nav__link:active, +[data-md-color-primary="pink"] .md-nav__link--active { + color: #e91e63; } + +[data-md-color-primary="pink"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="purple"] { + background-color: #ab47bc; } + +[data-md-color-primary="purple"] .md-typeset a { + color: #ab47bc; } + +[data-md-color-primary="purple"] .md-header { + background-color: #ab47bc; } + +[data-md-color-primary="purple"] .md-hero { + background-color: #ab47bc; } + +[data-md-color-primary="purple"] .md-nav__link:active, +[data-md-color-primary="purple"] .md-nav__link--active { + color: #ab47bc; } + +[data-md-color-primary="purple"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="deep-purple"] { + background-color: #7e57c2; } + +[data-md-color-primary="deep-purple"] .md-typeset a { + color: #7e57c2; } + +[data-md-color-primary="deep-purple"] .md-header { + background-color: #7e57c2; } + +[data-md-color-primary="deep-purple"] .md-hero { + background-color: #7e57c2; } + +[data-md-color-primary="deep-purple"] .md-nav__link:active, +[data-md-color-primary="deep-purple"] .md-nav__link--active { + color: #7e57c2; } + +[data-md-color-primary="deep-purple"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="indigo"] { + background-color: #3f51b5; } + +[data-md-color-primary="indigo"] .md-typeset a { + color: #3f51b5; } + +[data-md-color-primary="indigo"] .md-header { + background-color: #3f51b5; } + +[data-md-color-primary="indigo"] .md-hero { + background-color: #3f51b5; } + +[data-md-color-primary="indigo"] .md-nav__link:active, +[data-md-color-primary="indigo"] .md-nav__link--active { + color: #3f51b5; } + +[data-md-color-primary="indigo"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="blue"] { + background-color: #2196f3; } + +[data-md-color-primary="blue"] .md-typeset a { + color: #2196f3; } + +[data-md-color-primary="blue"] .md-header { + background-color: #2196f3; } + +[data-md-color-primary="blue"] .md-hero { + background-color: #2196f3; } + +[data-md-color-primary="blue"] .md-nav__link:active, +[data-md-color-primary="blue"] .md-nav__link--active { + color: #2196f3; } + +[data-md-color-primary="blue"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="light-blue"] { + background-color: #03a9f4; } + +[data-md-color-primary="light-blue"] .md-typeset a { + color: #03a9f4; } + +[data-md-color-primary="light-blue"] .md-header { + background-color: #03a9f4; } + +[data-md-color-primary="light-blue"] .md-hero { + background-color: #03a9f4; } + +[data-md-color-primary="light-blue"] .md-nav__link:active, +[data-md-color-primary="light-blue"] .md-nav__link--active { + color: #03a9f4; } + +[data-md-color-primary="light-blue"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="cyan"] { + background-color: #00bcd4; } + +[data-md-color-primary="cyan"] .md-typeset a { + color: #00bcd4; } + +[data-md-color-primary="cyan"] .md-header { + background-color: #00bcd4; } + +[data-md-color-primary="cyan"] .md-hero { + background-color: #00bcd4; } + +[data-md-color-primary="cyan"] .md-nav__link:active, +[data-md-color-primary="cyan"] .md-nav__link--active { + color: #00bcd4; } + +[data-md-color-primary="cyan"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="teal"] { + background-color: #009688; } + +[data-md-color-primary="teal"] .md-typeset a { + color: #009688; } + +[data-md-color-primary="teal"] .md-header { + background-color: #009688; } + +[data-md-color-primary="teal"] .md-hero { + background-color: #009688; } + +[data-md-color-primary="teal"] .md-nav__link:active, +[data-md-color-primary="teal"] .md-nav__link--active { + color: #009688; } + +[data-md-color-primary="teal"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="green"] { + background-color: #4caf50; } + +[data-md-color-primary="green"] .md-typeset a { + color: #4caf50; } + +[data-md-color-primary="green"] .md-header { + background-color: #4caf50; } + +[data-md-color-primary="green"] .md-hero { + background-color: #4caf50; } + +[data-md-color-primary="green"] .md-nav__link:active, +[data-md-color-primary="green"] .md-nav__link--active { + color: #4caf50; } + +[data-md-color-primary="green"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="light-green"] { + background-color: #7cb342; } + +[data-md-color-primary="light-green"] .md-typeset a { + color: #7cb342; } + +[data-md-color-primary="light-green"] .md-header { + background-color: #7cb342; } + +[data-md-color-primary="light-green"] .md-hero { + background-color: #7cb342; } + +[data-md-color-primary="light-green"] .md-nav__link:active, +[data-md-color-primary="light-green"] .md-nav__link--active { + color: #7cb342; } + +[data-md-color-primary="light-green"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="lime"] { + background-color: #c0ca33; } + +[data-md-color-primary="lime"] .md-typeset a { + color: #c0ca33; } + +[data-md-color-primary="lime"] .md-header { + background-color: #c0ca33; } + +[data-md-color-primary="lime"] .md-hero { + background-color: #c0ca33; } + +[data-md-color-primary="lime"] .md-nav__link:active, +[data-md-color-primary="lime"] .md-nav__link--active { + color: #c0ca33; } + +[data-md-color-primary="lime"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="yellow"] { + background-color: #f9a825; } + +[data-md-color-primary="yellow"] .md-typeset a { + color: #f9a825; } + +[data-md-color-primary="yellow"] .md-header { + background-color: #f9a825; } + +[data-md-color-primary="yellow"] .md-hero { + background-color: #f9a825; } + +[data-md-color-primary="yellow"] .md-nav__link:active, +[data-md-color-primary="yellow"] .md-nav__link--active { + color: #f9a825; } + +[data-md-color-primary="yellow"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="amber"] { + background-color: #ffa000; } + +[data-md-color-primary="amber"] .md-typeset a { + color: #ffa000; } + +[data-md-color-primary="amber"] .md-header { + background-color: #ffa000; } + +[data-md-color-primary="amber"] .md-hero { + background-color: #ffa000; } + +[data-md-color-primary="amber"] .md-nav__link:active, +[data-md-color-primary="amber"] .md-nav__link--active { + color: #ffa000; } + +[data-md-color-primary="amber"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="orange"] { + background-color: #fb8c00; } + +[data-md-color-primary="orange"] .md-typeset a { + color: #fb8c00; } + +[data-md-color-primary="orange"] .md-header { + background-color: #fb8c00; } + +[data-md-color-primary="orange"] .md-hero { + background-color: #fb8c00; } + +[data-md-color-primary="orange"] .md-nav__link:active, +[data-md-color-primary="orange"] .md-nav__link--active { + color: #fb8c00; } + +[data-md-color-primary="orange"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="deep-orange"] { + background-color: #ff7043; } + +[data-md-color-primary="deep-orange"] .md-typeset a { + color: #ff7043; } + +[data-md-color-primary="deep-orange"] .md-header { + background-color: #ff7043; } + +[data-md-color-primary="deep-orange"] .md-hero { + background-color: #ff7043; } + +[data-md-color-primary="deep-orange"] .md-nav__link:active, +[data-md-color-primary="deep-orange"] .md-nav__link--active { + color: #ff7043; } + +[data-md-color-primary="deep-orange"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="brown"] { + background-color: #795548; } + +[data-md-color-primary="brown"] .md-typeset a { + color: #795548; } + +[data-md-color-primary="brown"] .md-header { + background-color: #795548; } + +[data-md-color-primary="brown"] .md-hero { + background-color: #795548; } + +[data-md-color-primary="brown"] .md-nav__link:active, +[data-md-color-primary="brown"] .md-nav__link--active { + color: #795548; } + +[data-md-color-primary="brown"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="grey"] { + background-color: #757575; } + +[data-md-color-primary="grey"] .md-typeset a { + color: #757575; } + +[data-md-color-primary="grey"] .md-header { + background-color: #757575; } + +[data-md-color-primary="grey"] .md-hero { + background-color: #757575; } + +[data-md-color-primary="grey"] .md-nav__link:active, +[data-md-color-primary="grey"] .md-nav__link--active { + color: #757575; } + +[data-md-color-primary="grey"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="blue-grey"] { + background-color: #546e7a; } + +[data-md-color-primary="blue-grey"] .md-typeset a { + color: #546e7a; } + +[data-md-color-primary="blue-grey"] .md-header { + background-color: #546e7a; } + +[data-md-color-primary="blue-grey"] .md-hero { + background-color: #546e7a; } + +[data-md-color-primary="blue-grey"] .md-nav__link:active, +[data-md-color-primary="blue-grey"] .md-nav__link--active { + color: #546e7a; } + +[data-md-color-primary="blue-grey"] .md-nav__item--nested > .md-nav__link { + color: inherit; } + +button[data-md-color-primary="white"] { + background-color: white; + color: rgba(0, 0, 0, 0.87); + box-shadow: 0 0 0.1rem rgba(0, 0, 0, 0.54) inset; } + +[data-md-color-primary="white"] .md-header { + background-color: white; + color: rgba(0, 0, 0, 0.87); } + +[data-md-color-primary="white"] .md-hero { + background-color: white; + color: rgba(0, 0, 0, 0.87); } + [data-md-color-primary="white"] .md-hero--expand { + border-bottom: 0.1rem solid rgba(0, 0, 0, 0.07); } + +button[data-md-color-accent="red"] { + background-color: #ff1744; } + +[data-md-color-accent="red"] .md-typeset a:hover, +[data-md-color-accent="red"] .md-typeset a:active { + color: #ff1744; } + +[data-md-color-accent="red"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="red"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #ff1744; } + +[data-md-color-accent="red"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="red"] .md-typeset .md-clipboard:active::before { + color: #ff1744; } + +[data-md-color-accent="red"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="red"] .md-typeset .footnote li:target .footnote-backref { + color: #ff1744; } + +[data-md-color-accent="red"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="red"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="red"] .md-typeset [id] .headerlink:focus { + color: #ff1744; } + +[data-md-color-accent="red"] .md-nav__link:focus, +[data-md-color-accent="red"] .md-nav__link:hover { + color: #ff1744; } + +[data-md-color-accent="red"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ff1744; } + +[data-md-color-accent="red"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="red"] .md-search-result__link:hover { + background-color: rgba(255, 23, 68, 0.1); } + +[data-md-color-accent="red"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ff1744; } + +[data-md-color-accent="red"] .md-source-file:hover::before { + background-color: #ff1744; } + +button[data-md-color-accent="pink"] { + background-color: #f50057; } + +[data-md-color-accent="pink"] .md-typeset a:hover, +[data-md-color-accent="pink"] .md-typeset a:active { + color: #f50057; } + +[data-md-color-accent="pink"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="pink"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #f50057; } + +[data-md-color-accent="pink"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="pink"] .md-typeset .md-clipboard:active::before { + color: #f50057; } + +[data-md-color-accent="pink"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="pink"] .md-typeset .footnote li:target .footnote-backref { + color: #f50057; } + +[data-md-color-accent="pink"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="pink"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="pink"] .md-typeset [id] .headerlink:focus { + color: #f50057; } + +[data-md-color-accent="pink"] .md-nav__link:focus, +[data-md-color-accent="pink"] .md-nav__link:hover { + color: #f50057; } + +[data-md-color-accent="pink"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #f50057; } + +[data-md-color-accent="pink"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="pink"] .md-search-result__link:hover { + background-color: rgba(245, 0, 87, 0.1); } + +[data-md-color-accent="pink"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #f50057; } + +[data-md-color-accent="pink"] .md-source-file:hover::before { + background-color: #f50057; } + +button[data-md-color-accent="purple"] { + background-color: #e040fb; } + +[data-md-color-accent="purple"] .md-typeset a:hover, +[data-md-color-accent="purple"] .md-typeset a:active { + color: #e040fb; } + +[data-md-color-accent="purple"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="purple"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #e040fb; } + +[data-md-color-accent="purple"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="purple"] .md-typeset .md-clipboard:active::before { + color: #e040fb; } + +[data-md-color-accent="purple"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="purple"] .md-typeset .footnote li:target .footnote-backref { + color: #e040fb; } + +[data-md-color-accent="purple"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="purple"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="purple"] .md-typeset [id] .headerlink:focus { + color: #e040fb; } + +[data-md-color-accent="purple"] .md-nav__link:focus, +[data-md-color-accent="purple"] .md-nav__link:hover { + color: #e040fb; } + +[data-md-color-accent="purple"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #e040fb; } + +[data-md-color-accent="purple"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="purple"] .md-search-result__link:hover { + background-color: rgba(224, 64, 251, 0.1); } + +[data-md-color-accent="purple"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #e040fb; } + +[data-md-color-accent="purple"] .md-source-file:hover::before { + background-color: #e040fb; } + +button[data-md-color-accent="deep-purple"] { + background-color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-typeset a:hover, +[data-md-color-accent="deep-purple"] .md-typeset a:active { + color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="deep-purple"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="deep-purple"] .md-typeset .md-clipboard:active::before { + color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="deep-purple"] .md-typeset .footnote li:target .footnote-backref { + color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="deep-purple"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="deep-purple"] .md-typeset [id] .headerlink:focus { + color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-nav__link:focus, +[data-md-color-accent="deep-purple"] .md-nav__link:hover { + color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="deep-purple"] .md-search-result__link:hover { + background-color: rgba(124, 77, 255, 0.1); } + +[data-md-color-accent="deep-purple"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #7c4dff; } + +[data-md-color-accent="deep-purple"] .md-source-file:hover::before { + background-color: #7c4dff; } + +button[data-md-color-accent="indigo"] { + background-color: #536dfe; } + +[data-md-color-accent="indigo"] .md-typeset a:hover, +[data-md-color-accent="indigo"] .md-typeset a:active { + color: #536dfe; } + +[data-md-color-accent="indigo"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="indigo"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #536dfe; } + +[data-md-color-accent="indigo"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="indigo"] .md-typeset .md-clipboard:active::before { + color: #536dfe; } + +[data-md-color-accent="indigo"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="indigo"] .md-typeset .footnote li:target .footnote-backref { + color: #536dfe; } + +[data-md-color-accent="indigo"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="indigo"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="indigo"] .md-typeset [id] .headerlink:focus { + color: #536dfe; } + +[data-md-color-accent="indigo"] .md-nav__link:focus, +[data-md-color-accent="indigo"] .md-nav__link:hover { + color: #536dfe; } + +[data-md-color-accent="indigo"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #536dfe; } + +[data-md-color-accent="indigo"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="indigo"] .md-search-result__link:hover { + background-color: rgba(83, 109, 254, 0.1); } + +[data-md-color-accent="indigo"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #536dfe; } + +[data-md-color-accent="indigo"] .md-source-file:hover::before { + background-color: #536dfe; } + +button[data-md-color-accent="blue"] { + background-color: #448aff; } + +[data-md-color-accent="blue"] .md-typeset a:hover, +[data-md-color-accent="blue"] .md-typeset a:active { + color: #448aff; } + +[data-md-color-accent="blue"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="blue"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #448aff; } + +[data-md-color-accent="blue"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="blue"] .md-typeset .md-clipboard:active::before { + color: #448aff; } + +[data-md-color-accent="blue"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="blue"] .md-typeset .footnote li:target .footnote-backref { + color: #448aff; } + +[data-md-color-accent="blue"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="blue"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="blue"] .md-typeset [id] .headerlink:focus { + color: #448aff; } + +[data-md-color-accent="blue"] .md-nav__link:focus, +[data-md-color-accent="blue"] .md-nav__link:hover { + color: #448aff; } + +[data-md-color-accent="blue"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #448aff; } + +[data-md-color-accent="blue"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="blue"] .md-search-result__link:hover { + background-color: rgba(68, 138, 255, 0.1); } + +[data-md-color-accent="blue"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #448aff; } + +[data-md-color-accent="blue"] .md-source-file:hover::before { + background-color: #448aff; } + +button[data-md-color-accent="light-blue"] { + background-color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-typeset a:hover, +[data-md-color-accent="light-blue"] .md-typeset a:active { + color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="light-blue"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="light-blue"] .md-typeset .md-clipboard:active::before { + color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="light-blue"] .md-typeset .footnote li:target .footnote-backref { + color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="light-blue"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="light-blue"] .md-typeset [id] .headerlink:focus { + color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-nav__link:focus, +[data-md-color-accent="light-blue"] .md-nav__link:hover { + color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="light-blue"] .md-search-result__link:hover { + background-color: rgba(0, 145, 234, 0.1); } + +[data-md-color-accent="light-blue"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #0091ea; } + +[data-md-color-accent="light-blue"] .md-source-file:hover::before { + background-color: #0091ea; } + +button[data-md-color-accent="cyan"] { + background-color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-typeset a:hover, +[data-md-color-accent="cyan"] .md-typeset a:active { + color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="cyan"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="cyan"] .md-typeset .md-clipboard:active::before { + color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="cyan"] .md-typeset .footnote li:target .footnote-backref { + color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="cyan"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="cyan"] .md-typeset [id] .headerlink:focus { + color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-nav__link:focus, +[data-md-color-accent="cyan"] .md-nav__link:hover { + color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="cyan"] .md-search-result__link:hover { + background-color: rgba(0, 184, 212, 0.1); } + +[data-md-color-accent="cyan"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #00b8d4; } + +[data-md-color-accent="cyan"] .md-source-file:hover::before { + background-color: #00b8d4; } + +button[data-md-color-accent="teal"] { + background-color: #00bfa5; } + +[data-md-color-accent="teal"] .md-typeset a:hover, +[data-md-color-accent="teal"] .md-typeset a:active { + color: #00bfa5; } + +[data-md-color-accent="teal"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="teal"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #00bfa5; } + +[data-md-color-accent="teal"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="teal"] .md-typeset .md-clipboard:active::before { + color: #00bfa5; } + +[data-md-color-accent="teal"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="teal"] .md-typeset .footnote li:target .footnote-backref { + color: #00bfa5; } + +[data-md-color-accent="teal"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="teal"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="teal"] .md-typeset [id] .headerlink:focus { + color: #00bfa5; } + +[data-md-color-accent="teal"] .md-nav__link:focus, +[data-md-color-accent="teal"] .md-nav__link:hover { + color: #00bfa5; } + +[data-md-color-accent="teal"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #00bfa5; } + +[data-md-color-accent="teal"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="teal"] .md-search-result__link:hover { + background-color: rgba(0, 191, 165, 0.1); } + +[data-md-color-accent="teal"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #00bfa5; } + +[data-md-color-accent="teal"] .md-source-file:hover::before { + background-color: #00bfa5; } + +button[data-md-color-accent="green"] { + background-color: #00c853; } + +[data-md-color-accent="green"] .md-typeset a:hover, +[data-md-color-accent="green"] .md-typeset a:active { + color: #00c853; } + +[data-md-color-accent="green"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="green"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #00c853; } + +[data-md-color-accent="green"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="green"] .md-typeset .md-clipboard:active::before { + color: #00c853; } + +[data-md-color-accent="green"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="green"] .md-typeset .footnote li:target .footnote-backref { + color: #00c853; } + +[data-md-color-accent="green"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="green"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="green"] .md-typeset [id] .headerlink:focus { + color: #00c853; } + +[data-md-color-accent="green"] .md-nav__link:focus, +[data-md-color-accent="green"] .md-nav__link:hover { + color: #00c853; } + +[data-md-color-accent="green"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #00c853; } + +[data-md-color-accent="green"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="green"] .md-search-result__link:hover { + background-color: rgba(0, 200, 83, 0.1); } + +[data-md-color-accent="green"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #00c853; } + +[data-md-color-accent="green"] .md-source-file:hover::before { + background-color: #00c853; } + +button[data-md-color-accent="light-green"] { + background-color: #64dd17; } + +[data-md-color-accent="light-green"] .md-typeset a:hover, +[data-md-color-accent="light-green"] .md-typeset a:active { + color: #64dd17; } + +[data-md-color-accent="light-green"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="light-green"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #64dd17; } + +[data-md-color-accent="light-green"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="light-green"] .md-typeset .md-clipboard:active::before { + color: #64dd17; } + +[data-md-color-accent="light-green"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="light-green"] .md-typeset .footnote li:target .footnote-backref { + color: #64dd17; } + +[data-md-color-accent="light-green"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="light-green"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="light-green"] .md-typeset [id] .headerlink:focus { + color: #64dd17; } + +[data-md-color-accent="light-green"] .md-nav__link:focus, +[data-md-color-accent="light-green"] .md-nav__link:hover { + color: #64dd17; } + +[data-md-color-accent="light-green"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #64dd17; } + +[data-md-color-accent="light-green"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="light-green"] .md-search-result__link:hover { + background-color: rgba(100, 221, 23, 0.1); } + +[data-md-color-accent="light-green"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #64dd17; } + +[data-md-color-accent="light-green"] .md-source-file:hover::before { + background-color: #64dd17; } + +button[data-md-color-accent="lime"] { + background-color: #aeea00; } + +[data-md-color-accent="lime"] .md-typeset a:hover, +[data-md-color-accent="lime"] .md-typeset a:active { + color: #aeea00; } + +[data-md-color-accent="lime"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="lime"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #aeea00; } + +[data-md-color-accent="lime"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="lime"] .md-typeset .md-clipboard:active::before { + color: #aeea00; } + +[data-md-color-accent="lime"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="lime"] .md-typeset .footnote li:target .footnote-backref { + color: #aeea00; } + +[data-md-color-accent="lime"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="lime"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="lime"] .md-typeset [id] .headerlink:focus { + color: #aeea00; } + +[data-md-color-accent="lime"] .md-nav__link:focus, +[data-md-color-accent="lime"] .md-nav__link:hover { + color: #aeea00; } + +[data-md-color-accent="lime"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #aeea00; } + +[data-md-color-accent="lime"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="lime"] .md-search-result__link:hover { + background-color: rgba(174, 234, 0, 0.1); } + +[data-md-color-accent="lime"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #aeea00; } + +[data-md-color-accent="lime"] .md-source-file:hover::before { + background-color: #aeea00; } + +button[data-md-color-accent="yellow"] { + background-color: #ffd600; } + +[data-md-color-accent="yellow"] .md-typeset a:hover, +[data-md-color-accent="yellow"] .md-typeset a:active { + color: #ffd600; } + +[data-md-color-accent="yellow"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="yellow"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #ffd600; } + +[data-md-color-accent="yellow"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="yellow"] .md-typeset .md-clipboard:active::before { + color: #ffd600; } + +[data-md-color-accent="yellow"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="yellow"] .md-typeset .footnote li:target .footnote-backref { + color: #ffd600; } + +[data-md-color-accent="yellow"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="yellow"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="yellow"] .md-typeset [id] .headerlink:focus { + color: #ffd600; } + +[data-md-color-accent="yellow"] .md-nav__link:focus, +[data-md-color-accent="yellow"] .md-nav__link:hover { + color: #ffd600; } + +[data-md-color-accent="yellow"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ffd600; } + +[data-md-color-accent="yellow"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="yellow"] .md-search-result__link:hover { + background-color: rgba(255, 214, 0, 0.1); } + +[data-md-color-accent="yellow"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ffd600; } + +[data-md-color-accent="yellow"] .md-source-file:hover::before { + background-color: #ffd600; } + +button[data-md-color-accent="amber"] { + background-color: #ffab00; } + +[data-md-color-accent="amber"] .md-typeset a:hover, +[data-md-color-accent="amber"] .md-typeset a:active { + color: #ffab00; } + +[data-md-color-accent="amber"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="amber"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #ffab00; } + +[data-md-color-accent="amber"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="amber"] .md-typeset .md-clipboard:active::before { + color: #ffab00; } + +[data-md-color-accent="amber"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="amber"] .md-typeset .footnote li:target .footnote-backref { + color: #ffab00; } + +[data-md-color-accent="amber"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="amber"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="amber"] .md-typeset [id] .headerlink:focus { + color: #ffab00; } + +[data-md-color-accent="amber"] .md-nav__link:focus, +[data-md-color-accent="amber"] .md-nav__link:hover { + color: #ffab00; } + +[data-md-color-accent="amber"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ffab00; } + +[data-md-color-accent="amber"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="amber"] .md-search-result__link:hover { + background-color: rgba(255, 171, 0, 0.1); } + +[data-md-color-accent="amber"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ffab00; } + +[data-md-color-accent="amber"] .md-source-file:hover::before { + background-color: #ffab00; } + +button[data-md-color-accent="orange"] { + background-color: #ff9100; } + +[data-md-color-accent="orange"] .md-typeset a:hover, +[data-md-color-accent="orange"] .md-typeset a:active { + color: #ff9100; } + +[data-md-color-accent="orange"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="orange"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #ff9100; } + +[data-md-color-accent="orange"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="orange"] .md-typeset .md-clipboard:active::before { + color: #ff9100; } + +[data-md-color-accent="orange"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="orange"] .md-typeset .footnote li:target .footnote-backref { + color: #ff9100; } + +[data-md-color-accent="orange"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="orange"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="orange"] .md-typeset [id] .headerlink:focus { + color: #ff9100; } + +[data-md-color-accent="orange"] .md-nav__link:focus, +[data-md-color-accent="orange"] .md-nav__link:hover { + color: #ff9100; } + +[data-md-color-accent="orange"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ff9100; } + +[data-md-color-accent="orange"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="orange"] .md-search-result__link:hover { + background-color: rgba(255, 145, 0, 0.1); } + +[data-md-color-accent="orange"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ff9100; } + +[data-md-color-accent="orange"] .md-source-file:hover::before { + background-color: #ff9100; } + +button[data-md-color-accent="deep-orange"] { + background-color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-typeset a:hover, +[data-md-color-accent="deep-orange"] .md-typeset a:active { + color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-typeset pre code::-webkit-scrollbar-thumb:hover, +[data-md-color-accent="deep-orange"] .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-typeset .md-clipboard:hover::before, +[data-md-color-accent="deep-orange"] .md-typeset .md-clipboard:active::before { + color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-typeset .footnote li:hover .footnote-backref:hover, +[data-md-color-accent="deep-orange"] .md-typeset .footnote li:target .footnote-backref { + color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-typeset [id]:hover .headerlink:hover, +[data-md-color-accent="deep-orange"] .md-typeset [id]:target .headerlink, +[data-md-color-accent="deep-orange"] .md-typeset [id] .headerlink:focus { + color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-nav__link:focus, +[data-md-color-accent="deep-orange"] .md-nav__link:hover { + color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-search-result__link[data-md-state="active"], [data-md-color-accent="deep-orange"] .md-search-result__link:hover { + background-color: rgba(255, 110, 64, 0.1); } + +[data-md-color-accent="deep-orange"] .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #ff6e40; } + +[data-md-color-accent="deep-orange"] .md-source-file:hover::before { + background-color: #ff6e40; } + +@media only screen and (max-width: 59.9375em) { + [data-md-color-primary="red"] .md-nav__source { + background-color: rgba(190, 66, 64, 0.9675); } + [data-md-color-primary="pink"] .md-nav__source { + background-color: rgba(185, 24, 79, 0.9675); } + [data-md-color-primary="purple"] .md-nav__source { + background-color: rgba(136, 57, 150, 0.9675); } + [data-md-color-primary="deep-purple"] .md-nav__source { + background-color: rgba(100, 69, 154, 0.9675); } + [data-md-color-primary="indigo"] .md-nav__source { + background-color: rgba(50, 64, 144, 0.9675); } + [data-md-color-primary="blue"] .md-nav__source { + background-color: rgba(26, 119, 193, 0.9675); } + [data-md-color-primary="light-blue"] .md-nav__source { + background-color: rgba(2, 134, 194, 0.9675); } + [data-md-color-primary="cyan"] .md-nav__source { + background-color: rgba(0, 150, 169, 0.9675); } + [data-md-color-primary="teal"] .md-nav__source { + background-color: rgba(0, 119, 108, 0.9675); } + [data-md-color-primary="green"] .md-nav__source { + background-color: rgba(60, 139, 64, 0.9675); } + [data-md-color-primary="light-green"] .md-nav__source { + background-color: rgba(99, 142, 53, 0.9675); } + [data-md-color-primary="lime"] .md-nav__source { + background-color: rgba(153, 161, 41, 0.9675); } + [data-md-color-primary="yellow"] .md-nav__source { + background-color: rgba(198, 134, 29, 0.9675); } + [data-md-color-primary="amber"] .md-nav__source { + background-color: rgba(203, 127, 0, 0.9675); } + [data-md-color-primary="orange"] .md-nav__source { + background-color: rgba(200, 111, 0, 0.9675); } + [data-md-color-primary="deep-orange"] .md-nav__source { + background-color: rgba(203, 89, 53, 0.9675); } + [data-md-color-primary="brown"] .md-nav__source { + background-color: rgba(96, 68, 57, 0.9675); } + [data-md-color-primary="grey"] .md-nav__source { + background-color: rgba(93, 93, 93, 0.9675); } + [data-md-color-primary="blue-grey"] .md-nav__source { + background-color: rgba(67, 88, 97, 0.9675); } + [data-md-color-primary="white"] .md-nav__source { + background-color: rgba(0, 0, 0, 0.07); + color: rgba(0, 0, 0, 0.87); } } + +@media only screen and (max-width: 76.1875em) { + html [data-md-color-primary="red"] .md-nav--primary .md-nav__title--site { + background-color: #ef5350; } + html [data-md-color-primary="pink"] .md-nav--primary .md-nav__title--site { + background-color: #e91e63; } + html [data-md-color-primary="purple"] .md-nav--primary .md-nav__title--site { + background-color: #ab47bc; } + html [data-md-color-primary="deep-purple"] .md-nav--primary .md-nav__title--site { + background-color: #7e57c2; } + html [data-md-color-primary="indigo"] .md-nav--primary .md-nav__title--site { + background-color: #3f51b5; } + html [data-md-color-primary="blue"] .md-nav--primary .md-nav__title--site { + background-color: #2196f3; } + html [data-md-color-primary="light-blue"] .md-nav--primary .md-nav__title--site { + background-color: #03a9f4; } + html [data-md-color-primary="cyan"] .md-nav--primary .md-nav__title--site { + background-color: #00bcd4; } + html [data-md-color-primary="teal"] .md-nav--primary .md-nav__title--site { + background-color: #009688; } + html [data-md-color-primary="green"] .md-nav--primary .md-nav__title--site { + background-color: #4caf50; } + html [data-md-color-primary="light-green"] .md-nav--primary .md-nav__title--site { + background-color: #7cb342; } + html [data-md-color-primary="lime"] .md-nav--primary .md-nav__title--site { + background-color: #c0ca33; } + html [data-md-color-primary="yellow"] .md-nav--primary .md-nav__title--site { + background-color: #f9a825; } + html [data-md-color-primary="amber"] .md-nav--primary .md-nav__title--site { + background-color: #ffa000; } + html [data-md-color-primary="orange"] .md-nav--primary .md-nav__title--site { + background-color: #fb8c00; } + html [data-md-color-primary="deep-orange"] .md-nav--primary .md-nav__title--site { + background-color: #ff7043; } + html [data-md-color-primary="brown"] .md-nav--primary .md-nav__title--site { + background-color: #795548; } + html [data-md-color-primary="grey"] .md-nav--primary .md-nav__title--site { + background-color: #757575; } + html [data-md-color-primary="blue-grey"] .md-nav--primary .md-nav__title--site { + background-color: #546e7a; } + html [data-md-color-primary="white"] .md-nav--primary .md-nav__title--site { + background-color: white; + color: rgba(0, 0, 0, 0.87); } + [data-md-color-primary="white"] .md-hero { + border-bottom: 0.1rem solid rgba(0, 0, 0, 0.07); } } + +@media only screen and (min-width: 76.25em) { + [data-md-color-primary="red"] .md-tabs { + background-color: #ef5350; } + [data-md-color-primary="pink"] .md-tabs { + background-color: #e91e63; } + [data-md-color-primary="purple"] .md-tabs { + background-color: #ab47bc; } + [data-md-color-primary="deep-purple"] .md-tabs { + background-color: #7e57c2; } + [data-md-color-primary="indigo"] .md-tabs { + background-color: #3f51b5; } + [data-md-color-primary="blue"] .md-tabs { + background-color: #2196f3; } + [data-md-color-primary="light-blue"] .md-tabs { + background-color: #03a9f4; } + [data-md-color-primary="cyan"] .md-tabs { + background-color: #00bcd4; } + [data-md-color-primary="teal"] .md-tabs { + background-color: #009688; } + [data-md-color-primary="green"] .md-tabs { + background-color: #4caf50; } + [data-md-color-primary="light-green"] .md-tabs { + background-color: #7cb342; } + [data-md-color-primary="lime"] .md-tabs { + background-color: #c0ca33; } + [data-md-color-primary="yellow"] .md-tabs { + background-color: #f9a825; } + [data-md-color-primary="amber"] .md-tabs { + background-color: #ffa000; } + [data-md-color-primary="orange"] .md-tabs { + background-color: #fb8c00; } + [data-md-color-primary="deep-orange"] .md-tabs { + background-color: #ff7043; } + [data-md-color-primary="brown"] .md-tabs { + background-color: #795548; } + [data-md-color-primary="grey"] .md-tabs { + background-color: #757575; } + [data-md-color-primary="blue-grey"] .md-tabs { + background-color: #546e7a; } + [data-md-color-primary="white"] .md-tabs { + border-bottom: 0.1rem solid rgba(0, 0, 0, 0.07); + background-color: white; + color: rgba(0, 0, 0, 0.87); } } + +@media only screen and (min-width: 60em) { + [data-md-color-primary="white"] .md-search__input { + background-color: rgba(0, 0, 0, 0.07); } + [data-md-color-primary="white"] .md-search__input::-webkit-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + [data-md-color-primary="white"] .md-search__input:-ms-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + [data-md-color-primary="white"] .md-search__input::-ms-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + [data-md-color-primary="white"] .md-search__input::placeholder { + color: rgba(0, 0, 0, 0.54); } } + +/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiJhc3NldHMvc3R5bGVzaGVldHMvYXBwbGljYXRpb24tcGFsZXR0ZS4yMjkxNTEyNi5jc3MiLCJzb3VyY2VSb290IjoiIn0=*/ \ No newline at end of file diff --git a/site/assets/stylesheets/application-palette.scss b/site/assets/stylesheets/application-palette.scss new file mode 100644 index 000000000..48af85de4 --- /dev/null +++ b/site/assets/stylesheets/application-palette.scss @@ -0,0 +1,323 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Dependencies +// ---------------------------------------------------------------------------- + +@import "modularscale"; +@import "material-color"; +@import "material-shadows"; + +// ---------------------------------------------------------------------------- +// Local imports +// ---------------------------------------------------------------------------- + +@import "helpers/break"; +@import "helpers/px2em"; + +@import "config"; + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Color tile for presentation in theme documentation +button[data-md-color-primary], +button[data-md-color-accent] { + width: 13rem; + margin-bottom: 0.4rem; + padding: 2.4rem 0.8rem 0.4rem; + transition: + background-color 0.25s, + opacity 0.25s; + border-radius: 0.2rem; + color: $md-color-white; + font-size: ms(-1); + text-align: left; + cursor: pointer; + + // Hovered color tile + &:hover { + opacity: 0.75; + } +} + +// Build primary colors +@each $name, $color in ( + "red": $clr-red-400, + "pink": $clr-pink-500, + "purple": $clr-purple-400, + "deep-purple": $clr-deep-purple-400, + "indigo": $clr-indigo-500, + "blue": $clr-blue-500, + "light-blue": $clr-light-blue-500, + "cyan": $clr-cyan-500, + "teal": $clr-teal-500, + "green": $clr-green-500, + "light-green": $clr-light-green-600, + "lime": $clr-lime-600, + "yellow": $clr-yellow-800, + "amber": $clr-amber-700, + "orange": $clr-orange-600, + "deep-orange": $clr-deep-orange-400, + "brown": $clr-brown-500, + "grey": $clr-grey-600, + "blue-grey": $clr-blue-grey-600 +) { + + // Color tile for presentation in theme documentation + button[data-md-color-primary="#{$name}"] { + background-color: $color; + } + + // Color palette + [data-md-color-primary="#{$name}"] { + + // Links in typesetted content + .md-typeset a { + color: $color; + } + + // Application header (stays always on top) + .md-header { + background-color: $color; + } + + // Hero teaser + .md-hero { + background-color: $color; + } + + // Current or active link + .md-nav__link:active, + .md-nav__link--active { + color: $color; + } + + // Reset active color for nested list titles + .md-nav__item--nested > .md-nav__link { + color: inherit; + } + + // [tablet portrait -]: Layered navigation + @include break-to-device(tablet portrait) { + + // Repository containing source + .md-nav__source { + background-color: mix($color, $md-color-black, 75%); + } + } + + // [tablet -]: Layered navigation + @include break-to-device(tablet) { + + // Site title in main navigation + html & .md-nav--primary .md-nav__title--site { + background-color: $color; + } + } + + // [screen +]: Set background color for tabs + @include break-from-device(screen) { + + // Tabs with outline + .md-tabs { + background-color: $color; + } + } + } +} + +// Color tile for presentation in theme documentation +button[data-md-color-primary="white"] { + background-color: $md-color-white; + color: $md-color-black; + box-shadow: 0 0 0.1rem $md-color-black--light inset; +} + +// Overrides for white color +[data-md-color-primary="white"] { + + // Application header (stays always on top) + .md-header { + background-color: $md-color-white; + color: $md-color-black; + } + + // Hero teaser + .md-hero { + background-color: $md-color-white; + color: $md-color-black; + + // Add a border if there are no tabs + &--expand { + border-bottom: 0.1rem solid $md-color-black--lightest; + } + } + + // [tablet portrait -]: Layered navigation + @include break-to-device(tablet portrait) { + + // Repository containing source + .md-nav__source { + background-color: $md-color-black--lightest; + color: $md-color-black; + } + } + + // [tablet portrait +]: Change color of search input + @include break-from-device(tablet landscape) { + + // Search input + .md-search__input { + background-color: $md-color-black--lightest; + + // Search input placeholder + &::placeholder { + color: $md-color-black--light; + } + } + } + + // [tablet -]: Layered navigation + @include break-to-device(tablet) { + + // Site title in main navigation + html & .md-nav--primary .md-nav__title--site { + background-color: $md-color-white; + color: $md-color-black; + } + + // Hero teaser + .md-hero { + border-bottom: 0.1rem solid $md-color-black--lightest; + } + } + + // [screen +]: Set background color for tabs + @include break-from-device(screen) { + + // Tabs with outline + .md-tabs { + border-bottom: 0.1rem solid $md-color-black--lightest; + background-color: $md-color-white; + color: $md-color-black; + } + } +} + +// Build accent colors +@each $name, $color in ( + "red": $clr-red-a400, + "pink": $clr-pink-a400, + "purple": $clr-purple-a200, + "deep-purple": $clr-deep-purple-a200, + "indigo": $clr-indigo-a200, + "blue": $clr-blue-a200, + "light-blue": $clr-light-blue-a700, + "cyan": $clr-cyan-a700, + "teal": $clr-teal-a700, + "green": $clr-green-a700, + "light-green": $clr-light-green-a700, + "lime": $clr-lime-a700, + "yellow": $clr-yellow-a700, + "amber": $clr-amber-a700, + "orange": $clr-orange-a400, + "deep-orange": $clr-deep-orange-a200 +) { + + // Color tile for presentation in theme documentation + button[data-md-color-accent="#{$name}"] { + background-color: $color; + } + + // Color palette + [data-md-color-accent="#{$name}"] { + + // Typesetted content + .md-typeset { + + // Hovered and active links + a:hover, + a:active { + color: $color; + } + + // Hovered scrollbar thumb + pre code::-webkit-scrollbar-thumb:hover, + .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: $color; + } + + // Copy to clipboard active icon + .md-clipboard:hover::before, + .md-clipboard:active::before { + color: $color; + } + + // Active or targeted back reference + .footnote li:hover .footnote-backref:hover, + .footnote li:target .footnote-backref { + color: $color; + } + + // Active, targeted or focused permalink + [id]:hover .headerlink:hover, + [id]:target .headerlink, + [id] .headerlink:focus { + color: $color; + } + } + + // Focused or hovered link + .md-nav__link:focus, + .md-nav__link:hover { + color: $color; + } + + // Search container scrollbar thumb + .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: $color; + } + + // Search result link + .md-search-result__link { + + // Active or hovered link + &[data-md-state="active"], + &:hover { + background-color: transparentize($color, 0.9); + } + } + + // Wrapper for scrolling on overflow + .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: $color; + } + + // Source file icon + .md-source-file:hover::before { + background-color: $color; + } + } +} diff --git a/site/assets/stylesheets/application.11e41852.css b/site/assets/stylesheets/application.11e41852.css new file mode 100644 index 000000000..01456b445 --- /dev/null +++ b/site/assets/stylesheets/application.11e41852.css @@ -0,0 +1,2563 @@ +@charset "UTF-8"; +html { + box-sizing: border-box; } + +*, +*::before, +*::after { + box-sizing: inherit; } + +html { + -webkit-text-size-adjust: none; + -moz-text-size-adjust: none; + -ms-text-size-adjust: none; + text-size-adjust: none; } + +body { + margin: 0; } + +hr { + overflow: visible; + box-sizing: content-box; } + +a { + -webkit-text-decoration-skip: objects; } + +a, +button, +label, +input { + -webkit-tap-highlight-color: transparent; } + +a { + color: inherit; + text-decoration: none; } + +small { + font-size: 80%; } + +sub, +sup { + position: relative; + font-size: 80%; + line-height: 0; + vertical-align: baseline; } + +sub { + bottom: -0.25em; } + +sup { + top: -0.5em; } + +img { + border-style: none; } + +table { + border-collapse: separate; + border-spacing: 0; } + +td, +th { + font-weight: normal; + vertical-align: top; } + +button { + margin: 0; + padding: 0; + border: 0; + outline-style: none; + background: transparent; + font-size: inherit; } + +input { + border: 0; + outline: 0; } + +.md-icon, .md-clipboard::before, .md-nav__title::before, .md-nav__button, .md-nav__link::after, .md-search-result__article--document::before, .md-source-file::before, .md-typeset .admonition > .admonition-title::before, .md-typeset details > .admonition-title::before, .md-typeset .admonition > summary::before, .md-typeset details > summary::before, .md-typeset .footnote-backref, .md-typeset .critic.comment::before, .md-typeset summary::after, .md-typeset .task-list-control .task-list-indicator::before { + font-family: "Material Icons"; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: 1; + text-transform: none; + white-space: nowrap; + speak: none; + word-wrap: normal; + direction: ltr; } + .md-content__icon, .md-header-nav__button, .md-footer-nav__button, .md-nav__title::before, .md-nav__button, .md-search-result__article--document::before { + display: inline-block; + margin: 0.4rem; + padding: 0.8rem; + font-size: 2.4rem; + cursor: pointer; } + +.md-icon--arrow-back::before { + content: "\E5C4"; } + +.md-icon--arrow-forward::before { + content: "\E5C8"; } + +.md-icon--menu::before { + content: "\E5D2"; } + +.md-icon--search::before { + content: "\E8B6"; } + +[dir="rtl"] .md-icon--arrow-back::before { + content: "\E5C8"; } + +[dir="rtl"] .md-icon--arrow-forward::before { + content: "\E5C4"; } + +body { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } + +body, +input { + color: rgba(0, 0, 0, 0.87); + -webkit-font-feature-settings: "kern", "liga"; + font-feature-settings: "kern", "liga"; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } + +pre, +code, +kbd { + color: rgba(0, 0, 0, 0.87); + -webkit-font-feature-settings: "kern"; + font-feature-settings: "kern"; + font-family: "Courier New", Courier, monospace; } + +.md-typeset { + font-size: 1.6rem; + line-height: 1.6; + -webkit-print-color-adjust: exact; } + .md-typeset p, + .md-typeset ul, + .md-typeset ol, + .md-typeset blockquote { + margin: 1em 0; } + .md-typeset h1 { + margin: 0 0 4rem; + color: rgba(0, 0, 0, 0.54); + font-size: 3.125rem; + font-weight: 300; + letter-spacing: -0.01em; + line-height: 1.3; } + .md-typeset h2 { + margin: 4rem 0 1.6rem; + font-size: 2.5rem; + font-weight: 300; + letter-spacing: -0.01em; + line-height: 1.4; } + .md-typeset h3 { + margin: 3.2rem 0 1.6rem; + font-size: 2rem; + font-weight: 400; + letter-spacing: -0.01em; + line-height: 1.5; } + .md-typeset h2 + h3 { + margin-top: 1.6rem; } + .md-typeset h4 { + margin: 1.6rem 0; + font-size: 1.6rem; + font-weight: 700; + letter-spacing: -0.01em; } + .md-typeset h5, + .md-typeset h6 { + margin: 1.6rem 0; + color: rgba(0, 0, 0, 0.54); + font-size: 1.28rem; + font-weight: 700; + letter-spacing: -0.01em; } + .md-typeset h5 { + text-transform: uppercase; } + .md-typeset hr { + margin: 1.5em 0; + border-bottom: 0.1rem dotted rgba(0, 0, 0, 0.26); } + .md-typeset a { + color: #3f51b5; + word-break: break-word; } + .md-typeset a, .md-typeset a::before { + transition: color 0.125s; } + .md-typeset a:hover, .md-typeset a:active { + color: #536dfe; } + .md-typeset code, + .md-typeset pre { + background-color: rgba(236, 236, 236, 0.5); + color: #37474F; + font-size: 85%; + direction: ltr; } + .md-typeset code { + margin: 0 0.29412em; + padding: 0.07353em 0; + border-radius: 0.2rem; + box-shadow: 0.29412em 0 0 rgba(236, 236, 236, 0.5), -0.29412em 0 0 rgba(236, 236, 236, 0.5); + word-break: break-word; + -webkit-box-decoration-break: clone; + box-decoration-break: clone; } + .md-typeset h1 code, + .md-typeset h2 code, + .md-typeset h3 code, + .md-typeset h4 code, + .md-typeset h5 code, + .md-typeset h6 code { + margin: 0; + background-color: transparent; + box-shadow: none; } + .md-typeset a > code { + margin: inherit; + padding: inherit; + border-radius: none; + background-color: inherit; + color: inherit; + box-shadow: none; } + .md-typeset pre { + position: relative; + margin: 1em 0; + border-radius: 0.2rem; + line-height: 1.4; + -webkit-overflow-scrolling: touch; } + .md-typeset pre > code { + display: block; + margin: 0; + padding: 1.05rem 1.2rem; + background-color: transparent; + font-size: inherit; + box-shadow: none; + -webkit-box-decoration-break: none; + box-decoration-break: none; + overflow: auto; } + .md-typeset pre > code::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; } + .md-typeset pre > code::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.26); } + .md-typeset pre > code::-webkit-scrollbar-thumb:hover { + background-color: #536dfe; } + .md-typeset kbd { + padding: 0 0.29412em; + border: 0.1rem solid #c9c9c9; + border-radius: 0.3rem; + border-bottom-color: #bcbcbc; + background-color: #FCFCFC; + color: #555555; + font-size: 85%; + box-shadow: 0 0.1rem 0 #b0b0b0; + word-break: break-word; } + .md-typeset mark { + margin: 0 0.25em; + padding: 0.0625em 0; + border-radius: 0.2rem; + background-color: rgba(255, 235, 59, 0.5); + box-shadow: 0.25em 0 0 rgba(255, 235, 59, 0.5), -0.25em 0 0 rgba(255, 235, 59, 0.5); + word-break: break-word; + -webkit-box-decoration-break: clone; + box-decoration-break: clone; } + .md-typeset abbr { + border-bottom: 0.1rem dotted rgba(0, 0, 0, 0.54); + text-decoration: none; + cursor: help; } + .md-typeset small { + opacity: 0.75; } + .md-typeset sup, + .md-typeset sub { + margin-left: 0.07812em; } + [dir="rtl"] .md-typeset sup, [dir="rtl"] + .md-typeset sub { + margin-right: 0.07812em; + margin-left: initial; } + .md-typeset blockquote { + padding-left: 1.2rem; + border-left: 0.4rem solid rgba(0, 0, 0, 0.26); + color: rgba(0, 0, 0, 0.54); } + [dir="rtl"] .md-typeset blockquote { + padding-right: 1.2rem; + padding-left: initial; + border-right: 0.4rem solid rgba(0, 0, 0, 0.26); + border-left: initial; } + .md-typeset ul { + list-style-type: disc; } + .md-typeset ul, + .md-typeset ol { + margin-left: 0.625em; + padding: 0; } + [dir="rtl"] .md-typeset ul, [dir="rtl"] + .md-typeset ol { + margin-right: 0.625em; + margin-left: initial; } + .md-typeset ul ol, + .md-typeset ol ol { + list-style-type: lower-alpha; } + .md-typeset ul ol ol, + .md-typeset ol ol ol { + list-style-type: lower-roman; } + .md-typeset ul li, + .md-typeset ol li { + margin-bottom: 0.5em; + margin-left: 1.25em; } + [dir="rtl"] .md-typeset ul li, [dir="rtl"] + .md-typeset ol li { + margin-right: 1.25em; + margin-left: initial; } + .md-typeset ul li p, + .md-typeset ul li blockquote, + .md-typeset ol li p, + .md-typeset ol li blockquote { + margin: 0.5em 0; } + .md-typeset ul li:last-child, + .md-typeset ol li:last-child { + margin-bottom: 0; } + .md-typeset ul li ul, + .md-typeset ul li ol, + .md-typeset ol li ul, + .md-typeset ol li ol { + margin: 0.5em 0 0.5em 0.625em; } + [dir="rtl"] .md-typeset ul li ul, [dir="rtl"] + .md-typeset ul li ol, [dir="rtl"] + .md-typeset ol li ul, [dir="rtl"] + .md-typeset ol li ol { + margin-right: 0.625em; + margin-left: initial; } + .md-typeset dd { + margin: 1em 0 1em 1.875em; } + [dir="rtl"] .md-typeset dd { + margin-right: 1.875em; + margin-left: initial; } + .md-typeset iframe, + .md-typeset img, + .md-typeset svg { + max-width: 100%; } + .md-typeset table:not([class]) { + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2); + display: inline-block; + max-width: 100%; + border-radius: 0.2rem; + font-size: 1.28rem; + overflow: auto; + -webkit-overflow-scrolling: touch; } + .md-typeset table:not([class]) + * { + margin-top: 1.5em; } + .md-typeset table:not([class]) th:not([align]), + .md-typeset table:not([class]) td:not([align]) { + text-align: left; } + [dir="rtl"] .md-typeset table:not([class]) th:not([align]), [dir="rtl"] + .md-typeset table:not([class]) td:not([align]) { + text-align: right; } + .md-typeset table:not([class]) th { + min-width: 10rem; + padding: 1.2rem 1.6rem; + background-color: rgba(0, 0, 0, 0.54); + color: white; + vertical-align: top; } + .md-typeset table:not([class]) td { + padding: 1.2rem 1.6rem; + border-top: 0.1rem solid rgba(0, 0, 0, 0.07); + vertical-align: top; } + .md-typeset table:not([class]) tr:first-child td { + border-top: 0; } + .md-typeset table:not([class]) a { + word-break: normal; } + .md-typeset__scrollwrap { + margin: 1em -1.6rem; + overflow-x: auto; + -webkit-overflow-scrolling: touch; } + .md-typeset .md-typeset__table { + display: inline-block; + margin-bottom: 0.5em; + padding: 0 1.6rem; } + .md-typeset .md-typeset__table table { + display: table; + width: 100%; + margin: 0; + overflow: hidden; } + +html { + height: 100%; + font-size: 62.5%; + overflow-x: hidden; } + +body { + position: relative; + height: 100%; } + +hr { + display: block; + height: 0.1rem; + padding: 0; + border: 0; } + +.md-svg { + display: none; } + +.md-grid { + max-width: 122rem; + margin-right: auto; + margin-left: auto; } + +.md-container, +.md-main { + overflow: auto; } + +.md-container { + display: table; + width: 100%; + height: 100%; + padding-top: 4.8rem; + table-layout: fixed; } + +.md-main { + display: table-row; + height: 100%; } + .md-main__inner { + height: 100%; + padding-top: 3rem; + padding-bottom: 0.1rem; } + +.md-toggle { + display: none; } + +.md-overlay { + position: fixed; + top: 0; + width: 0; + height: 0; + transition: width 0s 0.25s, height 0s 0.25s, opacity 0.25s; + background-color: rgba(0, 0, 0, 0.54); + opacity: 0; + z-index: 3; } + +.md-flex { + display: table; } + .md-flex__cell { + display: table-cell; + position: relative; + vertical-align: top; } + .md-flex__cell--shrink { + width: 0%; } + .md-flex__cell--stretch { + display: table; + width: 100%; + table-layout: fixed; } + .md-flex__ellipsis { + display: table-cell; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; } + +.md-skip { + position: fixed; + width: 0.1rem; + height: 0.1rem; + margin: 1rem; + padding: 0.6rem 1rem; + clip: rect(0.1rem); + -webkit-transform: translateY(0.8rem); + transform: translateY(0.8rem); + border-radius: 0.2rem; + background-color: rgba(0, 0, 0, 0.87); + color: white; + font-size: 1.28rem; + opacity: 0; + overflow: hidden; } + .md-skip:focus { + width: auto; + height: auto; + clip: auto; + -webkit-transform: translateX(0); + transform: translateX(0); + transition: opacity 0.175s 0.075s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.175s 0.075s; + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.175s 0.075s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + opacity: 1; + z-index: 10; } + +@page { + margin: 25mm; } + +.md-clipboard { + position: absolute; + top: 0.6rem; + right: 0.6rem; + width: 2.8rem; + height: 2.8rem; + border-radius: 0.2rem; + font-size: 1.6rem; + cursor: pointer; + z-index: 1; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + .md-clipboard::before { + transition: color 0.25s, opacity 0.25s; + color: rgba(0, 0, 0, 0.07); + content: "\E14D"; } + pre:hover .md-clipboard::before, + .codehilite:hover .md-clipboard::before, + .md-typeset .highlight:hover .md-clipboard::before { + color: rgba(0, 0, 0, 0.54); } + .md-clipboard:focus::before, .md-clipboard:hover::before { + color: #536dfe; } + .md-clipboard__message { + display: block; + position: absolute; + top: 0; + right: 3.4rem; + padding: 0.6rem 1rem; + -webkit-transform: translateX(0.8rem); + transform: translateX(0.8rem); + transition: opacity 0.175s, -webkit-transform 0.25s cubic-bezier(0.9, 0.1, 0.9, 0); + transition: transform 0.25s cubic-bezier(0.9, 0.1, 0.9, 0), opacity 0.175s; + transition: transform 0.25s cubic-bezier(0.9, 0.1, 0.9, 0), opacity 0.175s, -webkit-transform 0.25s cubic-bezier(0.9, 0.1, 0.9, 0); + border-radius: 0.2rem; + background-color: rgba(0, 0, 0, 0.54); + color: white; + font-size: 1.28rem; + white-space: nowrap; + opacity: 0; + pointer-events: none; } + .md-clipboard__message--active { + -webkit-transform: translateX(0); + transform: translateX(0); + transition: opacity 0.175s 0.075s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.175s 0.075s; + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.175s 0.075s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + opacity: 1; + pointer-events: initial; } + .md-clipboard__message::before { + content: attr(aria-label); } + .md-clipboard__message::after { + display: block; + position: absolute; + top: 50%; + right: -0.4rem; + width: 0; + margin-top: -0.4rem; + border-width: 0.4rem 0 0.4rem 0.4rem; + border-style: solid; + border-color: transparent rgba(0, 0, 0, 0.54); + content: ""; } + +.md-content__inner { + margin: 0 1.6rem 2.4rem; + padding-top: 1.2rem; } + .md-content__inner::before { + display: block; + height: 0.8rem; + content: ""; } + .md-content__inner > :last-child { + margin-bottom: 0; } + +.md-content__icon { + position: relative; + margin: 0.8rem 0; + padding: 0; + float: right; } + .md-typeset .md-content__icon { + color: rgba(0, 0, 0, 0.26); } + +.md-header { + position: fixed; + top: 0; + right: 0; + left: 0; + height: 4.8rem; + transition: background-color 0.25s, color 0.25s; + background-color: #3f51b5; + color: white; + box-shadow: none; + z-index: 2; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + .no-js .md-header { + transition: none; + box-shadow: none; } + .md-header[data-md-state="shadow"] { + transition: background-color 0.25s, color 0.25s, box-shadow 0.25s; + box-shadow: 0 0 0.4rem rgba(0, 0, 0, 0.1), 0 0.4rem 0.8rem rgba(0, 0, 0, 0.2); } + +.md-header-nav { + padding: 0 0.4rem; } + .md-header-nav__button { + position: relative; + transition: opacity 0.25s; + z-index: 1; } + .md-header-nav__button:hover { + opacity: 0.7; } + .md-header-nav__button.md-logo * { + display: block; } + .no-js .md-header-nav__button.md-icon--search { + display: none; } + .md-header-nav__topic { + display: block; + position: absolute; + transition: opacity 0.15s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); + transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s; + transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; } + .md-header-nav__topic + .md-header-nav__topic { + -webkit-transform: translateX(2.5rem); + transform: translateX(2.5rem); + transition: opacity 0.15s, -webkit-transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1); + transition: transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1), opacity 0.15s; + transition: transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1), opacity 0.15s, -webkit-transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1); + opacity: 0; + z-index: -1; + pointer-events: none; } + [dir="rtl"] .md-header-nav__topic + .md-header-nav__topic { + -webkit-transform: translateX(-2.5rem); + transform: translateX(-2.5rem); } + .no-js .md-header-nav__topic { + position: initial; } + .no-js .md-header-nav__topic + .md-header-nav__topic { + display: none; } + .md-header-nav__title { + padding: 0 2rem; + font-size: 1.8rem; + line-height: 4.8rem; } + .md-header-nav__title[data-md-state="active"] .md-header-nav__topic { + -webkit-transform: translateX(-2.5rem); + transform: translateX(-2.5rem); + transition: opacity 0.15s, -webkit-transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1); + transition: transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1), opacity 0.15s; + transition: transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1), opacity 0.15s, -webkit-transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1); + opacity: 0; + z-index: -1; + pointer-events: none; } + [dir="rtl"] .md-header-nav__title[data-md-state="active"] .md-header-nav__topic { + -webkit-transform: translateX(2.5rem); + transform: translateX(2.5rem); } + .md-header-nav__title[data-md-state="active"] .md-header-nav__topic + .md-header-nav__topic { + -webkit-transform: translateX(0); + transform: translateX(0); + transition: opacity 0.15s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); + transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s; + transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); + opacity: 1; + z-index: 0; + pointer-events: initial; } + .md-header-nav__source { + display: none; } + +.md-hero { + transition: background 0.25s; + background-color: #3f51b5; + color: white; + font-size: 2rem; + overflow: hidden; } + .md-hero__inner { + margin-top: 2rem; + padding: 1.6rem 1.6rem 0.8rem; + transition: opacity 0.25s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); + transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.25s; + transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.25s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); + transition-delay: 0.1s; } + [data-md-state="hidden"] .md-hero__inner { + pointer-events: none; + -webkit-transform: translateY(1.25rem); + transform: translateY(1.25rem); + transition: opacity 0.1s 0s, -webkit-transform 0s 0.4s; + transition: transform 0s 0.4s, opacity 0.1s 0s; + transition: transform 0s 0.4s, opacity 0.1s 0s, -webkit-transform 0s 0.4s; + opacity: 0; } + .md-hero--expand .md-hero__inner { + margin-bottom: 2.4rem; } + +.md-footer-nav { + background-color: rgba(0, 0, 0, 0.87); + color: white; } + .md-footer-nav__inner { + padding: 0.4rem; + overflow: auto; } + .md-footer-nav__link { + padding-top: 2.8rem; + padding-bottom: 0.8rem; + transition: opacity 0.25s; } + .md-footer-nav__link:hover { + opacity: 0.7; } + .md-footer-nav__link--prev { + width: 25%; + float: left; } + [dir="rtl"] .md-footer-nav__link--prev { + float: right; } + .md-footer-nav__link--next { + width: 75%; + float: right; + text-align: right; } + [dir="rtl"] .md-footer-nav__link--next { + float: left; + text-align: left; } + .md-footer-nav__button { + transition: background 0.25s; } + .md-footer-nav__title { + position: relative; + padding: 0 2rem; + font-size: 1.8rem; + line-height: 4.8rem; } + .md-footer-nav__direction { + position: absolute; + right: 0; + left: 0; + margin-top: -2rem; + padding: 0 2rem; + color: rgba(255, 255, 255, 0.7); + font-size: 1.5rem; } + +.md-footer-meta { + background-color: rgba(0, 0, 0, 0.895); } + .md-footer-meta__inner { + padding: 0.4rem; + overflow: auto; } + html .md-footer-meta.md-typeset a { + color: rgba(255, 255, 255, 0.7); } + html .md-footer-meta.md-typeset a:focus, html .md-footer-meta.md-typeset a:hover { + color: white; } + +.md-footer-copyright { + margin: 0 1.2rem; + padding: 0.8rem 0; + color: rgba(255, 255, 255, 0.3); + font-size: 1.28rem; } + .md-footer-copyright__highlight { + color: rgba(255, 255, 255, 0.7); } + +.md-footer-social { + margin: 0 0.8rem; + padding: 0.4rem 0 1.2rem; } + .md-footer-social__link { + display: inline-block; + width: 3.2rem; + height: 3.2rem; + font-size: 1.6rem; + text-align: center; } + .md-footer-social__link::before { + line-height: 1.9; } + +.md-nav { + font-size: 1.4rem; + line-height: 1.3; } + .md-nav__title { + display: block; + padding: 0 1.2rem; + font-weight: 700; + text-overflow: ellipsis; + overflow: hidden; } + .md-nav__title::before { + display: none; + content: "\E5C4"; } + [dir="rtl"] .md-nav__title::before { + content: "\E5C8"; } + .md-nav__title .md-nav__button { + display: none; } + .md-nav__list { + margin: 0; + padding: 0; + list-style: none; } + .md-nav__item { + padding: 0 1.2rem; } + .md-nav__item:last-child { + padding-bottom: 1.2rem; } + .md-nav__item .md-nav__item { + padding-right: 0; } + [dir="rtl"] .md-nav__item .md-nav__item { + padding-right: 1.2rem; + padding-left: 0; } + .md-nav__item .md-nav__item:last-child { + padding-bottom: 0; } + .md-nav__button img { + width: 100%; + height: auto; } + .md-nav__link { + display: block; + margin-top: 0.625em; + transition: color 0.125s; + text-overflow: ellipsis; + cursor: pointer; + overflow: hidden; } + .md-nav__item--nested > .md-nav__link::after { + content: "\E313"; } + html .md-nav__link[for="__toc"] { + display: none; } + html .md-nav__link[for="__toc"] ~ .md-nav { + display: none; } + html .md-nav__link[for="__toc"] + .md-nav__link::after { + display: none; } + .md-nav__link[data-md-state="blur"] { + color: rgba(0, 0, 0, 0.54); } + .md-nav__link:active, .md-nav__link--active { + color: #3f51b5; } + .md-nav__item--nested > .md-nav__link { + color: inherit; } + .md-nav__link:focus, .md-nav__link:hover { + color: #536dfe; } + .md-nav__source { + display: none; } + +.no-js .md-search { + display: none; } + +.md-search__overlay { + opacity: 0; + z-index: 1; } + +.md-search__form { + position: relative; } + +.md-search__input { + position: relative; + padding: 0 4.4rem 0 7.2rem; + text-overflow: ellipsis; + z-index: 2; } + [dir="rtl"] .md-search__input { + padding: 0 7.2rem 0 4.4rem; } + .md-search__input::-webkit-input-placeholder { + transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); } + .md-search__input:-ms-input-placeholder { + transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); } + .md-search__input::-ms-input-placeholder { + transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); } + .md-search__input::placeholder { + transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); } + .md-search__input ~ .md-search__icon, .md-search__input::-webkit-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + .md-search__input ~ .md-search__icon, .md-search__input:-ms-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + .md-search__input ~ .md-search__icon, .md-search__input::-ms-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + .md-search__input ~ .md-search__icon, .md-search__input::placeholder { + color: rgba(0, 0, 0, 0.54); } + .md-search__input::-ms-clear { + display: none; } + +.md-search__icon { + position: absolute; + transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.25s; + font-size: 2.4rem; + cursor: pointer; + z-index: 2; } + .md-search__icon:hover { + opacity: 0.7; } + .md-search__icon[for="__search"] { + top: 0.6rem; + left: 1rem; } + [dir="rtl"] .md-search__icon[for="__search"] { + right: 1rem; + left: initial; } + .md-search__icon[for="__search"]::before { + content: "\E8B6"; } + .md-search__icon[type="reset"] { + top: 0.6rem; + right: 1rem; + -webkit-transform: scale(0.125); + transform: scale(0.125); + transition: opacity 0.15s, -webkit-transform 0.15s cubic-bezier(0.1, 0.7, 0.1, 1); + transition: transform 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s; + transition: transform 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s, -webkit-transform 0.15s cubic-bezier(0.1, 0.7, 0.1, 1); + opacity: 0; } + [dir="rtl"] .md-search__icon[type="reset"] { + right: initial; + left: 1rem; } + [data-md-toggle="search"]:checked ~ .md-header .md-search__input:valid ~ .md-search__icon[type="reset"] { + -webkit-transform: scale(1); + transform: scale(1); + opacity: 1; } + [data-md-toggle="search"]:checked ~ .md-header .md-search__input:valid ~ .md-search__icon[type="reset"]:hover { + opacity: 0.7; } + +.md-search__output { + position: absolute; + width: 100%; + border-radius: 0 0 0.2rem 0.2rem; + overflow: hidden; + z-index: 1; } + +.md-search__scrollwrap { + height: 100%; + background-color: white; + box-shadow: 0 0.1rem 0 rgba(0, 0, 0, 0.07) inset; + overflow-y: auto; + -webkit-overflow-scrolling: touch; } + +.md-search-result { + color: rgba(0, 0, 0, 0.87); + word-break: break-word; } + .md-search-result__meta { + padding: 0 1.6rem; + background-color: rgba(0, 0, 0, 0.07); + color: rgba(0, 0, 0, 0.54); + font-size: 1.28rem; + line-height: 3.6rem; } + .md-search-result__list { + margin: 0; + padding: 0; + border-top: 0.1rem solid rgba(0, 0, 0, 0.07); + list-style: none; } + .md-search-result__item { + box-shadow: 0 -0.1rem 0 rgba(0, 0, 0, 0.07); } + .md-search-result__link { + display: block; + transition: background 0.25s; + outline: 0; + overflow: hidden; } + .md-search-result__link[data-md-state="active"], .md-search-result__link:hover { + background-color: rgba(83, 109, 254, 0.1); } + .md-search-result__link[data-md-state="active"] .md-search-result__article::before, .md-search-result__link:hover .md-search-result__article::before { + opacity: 0.7; } + .md-search-result__link:last-child .md-search-result__teaser { + margin-bottom: 1.2rem; } + .md-search-result__article { + position: relative; + padding: 0 1.6rem; + overflow: auto; } + .md-search-result__article--document::before { + position: absolute; + left: 0; + margin: 0.2rem; + transition: opacity 0.25s; + color: rgba(0, 0, 0, 0.54); + content: "\E880"; } + [dir="rtl"] .md-search-result__article--document::before { + right: 0; + left: initial; } + .md-search-result__article--document .md-search-result__title { + margin: 1.1rem 0; + font-size: 1.6rem; + font-weight: 400; + line-height: 1.4; } + .md-search-result__title { + margin: 0.5em 0; + font-size: 1.28rem; + font-weight: 700; + line-height: 1.4; } + .md-search-result__teaser { + display: -webkit-box; + max-height: 3.3rem; + margin: 0.5em 0; + color: rgba(0, 0, 0, 0.54); + font-size: 1.28rem; + line-height: 1.4; + text-overflow: ellipsis; + overflow: hidden; + -webkit-line-clamp: 2; } + .md-search-result em { + font-style: normal; + font-weight: 700; + text-decoration: underline; } + +.md-sidebar { + position: absolute; + width: 24.2rem; + padding: 2.4rem 0; + overflow: hidden; } + .md-sidebar[data-md-state="lock"] { + position: fixed; + top: 4.8rem; } + .md-sidebar--secondary { + display: none; } + .md-sidebar__scrollwrap { + max-height: 100%; + margin: 0 0.4rem; + overflow-y: auto; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; } + .md-sidebar__scrollwrap::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; } + .md-sidebar__scrollwrap::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.26); } + .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #536dfe; } + +@-webkit-keyframes md-source__facts--done { + 0% { + height: 0; } + 100% { + height: 1.3rem; } } + +@keyframes md-source__facts--done { + 0% { + height: 0; } + 100% { + height: 1.3rem; } } + +@-webkit-keyframes md-source__fact--done { + 0% { + -webkit-transform: translateY(100%); + transform: translateY(100%); + opacity: 0; } + 50% { + opacity: 0; } + 100% { + -webkit-transform: translateY(0%); + transform: translateY(0%); + opacity: 1; } } + +@keyframes md-source__fact--done { + 0% { + -webkit-transform: translateY(100%); + transform: translateY(100%); + opacity: 0; } + 50% { + opacity: 0; } + 100% { + -webkit-transform: translateY(0%); + transform: translateY(0%); + opacity: 1; } } + +.md-source { + display: block; + padding-right: 1.2rem; + transition: opacity 0.25s; + font-size: 1.3rem; + line-height: 1.2; + white-space: nowrap; } + [dir="rtl"] .md-source { + padding-right: initial; + padding-left: 1.2rem; } + .md-source:hover { + opacity: 0.7; } + .md-source::after { + display: inline-block; + height: 4.8rem; + content: ""; + vertical-align: middle; } + .md-source__icon { + display: inline-block; + width: 4.8rem; + height: 4.8rem; + content: ""; + vertical-align: middle; } + .md-source__icon svg { + width: 2.4rem; + height: 2.4rem; + margin-top: 1.2rem; + margin-left: 1.2rem; } + [dir="rtl"] .md-source__icon svg { + margin-right: 1.2rem; + margin-left: initial; } + .md-source__icon + .md-source__repository { + margin-left: -4.4rem; + padding-left: 4rem; } + [dir="rtl"] .md-source__icon + .md-source__repository { + margin-right: -4.4rem; + margin-left: initial; + padding-right: 4rem; + padding-left: initial; } + .md-source__repository { + display: inline-block; + max-width: 100%; + margin-left: 1.2rem; + font-weight: 700; + text-overflow: ellipsis; + overflow: hidden; + vertical-align: middle; } + .md-source__facts { + margin: 0; + padding: 0; + font-size: 1.1rem; + font-weight: 700; + list-style-type: none; + opacity: 0.75; + overflow: hidden; } + [data-md-state="done"] .md-source__facts { + -webkit-animation: md-source__facts--done 0.25s ease-in; + animation: md-source__facts--done 0.25s ease-in; } + .md-source__fact { + float: left; } + [dir="rtl"] .md-source__fact { + float: right; } + [data-md-state="done"] .md-source__fact { + -webkit-animation: md-source__fact--done 0.4s ease-out; + animation: md-source__fact--done 0.4s ease-out; } + .md-source__fact::before { + margin: 0 0.2rem; + content: "\B7"; } + .md-source__fact:first-child::before { + display: none; } + +.md-source-file { + display: inline-block; + margin: 1em 0.5em 1em 0; + padding-right: 0.5rem; + border-radius: 0.2rem; + background-color: rgba(0, 0, 0, 0.07); + font-size: 1.28rem; + list-style-type: none; + cursor: pointer; + overflow: hidden; } + .md-source-file::before { + display: inline-block; + margin-right: 0.5rem; + padding: 0.5rem; + background-color: rgba(0, 0, 0, 0.26); + color: white; + font-size: 1.6rem; + content: "\E86F"; + vertical-align: middle; } + html .md-source-file { + transition: background 0.4s, color 0.4s, box-shadow 0.4s cubic-bezier(0.4, 0, 0.2, 1); } + html .md-source-file::before { + transition: inherit; } + html body .md-typeset .md-source-file { + color: rgba(0, 0, 0, 0.54); } + .md-source-file:hover { + box-shadow: 0 0 8px rgba(0, 0, 0, 0.18), 0 8px 16px rgba(0, 0, 0, 0.36); } + .md-source-file:hover::before { + background-color: #536dfe; } + +.md-tabs { + width: 100%; + transition: background 0.25s; + background-color: #3f51b5; + color: white; + overflow: auto; } + .md-tabs__list { + margin: 0; + margin-left: 0.4rem; + padding: 0; + list-style: none; + white-space: nowrap; } + .md-tabs__item { + display: inline-block; + height: 4.8rem; + padding-right: 1.2rem; + padding-left: 1.2rem; } + .md-tabs__link { + display: block; + margin-top: 1.6rem; + transition: opacity 0.25s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); + transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.25s; + transition: transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.25s, -webkit-transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1); + font-size: 1.4rem; + opacity: 0.7; } + .md-tabs__link--active, .md-tabs__link:hover { + color: inherit; + opacity: 1; } + .md-tabs__item:nth-child(2) .md-tabs__link { + transition-delay: 0.02s; } + .md-tabs__item:nth-child(3) .md-tabs__link { + transition-delay: 0.04s; } + .md-tabs__item:nth-child(4) .md-tabs__link { + transition-delay: 0.06s; } + .md-tabs__item:nth-child(5) .md-tabs__link { + transition-delay: 0.08s; } + .md-tabs__item:nth-child(6) .md-tabs__link { + transition-delay: 0.1s; } + .md-tabs__item:nth-child(7) .md-tabs__link { + transition-delay: 0.12s; } + .md-tabs__item:nth-child(8) .md-tabs__link { + transition-delay: 0.14s; } + .md-tabs__item:nth-child(9) .md-tabs__link { + transition-delay: 0.16s; } + .md-tabs__item:nth-child(10) .md-tabs__link { + transition-delay: 0.18s; } + .md-tabs__item:nth-child(11) .md-tabs__link { + transition-delay: 0.2s; } + .md-tabs__item:nth-child(12) .md-tabs__link { + transition-delay: 0.22s; } + .md-tabs__item:nth-child(13) .md-tabs__link { + transition-delay: 0.24s; } + .md-tabs__item:nth-child(14) .md-tabs__link { + transition-delay: 0.26s; } + .md-tabs__item:nth-child(15) .md-tabs__link { + transition-delay: 0.28s; } + .md-tabs__item:nth-child(16) .md-tabs__link { + transition-delay: 0.3s; } + .md-tabs[data-md-state="hidden"] { + pointer-events: none; } + .md-tabs[data-md-state="hidden"] .md-tabs__link { + -webkit-transform: translateY(50%); + transform: translateY(50%); + transition: color 0.25s, opacity 0.1s, -webkit-transform 0s 0.4s; + transition: color 0.25s, transform 0s 0.4s, opacity 0.1s; + transition: color 0.25s, transform 0s 0.4s, opacity 0.1s, -webkit-transform 0s 0.4s; + opacity: 0; } + +.md-typeset .admonition, .md-typeset details { + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2); + position: relative; + margin: 1.5625em 0; + padding: 0 1.2rem; + border-left: 0.4rem solid #448aff; + border-radius: 0.2rem; + font-size: 1.28rem; + overflow: auto; } + [dir="rtl"] .md-typeset .admonition, [dir="rtl"] .md-typeset details { + border-right: 0.4rem solid #448aff; + border-left: none; } + html .md-typeset .admonition > :last-child, html .md-typeset details > :last-child { + margin-bottom: 1.2rem; } + .md-typeset .admonition .admonition, .md-typeset details .admonition, .md-typeset .admonition details, .md-typeset details details { + margin: 1em 0; } + .md-typeset .admonition > .admonition-title, .md-typeset details > .admonition-title, .md-typeset .admonition > summary, .md-typeset details > summary { + margin: 0 -1.2rem; + padding: 0.8rem 1.2rem 0.8rem 4rem; + border-bottom: 0.1rem solid rgba(68, 138, 255, 0.1); + background-color: rgba(68, 138, 255, 0.1); + font-weight: 700; } + [dir="rtl"] .md-typeset .admonition > .admonition-title, [dir="rtl"] .md-typeset details > .admonition-title, [dir="rtl"] .md-typeset .admonition > summary, [dir="rtl"] .md-typeset details > summary { + padding: 0.8rem 4rem 0.8rem 1.2rem; } + .md-typeset .admonition > .admonition-title:last-child, .md-typeset details > .admonition-title:last-child, .md-typeset .admonition > summary:last-child, .md-typeset details > summary:last-child { + margin-bottom: 0; } + .md-typeset .admonition > .admonition-title::before, .md-typeset details > .admonition-title::before, .md-typeset .admonition > summary::before, .md-typeset details > summary::before { + position: absolute; + left: 1.2rem; + color: #448aff; + font-size: 2rem; + content: "\E3C9"; } + [dir="rtl"] .md-typeset .admonition > .admonition-title::before, [dir="rtl"] .md-typeset details > .admonition-title::before, [dir="rtl"] .md-typeset .admonition > summary::before, [dir="rtl"] .md-typeset details > summary::before { + right: 1.2rem; + left: initial; } + .md-typeset .admonition.summary, .md-typeset details.summary, .md-typeset .admonition.tldr, .md-typeset details.tldr, .md-typeset .admonition.abstract, .md-typeset details.abstract { + border-left-color: #00b0ff; } + [dir="rtl"] .md-typeset .admonition.summary, [dir="rtl"] .md-typeset details.summary, [dir="rtl"] .md-typeset .admonition.tldr, [dir="rtl"] .md-typeset details.tldr, [dir="rtl"] .md-typeset .admonition.abstract, [dir="rtl"] .md-typeset details.abstract { + border-right-color: #00b0ff; } + .md-typeset .admonition.summary > .admonition-title, .md-typeset details.summary > .admonition-title, .md-typeset .admonition.tldr > .admonition-title, .md-typeset details.tldr > .admonition-title, .md-typeset .admonition.summary > summary, .md-typeset details.summary > summary, .md-typeset .admonition.tldr > summary, .md-typeset details.tldr > summary, .md-typeset .admonition.abstract > .admonition-title, .md-typeset details.abstract > .admonition-title, .md-typeset .admonition.abstract > summary, .md-typeset details.abstract > summary { + border-bottom-color: 0.1rem solid rgba(0, 176, 255, 0.1); + background-color: rgba(0, 176, 255, 0.1); } + .md-typeset .admonition.summary > .admonition-title::before, .md-typeset details.summary > .admonition-title::before, .md-typeset .admonition.tldr > .admonition-title::before, .md-typeset details.tldr > .admonition-title::before, .md-typeset .admonition.summary > summary::before, .md-typeset details.summary > summary::before, .md-typeset .admonition.tldr > summary::before, .md-typeset details.tldr > summary::before, .md-typeset .admonition.abstract > .admonition-title::before, .md-typeset details.abstract > .admonition-title::before, .md-typeset .admonition.abstract > summary::before, .md-typeset details.abstract > summary::before { + color: #00b0ff; + content: "\E8D2"; } + .md-typeset .admonition.todo, .md-typeset details.todo, .md-typeset .admonition.info, .md-typeset details.info { + border-left-color: #00b8d4; } + [dir="rtl"] .md-typeset .admonition.todo, [dir="rtl"] .md-typeset details.todo, [dir="rtl"] .md-typeset .admonition.info, [dir="rtl"] .md-typeset details.info { + border-right-color: #00b8d4; } + .md-typeset .admonition.todo > .admonition-title, .md-typeset details.todo > .admonition-title, .md-typeset .admonition.todo > summary, .md-typeset details.todo > summary, .md-typeset .admonition.info > .admonition-title, .md-typeset details.info > .admonition-title, .md-typeset .admonition.info > summary, .md-typeset details.info > summary { + border-bottom-color: 0.1rem solid rgba(0, 184, 212, 0.1); + background-color: rgba(0, 184, 212, 0.1); } + .md-typeset .admonition.todo > .admonition-title::before, .md-typeset details.todo > .admonition-title::before, .md-typeset .admonition.todo > summary::before, .md-typeset details.todo > summary::before, .md-typeset .admonition.info > .admonition-title::before, .md-typeset details.info > .admonition-title::before, .md-typeset .admonition.info > summary::before, .md-typeset details.info > summary::before { + color: #00b8d4; + content: "\E88E"; } + .md-typeset .admonition.hint, .md-typeset details.hint, .md-typeset .admonition.important, .md-typeset details.important, .md-typeset .admonition.tip, .md-typeset details.tip { + border-left-color: #00bfa5; } + [dir="rtl"] .md-typeset .admonition.hint, [dir="rtl"] .md-typeset details.hint, [dir="rtl"] .md-typeset .admonition.important, [dir="rtl"] .md-typeset details.important, [dir="rtl"] .md-typeset .admonition.tip, [dir="rtl"] .md-typeset details.tip { + border-right-color: #00bfa5; } + .md-typeset .admonition.hint > .admonition-title, .md-typeset details.hint > .admonition-title, .md-typeset .admonition.important > .admonition-title, .md-typeset details.important > .admonition-title, .md-typeset .admonition.hint > summary, .md-typeset details.hint > summary, .md-typeset .admonition.important > summary, .md-typeset details.important > summary, .md-typeset .admonition.tip > .admonition-title, .md-typeset details.tip > .admonition-title, .md-typeset .admonition.tip > summary, .md-typeset details.tip > summary { + border-bottom-color: 0.1rem solid rgba(0, 191, 165, 0.1); + background-color: rgba(0, 191, 165, 0.1); } + .md-typeset .admonition.hint > .admonition-title::before, .md-typeset details.hint > .admonition-title::before, .md-typeset .admonition.important > .admonition-title::before, .md-typeset details.important > .admonition-title::before, .md-typeset .admonition.hint > summary::before, .md-typeset details.hint > summary::before, .md-typeset .admonition.important > summary::before, .md-typeset details.important > summary::before, .md-typeset .admonition.tip > .admonition-title::before, .md-typeset details.tip > .admonition-title::before, .md-typeset .admonition.tip > summary::before, .md-typeset details.tip > summary::before { + color: #00bfa5; + content: "\E80E"; } + .md-typeset .admonition.check, .md-typeset details.check, .md-typeset .admonition.done, .md-typeset details.done, .md-typeset .admonition.success, .md-typeset details.success { + border-left-color: #00c853; } + [dir="rtl"] .md-typeset .admonition.check, [dir="rtl"] .md-typeset details.check, [dir="rtl"] .md-typeset .admonition.done, [dir="rtl"] .md-typeset details.done, [dir="rtl"] .md-typeset .admonition.success, [dir="rtl"] .md-typeset details.success { + border-right-color: #00c853; } + .md-typeset .admonition.check > .admonition-title, .md-typeset details.check > .admonition-title, .md-typeset .admonition.done > .admonition-title, .md-typeset details.done > .admonition-title, .md-typeset .admonition.check > summary, .md-typeset details.check > summary, .md-typeset .admonition.done > summary, .md-typeset details.done > summary, .md-typeset .admonition.success > .admonition-title, .md-typeset details.success > .admonition-title, .md-typeset .admonition.success > summary, .md-typeset details.success > summary { + border-bottom-color: 0.1rem solid rgba(0, 200, 83, 0.1); + background-color: rgba(0, 200, 83, 0.1); } + .md-typeset .admonition.check > .admonition-title::before, .md-typeset details.check > .admonition-title::before, .md-typeset .admonition.done > .admonition-title::before, .md-typeset details.done > .admonition-title::before, .md-typeset .admonition.check > summary::before, .md-typeset details.check > summary::before, .md-typeset .admonition.done > summary::before, .md-typeset details.done > summary::before, .md-typeset .admonition.success > .admonition-title::before, .md-typeset details.success > .admonition-title::before, .md-typeset .admonition.success > summary::before, .md-typeset details.success > summary::before { + color: #00c853; + content: "\E876"; } + .md-typeset .admonition.help, .md-typeset details.help, .md-typeset .admonition.faq, .md-typeset details.faq, .md-typeset .admonition.question, .md-typeset details.question { + border-left-color: #64dd17; } + [dir="rtl"] .md-typeset .admonition.help, [dir="rtl"] .md-typeset details.help, [dir="rtl"] .md-typeset .admonition.faq, [dir="rtl"] .md-typeset details.faq, [dir="rtl"] .md-typeset .admonition.question, [dir="rtl"] .md-typeset details.question { + border-right-color: #64dd17; } + .md-typeset .admonition.help > .admonition-title, .md-typeset details.help > .admonition-title, .md-typeset .admonition.faq > .admonition-title, .md-typeset details.faq > .admonition-title, .md-typeset .admonition.help > summary, .md-typeset details.help > summary, .md-typeset .admonition.faq > summary, .md-typeset details.faq > summary, .md-typeset .admonition.question > .admonition-title, .md-typeset details.question > .admonition-title, .md-typeset .admonition.question > summary, .md-typeset details.question > summary { + border-bottom-color: 0.1rem solid rgba(100, 221, 23, 0.1); + background-color: rgba(100, 221, 23, 0.1); } + .md-typeset .admonition.help > .admonition-title::before, .md-typeset details.help > .admonition-title::before, .md-typeset .admonition.faq > .admonition-title::before, .md-typeset details.faq > .admonition-title::before, .md-typeset .admonition.help > summary::before, .md-typeset details.help > summary::before, .md-typeset .admonition.faq > summary::before, .md-typeset details.faq > summary::before, .md-typeset .admonition.question > .admonition-title::before, .md-typeset details.question > .admonition-title::before, .md-typeset .admonition.question > summary::before, .md-typeset details.question > summary::before { + color: #64dd17; + content: "\E887"; } + .md-typeset .admonition.caution, .md-typeset details.caution, .md-typeset .admonition.attention, .md-typeset details.attention, .md-typeset .admonition.warning, .md-typeset details.warning { + border-left-color: #ff9100; } + [dir="rtl"] .md-typeset .admonition.caution, [dir="rtl"] .md-typeset details.caution, [dir="rtl"] .md-typeset .admonition.attention, [dir="rtl"] .md-typeset details.attention, [dir="rtl"] .md-typeset .admonition.warning, [dir="rtl"] .md-typeset details.warning { + border-right-color: #ff9100; } + .md-typeset .admonition.caution > .admonition-title, .md-typeset details.caution > .admonition-title, .md-typeset .admonition.attention > .admonition-title, .md-typeset details.attention > .admonition-title, .md-typeset .admonition.caution > summary, .md-typeset details.caution > summary, .md-typeset .admonition.attention > summary, .md-typeset details.attention > summary, .md-typeset .admonition.warning > .admonition-title, .md-typeset details.warning > .admonition-title, .md-typeset .admonition.warning > summary, .md-typeset details.warning > summary { + border-bottom-color: 0.1rem solid rgba(255, 145, 0, 0.1); + background-color: rgba(255, 145, 0, 0.1); } + .md-typeset .admonition.caution > .admonition-title::before, .md-typeset details.caution > .admonition-title::before, .md-typeset .admonition.attention > .admonition-title::before, .md-typeset details.attention > .admonition-title::before, .md-typeset .admonition.caution > summary::before, .md-typeset details.caution > summary::before, .md-typeset .admonition.attention > summary::before, .md-typeset details.attention > summary::before, .md-typeset .admonition.warning > .admonition-title::before, .md-typeset details.warning > .admonition-title::before, .md-typeset .admonition.warning > summary::before, .md-typeset details.warning > summary::before { + color: #ff9100; + content: "\E002"; } + .md-typeset .admonition.fail, .md-typeset details.fail, .md-typeset .admonition.missing, .md-typeset details.missing, .md-typeset .admonition.failure, .md-typeset details.failure { + border-left-color: #ff5252; } + [dir="rtl"] .md-typeset .admonition.fail, [dir="rtl"] .md-typeset details.fail, [dir="rtl"] .md-typeset .admonition.missing, [dir="rtl"] .md-typeset details.missing, [dir="rtl"] .md-typeset .admonition.failure, [dir="rtl"] .md-typeset details.failure { + border-right-color: #ff5252; } + .md-typeset .admonition.fail > .admonition-title, .md-typeset details.fail > .admonition-title, .md-typeset .admonition.missing > .admonition-title, .md-typeset details.missing > .admonition-title, .md-typeset .admonition.fail > summary, .md-typeset details.fail > summary, .md-typeset .admonition.missing > summary, .md-typeset details.missing > summary, .md-typeset .admonition.failure > .admonition-title, .md-typeset details.failure > .admonition-title, .md-typeset .admonition.failure > summary, .md-typeset details.failure > summary { + border-bottom-color: 0.1rem solid rgba(255, 82, 82, 0.1); + background-color: rgba(255, 82, 82, 0.1); } + .md-typeset .admonition.fail > .admonition-title::before, .md-typeset details.fail > .admonition-title::before, .md-typeset .admonition.missing > .admonition-title::before, .md-typeset details.missing > .admonition-title::before, .md-typeset .admonition.fail > summary::before, .md-typeset details.fail > summary::before, .md-typeset .admonition.missing > summary::before, .md-typeset details.missing > summary::before, .md-typeset .admonition.failure > .admonition-title::before, .md-typeset details.failure > .admonition-title::before, .md-typeset .admonition.failure > summary::before, .md-typeset details.failure > summary::before { + color: #ff5252; + content: "\E14C"; } + .md-typeset .admonition.error, .md-typeset details.error, .md-typeset .admonition.danger, .md-typeset details.danger { + border-left-color: #ff1744; } + [dir="rtl"] .md-typeset .admonition.error, [dir="rtl"] .md-typeset details.error, [dir="rtl"] .md-typeset .admonition.danger, [dir="rtl"] .md-typeset details.danger { + border-right-color: #ff1744; } + .md-typeset .admonition.error > .admonition-title, .md-typeset details.error > .admonition-title, .md-typeset .admonition.error > summary, .md-typeset details.error > summary, .md-typeset .admonition.danger > .admonition-title, .md-typeset details.danger > .admonition-title, .md-typeset .admonition.danger > summary, .md-typeset details.danger > summary { + border-bottom-color: 0.1rem solid rgba(255, 23, 68, 0.1); + background-color: rgba(255, 23, 68, 0.1); } + .md-typeset .admonition.error > .admonition-title::before, .md-typeset details.error > .admonition-title::before, .md-typeset .admonition.error > summary::before, .md-typeset details.error > summary::before, .md-typeset .admonition.danger > .admonition-title::before, .md-typeset details.danger > .admonition-title::before, .md-typeset .admonition.danger > summary::before, .md-typeset details.danger > summary::before { + color: #ff1744; + content: "\E3E7"; } + .md-typeset .admonition.bug, .md-typeset details.bug { + border-left-color: #f50057; } + [dir="rtl"] .md-typeset .admonition.bug, [dir="rtl"] .md-typeset details.bug { + border-right-color: #f50057; } + .md-typeset .admonition.bug > .admonition-title, .md-typeset details.bug > .admonition-title, .md-typeset .admonition.bug > summary, .md-typeset details.bug > summary { + border-bottom-color: 0.1rem solid rgba(245, 0, 87, 0.1); + background-color: rgba(245, 0, 87, 0.1); } + .md-typeset .admonition.bug > .admonition-title::before, .md-typeset details.bug > .admonition-title::before, .md-typeset .admonition.bug > summary::before, .md-typeset details.bug > summary::before { + color: #f50057; + content: "\E868"; } + .md-typeset .admonition.example, .md-typeset details.example { + border-left-color: #651fff; } + [dir="rtl"] .md-typeset .admonition.example, [dir="rtl"] .md-typeset details.example { + border-right-color: #651fff; } + .md-typeset .admonition.example > .admonition-title, .md-typeset details.example > .admonition-title, .md-typeset .admonition.example > summary, .md-typeset details.example > summary { + border-bottom-color: 0.1rem solid rgba(101, 31, 255, 0.1); + background-color: rgba(101, 31, 255, 0.1); } + .md-typeset .admonition.example > .admonition-title::before, .md-typeset details.example > .admonition-title::before, .md-typeset .admonition.example > summary::before, .md-typeset details.example > summary::before { + color: #651fff; + content: "\E242"; } + .md-typeset .admonition.cite, .md-typeset details.cite, .md-typeset .admonition.quote, .md-typeset details.quote { + border-left-color: #9e9e9e; } + [dir="rtl"] .md-typeset .admonition.cite, [dir="rtl"] .md-typeset details.cite, [dir="rtl"] .md-typeset .admonition.quote, [dir="rtl"] .md-typeset details.quote { + border-right-color: #9e9e9e; } + .md-typeset .admonition.cite > .admonition-title, .md-typeset details.cite > .admonition-title, .md-typeset .admonition.cite > summary, .md-typeset details.cite > summary, .md-typeset .admonition.quote > .admonition-title, .md-typeset details.quote > .admonition-title, .md-typeset .admonition.quote > summary, .md-typeset details.quote > summary { + border-bottom-color: 0.1rem solid rgba(158, 158, 158, 0.1); + background-color: rgba(158, 158, 158, 0.1); } + .md-typeset .admonition.cite > .admonition-title::before, .md-typeset details.cite > .admonition-title::before, .md-typeset .admonition.cite > summary::before, .md-typeset details.cite > summary::before, .md-typeset .admonition.quote > .admonition-title::before, .md-typeset details.quote > .admonition-title::before, .md-typeset .admonition.quote > summary::before, .md-typeset details.quote > summary::before { + color: #9e9e9e; + content: "\E244"; } + +.codehilite .o, .md-typeset .highlight .o { + color: inherit; } + +.codehilite .ow, .md-typeset .highlight .ow { + color: inherit; } + +.codehilite .ge, .md-typeset .highlight .ge { + color: #000000; } + +.codehilite .gr, .md-typeset .highlight .gr { + color: #AA0000; } + +.codehilite .gh, .md-typeset .highlight .gh { + color: #999999; } + +.codehilite .go, .md-typeset .highlight .go { + color: #888888; } + +.codehilite .gp, .md-typeset .highlight .gp { + color: #555555; } + +.codehilite .gs, .md-typeset .highlight .gs { + color: inherit; } + +.codehilite .gu, .md-typeset .highlight .gu { + color: #AAAAAA; } + +.codehilite .gt, .md-typeset .highlight .gt { + color: #AA0000; } + +.codehilite .gd, .md-typeset .highlight .gd { + background-color: #FFDDDD; } + +.codehilite .gi, .md-typeset .highlight .gi { + background-color: #DDFFDD; } + +.codehilite .k, .md-typeset .highlight .k { + color: #3B78E7; } + +.codehilite .kc, .md-typeset .highlight .kc { + color: #A71D5D; } + +.codehilite .kd, .md-typeset .highlight .kd { + color: #3B78E7; } + +.codehilite .kn, .md-typeset .highlight .kn { + color: #3B78E7; } + +.codehilite .kp, .md-typeset .highlight .kp { + color: #A71D5D; } + +.codehilite .kr, .md-typeset .highlight .kr { + color: #3E61A2; } + +.codehilite .kt, .md-typeset .highlight .kt { + color: #3E61A2; } + +.codehilite .c, .md-typeset .highlight .c { + color: #999999; } + +.codehilite .cm, .md-typeset .highlight .cm { + color: #999999; } + +.codehilite .cp, .md-typeset .highlight .cp { + color: #666666; } + +.codehilite .c1, .md-typeset .highlight .c1 { + color: #999999; } + +.codehilite .ch, .md-typeset .highlight .ch { + color: #999999; } + +.codehilite .cs, .md-typeset .highlight .cs { + color: #999999; } + +.codehilite .na, .md-typeset .highlight .na { + color: #C2185B; } + +.codehilite .nb, .md-typeset .highlight .nb { + color: #C2185B; } + +.codehilite .bp, .md-typeset .highlight .bp { + color: #3E61A2; } + +.codehilite .nc, .md-typeset .highlight .nc { + color: #C2185B; } + +.codehilite .no, .md-typeset .highlight .no { + color: #3E61A2; } + +.codehilite .nd, .md-typeset .highlight .nd { + color: #666666; } + +.codehilite .ni, .md-typeset .highlight .ni { + color: #666666; } + +.codehilite .ne, .md-typeset .highlight .ne { + color: #C2185B; } + +.codehilite .nf, .md-typeset .highlight .nf { + color: #C2185B; } + +.codehilite .nl, .md-typeset .highlight .nl { + color: #3B5179; } + +.codehilite .nn, .md-typeset .highlight .nn { + color: #EC407A; } + +.codehilite .nt, .md-typeset .highlight .nt { + color: #3B78E7; } + +.codehilite .nv, .md-typeset .highlight .nv { + color: #3E61A2; } + +.codehilite .vc, .md-typeset .highlight .vc { + color: #3E61A2; } + +.codehilite .vg, .md-typeset .highlight .vg { + color: #3E61A2; } + +.codehilite .vi, .md-typeset .highlight .vi { + color: #3E61A2; } + +.codehilite .nx, .md-typeset .highlight .nx { + color: #EC407A; } + +.codehilite .m, .md-typeset .highlight .m { + color: #E74C3C; } + +.codehilite .mf, .md-typeset .highlight .mf { + color: #E74C3C; } + +.codehilite .mh, .md-typeset .highlight .mh { + color: #E74C3C; } + +.codehilite .mi, .md-typeset .highlight .mi { + color: #E74C3C; } + +.codehilite .il, .md-typeset .highlight .il { + color: #E74C3C; } + +.codehilite .mo, .md-typeset .highlight .mo { + color: #E74C3C; } + +.codehilite .s, .md-typeset .highlight .s { + color: #0D904F; } + +.codehilite .sb, .md-typeset .highlight .sb { + color: #0D904F; } + +.codehilite .sc, .md-typeset .highlight .sc { + color: #0D904F; } + +.codehilite .sd, .md-typeset .highlight .sd { + color: #999999; } + +.codehilite .s2, .md-typeset .highlight .s2 { + color: #0D904F; } + +.codehilite .se, .md-typeset .highlight .se { + color: #183691; } + +.codehilite .sh, .md-typeset .highlight .sh { + color: #183691; } + +.codehilite .si, .md-typeset .highlight .si { + color: #183691; } + +.codehilite .sx, .md-typeset .highlight .sx { + color: #183691; } + +.codehilite .sr, .md-typeset .highlight .sr { + color: #009926; } + +.codehilite .s1, .md-typeset .highlight .s1 { + color: #0D904F; } + +.codehilite .ss, .md-typeset .highlight .ss { + color: #0D904F; } + +.codehilite .err, .md-typeset .highlight .err { + color: #A61717; } + +.codehilite .w, .md-typeset .highlight .w { + color: transparent; } + +.codehilite .hll, .md-typeset .highlight .hll { + display: block; + margin: 0 -1.2rem; + padding: 0 1.2rem; + background-color: rgba(255, 235, 59, 0.5); } + +.md-typeset .codehilite, .md-typeset .highlight { + position: relative; + margin: 1em 0; + padding: 0; + border-radius: 0.2rem; + background-color: rgba(236, 236, 236, 0.5); + color: #37474F; + line-height: 1.4; + -webkit-overflow-scrolling: touch; } + .md-typeset .codehilite pre, .md-typeset .highlight pre, + .md-typeset .codehilite code, + .md-typeset .highlight code { + display: block; + margin: 0; + padding: 1.05rem 1.2rem; + background-color: transparent; + overflow: auto; + vertical-align: top; } + .md-typeset .codehilite pre::-webkit-scrollbar, .md-typeset .highlight pre::-webkit-scrollbar, + .md-typeset .codehilite code::-webkit-scrollbar, + .md-typeset .highlight code::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; } + .md-typeset .codehilite pre::-webkit-scrollbar-thumb, .md-typeset .highlight pre::-webkit-scrollbar-thumb, + .md-typeset .codehilite code::-webkit-scrollbar-thumb, + .md-typeset .highlight code::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.26); } + .md-typeset .codehilite pre::-webkit-scrollbar-thumb:hover, .md-typeset .highlight pre::-webkit-scrollbar-thumb:hover, + .md-typeset .codehilite code::-webkit-scrollbar-thumb:hover, + .md-typeset .highlight code::-webkit-scrollbar-thumb:hover { + background-color: #536dfe; } + +.md-typeset pre.codehilite, .md-typeset pre.highlight { + overflow: visible; } + .md-typeset pre.codehilite code, .md-typeset pre.highlight code { + display: block; + padding: 1.05rem 1.2rem; + overflow: auto; } + +.md-typeset .codehilitetable, .md-typeset .highlighttable { + display: block; + margin: 1em 0; + border-radius: 0.2em; + font-size: 1.6rem; + overflow: hidden; } + .md-typeset .codehilitetable tbody, .md-typeset .highlighttable tbody, + .md-typeset .codehilitetable td, + .md-typeset .highlighttable td { + display: block; + padding: 0; } + .md-typeset .codehilitetable tr, .md-typeset .highlighttable tr { + display: flex; } + .md-typeset .codehilitetable .codehilite, .md-typeset .highlighttable .codehilite, .md-typeset .codehilitetable .highlight, .md-typeset .highlighttable .highlight, + .md-typeset .codehilitetable .linenodiv, + .md-typeset .highlighttable .linenodiv { + margin: 0; + border-radius: 0; } + + .md-typeset .codehilitetable .linenodiv, + .md-typeset .highlighttable .linenodiv { + padding: 1.05rem 1.2rem; } + .md-typeset .codehilitetable .linenos, .md-typeset .highlighttable .linenos { + background-color: rgba(0, 0, 0, 0.07); + color: rgba(0, 0, 0, 0.26); + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + .md-typeset .codehilitetable .linenos pre, .md-typeset .highlighttable .linenos pre { + margin: 0; + padding: 0; + background-color: transparent; + color: inherit; + text-align: right; } + .md-typeset .codehilitetable .code, .md-typeset .highlighttable .code { + flex: 1; + overflow: hidden; } + +.md-typeset > .codehilitetable, .md-typeset > .highlighttable { + box-shadow: none; } + +.md-typeset [id^="fnref:"] { + display: inline-block; } + .md-typeset [id^="fnref:"]:target { + margin-top: -7.6rem; + padding-top: 7.6rem; + pointer-events: none; } + +.md-typeset [id^="fn:"]::before { + display: none; + height: 0; + content: ""; } + +.md-typeset [id^="fn:"]:target::before { + display: block; + margin-top: -7rem; + padding-top: 7rem; + pointer-events: none; } + +.md-typeset .footnote { + color: rgba(0, 0, 0, 0.54); + font-size: 1.28rem; } + .md-typeset .footnote ol { + margin-left: 0; } + .md-typeset .footnote li { + transition: color 0.25s; } + .md-typeset .footnote li:target { + color: rgba(0, 0, 0, 0.87); } + .md-typeset .footnote li :first-child { + margin-top: 0; } + .md-typeset .footnote li:hover .footnote-backref, + .md-typeset .footnote li:target .footnote-backref { + -webkit-transform: translateX(0); + transform: translateX(0); + opacity: 1; } + .md-typeset .footnote li:hover .footnote-backref:hover, + .md-typeset .footnote li:target .footnote-backref { + color: #536dfe; } + +.md-typeset .footnote-ref { + display: inline-block; + pointer-events: initial; } + .md-typeset .footnote-ref::before { + display: inline; + margin: 0 0.2em; + border-left: 0.1rem solid rgba(0, 0, 0, 0.26); + font-size: 1.25em; + content: ""; + vertical-align: -0.5rem; } + +.md-typeset .footnote-backref { + display: inline-block; + -webkit-transform: translateX(0.5rem); + transform: translateX(0.5rem); + transition: color 0.25s, opacity 0.125s 0.125s, -webkit-transform 0.25s 0.125s; + transition: transform 0.25s 0.125s, color 0.25s, opacity 0.125s 0.125s; + transition: transform 0.25s 0.125s, color 0.25s, opacity 0.125s 0.125s, -webkit-transform 0.25s 0.125s; + color: rgba(0, 0, 0, 0.26); + font-size: 0; + opacity: 0; + vertical-align: text-bottom; } + [dir="rtl"] .md-typeset .footnote-backref { + -webkit-transform: translateX(-0.5rem); + transform: translateX(-0.5rem); } + .md-typeset .footnote-backref::before { + display: inline-block; + font-size: 1.6rem; + content: "\E31B"; } + [dir="rtl"] .md-typeset .footnote-backref::before { + -webkit-transform: scaleX(-1); + transform: scaleX(-1); } + +.md-typeset .headerlink { + display: inline-block; + margin-left: 1rem; + -webkit-transform: translate(0, 0.5rem); + transform: translate(0, 0.5rem); + transition: color 0.25s, opacity 0.125s 0.25s, -webkit-transform 0.25s 0.25s; + transition: transform 0.25s 0.25s, color 0.25s, opacity 0.125s 0.25s; + transition: transform 0.25s 0.25s, color 0.25s, opacity 0.125s 0.25s, -webkit-transform 0.25s 0.25s; + opacity: 0; } + [dir="rtl"] .md-typeset .headerlink { + margin-right: 1rem; + margin-left: initial; } + html body .md-typeset .headerlink { + color: rgba(0, 0, 0, 0.26); } + +.md-typeset h1[id]::before { + display: block; + margin-top: -0.9rem; + padding-top: 0.9rem; + content: ""; } + +.md-typeset h1[id]:target::before { + margin-top: -6.9rem; + padding-top: 6.9rem; } + +.md-typeset h1[id]:hover .headerlink, +.md-typeset h1[id]:target .headerlink, +.md-typeset h1[id] .headerlink:focus { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + opacity: 1; } + +.md-typeset h1[id]:hover .headerlink:hover, +.md-typeset h1[id]:target .headerlink, +.md-typeset h1[id] .headerlink:focus { + color: #536dfe; } + +.md-typeset h2[id]::before { + display: block; + margin-top: -0.8rem; + padding-top: 0.8rem; + content: ""; } + +.md-typeset h2[id]:target::before { + margin-top: -6.8rem; + padding-top: 6.8rem; } + +.md-typeset h2[id]:hover .headerlink, +.md-typeset h2[id]:target .headerlink, +.md-typeset h2[id] .headerlink:focus { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + opacity: 1; } + +.md-typeset h2[id]:hover .headerlink:hover, +.md-typeset h2[id]:target .headerlink, +.md-typeset h2[id] .headerlink:focus { + color: #536dfe; } + +.md-typeset h3[id]::before { + display: block; + margin-top: -0.9rem; + padding-top: 0.9rem; + content: ""; } + +.md-typeset h3[id]:target::before { + margin-top: -6.9rem; + padding-top: 6.9rem; } + +.md-typeset h3[id]:hover .headerlink, +.md-typeset h3[id]:target .headerlink, +.md-typeset h3[id] .headerlink:focus { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + opacity: 1; } + +.md-typeset h3[id]:hover .headerlink:hover, +.md-typeset h3[id]:target .headerlink, +.md-typeset h3[id] .headerlink:focus { + color: #536dfe; } + +.md-typeset h4[id]::before { + display: block; + margin-top: -0.9rem; + padding-top: 0.9rem; + content: ""; } + +.md-typeset h4[id]:target::before { + margin-top: -6.9rem; + padding-top: 6.9rem; } + +.md-typeset h4[id]:hover .headerlink, +.md-typeset h4[id]:target .headerlink, +.md-typeset h4[id] .headerlink:focus { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + opacity: 1; } + +.md-typeset h4[id]:hover .headerlink:hover, +.md-typeset h4[id]:target .headerlink, +.md-typeset h4[id] .headerlink:focus { + color: #536dfe; } + +.md-typeset h5[id]::before { + display: block; + margin-top: -1.1rem; + padding-top: 1.1rem; + content: ""; } + +.md-typeset h5[id]:target::before { + margin-top: -7.1rem; + padding-top: 7.1rem; } + +.md-typeset h5[id]:hover .headerlink, +.md-typeset h5[id]:target .headerlink, +.md-typeset h5[id] .headerlink:focus { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + opacity: 1; } + +.md-typeset h5[id]:hover .headerlink:hover, +.md-typeset h5[id]:target .headerlink, +.md-typeset h5[id] .headerlink:focus { + color: #536dfe; } + +.md-typeset h6[id]::before { + display: block; + margin-top: -1.1rem; + padding-top: 1.1rem; + content: ""; } + +.md-typeset h6[id]:target::before { + margin-top: -7.1rem; + padding-top: 7.1rem; } + +.md-typeset h6[id]:hover .headerlink, +.md-typeset h6[id]:target .headerlink, +.md-typeset h6[id] .headerlink:focus { + -webkit-transform: translate(0, 0); + transform: translate(0, 0); + opacity: 1; } + +.md-typeset h6[id]:hover .headerlink:hover, +.md-typeset h6[id]:target .headerlink, +.md-typeset h6[id] .headerlink:focus { + color: #536dfe; } + +.md-typeset .MJXc-display { + margin: 0.75em 0; + padding: 0.75em 0; + overflow: auto; + -webkit-overflow-scrolling: touch; } + +.md-typeset .MathJax_CHTML { + outline: 0; } + +.md-typeset del.critic, +.md-typeset ins.critic, +.md-typeset .critic.comment { + margin: 0 0.25em; + padding: 0.0625em 0; + border-radius: 0.2rem; + -webkit-box-decoration-break: clone; + box-decoration-break: clone; } + +.md-typeset del.critic { + background-color: #FFDDDD; + box-shadow: 0.25em 0 0 #FFDDDD, -0.25em 0 0 #FFDDDD; } + +.md-typeset ins.critic { + background-color: #DDFFDD; + box-shadow: 0.25em 0 0 #DDFFDD, -0.25em 0 0 #DDFFDD; } + +.md-typeset .critic.comment { + background-color: rgba(236, 236, 236, 0.5); + color: #37474F; + box-shadow: 0.25em 0 0 rgba(236, 236, 236, 0.5), -0.25em 0 0 rgba(236, 236, 236, 0.5); } + .md-typeset .critic.comment::before { + padding-right: 0.125em; + color: rgba(0, 0, 0, 0.26); + content: "\E0B7"; + vertical-align: -0.125em; } + +.md-typeset .critic.block { + display: block; + margin: 1em 0; + padding-right: 1.6rem; + padding-left: 1.6rem; + box-shadow: none; } + .md-typeset .critic.block :first-child { + margin-top: 0.5em; } + .md-typeset .critic.block :last-child { + margin-bottom: 0.5em; } + +.md-typeset details { + display: block; + padding-top: 0; } + .md-typeset details[open] > summary::after { + -webkit-transform: rotate(180deg); + transform: rotate(180deg); } + .md-typeset details:not([open]) { + padding-bottom: 0; } + .md-typeset details:not([open]) > summary { + border-bottom: none; } + .md-typeset details summary { + padding-right: 4rem; } + [dir="rtl"] .md-typeset details summary { + padding-left: 4rem; } + .no-details .md-typeset details:not([open]) > * { + display: none; } + .no-details .md-typeset details:not([open]) summary { + display: block; } + +.md-typeset summary { + display: block; + outline: none; + cursor: pointer; } + .md-typeset summary::-webkit-details-marker { + display: none; } + .md-typeset summary::after { + position: absolute; + top: 0.8rem; + right: 1.2rem; + color: rgba(0, 0, 0, 0.26); + font-size: 2rem; + content: "\E313"; } + [dir="rtl"] .md-typeset summary::after { + right: initial; + left: 1.2rem; } + +.md-typeset .emojione { + width: 2rem; + vertical-align: text-top; } + +.md-typeset code.codehilite, .md-typeset code.highlight { + margin: 0 0.29412em; + padding: 0.07353em 0; } + +.md-typeset .superfences-content { + display: none; + order: 99; + width: 100%; + background-color: white; } + .md-typeset .superfences-content > * { + margin: 0; + border-radius: 0; } + +.md-typeset .superfences-tabs { + display: flex; + position: relative; + flex-wrap: wrap; + margin: 1em 0; + border: 0.1rem solid rgba(0, 0, 0, 0.07); + border-radius: 0.2em; } + .md-typeset .superfences-tabs > input { + display: none; } + .md-typeset .superfences-tabs > input:checked + label { + font-weight: 700; } + .md-typeset .superfences-tabs > input:checked + label + .superfences-content { + display: block; } + .md-typeset .superfences-tabs > label { + width: auto; + padding: 1.2rem 1.2rem; + transition: color 0.125s; + font-size: 1.28rem; + cursor: pointer; } + html .md-typeset .superfences-tabs > label:hover { + color: #536dfe; } + +.md-typeset .task-list-item { + position: relative; + list-style-type: none; } + .md-typeset .task-list-item [type="checkbox"] { + position: absolute; + top: 0.45em; + left: -2em; } + [dir="rtl"] .md-typeset .task-list-item [type="checkbox"] { + right: -2em; + left: initial; } + +.md-typeset .task-list-control .task-list-indicator::before { + position: absolute; + top: 0.15em; + left: -1.25em; + color: rgba(0, 0, 0, 0.26); + font-size: 1.25em; + content: "\E835"; + vertical-align: -0.25em; } + [dir="rtl"] .md-typeset .task-list-control .task-list-indicator::before { + right: -1.25em; + left: initial; } + +.md-typeset .task-list-control [type="checkbox"]:checked + .task-list-indicator::before { + content: "\E834"; } + +.md-typeset .task-list-control [type="checkbox"] { + opacity: 0; + z-index: -1; } + +@media print { + .md-typeset a::after { + color: rgba(0, 0, 0, 0.54); + content: " [" attr(href) "]"; } + .md-typeset code, + .md-typeset pre { + white-space: pre-wrap; } + .md-typeset code { + box-shadow: none; + -webkit-box-decoration-break: initial; + box-decoration-break: initial; } + .md-clipboard { + display: none; } + .md-content__icon { + display: none; } + .md-header { + display: none; } + .md-footer { + display: none; } + .md-sidebar { + display: none; } + .md-tabs { + display: none; } + .md-typeset .headerlink { + display: none; } } + +@media only screen and (max-width: 44.9375em) { + .md-typeset pre { + margin: 1em -1.6rem; + border-radius: 0; } + .md-typeset pre > code { + padding: 1.05rem 1.6rem; } + .md-footer-nav__link--prev .md-footer-nav__title { + display: none; } + .md-search-result__teaser { + max-height: 5rem; + -webkit-line-clamp: 3; } + .codehilite .hll, .md-typeset .highlight .hll { + margin: 0 -1.6rem; + padding: 0 1.6rem; } + .md-typeset > .codehilite, .md-typeset > .highlight { + margin: 1em -1.6rem; + border-radius: 0; } + .md-typeset > .codehilite pre, .md-typeset > .highlight pre, + .md-typeset > .codehilite code, + .md-typeset > .highlight code { + padding: 1.05rem 1.6rem; } + .md-typeset > .codehilitetable, .md-typeset > .highlighttable { + margin: 1em -1.6rem; + border-radius: 0; } + .md-typeset > .codehilitetable .codehilite > pre, .md-typeset > .highlighttable .codehilite > pre, .md-typeset > .codehilitetable .highlight > pre, .md-typeset > .highlighttable .highlight > pre, + .md-typeset > .codehilitetable .codehilite > code, + .md-typeset > .highlighttable .codehilite > code, + .md-typeset > .codehilitetable .highlight > code, + .md-typeset > .highlighttable .highlight > code, + .md-typeset > .codehilitetable .linenodiv, + .md-typeset > .highlighttable .linenodiv { + padding: 1rem 1.6rem; } + .md-typeset > p > .MJXc-display { + margin: 0.75em -1.6rem; + padding: 0.25em 1.6rem; } + .md-typeset > .superfences-tabs { + margin: 1em -1.6rem; + border: 0; + border-top: 0.1rem solid rgba(0, 0, 0, 0.07); + border-radius: 0; } + .md-typeset > .superfences-tabs pre, + .md-typeset > .superfences-tabs code { + padding: 1.05rem 1.6rem; } } + +@media only screen and (min-width: 100em) { + html { + font-size: 68.75%; } } + +@media only screen and (min-width: 125em) { + html { + font-size: 75%; } } + +@media only screen and (max-width: 59.9375em) { + body[data-md-state="lock"] { + overflow: hidden; } + .ios body[data-md-state="lock"] .md-container { + display: none; } + html .md-nav__link[for="__toc"] { + display: block; + padding-right: 4.8rem; } + html .md-nav__link[for="__toc"]::after { + color: inherit; + content: "\E8DE"; } + html .md-nav__link[for="__toc"] + .md-nav__link { + display: none; } + html .md-nav__link[for="__toc"] ~ .md-nav { + display: flex; } + html [dir="rtl"] .md-nav__link { + padding-right: 1.6rem; + padding-left: 4.8rem; } + .md-nav__source { + display: block; + padding: 0 0.4rem; + background-color: rgba(50, 64, 144, 0.9675); + color: white; } + .md-search__overlay { + position: absolute; + top: 0.4rem; + left: 0.4rem; + width: 3.6rem; + height: 3.6rem; + -webkit-transform-origin: center; + transform-origin: center; + transition: opacity 0.2s 0.2s, -webkit-transform 0.3s 0.1s; + transition: transform 0.3s 0.1s, opacity 0.2s 0.2s; + transition: transform 0.3s 0.1s, opacity 0.2s 0.2s, -webkit-transform 0.3s 0.1s; + border-radius: 2rem; + background-color: white; + overflow: hidden; + pointer-events: none; } + [dir="rtl"] .md-search__overlay { + right: 0.4rem; + left: initial; } + [data-md-toggle="search"]:checked ~ .md-header .md-search__overlay { + transition: opacity 0.1s, -webkit-transform 0.4s; + transition: transform 0.4s, opacity 0.1s; + transition: transform 0.4s, opacity 0.1s, -webkit-transform 0.4s; + opacity: 1; } + .md-search__inner { + position: fixed; + top: 0; + left: 100%; + width: 100%; + height: 100%; + -webkit-transform: translateX(5%); + transform: translateX(5%); + transition: right 0s 0.3s, left 0s 0.3s, opacity 0.15s 0.15s, -webkit-transform 0.15s 0.15s cubic-bezier(0.4, 0, 0.2, 1); + transition: right 0s 0.3s, left 0s 0.3s, transform 0.15s 0.15s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.15s 0.15s; + transition: right 0s 0.3s, left 0s 0.3s, transform 0.15s 0.15s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.15s 0.15s, -webkit-transform 0.15s 0.15s cubic-bezier(0.4, 0, 0.2, 1); + opacity: 0; + z-index: 2; } + [data-md-toggle="search"]:checked ~ .md-header .md-search__inner { + left: 0; + -webkit-transform: translateX(0); + transform: translateX(0); + transition: right 0s 0s, left 0s 0s, opacity 0.15s 0.15s, -webkit-transform 0.15s 0.15s cubic-bezier(0.1, 0.7, 0.1, 1); + transition: right 0s 0s, left 0s 0s, transform 0.15s 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s 0.15s; + transition: right 0s 0s, left 0s 0s, transform 0.15s 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), opacity 0.15s 0.15s, -webkit-transform 0.15s 0.15s cubic-bezier(0.1, 0.7, 0.1, 1); + opacity: 1; } + [dir="rtl"] [data-md-toggle="search"]:checked ~ .md-header .md-search__inner { + right: 0; + left: initial; } + html [dir="rtl"] .md-search__inner { + right: 100%; + left: initial; + -webkit-transform: translateX(-5%); + transform: translateX(-5%); } + .md-search__input { + width: 100%; + height: 4.8rem; + font-size: 1.8rem; } + .md-search__icon[for="__search"] { + top: 1.2rem; + left: 1.6rem; } + .md-search__icon[for="__search"][for="__search"]::before { + content: "\E5C4"; } + [dir="rtl"] .md-search__icon[for="__search"][for="__search"]::before { + content: "\E5C8"; } + .md-search__icon[type="reset"] { + top: 1.2rem; + right: 1.6rem; } + .md-search__output { + top: 4.8rem; + bottom: 0; } + .md-search-result__article--document::before { + display: none; } } + +@media only screen and (max-width: 76.1875em) { + [data-md-toggle="drawer"]:checked ~ .md-overlay { + width: 100%; + height: 100%; + transition: width 0s, height 0s, opacity 0.25s; + opacity: 1; } + .md-header-nav__button.md-icon--home, .md-header-nav__button.md-logo { + display: none; } + .md-hero__inner { + margin-top: 4.8rem; + margin-bottom: 2.4rem; } + .md-nav { + background-color: white; } + .md-nav--primary, + .md-nav--primary .md-nav { + display: flex; + position: absolute; + top: 0; + right: 0; + left: 0; + flex-direction: column; + height: 100%; + z-index: 1; } + .md-nav--primary .md-nav__title, + .md-nav--primary .md-nav__item { + font-size: 1.6rem; + line-height: 1.5; } + html .md-nav--primary .md-nav__title { + position: relative; + height: 11.2rem; + padding: 6rem 1.6rem 0.4rem; + background-color: rgba(0, 0, 0, 0.07); + color: rgba(0, 0, 0, 0.54); + font-weight: 400; + line-height: 4.8rem; + white-space: nowrap; + cursor: pointer; } + html .md-nav--primary .md-nav__title::before { + display: block; + position: absolute; + top: 0.4rem; + left: 0.4rem; + width: 4rem; + height: 4rem; + color: rgba(0, 0, 0, 0.54); } + html .md-nav--primary .md-nav__title ~ .md-nav__list { + background-color: white; + box-shadow: 0 0.1rem 0 rgba(0, 0, 0, 0.07) inset; } + html .md-nav--primary .md-nav__title ~ .md-nav__list > .md-nav__item:first-child { + border-top: 0; } + html .md-nav--primary .md-nav__title--site { + position: relative; + background-color: #3f51b5; + color: white; } + html .md-nav--primary .md-nav__title--site .md-nav__button { + display: block; + position: absolute; + top: 0.4rem; + left: 0.4rem; + width: 6.4rem; + height: 6.4rem; + font-size: 4.8rem; } + html .md-nav--primary .md-nav__title--site::before { + display: none; } + html [dir="rtl"] .md-nav--primary .md-nav__title::before { + right: 0.4rem; + left: initial; } + html [dir="rtl"] .md-nav--primary .md-nav__title--site .md-nav__button { + right: 0.4rem; + left: initial; } + .md-nav--primary .md-nav__list { + flex: 1; + overflow-y: auto; } + .md-nav--primary .md-nav__item { + padding: 0; + border-top: 0.1rem solid rgba(0, 0, 0, 0.07); } + [dir="rtl"] .md-nav--primary .md-nav__item { + padding: 0; } + .md-nav--primary .md-nav__item--nested > .md-nav__link { + padding-right: 4.8rem; } + [dir="rtl"] .md-nav--primary .md-nav__item--nested > .md-nav__link { + padding-right: 1.6rem; + padding-left: 4.8rem; } + .md-nav--primary .md-nav__item--nested > .md-nav__link::after { + content: "\E315"; } + [dir="rtl"] .md-nav--primary .md-nav__item--nested > .md-nav__link::after { + content: "\E314"; } + .md-nav--primary .md-nav__link { + position: relative; + margin-top: 0; + padding: 1.2rem 1.6rem; } + .md-nav--primary .md-nav__link::after { + position: absolute; + top: 50%; + right: 1.2rem; + margin-top: -1.2rem; + color: inherit; + font-size: 2.4rem; } + [dir="rtl"] .md-nav--primary .md-nav__link::after { + right: initial; + left: 1.2rem; } + .md-nav--primary .md-nav--secondary .md-nav__link { + position: static; } + .md-nav--primary .md-nav--secondary .md-nav { + position: static; + background-color: transparent; } + .md-nav--primary .md-nav--secondary .md-nav .md-nav__link { + padding-left: 2.8rem; } + [dir="rtl"] .md-nav--primary .md-nav--secondary .md-nav .md-nav__link { + padding-right: 2.8rem; + padding-left: initial; } + .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link { + padding-left: 4rem; } + [dir="rtl"] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link { + padding-right: 4rem; + padding-left: initial; } + .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link { + padding-left: 5.2rem; } + [dir="rtl"] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link { + padding-right: 5.2rem; + padding-left: initial; } + .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link { + padding-left: 6.4rem; } + [dir="rtl"] .md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link { + padding-right: 6.4rem; + padding-left: initial; } + .md-nav__toggle ~ .md-nav { + display: flex; + -webkit-transform: translateX(100%); + transform: translateX(100%); + transition: opacity 0.125s 0.05s, -webkit-transform 0.25s cubic-bezier(0.8, 0, 0.6, 1); + transition: transform 0.25s cubic-bezier(0.8, 0, 0.6, 1), opacity 0.125s 0.05s; + transition: transform 0.25s cubic-bezier(0.8, 0, 0.6, 1), opacity 0.125s 0.05s, -webkit-transform 0.25s cubic-bezier(0.8, 0, 0.6, 1); + opacity: 0; } + [dir="rtl"] .md-nav__toggle ~ .md-nav { + -webkit-transform: translateX(-100%); + transform: translateX(-100%); } + .no-csstransforms3d .md-nav__toggle ~ .md-nav { + display: none; } + .md-nav__toggle:checked ~ .md-nav { + -webkit-transform: translateX(0); + transform: translateX(0); + transition: opacity 0.125s 0.125s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.125s 0.125s; + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.125s 0.125s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + opacity: 1; } + .no-csstransforms3d .md-nav__toggle:checked ~ .md-nav { + display: flex; } + .md-sidebar--primary { + position: fixed; + top: 0; + left: -24.2rem; + width: 24.2rem; + height: 100%; + -webkit-transform: translateX(0); + transform: translateX(0); + transition: box-shadow 0.25s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.25s; + transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), box-shadow 0.25s, -webkit-transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); + background-color: white; + z-index: 3; } + [dir="rtl"] .md-sidebar--primary { + right: -24.2rem; + left: initial; } + .no-csstransforms3d .md-sidebar--primary { + display: none; } + [data-md-toggle="drawer"]:checked ~ .md-container .md-sidebar--primary { + box-shadow: 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12), 0 5px 5px -3px rgba(0, 0, 0, 0.4); + -webkit-transform: translateX(24.2rem); + transform: translateX(24.2rem); } + [dir="rtl"] [data-md-toggle="drawer"]:checked ~ .md-container .md-sidebar--primary { + -webkit-transform: translateX(-24.2rem); + transform: translateX(-24.2rem); } + .no-csstransforms3d [data-md-toggle="drawer"]:checked ~ .md-container .md-sidebar--primary { + display: block; } + .md-sidebar--primary .md-sidebar__scrollwrap { + overflow: hidden; } + .md-sidebar--primary .md-sidebar__scrollwrap { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + margin: 0; } + .md-tabs { + display: none; } } + +@media only screen and (min-width: 60em) { + .md-content { + margin-right: 24.2rem; } + [dir="rtl"] .md-content { + margin-right: initial; + margin-left: 24.2rem; } + .md-header-nav__button.md-icon--search { + display: none; } + .md-header-nav__source { + display: block; + width: 23rem; + max-width: 23rem; + margin-left: 2.8rem; + padding-right: 1.2rem; } + [dir="rtl"] .md-header-nav__source { + margin-right: 2.8rem; + margin-left: initial; + padding-right: initial; + padding-left: 1.2rem; } + .md-search { + padding: 0.4rem; } + .md-search__overlay { + position: fixed; + top: 0; + left: 0; + width: 0; + height: 0; + transition: width 0s 0.25s, height 0s 0.25s, opacity 0.25s; + background-color: rgba(0, 0, 0, 0.54); + cursor: pointer; } + [dir="rtl"] .md-search__overlay { + right: 0; + left: initial; } + [data-md-toggle="search"]:checked ~ .md-header .md-search__overlay { + width: 100%; + height: 100%; + transition: width 0s, height 0s, opacity 0.25s; + opacity: 1; } + .md-search__inner { + position: relative; + width: 23rem; + padding: 0.2rem 0; + float: right; + transition: width 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); } + [dir="rtl"] .md-search__inner { + float: left; } + .md-search__form { + border-radius: 0.2rem; } + .md-search__input { + width: 100%; + height: 3.6rem; + padding-left: 4.4rem; + transition: background-color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1), color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); + border-radius: 0.2rem; + background-color: rgba(0, 0, 0, 0.26); + color: inherit; + font-size: 1.6rem; } + [dir="rtl"] .md-search__input { + padding-right: 4.4rem; } + .md-search__input + .md-search__icon { + color: inherit; } + .md-search__input::-webkit-input-placeholder { + color: rgba(255, 255, 255, 0.7); } + .md-search__input:-ms-input-placeholder { + color: rgba(255, 255, 255, 0.7); } + .md-search__input::-ms-input-placeholder { + color: rgba(255, 255, 255, 0.7); } + .md-search__input::placeholder { + color: rgba(255, 255, 255, 0.7); } + .md-search__input:hover { + background-color: rgba(255, 255, 255, 0.12); } + [data-md-toggle="search"]:checked ~ .md-header .md-search__input { + border-radius: 0.2rem 0.2rem 0 0; + background-color: white; + color: rgba(0, 0, 0, 0.87); + text-overflow: none; } + [data-md-toggle="search"]:checked ~ .md-header .md-search__input + .md-search__icon, [data-md-toggle="search"]:checked ~ .md-header .md-search__input::-webkit-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + [data-md-toggle="search"]:checked ~ .md-header .md-search__input + .md-search__icon, [data-md-toggle="search"]:checked ~ .md-header .md-search__input:-ms-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + [data-md-toggle="search"]:checked ~ .md-header .md-search__input + .md-search__icon, [data-md-toggle="search"]:checked ~ .md-header .md-search__input::-ms-input-placeholder { + color: rgba(0, 0, 0, 0.54); } + [data-md-toggle="search"]:checked ~ .md-header .md-search__input + .md-search__icon, [data-md-toggle="search"]:checked ~ .md-header .md-search__input::placeholder { + color: rgba(0, 0, 0, 0.54); } + .md-search__output { + top: 3.8rem; + transition: opacity 0.4s; + opacity: 0; } + [data-md-toggle="search"]:checked ~ .md-header .md-search__output { + box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12), 0 3px 5px -1px rgba(0, 0, 0, 0.4); + opacity: 1; } + .md-search__scrollwrap { + max-height: 0; } + [data-md-toggle="search"]:checked ~ .md-header .md-search__scrollwrap { + max-height: 75vh; } + .md-search__scrollwrap::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; } + .md-search__scrollwrap::-webkit-scrollbar-thumb { + background-color: rgba(0, 0, 0, 0.26); } + .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: #536dfe; } + .md-search-result__meta { + padding-left: 4.4rem; } + [dir="rtl"] .md-search-result__meta { + padding-right: 4.4rem; + padding-left: initial; } + .md-search-result__article { + padding-left: 4.4rem; } + [dir="rtl"] .md-search-result__article { + padding-right: 4.4rem; + padding-left: 1.6rem; } + .md-sidebar--secondary { + display: block; + margin-left: 100%; + -webkit-transform: translate(-100%, 0); + transform: translate(-100%, 0); } + [dir="rtl"] .md-sidebar--secondary { + margin-right: 100%; + margin-left: initial; + -webkit-transform: translate(100%, 0); + transform: translate(100%, 0); } } + +@media only screen and (min-width: 76.25em) { + .md-content { + margin-left: 24.2rem; } + [dir="rtl"] .md-content { + margin-right: 24.2rem; } + .md-content__inner { + margin-right: 2.4rem; + margin-left: 2.4rem; } + .md-header-nav__button.md-icon--menu { + display: none; } + .md-nav[data-md-state="animate"] { + transition: max-height 0.25s cubic-bezier(0.86, 0, 0.07, 1); } + .md-nav__toggle ~ .md-nav { + max-height: 0; + overflow: hidden; } + .no-js .md-nav__toggle ~ .md-nav { + display: none; } + .md-nav__toggle:checked ~ .md-nav, .md-nav[data-md-state="expand"] { + max-height: 100%; } + .no-js .md-nav__toggle:checked ~ .md-nav, .no-js .md-nav[data-md-state="expand"] { + display: block; } + .md-nav__item--nested > .md-nav > .md-nav__title { + display: none; } + .md-nav__item--nested > .md-nav__link::after { + display: inline-block; + -webkit-transform-origin: 0.45em 0.45em; + transform-origin: 0.45em 0.45em; + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; + vertical-align: -0.125em; } + .js .md-nav__item--nested > .md-nav__link::after { + transition: -webkit-transform 0.4s; + transition: transform 0.4s; + transition: transform 0.4s, -webkit-transform 0.4s; } + .md-nav__item--nested .md-nav__toggle:checked ~ .md-nav__link::after { + -webkit-transform: rotateX(180deg); + transform: rotateX(180deg); } + [data-md-toggle="search"]:checked ~ .md-header .md-search__inner { + width: 68.8rem; } + .md-search__scrollwrap { + width: 68.8rem; } + .md-sidebar--secondary { + margin-left: 122rem; } + [dir="rtl"] .md-sidebar--secondary { + margin-right: 122rem; + margin-left: initial; } + .md-tabs ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item--nested { + font-size: 0; + visibility: hidden; } + .md-tabs--active ~ .md-main .md-nav--primary .md-nav__title { + display: block; + padding: 0; } + .md-tabs--active ~ .md-main .md-nav--primary .md-nav__title--site { + display: none; } + .no-js .md-tabs--active ~ .md-main .md-nav--primary .md-nav { + display: block; } + .md-tabs--active ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item { + font-size: 0; + visibility: hidden; } + .md-tabs--active ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item--nested { + display: none; + font-size: 1.4rem; + overflow: auto; + visibility: visible; } + .md-tabs--active ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item--nested > .md-nav__link { + display: none; } + .md-tabs--active ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item--active { + display: block; } + .md-tabs--active ~ .md-main .md-nav[data-md-level="1"] { + max-height: initial; + overflow: visible; } + .md-tabs--active ~ .md-main .md-nav[data-md-level="1"] > .md-nav__list > .md-nav__item { + padding-left: 0; } + .md-tabs--active ~ .md-main .md-nav[data-md-level="1"] .md-nav .md-nav__title { + display: none; } } + +@media only screen and (min-width: 45em) { + .md-footer-nav__link { + width: 50%; } + .md-footer-copyright { + max-width: 75%; + float: left; } + [dir="rtl"] .md-footer-copyright { + float: right; } + .md-footer-social { + padding: 1.2rem 0; + float: right; } + [dir="rtl"] .md-footer-social { + float: left; } } + +@media only screen and (max-width: 29.9375em) { + [data-md-toggle="search"]:checked ~ .md-header .md-search__overlay { + -webkit-transform: scale(45); + transform: scale(45); } } + +@media only screen and (min-width: 30em) and (max-width: 44.9375em) { + [data-md-toggle="search"]:checked ~ .md-header .md-search__overlay { + -webkit-transform: scale(60); + transform: scale(60); } } + +@media only screen and (min-width: 45em) and (max-width: 59.9375em) { + [data-md-toggle="search"]:checked ~ .md-header .md-search__overlay { + -webkit-transform: scale(75); + transform: scale(75); } } + +@media only screen and (min-width: 60em) and (max-width: 76.1875em) { + [data-md-toggle="search"]:checked ~ .md-header .md-search__inner { + width: 46.8rem; } + .md-search__scrollwrap { + width: 46.8rem; } + .md-search-result__teaser { + max-height: 5rem; + -webkit-line-clamp: 3; } } + +/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsImZpbGUiOiJhc3NldHMvc3R5bGVzaGVldHMvYXBwbGljYXRpb24uMTFlNDE4NTIuY3NzIiwic291cmNlUm9vdCI6IiJ9*/ \ No newline at end of file diff --git a/site/assets/stylesheets/application.scss b/site/assets/stylesheets/application.scss new file mode 100644 index 000000000..e135d9381 --- /dev/null +++ b/site/assets/stylesheets/application.scss @@ -0,0 +1,69 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Dependencies +// ---------------------------------------------------------------------------- + +@import "modularscale"; +@import "material-color"; +@import "material-shadows"; + +// ---------------------------------------------------------------------------- +// Local imports +// ---------------------------------------------------------------------------- + +@import "helpers/break"; +@import "helpers/px2em"; + +@import "config"; + +@import "base/reset"; +@import "base/icons"; +@import "base/typeset"; + +@import "layout/base"; +@import "layout/clipboard"; +@import "layout/content"; +@import "layout/header"; +@import "layout/hero"; +@import "layout/footer"; +@import "layout/nav"; +@import "layout/search"; +@import "layout/sidebar"; +@import "layout/source"; +@import "layout/tabs"; + +@import "extensions/admonition"; +@import "extensions/codehilite"; +@import "extensions/footnotes"; +@import "extensions/permalinks"; + +@import "extensions/pymdown/arithmatex"; +@import "extensions/pymdown/critic"; +@import "extensions/pymdown/details"; +@import "extensions/pymdown/emoji"; +@import "extensions/pymdown/inlinehilite"; +@import "extensions/pymdown/superfences"; +@import "extensions/pymdown/tasklist"; + +@import "shame"; diff --git a/site/assets/stylesheets/base/.stylelintrc b/site/assets/stylesheets/base/.stylelintrc new file mode 100644 index 000000000..422ff2c6f --- /dev/null +++ b/site/assets/stylesheets/base/.stylelintrc @@ -0,0 +1,7 @@ +{ + "extends": "../../../../.stylelintrc", + "rules": { + "font-weight-notation": null, + "property-no-vendor-prefix": null + } +} diff --git a/site/assets/stylesheets/base/_icons.scss b/site/assets/stylesheets/base/_icons.scss new file mode 100644 index 000000000..aaf4e9e1d --- /dev/null +++ b/site/assets/stylesheets/base/_icons.scss @@ -0,0 +1,81 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// stylelint-disable font-family-no-missing-generic-family-keyword + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Icon placeholders +%md-icon { + font-family: "Material Icons"; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: 1; + text-transform: none; + white-space: nowrap; + speak: none; + word-wrap: normal; + direction: ltr; + + // Icon rendered as button + &__button { + display: inline-block; + margin: $md-icon-margin; + padding: $md-icon-padding; + font-size: $md-icon-size; + cursor: pointer; + } +} + +// Representational classes +.md-icon { + @extend %md-icon; + + // Build representational classes + @each $ligature, $name in ( + "\E5C4": "arrow-back", // arrow_back + "\E5C8": "arrow-forward", // arrow_forward + "\E5D2": "menu", // menu + "\E8B6": "search" // search + ) { + &--#{$name}::before { + content: $ligature; + } + } + + // Adjust for RTL languages + [dir="rtl"] & { + + // Flip ligatures for arrows + @each $ligature, $name in ( + "\E5C8": "arrow-back", // arrow_forward + "\E5C4": "arrow-forward" // arrow_back + ) { + &--#{$name}::before { + content: $ligature; + } + } + } +} diff --git a/site/assets/stylesheets/base/_reset.scss b/site/assets/stylesheets/base/_reset.scss new file mode 100644 index 000000000..73bbd6bf2 --- /dev/null +++ b/site/assets/stylesheets/base/_reset.scss @@ -0,0 +1,132 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// stylelint-disable no-duplicate-selectors + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Enforce correct box model +html { + box-sizing: border-box; +} + +// All elements shall inherit the document default +*, +*::before, +*::after { + box-sizing: inherit; +} + +// Prevent adjustments of font size after orientation changes in IE and iOS +html { + text-size-adjust: none; +} + +// Remove margin in all browsers +body { + margin: 0; +} + +// Reset horizontal rules in FF +hr { + overflow: visible; + box-sizing: content-box; +} + +// Remove gaps in underlined links in iOS >= 8 and Safari >= 8 +a { + -webkit-text-decoration-skip: objects; +} + +// Reset tap outlines on iOS and Android +a, +button, +label, +input { + -webkit-tap-highlight-color: transparent; +} + +// Reset link styles +a { + color: inherit; + text-decoration: none; +} + +// Normalize font-size in all browsers +small { + font-size: 80%; +} + +// Prevent subscript and superscript from affecting line-height +sub, +sup { + position: relative; + font-size: 80%; + line-height: 0; + vertical-align: baseline; +} + +// Correct subscript offset +sub { + bottom: -0.25em; +} + +// Correct superscript offset +sup { + top: -0.5em; +} + +// Remove borders on images +img { + border-style: none; +} + +// Reset table styles +table { + border-collapse: separate; + border-spacing: 0; +} + +// Reset table cell styles +td, +th { + font-weight: normal; + vertical-align: top; +} + +// Reset (native) button styles +button { + margin: 0; + padding: 0; + border: 0; + outline-style: none; + background: transparent; + font-size: inherit; +} + +// Reset (native) input styles +input { + border: 0; + outline: 0; +} diff --git a/site/assets/stylesheets/base/_typeset.scss b/site/assets/stylesheets/base/_typeset.scss new file mode 100644 index 000000000..2e89c8a55 --- /dev/null +++ b/site/assets/stylesheets/base/_typeset.scss @@ -0,0 +1,492 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules: font definitions +// ---------------------------------------------------------------------------- + +// Enable font-smoothing in Webkit and FF +body { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +// Default fonts +body, +input { + color: $md-color-black; + font-feature-settings: "kern", "liga"; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +// Proportionally spaced fonts +pre, +code, +kbd { + color: $md-color-black; + font-feature-settings: "kern"; + font-family: "Courier New", Courier, monospace; +} + +// ---------------------------------------------------------------------------- +// Rules: typesetted content +// ---------------------------------------------------------------------------- + +// Content that is typeset - if possible, all margins, paddings and font sizes +// should be set in ems, so nested blocks (e.g. Admonition) render correctly, +// except headlines that should only appear on the top level and need to have +// consistent spacing due to layout constraints. +.md-typeset { + font-size: ms(0); + line-height: 1.6; + + // Colors should be kept when printing + -webkit-print-color-adjust: exact; + + // Default spacing + p, + ul, + ol, + blockquote { + margin: 1em 0; + } + + // 1st level headline + h1 { + margin: 0 0 4rem; + color: $md-color-black--light; + font-size: ms(3); + font-weight: 300; + letter-spacing: -0.01em; + line-height: 1.3; + } + + // 2nd level headline + h2 { + margin: 4rem 0 1.6rem; + font-size: ms(2); + font-weight: 300; + letter-spacing: -0.01em; + line-height: 1.4; + } + + // 3rd level headline + h3 { + margin: 3.2rem 0 1.6rem; + font-size: ms(1); + font-weight: 400; + letter-spacing: -0.01em; + line-height: 1.5; + } + + // 3rd level headline following an 2nd level headline + h2 + h3 { + margin-top: 1.6rem; + } + + // 4th level headline + h4 { + margin: 1.6rem 0; + font-size: ms(0); + font-weight: 700; + letter-spacing: -0.01em; + } + + // 5th and 6th level headline + h5, + h6 { + margin: 1.6rem 0; + color: $md-color-black--light; + font-size: ms(-1); + font-weight: 700; + letter-spacing: -0.01em; + } + + // Overrides for 5th level headline + h5 { + text-transform: uppercase; + } + + // Horizontal separators + hr { + margin: 1.5em 0; + border-bottom: 0.1rem dotted $md-color-black--lighter; + } + + // Links + a { + color: $md-color-primary; + word-break: break-word; + + // Also enable color transition on pseudo elements + &, + &::before { + transition: color 0.125s; + } + + // Hovered and active links + &:hover, + &:active { + color: $md-color-accent; + } + + // Add URLs for print + @media print { + + // Show link URL + &::after { + color: $md-color-black--light; + content: " [" attr(href) "]"; + } + } + } + + // Code blocks + code, + pre { + background-color: $md-code-background; + color: $md-code-color; + font-size: 85%; + direction: ltr; + + // Wrap text and hide scollbars + @media print { + white-space: pre-wrap; + } + } + + // Inline code blocks, correct relative ems for smaller font size + code { + $correct: 1 / 0.85; + + margin: 0 0.25em * $correct; + padding: 0.0625em * $correct 0; + border-radius: 0.2rem; + box-shadow: + +0.25em * $correct 0 0 $md-code-background, + -0.25em * $correct 0 0 $md-code-background; + word-break: break-word; + box-decoration-break: clone; + + // Remove box-shadows for print + @media print { + box-shadow: none; + box-decoration-break: initial; + } + } + + // Disable containing block inside headlines + h1 code, + h2 code, + h3 code, + h4 code, + h5 code, + h6 code { + margin: 0; + background-color: transparent; + box-shadow: none; + } + + // Reset code if it's inside a link + a > code { + margin: inherit; + padding: inherit; + border-radius: none; + background-color: inherit; + color: inherit; + box-shadow: none; + } + + // Unformatted code blocks + pre { + position: relative; + margin: 1em 0; + border-radius: 0.2rem; + line-height: 1.4; + -webkit-overflow-scrolling: touch; + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 1em -1.6rem; + border-radius: 0; + } + + // Actual container with code, overflowing + > code { + display: block; + margin: 0; + padding: 1.05rem 1.2rem; + background-color: transparent; + font-size: inherit; + box-shadow: none; + box-decoration-break: none; + overflow: auto; + + // [mobile -]: Increase padding to match text + @include break-to-device(mobile) { + padding: 1.05rem 1.6rem; + } + + // Override native scrollbar styles + &::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; + } + + // Style scrollbar thumb + &::-webkit-scrollbar-thumb { + background-color: $md-color-black--lighter; + + // Hovered scrollbar thumb + &:hover { + background-color: $md-color-accent; + } + } + } + } + + // Keystrokes + kbd { + $correct: 1 / 0.85; + + padding: 0 0.25em * $correct; + border: 0.1rem solid darken($md-keyboard-background, 20%); + border-radius: 0.3rem; + border-bottom-color: darken($md-keyboard-background, 25%); + background-color: $md-keyboard-background; + color: $md-keyboard-color; + font-size: 85%; + box-shadow: 0 0.1rem 0 darken($md-keyboard-background, 30%); + word-break: break-word; + } + + // Text highlighting marker + mark { + margin: 0 0.25em; + padding: 0.0625em 0; + border-radius: 0.2rem; + background-color: transparentize($clr-yellow-500, 0.5); + box-shadow: + +0.25em 0 0 transparentize($clr-yellow-500, 0.5), + -0.25em 0 0 transparentize($clr-yellow-500, 0.5); + word-break: break-word; + box-decoration-break: clone; + } + + // Abbreviations + abbr { + border-bottom: 0.1rem dotted $md-color-black--light; + text-decoration: none; + cursor: help; + } + + // Small text + small { + opacity: 0.75; + } + + // Superscript and subscript + sup, + sub { + margin-left: 0.0625em * 1 / 0.8; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 0.0625em * 1 / 0.8; + margin-left: initial; + } + } + + // Blockquotes, possibly nested + blockquote { + padding-left: 1.2rem; + border-left: 0.4rem solid $md-color-black--lighter; + color: $md-color-black--light; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 1.2rem; + padding-left: initial; + border-right: 0.4rem solid $md-color-black--lighter; + border-left: initial; + } + } + + // Unordered lists + ul { + list-style-type: disc; + } + + // Unordered and ordered lists + ul, + ol { + margin-left: 0.625em; + padding: 0; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 0.625em; + margin-left: initial; + } + + // Nested ordered lists + ol { + list-style-type: lower-alpha; + + // Triply nested ordered list + ol { + list-style-type: lower-roman; + } + } + + // List elements + li { + margin-bottom: 0.5em; + margin-left: 1.25em; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 1.25em; + margin-left: initial; + } + + // Decrease vertical spacing + p, + blockquote { + margin: 0.5em 0; + } + + // Remove margin on last element + &:last-child { + margin-bottom: 0; + } + + // Nested lists + ul, + ol { + margin: 0.5em 0 0.5em 0.625em; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 0.625em; + margin-left: initial; + } + } + } + } + + // Definition lists + dd { + margin: 1em 0 1em 1.875em; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 1.875em; + margin-left: initial; + } + } + + // Limit width to container + iframe, + img, + svg { + max-width: 100%; + } + + // Data tables + table:not([class]) { + @include z-depth(2); + + display: inline-block; + max-width: 100%; + border-radius: 0.2rem; + font-size: ms(-1); + overflow: auto; + -webkit-overflow-scrolling: touch; + + // Due to margin collapse because of the necessary inline-block hack, we + // cannot increase the bottom margin on the table, so we just increase the + // top margin on the following element + & + * { + margin-top: 1.5em; + } + + // Table headings and cells + th:not([align]), + td:not([align]) { + text-align: left; + + // Adjust for RTL languages + [dir="rtl"] & { + text-align: right; + } + } + + // Table headings + th { + min-width: 10rem; + padding: 1.2rem 1.6rem; + background-color: $md-color-black--light; + color: $md-color-white; + vertical-align: top; + } + + // Table cells + td { + padding: 1.2rem 1.6rem; + border-top: 0.1rem solid $md-color-black--lightest; + vertical-align: top; + } + + // Remove top border on first row + tr:first-child td { + border-top: 0; + } + + // Do not wrap links in tables + a { + word-break: normal; + } + } + + // Wrapper for scrolling on overflow + &__scrollwrap { + margin: 1em -1.6rem; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } + + // Data table wrapper, in case JavaScript is available + .md-typeset__table { + display: inline-block; + margin-bottom: 0.5em; + padding: 0 1.6rem; + + // Data tables + table { + display: table; + width: 100%; + margin: 0; + overflow: hidden; + } + } +} diff --git a/site/assets/stylesheets/extensions/_admonition.scss b/site/assets/stylesheets/extensions/_admonition.scss new file mode 100644 index 000000000..7dfeeccdf --- /dev/null +++ b/site/assets/stylesheets/extensions/_admonition.scss @@ -0,0 +1,144 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Admonition extension + .admonition { + @include z-depth(2); + + position: relative; + margin: 1.5625em 0; + padding: 0 1.2rem; + border-left: 0.4rem solid $clr-blue-a200; + border-radius: 0.2rem; + font-size: ms(-1); + overflow: auto; + + // Adjust for RTL languages + [dir="rtl"] & { + border-right: 0.4rem solid $clr-blue-a200; + border-left: none; + } + + // Adjust spacing on last element + html & > :last-child { + margin-bottom: 1.2rem; + } + + // Adjust margin for nested admonition blocks + .admonition { + margin: 1em 0; + } + + // Title + > .admonition-title { + margin: 0 -1.2rem; + padding: 0.8rem 1.2rem 0.8rem 4rem; + border-bottom: 0.1rem solid transparentize($clr-blue-a200, 0.9); + background-color: transparentize($clr-blue-a200, 0.9); + font-weight: 700; + + // Adjust for RTL languages + [dir="rtl"] & { + padding: 0.8rem 4rem 0.8rem 1.2rem; + } + + // Reset spacing, if title is the only element + &:last-child { + margin-bottom: 0; + } + + // Icon + &::before { + @extend %md-icon; + + position: absolute; + left: 1.2rem; + color: $clr-blue-a200; + font-size: 2rem; + content: "\E3C9"; // edit + + // Adjust for RTL languages + [dir="rtl"] & { + right: 1.2rem; + left: initial; + } + } + } + + // Build representational classes + @each $names, $appearance in ( + abstract summary tldr: $clr-light-blue-a400 "\E8D2", // subject + info todo: $clr-cyan-a700 "\E88E", // info + tip hint important : $clr-teal-a700 "\E80E", // whatshot + success check done: $clr-green-a700 "\E876", // done + question help faq: $clr-light-green-a700 "\E887", // help + warning caution attention: $clr-orange-a400 "\E002", // warning + failure fail missing: $clr-red-a200 "\E14C", // clear + danger error: $clr-red-a400 "\E3E7", // flash_on + bug: $clr-pink-a400 "\E868", // bug_report + example: $clr-deep-purple-a400 "\E242", // format_list_numbered + quote cite: $clr-grey "\E244" // format_quote + ) { + $tint: nth($appearance, 1); + $icon: nth($appearance, 2); + + // Define base class + &%#{nth($names, 1)}, + &.#{nth($names, 1)} { + border-left-color: $tint; + + // Adjust for RTL languages + [dir="rtl"] & { + border-right-color: $tint; + } + + // Title + > .admonition-title { + border-bottom-color: 0.1rem solid transparentize($tint, 0.9); + background-color: transparentize($tint, 0.9); + + // Icon + &::before { + color: $tint; + content: $icon; + } + } + } + + // Define synonyms for base class + @if length($names) > 1 { + @for $n from 2 through length($names) { + &.#{nth($names, $n)} { + @extend .admonition%#{nth($names, 1)}; + } + } + } + } + } +} diff --git a/site/assets/stylesheets/extensions/_codehilite.scss b/site/assets/stylesheets/extensions/_codehilite.scss new file mode 100644 index 000000000..b2778ff16 --- /dev/null +++ b/site/assets/stylesheets/extensions/_codehilite.scss @@ -0,0 +1,373 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Variables +// ---------------------------------------------------------------------------- + +// Operators +$codehilite-operator: inherit; +$codehilite-operator-word: inherit; + +// Generics +$codehilite-generic-emph: #000000; +$codehilite-generic-error: #AA0000; +$codehilite-generic-heading: #999999; +$codehilite-generic-output: #888888; +$codehilite-generic-prompt: #555555; +$codehilite-generic-strong: inherit; +$codehilite-generic-subheading: #AAAAAA; +$codehilite-generic-traceback: #AA0000; + +// Diffs +$codehilite-diff-deleted: #FFDDDD; +$codehilite-diff-inserted: #DDFFDD; + +// Keywords +$codehilite-keyword: #3B78E7; +$codehilite-keyword-constant: #A71D5D; +$codehilite-keyword-declaration: #3B78E7; +$codehilite-keyword-namespace: #3B78E7; +$codehilite-keyword-pseudo: #A71D5D; +$codehilite-keyword-reserved: #3E61A2; +$codehilite-keyword-type: #3E61A2; + +// Comments +$codehilite-comment: #999999; +$codehilite-comment-multiline: #999999; +$codehilite-comment-preproc: #666666; +$codehilite-comment-single: #999999; +$codehilite-comment-shebang: #999999; +$codehilite-comment-special: #999999; + +// Names +$codehilite-name-attribute: #C2185B; +$codehilite-name-builtin: #C2185B; +$codehilite-name-builtin-pseudo: #3E61A2; +$codehilite-name-class: #C2185B; +$codehilite-name-constant: #3E61A2; +$codehilite-name-decorator: #666666; +$codehilite-name-entity: #666666; +$codehilite-name-exception: #C2185B; +$codehilite-name-function: #C2185B; +$codehilite-name-label: #3B5179; +$codehilite-name-namespace: #EC407A; +$codehilite-name-tag: #3B78E7; +$codehilite-name-variable: #3E61A2; +$codehilite-name-variable-class: #3E61A2; +$codehilite-name-variable-instance: #3E61A2; +$codehilite-name-variable-global: #3E61A2; +$codehilite-name-extension: #EC407A; + +// Numbers +$codehilite-literal-number: #E74C3C; +$codehilite-literal-number-float: #E74C3C; +$codehilite-literal-number-hex: #E74C3C; +$codehilite-literal-number-integer: #E74C3C; +$codehilite-literal-number-integer-long: #E74C3C; +$codehilite-literal-number-oct: #E74C3C; + +// Strings +$codehilite-literal-string: #0D904F; +$codehilite-literal-string-backticks: #0D904F; +$codehilite-literal-string-char: #0D904F; +$codehilite-literal-string-doc: #999999; +$codehilite-literal-string-double: #0D904F; +$codehilite-literal-string-escape: #183691; +$codehilite-literal-string-heredoc: #183691; +$codehilite-literal-string-interpol: #183691; +$codehilite-literal-string-other: #183691; +$codehilite-literal-string-regex: #009926; +$codehilite-literal-string-single: #0D904F; +$codehilite-literal-string-symbol: #0D904F; + +// Miscellaneous +$codehilite-error: #A61717; +$codehilite-whitespace: transparent; + +// ---------------------------------------------------------------------------- +// Rules: syntax highlighting +// ---------------------------------------------------------------------------- + +// Codehilite extension +.codehilite { + + // Operators + .o { color: $codehilite-operator; } + .ow { color: $codehilite-operator-word; } + + // Generics + .ge { color: $codehilite-generic-emph; } + .gr { color: $codehilite-generic-error; } + .gh { color: $codehilite-generic-heading; } + .go { color: $codehilite-generic-output; } + .gp { color: $codehilite-generic-prompt; } + .gs { color: $codehilite-generic-strong; } + .gu { color: $codehilite-generic-subheading; } + .gt { color: $codehilite-generic-traceback; } + + // Diffs + .gd { background-color: $codehilite-diff-deleted; } + .gi { background-color: $codehilite-diff-inserted; } + + // Keywords + .k { color: $codehilite-keyword; } + .kc { color: $codehilite-keyword-constant; } + .kd { color: $codehilite-keyword-declaration; } + .kn { color: $codehilite-keyword-namespace; } + .kp { color: $codehilite-keyword-pseudo; } + .kr { color: $codehilite-keyword-reserved; } + .kt { color: $codehilite-keyword-type; } + + // Comments + .c { color: $codehilite-comment; } + .cm { color: $codehilite-comment-multiline; } + .cp { color: $codehilite-comment-preproc; } + .c1 { color: $codehilite-comment-single; } + .ch { color: $codehilite-comment-shebang; } + .cs { color: $codehilite-comment-special; } + + // Names + .na { color: $codehilite-name-attribute; } + .nb { color: $codehilite-name-builtin; } + .bp { color: $codehilite-name-builtin-pseudo; } + .nc { color: $codehilite-name-class; } + .no { color: $codehilite-name-constant; } + .nd { color: $codehilite-name-entity; } + .ni { color: $codehilite-name-entity; } + .ne { color: $codehilite-name-exception; } + .nf { color: $codehilite-name-function; } + .nl { color: $codehilite-name-label; } + .nn { color: $codehilite-name-namespace; } + .nt { color: $codehilite-name-tag; } + .nv { color: $codehilite-name-variable; } + .vc { color: $codehilite-name-variable-class; } + .vg { color: $codehilite-name-variable-global; } + .vi { color: $codehilite-name-variable-instance; } + .nx { color: $codehilite-name-extension; } + + // Numbers + .m { color: $codehilite-literal-number; } + .mf { color: $codehilite-literal-number-float; } + .mh { color: $codehilite-literal-number-hex; } + .mi { color: $codehilite-literal-number-integer; } + .il { color: $codehilite-literal-number-integer-long; } + .mo { color: $codehilite-literal-number-oct; } + + // Strings + .s { color: $codehilite-literal-string; } + .sb { color: $codehilite-literal-string-backticks; } + .sc { color: $codehilite-literal-string-char; } + .sd { color: $codehilite-literal-string-doc; } + .s2 { color: $codehilite-literal-string-double; } + .se { color: $codehilite-literal-string-escape; } + .sh { color: $codehilite-literal-string-heredoc; } + .si { color: $codehilite-literal-string-interpol; } + .sx { color: $codehilite-literal-string-other; } + .sr { color: $codehilite-literal-string-regex; } + .s1 { color: $codehilite-literal-string-single; } + .ss { color: $codehilite-literal-string-symbol; } + + // Miscellaneous + .err { color: $codehilite-error; } + .w { color: $codehilite-whitespace; } + + // Highlighted lines + .hll { + display: block; + margin: 0 -1.2rem; + padding: 0 1.2rem; + background-color: transparentize($clr-yellow-500, 0.5); + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 0 -1.6rem; + padding: 0 1.6rem; + } + } +} + +// ---------------------------------------------------------------------------- +// Rules: layout +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // If code blocks are wrapped with codehilite, the styles must be adjusted + // so the marker stretches to the whole width and the padding is respected + .codehilite { + position: relative; + margin: 1em 0; + padding: 0; + border-radius: 0.2rem; + background-color: $md-code-background; + color: $md-code-color; + line-height: 1.4; + -webkit-overflow-scrolling: touch; + + // Actual container with code, overflowing + pre, + code { + display: block; + margin: 0; + padding: 1.05rem 1.2rem; + background-color: transparent; + overflow: auto; + vertical-align: top; + + // Override native scrollbar styles + &::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; + } + + // Style scrollbar thumb + &::-webkit-scrollbar-thumb { + background-color: $md-color-black--lighter; + + // Hovered scrollbar thumb + &:hover { + background-color: $md-color-accent; + } + } + } + } + + // If not using Pygments, code will be under pre > code + pre.codehilite { + overflow: visible; + + // Actual container with code, overflowing + code { + display: block; + padding: 1.05rem 1.2rem; + overflow: auto; + } + } + + // Block with line numbers + .codehilitetable { + display: block; + margin: 1em 0; + border-radius: 0.2em; + font-size: ms(0); + overflow: hidden; + + // Set table elements to block layout, because otherwise the whole flexbox + // hacking won't work correctly + tbody, + td { + display: block; + padding: 0; + } + + // We need to use flexbox layout, because otherwise it's not possible to + // make the code container scroll while keeping the line numbers static + tr { + display: flex; + } + + // The pre tags are nested inside a table, so we need to remove the + // margin because it collapses below all the overflows + .codehilite, + .linenodiv { + margin: 0; + border-radius: 0; + } + + // Add spacing to line number container + .linenodiv { + padding: 1.05rem 1.2rem; + } + + // Disable user selection, so code can be easily copied without + // accidentally also copying the line numbers + .linenos { + background-color: $md-color-black--lightest; + color: $md-color-black--lighter; + user-select: none; + + // Reset spacings + pre { + margin: 0; + padding: 0; + background-color: transparent; + color: inherit; + text-align: right; + } + } + + // The table cell containing the code container wrapper and code should + // stretch horizontally to the remaining space + .code { + flex: 1; + overflow: hidden; + } + } + + // Full-width container + > .codehilite { + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 1em -1.6rem; + border-radius: 0; + + // Actual container with code, overflowing + pre, + code { + padding: 1.05rem 1.6rem; + } + } + } + + // Full-width container on top-level + > .codehilitetable { + box-shadow: none; + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 1em -1.6rem; + border-radius: 0; + + // Increase spacing + .codehilite > pre, + .codehilite > code, + .linenodiv { + padding: 1rem 1.6rem; + } + } + } + + // When pymdownx.superfences is enabled but codehilite is disabled, + // pymdownx.highlight will be used. When this happens, the outer + // container and tables get this class names by default. + .highlight { + @extend .codehilite; + } + + // Same as above, but for code blocks with line numbers enabled + .highlighttable { + @extend .codehilitetable; + } +} diff --git a/site/assets/stylesheets/extensions/_footnotes.scss b/site/assets/stylesheets/extensions/_footnotes.scss new file mode 100644 index 000000000..6b6518dfb --- /dev/null +++ b/site/assets/stylesheets/extensions/_footnotes.scss @@ -0,0 +1,149 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // All footnote references + [id^="fnref:"] { + display: inline-block; + + // Targeted anchor + &:target { + margin-top: -(4.8rem + 1.2rem + 1.6rem); + padding-top: (4.8rem + 1.2rem + 1.6rem); + pointer-events: none; + } + } + + // All footnote back references + [id^="fn:"] { + + // Add spacing to anchor for offset + &::before { + display: none; + height: 0; + content: ""; + } + + // Targeted anchor + &:target::before { + display: block; + margin-top: -(4.8rem + 1.2rem + 1rem); + padding-top: (4.8rem + 1.2rem + 1rem); + pointer-events: none; + } + } + + // Footnotes extension + .footnote { + color: $md-color-black--light; + font-size: ms(-1); + + // Remove additional spacing on footnotes + ol { + margin-left: 0; + } + + // Footnote + li { + transition: color 0.25s; + + // Darken color for targeted footnote + &:target { + color: $md-color-black; + } + + // Remove spacing on first element + :first-child { + margin-top: 0; + } + + // Make back references visible on hover + &:hover .footnote-backref, + &:target .footnote-backref { + transform: translateX(0); + opacity: 1; + } + + // Active or targeted back reference + &:hover .footnote-backref:hover, + &:target .footnote-backref { + color: $md-color-accent; + } + } + } + + // Footnote reference + .footnote-ref { + display: inline-block; + pointer-events: initial; + + // Render a thin line before footnote + &::before { + display: inline; + margin: 0 0.2em; + border-left: 0.1rem solid $md-color-black--lighter; + font-size: 1.25em; + content: ""; + vertical-align: -0.5rem; + } + } + + // Footnote back reference + .footnote-backref { + @extend %md-icon; + + display: inline-block; + transform: translateX(0.5rem); + transition: + transform 0.25s 0.125s, + color 0.25s, + opacity 0.125s 0.125s; + color: $md-color-black--lighter; + // Hack: remove Unicode arrow for icon + font-size: 0; + opacity: 0; + vertical-align: text-bottom; + + // Adjust for RTL languages + [dir="rtl"] & { + transform: translateX(-0.5rem); + } + + // Back reference icon + &::before { + display: inline-block; + font-size: 1.6rem; + content: "\E31B"; // keyboard_return + + // Adjust for RTL languages + [dir="rtl"] & { + transform: scaleX(-1) + } + } + } +} diff --git a/site/assets/stylesheets/extensions/_permalinks.scss b/site/assets/stylesheets/extensions/_permalinks.scss new file mode 100644 index 000000000..ef0b89ae7 --- /dev/null +++ b/site/assets/stylesheets/extensions/_permalinks.scss @@ -0,0 +1,99 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Permalinks extension + .headerlink { + display: inline-block; + margin-left: 1rem; + transform: translate(0, 0.5rem); + transition: + transform 0.25s 0.25s, + color 0.25s, + opacity 0.125s 0.25s; + opacity: 0; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 1rem; + margin-left: initial; + } + + // Higher specificity for color due to palettes integration + html body & { + color: $md-color-black--lighter; + } + + // Hide for print + @media print { + display: none; + } + } + + // Correct anchor offset for link blurring + @each $level, $delta in ( + h1: 0.9rem, + h2: 0.8rem, + h3: 0.9rem, + h4: 0.9rem, + h5: 1.1rem, + h6: 1.1rem + ) { + #{$level}[id] { + + // Un-targeted anchor + &::before { + display: block; + margin-top: -$delta; + padding-top: $delta; + content: ""; + } + + // Targeted anchor (48px from header, 12px from sidebar offset) + &:target::before { + margin-top: -(4.8rem + 1.2rem + $delta); + padding-top: (4.8rem + 1.2rem + $delta); + } + + // Make permalink visible on hover + &:hover .headerlink, + &:target .headerlink, + & .headerlink:focus { + transform: translate(0, 0); + opacity: 1; + } + + // Active or targeted permalink + &:hover .headerlink:hover, + &:target .headerlink, + & .headerlink:focus { + color: $md-color-accent; + } + } + } +} diff --git a/site/assets/stylesheets/extensions/pymdown/_arithmatex.scss b/site/assets/stylesheets/extensions/pymdown/_arithmatex.scss new file mode 100644 index 000000000..2ad22cbe7 --- /dev/null +++ b/site/assets/stylesheets/extensions/pymdown/_arithmatex.scss @@ -0,0 +1,54 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// stylelint-disable selector-class-pattern + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // MathJax integration - add padding to omit vertical scrollbar + .MJXc-display { + margin: 0.75em 0; + padding: 0.75em 0; + overflow: auto; + -webkit-overflow-scrolling: touch; + } + + // Stretch top-level containers + > p > .MJXc-display { + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 0.75em -1.6rem; + padding: 0.25em 1.6rem; + } + } + + // Remove outline on tab index + .MathJax_CHTML { + outline: 0; + } +} diff --git a/site/assets/stylesheets/extensions/pymdown/_critic.scss b/site/assets/stylesheets/extensions/pymdown/_critic.scss new file mode 100644 index 000000000..4aba7ebf2 --- /dev/null +++ b/site/assets/stylesheets/extensions/pymdown/_critic.scss @@ -0,0 +1,93 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Deletions, additions and comments + del.critic, + ins.critic, + .critic.comment { + margin: 0 0.25em; + padding: 0.0625em 0; + border-radius: 0.2rem; + box-decoration-break: clone; + } + + // Deletion + del.critic { + background-color: $codehilite-diff-deleted; // TODO: dependent on order of inclusion + box-shadow: + +0.25em 0 0 $codehilite-diff-deleted, + -0.25em 0 0 $codehilite-diff-deleted; + } + + // Addition + ins.critic { + background-color: $codehilite-diff-inserted; // TODO: dependent on order of inclusion + box-shadow: + +0.25em 0 0 $codehilite-diff-inserted, + -0.25em 0 0 $codehilite-diff-inserted; + } + + // Comment + .critic.comment { + background-color: $md-code-background; // TODO: rename, centralize somehow + color: $md-code-color; + box-shadow: + +0.25em 0 0 $md-code-background, + -0.25em 0 0 $md-code-background; + + // Icon + &::before { + @extend %md-icon; + + padding-right: 0.125em; + color: $md-color-black--lighter; + content: "\E0B7"; // chat + vertical-align: -0.125em; + } + } + + // Block + .critic.block { + display: block; + margin: 1em 0; + padding-right: 1.6rem; + padding-left: 1.6rem; + box-shadow: none; + + // Decrease spacing on first element + :first-child { + margin-top: 0.5em; + } + + // Decrease spacing on last element + :last-child { + margin-bottom: 0.5em; + } + } +} diff --git a/site/assets/stylesheets/extensions/pymdown/_details.scss b/site/assets/stylesheets/extensions/pymdown/_details.scss new file mode 100644 index 000000000..ee8d29909 --- /dev/null +++ b/site/assets/stylesheets/extensions/pymdown/_details.scss @@ -0,0 +1,109 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Details extension + details { + @extend .admonition; + + display: block; + padding-top: 0; + + // Rotate title icon + &[open] > summary::after { + transform: rotate(180deg); + } + + // Remove bottom spacing + &:not([open]) { + padding-bottom: 0; + + // Remove bottom border if block is closed + > summary { + border-bottom: none; + } + } + + // Increase spacing to the right - scoped here for higher specificity + summary { + padding-right: 4rem; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-left: 4rem; + } + } + + // Manually hide and show, if browser doesn't support details + .no-details &:not([open]) { + + // Hide all nested tags ... + > * { + display: none; + } + + // ... but show title + summary { + display: block; + } + } + } + + // Title + summary { + @extend .admonition-title; + + // Hack: set to block, so Firefox doesn't render marker + display: block; + outline: none; + cursor: pointer; + + // Remove default details marker + &::-webkit-details-marker { + display: none; + } + + // Icon + &::after { + @extend %md-icon; + + position: absolute; + top: 0.8rem; + right: 1.2rem; + color: $md-color-black--lighter; + font-size: 2rem; + content: "\E313"; // keyboard_arrow_down + + // Adjust for RTL languages + [dir="rtl"] & { + right: initial; + left: 1.2rem; + } + } + } +} diff --git a/site/assets/stylesheets/extensions/pymdown/_emoji.scss b/site/assets/stylesheets/extensions/pymdown/_emoji.scss new file mode 100644 index 000000000..f2cd14ab7 --- /dev/null +++ b/site/assets/stylesheets/extensions/pymdown/_emoji.scss @@ -0,0 +1,35 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Correct alignment of emojis + .emojione { + width: 2rem; + vertical-align: text-top; + } +} diff --git a/site/assets/stylesheets/extensions/pymdown/_inlinehilite.scss b/site/assets/stylesheets/extensions/pymdown/_inlinehilite.scss new file mode 100644 index 000000000..3f2d236ec --- /dev/null +++ b/site/assets/stylesheets/extensions/pymdown/_inlinehilite.scss @@ -0,0 +1,37 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Qualified class selector to distinguish inline code from code blocks + code.codehilite { + $correct: 1 / 0.85; + + margin: 0 0.25em * $correct; + padding: 0.0625em * $correct 0; + } +} diff --git a/site/assets/stylesheets/extensions/pymdown/_superfences.scss b/site/assets/stylesheets/extensions/pymdown/_superfences.scss new file mode 100644 index 000000000..c3dde1aff --- /dev/null +++ b/site/assets/stylesheets/extensions/pymdown/_superfences.scss @@ -0,0 +1,100 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Tabbed code block content + .superfences-content { + display: none; + order: 99; + width: 100%; + background-color: $md-color-white; + + // Actual content + > * { + margin: 0; + border-radius: 0 + } + } + + // Tabbed code block container + .superfences-tabs { + display: flex; + position: relative; + flex-wrap: wrap; + margin: 1em 0; + border: 0.1rem solid $md-color-black--lightest; + border-radius: 0.2em; + + // Hide radio buttons + > input { + display: none; + + // Active tab label + &:checked + label { + font-weight: 700; + + // Show code tab content + & + .superfences-content { + display: block; + } + } + } + + // Tab label + > label { + width: auto; + padding: 1.2rem 1.2rem; + transition: color 0.125s; + font-size: ms(-1); + cursor: pointer; + + // Hovered tab label + html &:hover { + color: $md-color-accent; + } + } + } + + // Full-width container on top-level + > .superfences-tabs { + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 1em -1.6rem; + border: 0; + border-top: 0.1rem solid $md-color-black--lightest; + border-radius: 0; + + // Actual container with code, overflowing + pre, + code { + padding: 1.05rem 1.6rem; + } + } + } +} diff --git a/site/assets/stylesheets/extensions/pymdown/_tasklist.scss b/site/assets/stylesheets/extensions/pymdown/_tasklist.scss new file mode 100644 index 000000000..be6ae8f44 --- /dev/null +++ b/site/assets/stylesheets/extensions/pymdown/_tasklist.scss @@ -0,0 +1,83 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Remove list icon on task items + .task-list-item { + position: relative; + list-style-type: none; + + // Make checkbox items align with normal list items, but position + // everything in ems for correct layout at smaller font sizes + [type="checkbox"] { + position: absolute; + top: 0.45em; + left: -2em; + + // Adjust for RTL languages + [dir="rtl"] & { + right: -2em; + left: initial; + } + } + } + + // Wrapper for list controls, in case custom checkboxes are enabled + .task-list-control { + + // Checkbox icon in unchecked state + .task-list-indicator::before { + @extend %md-icon; + + position: absolute; + top: 0.15em; + left: -1.25em; + color: $md-color-black--lighter; + font-size: 1.25em; + content: "\E835"; // check_box_outline_blank + vertical-align: -0.25em; + + // Adjust for RTL languages + [dir="rtl"] & { + right: -1.25em; + left: initial; + } + } + + // Checkbox icon in checked state + [type="checkbox"]:checked + .task-list-indicator::before { + content: "\E834"; // check_box + } + + // Hide original checkbox behind icon + [type="checkbox"] { + opacity: 0; + z-index: -1; + } + } +} diff --git a/site/assets/stylesheets/helpers/_break.scss b/site/assets/stylesheets/helpers/_break.scss new file mode 100644 index 000000000..eee7aa32b --- /dev/null +++ b/site/assets/stylesheets/helpers/_break.scss @@ -0,0 +1,250 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Variables +// ---------------------------------------------------------------------------- + +/// +/// Device-specific breakpoints +/// +/// @example +/// $break-devices: ( +/// mobile: ( +/// portrait: 220px 479px, +/// landscape: 480px 719px +/// ), +/// tablet: ( +/// portrait: 720px 959px, +/// landscape: 960px 1219px +/// ), +/// screen: ( +/// small: 1220px 1599px, +/// medium: 1600px 1999px, +/// large: 2000px +/// ) +/// ); +/// +/// @group helpers +/// @access private +/// @type Map +/// +$break-devices: () !default; + +// ---------------------------------------------------------------------------- +// Helpers +// ---------------------------------------------------------------------------- + +/// +/// Choose minimum and maximum device widths +/// +/// @group helpers +/// @access private +/// @param {Map} $devices Map of devices +/// @return {List} Minimum and maximum width +/// +@function break-select-min-max($devices) { + $min: 1000000; + $max: 0; + @each $key, $value in $devices { + @while type-of($value) == map { + $value: break-select-min-max($value); + } + @if type-of($value) == list { + @each $number in $value { + @if type-of($number) == number { + $min: min($number, $min); + @if $max != null { + $max: max($number, $max); + } + } @else { + @error "Invalid number: #{$number}"; + } + } + } @elseif type-of($value) == number { + $min: min($value, $min); + $max: null; + } @else { + @error "Invalid value: #{$value}"; + } + } + @return $min, $max; +} + +/// +/// Select minimum and maximum widths for a device breakpoint +/// +/// @group helpers +/// @access private +/// @param {String} $device Device +/// @return {List} Minimum and maximum width +/// +@function break-select-device($device) { + $current: $break-devices; + @for $n from 1 through length($device) { + @if type-of($current) == map { + $current: map-get($current, nth($device, $n)); + } @else { + @error "Invalid device map: #{$devices}"; + } + } + @if type-of($current) == list or type-of($current) == number { + $current: (default: $current); + } + @return break-select-min-max($current); +} + +// ---------------------------------------------------------------------------- +// Mixins +// ---------------------------------------------------------------------------- + +/// +/// A minimum-maximum media query breakpoint +/// +/// @group helpers +/// @access public +/// @param {Number|List} $breakpoint Number or number pair +/// +@mixin break-at($breakpoint) { + @if type-of($breakpoint) == number { + @media only screen and (min-width: $breakpoint) { + @content; + } + } @elseif type-of($breakpoint) == list { + $min: nth($breakpoint, 1); + $max: nth($breakpoint, 2); + @if type-of($min) == number and type-of($max) == number { + @media only screen and (min-width: $min) and (max-width: $max) { + @content; + } + } @else { + @error "Invalid breakpoint: #{$breakpoint}"; + } + } @else { + @error "Invalid breakpoint: #{$breakpoint}"; + } +} + +/// +/// An orientation media query breakpoint +/// +/// @group helpers +/// @access public +/// @param {String} $breakpoint Orientation +/// +@mixin break-at-orientation($breakpoint) { + @if type-of($breakpoint) == string { + @media only screen and (orientation: $breakpoint) { + @content; + } + } @else { + @error "Invalid breakpoint: #{$breakpoint}"; + } +} + +/// +/// A maximum-aspect-ratio media query breakpoint +/// +/// @group helpers +/// @access public +/// @param {Number} $breakpoint Ratio +/// +@mixin break-at-ratio($breakpoint) { + @if type-of($breakpoint) == number { + @media only screen and (max-aspect-ratio: $breakpoint) { + @content; + } + } @else { + @error "Invalid breakpoint: #{$breakpoint}"; + } +} + +/// +/// A minimum-maximum media query device breakpoint +/// +/// @group helpers +/// @access public +/// @param {String|List} $breakpoint Device +/// +@mixin break-at-device($device) { + @if type-of($device) == string { + $device: $device,; + } + @if type-of($device) == list { + $breakpoint: break-select-device($device); + @if nth($breakpoint, 2) != null { + $min: nth($breakpoint, 1); + $max: nth($breakpoint, 2); + @media only screen and (min-width: $min) and (max-width: $max) { + @content; + } + } @else { + @error "Invalid device: #{$device}"; + } + } @else { + @error "Invalid device: #{$device}"; + } +} + +/// +/// A minimum media query device breakpoint +/// +/// @group helpers +/// @access public +/// @param {String|List} $breakpoint Device +/// +@mixin break-from-device($device) { + @if type-of($device) == string { + $device: $device,; + } + @if type-of($device) == list { + $breakpoint: break-select-device($device); + $min: nth($breakpoint, 1); + @media only screen and (min-width: $min) { + @content; + } + } @else { + @error "Invalid device: #{$device}"; + } +} + +/// +/// A maximum media query device breakpoint +/// +/// @group helpers +/// @access public +/// @param {String|List} $breakpoint Device +/// +@mixin break-to-device($device) { + @if type-of($device) == string { + $device: $device,; + } + @if type-of($device) == list { + $breakpoint: break-select-device($device); + $max: nth($breakpoint, 2); + @media only screen and (max-width: $max) { + @content; + } + } @else { + @error "Invalid device: #{$device}"; + } +} diff --git a/site/assets/stylesheets/helpers/_px2em.scss b/site/assets/stylesheets/helpers/_px2em.scss new file mode 100644 index 000000000..2ca50e111 --- /dev/null +++ b/site/assets/stylesheets/helpers/_px2em.scss @@ -0,0 +1,46 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Helpers +// ---------------------------------------------------------------------------- + +/// +/// Convert font size in px to em. +/// +/// @group helpers +/// @access public +/// @param {Number} $size Font size in px +/// @param {Number} $base Base font size +/// @return {Number} Font size in em +/// +@function px2em($size, $base: 16px) { + @if unit($size) == px { + @if unit($base) == px { + @return ($size / $base) * 1em; + } @else { + @error "Invalid base: #{$base} - unit must be 'px'"; + } + } @else { + @error "Invalid size: #{$size} - unit must be 'px'"; + } +} diff --git a/site/assets/stylesheets/layout/_base.scss b/site/assets/stylesheets/layout/_base.scss new file mode 100644 index 000000000..38510f0cf --- /dev/null +++ b/site/assets/stylesheets/layout/_base.scss @@ -0,0 +1,245 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Variables +// ---------------------------------------------------------------------------- + +// Active (toggled) drawer +$md-toggle__drawer--checked: + "[data-md-toggle=\"drawer\"]:checked ~"; + +// ---------------------------------------------------------------------------- +// Rules: base grid and containers +// ---------------------------------------------------------------------------- + +// Stretch container to viewport and set base font-size to 10px for simple +// calculations base on relative ems (rems) +html { + height: 100%; + font-size: 62.5%; + // Hack: some browsers on some operating systems don't account for scroll + // bars when firing media queries, so we need to do this for safety. This + // currently impacts the table of contents component between 1220 and 1234px + // and is to current knowledge not fixable. + overflow-x: hidden; + + // [screen medium +]: Set base font-size to 11px + @include break-from-device(screen medium) { + font-size: 68.75%; + } + + // [screen large +]: Set base font-size to 12px + @include break-from-device(screen large) { + font-size: 75%; + } +} + +// Stretch body to container and leave room for footer +body { + position: relative; + height: 100%; + + // [tablet portrait -]: Lock body to disable scroll bubbling + @include break-to-device(tablet portrait) { + + // Lock body to viewport height (e.g. in search mode) + &[data-md-state="lock"] { + overflow: hidden; + + // Hide container on iOS, or the body will not be locked correctly + .ios & .md-container { + display: none; + } + } + } +} + +// Horizontal separators +hr { + display: block; + height: 0.1rem; + padding: 0; + border: 0; +} + +// Inline SVG container +.md-svg { + display: none; +} + +// Template-wide grid +.md-grid { + max-width: 122rem; + margin-right: auto; + margin-left: auto; +} + +// Prevent collapse of margin when setting margin on child element +.md-container, +.md-main { + overflow: auto; +} + +// Content wrapper - use display: table to make variable-height sticky footers +// work and fixed table-layout for IE, see http://bit.ly/2hZohXL +.md-container { + display: table; + width: 100%; + height: 100%; + padding-top: 4.8rem; + table-layout: fixed; +} + +// The main content should stretch to maximum height in the table +.md-main { + display: table-row; + height: 100%; + + // Increase top spacing of content area to give typography more room + &__inner { + height: 100%; + padding-top: 2.4rem + 0.6rem; + // Hack: induce margin-collapse, because otherwise the sidebar height is + // not calculated correctly and the overflow property on this element must + // be left in initial state for targetted link offsets to work properly + padding-bottom: 0.1rem; + } +} + +// ---------------------------------------------------------------------------- +// Rules: navigational elements +// ---------------------------------------------------------------------------- + +// Toggle checkbox +.md-toggle { + display: none; +} + +// Overlay below expanded drawer +.md-overlay { + position: fixed; + top: 0; + width: 0; + height: 0; + transition: + width 0s 0.25s, + height 0s 0.25s, + opacity 0.25s; + background-color: $md-color-black--light; + opacity: 0; + z-index: 3; + + // [tablet -]: Trigger overlay + @include break-to-device(tablet) { + + // Expanded drawer + #{$md-toggle__drawer--checked} & { + width: 100%; + height: 100%; + transition: + width 0s, + height 0s, + opacity 0.25s; + opacity: 1; + } + } +} + +// ---------------------------------------------------------------------------- +// Rules: flexible elements, implemented with table layout +// ---------------------------------------------------------------------------- + +// Flexible layout container +.md-flex { + display: table; + + // Flexible layout container cell/element + &__cell { + display: table-cell; + position: relative; + vertical-align: top; + + // Shrink to minimum width + &--shrink { + width: 0%; + } + + // Stretch to maximum width + &--stretch { + display: table; + width: 100%; + table-layout: fixed; + } + } + + // Apply ellipsis in case of overflowing text + &__ellipsis { + display: table-cell; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } +} + +// ---------------------------------------------------------------------------- +// Rules: skip link +// ---------------------------------------------------------------------------- + +// Skip link +.md-skip { + position: fixed; + width: 0.1rem; + height: 0.1rem; + margin: 1rem; + padding: 0.6rem 1rem; + clip: rect(0.1rem); + transform: translateY(0.8rem); + border-radius: 0.2rem; + background-color: $md-color-black; + color: $md-color-white; + font-size: ms(-1); + opacity: 0; + overflow: hidden; + + // Show skip link on focus + &:focus { + width: auto; + height: auto; + clip: auto; + transform: translateX(0); + transition: + transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), + opacity 0.175s 0.075s; + opacity: 1; + z-index: 10; + } +} + +// ---------------------------------------------------------------------------- +// Rules: print styles +// ---------------------------------------------------------------------------- + +// Add margins to page +@page { + margin: 25mm; +} diff --git a/site/assets/stylesheets/layout/_clipboard.scss b/site/assets/stylesheets/layout/_clipboard.scss new file mode 100644 index 000000000..c2d84f38f --- /dev/null +++ b/site/assets/stylesheets/layout/_clipboard.scss @@ -0,0 +1,117 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Copy to clipboard +.md-clipboard { + position: absolute; + top: 0.6rem; + right: 0.6rem; + width: 2.8rem; + height: 2.8rem; + border-radius: 0.2rem; + font-size: 1.6rem; + cursor: pointer; + z-index: 1; + // Hack: put everything on the GPU to omit flickering + backface-visibility: hidden; + + // Hide for print + @media print { + display: none; + } + + // Icon + &::before { + @extend %md-icon; + + transition: + color 0.25s, + opacity 0.25s; + color: $md-color-black--lightest; + content: "\E14D"; // content_copy + + // Show on container hover + pre:hover &, + .codehilite:hover & { + color: $md-color-black--light; + } + } + + // Focused or hovered icon + &:focus::before, + &:hover::before { + color: $md-color-accent; + } + + // Message + &__message { + display: block; + position: absolute; + top: 0; + right: 3.4rem; + padding: 0.6rem 1rem; + transform: translateX(0.8rem); + transition: + transform 0.25s cubic-bezier(0.9, 0.1, 0.9, 0), + opacity 0.175s; + border-radius: 0.2rem; + background-color: $md-color-black--light; + color: $md-color-white; + font-size: ms(-1); + white-space: nowrap; + opacity: 0; + pointer-events: none; + + // Active message + &--active { + transform: translateX(0); + transition: + transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), + opacity 0.175s 0.075s; + opacity: 1; + pointer-events: initial; + } + + // Inject content from ARIA label + &::before { + content: attr(aria-label); + } + + // Paint a nice speech bubble + &::after { + display: block; + position: absolute; + top: 50%; + right: -0.4rem; + width: 0; + margin-top: -0.4rem; + border-width: 0.4rem 0 0.4rem 0.4rem; + border-style: solid; + border-color: transparent $md-color-black--light; + content: ""; + } + } +} diff --git a/site/assets/stylesheets/layout/_content.scss b/site/assets/stylesheets/layout/_content.scss new file mode 100644 index 000000000..61e9fb8e8 --- /dev/null +++ b/site/assets/stylesheets/layout/_content.scss @@ -0,0 +1,95 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Content container +.md-content { + + // [tablet landscape +]: Add space for table of contents + @include break-from-device(tablet landscape) { + margin-right: 24.2rem; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: initial; + margin-left: 24.2rem; + } + } + + // [screen +]: Add space for table of contents + @include break-from-device(screen) { + margin-left: 24.2rem; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 24.2rem; + } + } + + // Define spacing + &__inner { + margin: 0 1.6rem 2.4rem; + padding-top: 1.2rem; + + // [screen +]: Increase horizontal spacing + @include break-from-device(screen) { + margin-right: 2.4rem; + margin-left: 2.4rem; + } + + // Hack: add pseudo element for spacing, as the overflow of the content + // container may not be hidden due to an imminent offset error on targets + &::before { + display: block; + height: 0.8rem; + content: ""; + } + + // Hack: remove bottom spacing of last element, due to margin collapse + > :last-child { + margin-bottom: 0; + } + } + + // Icons + &__icon { + @extend %md-icon__button; + + position: relative; + margin: 0.8rem 0; + padding: 0; + float: right; + + // Override default link color for icons + .md-typeset & { + color: $md-color-black--lighter; + } + + // Hide for print + @media print { + display: none; + } + } +} diff --git a/site/assets/stylesheets/layout/_footer.scss b/site/assets/stylesheets/layout/_footer.scss new file mode 100644 index 000000000..2446d81f2 --- /dev/null +++ b/site/assets/stylesheets/layout/_footer.scss @@ -0,0 +1,199 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Application footer +.md-footer { + + // Hide for print + @media print { + display: none; + } +} + +// Navigation within footer +.md-footer-nav { + background-color: $md-color-black; + color: $md-color-white; + + // Set spacing + &__inner { + padding: 0.4rem; + overflow: auto; + } + + // Links to previous and next page + &__link { + padding-top: 2.8rem; + padding-bottom: 0.8rem; + transition: opacity 0.25s; + + // [tablet +]: Set proportional width + @include break-from-device(tablet) { + width: 50%; + } + + // Hovered link + &:hover { + opacity: 0.7; + } + + // Link to previous page + &--prev { + width: 25%; + float: left; + + // Adjust for RTL languages + [dir="rtl"] & { + float: right; + } + + // Title + .md-footer-nav__title { + + // [mobile -]: Hide title for previous page + @include break-to-device(mobile) { + display: none; + } + } + } + + // Link to next page + &--next { + width: 75%; + float: right; + text-align: right; + + // Adjust for RTL languages + [dir="rtl"] & { + float: left; + text-align: left; + } + } + } + + // Icon buttons + &__button { + @extend %md-icon__button; + + transition: background 0.25s; + } + + // Link title - set line height to match icon for correct alignment + &__title { + position: relative; + padding: 0 2rem; + font-size: 1.8rem; + line-height: 4.8rem; + } + + // Link direction + &__direction { + position: absolute; + right: 0; + left: 0; + margin-top: -2rem; + padding: 0 2rem; + color: $md-color-white--light; + font-size: 1.5rem; + } +} + +// Non-navigational information +.md-footer-meta { + background-color: opacify($md-color-black, 0.025); + + // Set spacing + &__inner { + padding: 0.4rem; + overflow: auto; + } + + // Use a decent color for non-hovered links and ensure specificity + html &.md-typeset a { + color: $md-color-white--light; + + // Focused or hovered link + &:focus, + &:hover { + color: $md-color-white; + } + } +} + +// Copyright and theme information +.md-footer-copyright { + margin: 0 1.2rem; + padding: 0.8rem 0; + color: $md-color-white--lighter; + font-size: ms(-1); + + // [tablet portrait +]: Show next to social media links + @include break-from-device(tablet portrait) { + max-width: 75%; + float: left; + + // Adjust for RTL languages + [dir="rtl"] & { + float: right; + } + } + + // Highlight copyright information + &__highlight { + color: $md-color-white--light; + } +} + +// Social media links +.md-footer-social { + margin: 0 0.8rem; + padding: 0.4rem 0 1.2rem; + + // [tablet portrait +]: Show next to copyright information + @include break-from-device(tablet portrait) { + padding: 1.2rem 0; + float: right; + + // Adjust for RTL languages + [dir="rtl"] & { + float: left; + } + } + + // Link with icon + &__link { + display: inline-block; + width: 3.2rem; + height: 3.2rem; + font-size: 1.6rem; + text-align: center; + + // Adjust line-height to match height for correct alignment + &::before { + line-height: 1.9; + } + } +} diff --git a/site/assets/stylesheets/layout/_header.scss b/site/assets/stylesheets/layout/_header.scss new file mode 100644 index 000000000..79333359e --- /dev/null +++ b/site/assets/stylesheets/layout/_header.scss @@ -0,0 +1,216 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Application header (stays always on top) +.md-header { + position: fixed; + top: 0; + right: 0; + left: 0; + height: 4.8rem; + transition: + background-color 0.25s, + color 0.25s; + background-color: $md-color-primary; + color: $md-color-white; + box-shadow: none; + z-index: 2; + // Hack: putting the header on the GPU avoids unnecessary repaints + backface-visibility: hidden; + + // Always show shadow, in case JavaScript is not available + .no-js & { + transition: none; + box-shadow: none; + } + + // Show and animate shadow + &[data-md-state="shadow"] { + transition: + background-color 0.25s, + color 0.25s, + box-shadow 0.25s; + box-shadow: + 0 0 0.4rem rgba(0, 0, 0, 0.1), + 0 0.4rem 0.8rem rgba(0, 0, 0, 0.2); + } + + // Hide for print + @media print { + display: none; + } +} + +// Navigation within header +.md-header-nav { + padding: 0 0.4rem; + + // Icon buttons + &__button { + @extend %md-icon__button; + + position: relative; + transition: opacity 0.25s; + z-index: 1; + + // Hovered icon + &:hover { + opacity: 0.7; + } + + // Set correct display on image or icon + &.md-logo * { + display: block; + } + + // Hide search icon, if JavaScript is not available. + .no-js &.md-icon--search { + display: none; + } + + // [tablet landscape +]: Hide the search icon + @include break-from-device(tablet landscape) { + + // Search icon + &.md-icon--search { + display: none; + } + } + + // [tablet -]: Hide the home icon or logo + @include break-to-device(tablet) { + + // Home icon or logo + &.md-icon--home, + &.md-logo { + display: none; + } + } + + // [screen +]: Hide the menu icon + @include break-from-device(screen) { + + // Menu icon + &.md-icon--menu { + display: none; + } + } + } + + // Header topics + &__topic { + display: block; + position: absolute; + transition: + transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), + opacity 0.15s; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + + // Page title + & + & { + transform: translateX(2.5rem); + transition: + transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1), + opacity 0.15s; + opacity: 0; + z-index: -1; + pointer-events: none; + + // Adjust for RTL languages + [dir="rtl"] & { + transform: translateX(-2.5rem); + } + } + + // Induce ellipsis, if no JavaScript is available + .no-js & { + position: initial; + } + + // Hide page title as it is invisible anyway and will overflow the header + .no-js & + & { + display: none; + } + } + + // Header title - set line height to match icon for correct alignment + &__title { + padding: 0 2rem; + font-size: 1.8rem; + line-height: 4.8rem; + + // Show page title + &[data-md-state="active"] .md-header-nav__topic { + transform: translateX(-2.5rem); + transition: + transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1), + opacity 0.15s; + opacity: 0; + z-index: -1; + pointer-events: none; + + // Adjust for RTL languages + [dir="rtl"] & { + transform: translateX(2.5rem); + } + + // Page title + & + .md-header-nav__topic { + transform: translateX(0); + transition: + transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), + opacity 0.15s; + opacity: 1; + z-index: 0; + pointer-events: initial; + } + } + } + + // Repository containing source + &__source { + display: none; + + // [tablet landscape +]: Show the reposistory from tablet + @include break-from-device(tablet landscape) { + display: block; + width: 23rem; + max-width: 23rem; + margin-left: 2.8rem; + padding-right: 1.2rem; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 2.8rem; + margin-left: initial; + padding-right: initial; + padding-left: 1.2rem; + } + } + } +} diff --git a/site/assets/stylesheets/layout/_hero.scss b/site/assets/stylesheets/layout/_hero.scss new file mode 100644 index 000000000..d8d588b55 --- /dev/null +++ b/site/assets/stylesheets/layout/_hero.scss @@ -0,0 +1,65 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Hero teaser +.md-hero { + transition: background 0.25s; + background-color: $md-color-primary; + color: $md-color-white; + font-size: ms(1); + overflow: hidden; + + // Inner wrapper + &__inner { + margin-top: 2rem; + padding: 1.6rem 1.6rem 0.8rem; + transition: + transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), + opacity 0.25s; + transition-delay: 0.1s; + + // [tablet -]: Compensate for missing tabs + @include break-to-device(tablet) { + margin-top: 4.8rem; + margin-bottom: 2.4rem; + } + + // Fade-out tabs background upon scrolling + [data-md-state="hidden"] & { + pointer-events: none; + transform: translateY(1.25rem); + transition: + transform 0s 0.4s, + opacity 0.1s 0s; + opacity: 0; + } + + // Adjust bottom spacing if there are no tabs + .md-hero--expand & { + margin-bottom: 2.4rem; + } + } +} diff --git a/site/assets/stylesheets/layout/_nav.scss b/site/assets/stylesheets/layout/_nav.scss new file mode 100644 index 000000000..969a45622 --- /dev/null +++ b/site/assets/stylesheets/layout/_nav.scss @@ -0,0 +1,525 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Navigation container +.md-nav { + font-size: 1.4rem; + line-height: 1.3; + + // List title + &__title { + display: block; + padding: 0 1.2rem; + font-weight: 700; + text-overflow: ellipsis; + overflow: hidden; + + // Icon, hidden by default + &::before { + @extend %md-icon, %md-icon__button; + + display: none; + content: "\E5C4"; // arrow_back + + // Adjust for RTL languages + [dir="rtl"] & { + content: "\E5C8"; // arrow_forward + } + } + + // Hide button by default + .md-nav__button { + display: none; + } + } + + // List of items + &__list { + margin: 0; + padding: 0; + list-style: none; + } + + // List item + &__item { + padding: 0 1.2rem; + + // Add bottom spacing to last item + &:last-child { + padding-bottom: 1.2rem; + } + + // 2nd+ level items + & & { + padding-right: 0; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 1.2rem; + padding-left: 0; + } + + // Remove bottom spacing for nested items + &:last-child { + padding-bottom: 0; + } + } + } + + // Button with logo + &__button { + @extend %md-icon, %md-icon__button; + + // Stretch image + img { + width: 100%; + height: auto; + } + } + + // Link inside item + &__link { + display: block; + margin-top: 0.625em; + transition: color 0.125s; + text-overflow: ellipsis; + cursor: pointer; + overflow: hidden; + + // Icon + &::after { + @extend %md-icon; + + // Item contains a nested list + .md-nav__item--nested > & { + content: "\E313"; // keyboard_arrow_down + } + } + + // Hide link to table of contents by default - this will only match the + // table of contents inside the drawer below and including tablet portrait + html &[for="__toc"] { + display: none; + + // Hide table of contents by default + & ~ .md-nav { + display: none; + } + + // Hide icon for current item + + .md-nav__link::after { + display: none; + } + } + + // Blurred link + &[data-md-state="blur"] { + color: $md-color-black--light; + } + + // Active link + &:active, + &--active { + color: $md-color-primary; + } + + // Reset active color for nested list titles + .md-nav__item--nested > & { + color: inherit; + } + + // Focused or hovered link + &:focus, + &:hover { + color: $md-color-accent; + } + } + + // Repository containing source + &__source { + display: none; + } + + // [tablet -]: Layered navigation + @include break-to-device(tablet) { + background-color: $md-color-white; + + // Stretch primary navigation to drawer + &--primary, + &--primary .md-nav { + display: flex; + position: absolute; + top: 0; + right: 0; + left: 0; + flex-direction: column; + height: 100%; + z-index: 1; + } + + // Adjust styles for primary navigation + &--primary { + + // List title and item + .md-nav__title, + .md-nav__item { + font-size: 1.6rem; + line-height: 1.5; + } + + // List title - higher specificity is necessary to ensure that the title + // inside the drawer is always styled accordingly + html & .md-nav__title { + position: relative; + height: 11.2rem; + padding: 6rem 1.6rem 0.4rem; + background-color: $md-color-black--lightest; + color: $md-color-black--light; + font-weight: 400; + line-height: 4.8rem; + white-space: nowrap; + cursor: pointer; + + // Icon + &::before { + display: block; + position: absolute; + top: 0.4rem; + left: 0.4rem; + width: 4rem; + height: 4rem; + color: $md-color-black--light; + } + + // Main lists + ~ .md-nav__list { + background-color: $md-color-white; + box-shadow: 0 0.1rem 0 $md-color-black--lightest inset; + + // Remove border for first list item + & > .md-nav__item:first-child { + border-top: 0; + } + } + + // Site title in main navigation + &--site { + position: relative; + background-color: $md-color-primary; + color: $md-color-white; + + // Site logo + .md-nav__button { + display: block; + position: absolute; + top: 0.4rem; + left: 0.4rem; + width: 6.4rem; + height: 6.4rem; + font-size: 4.8rem; + } + + // Hide back arrow icon + &::before { + display: none; + } + } + } + + // Adjust for RTL languages + html [dir="rtl"] & .md-nav__title { + + // Icon + &::before { + right: 0.4rem; + left: initial; + } + + // Site title in main navigation + &--site .md-nav__button { + right: 0.4rem; + left: initial; + } + } + + // List of items + .md-nav__list { + flex: 1; + overflow-y: auto; + } + + // List item + .md-nav__item { + padding: 0; + border-top: 0.1rem solid $md-color-black--lightest; + + // Adjust for RTL languages + [dir="rtl"] & { + padding: 0; + } + + // Increase spacing to account for icon + &--nested > .md-nav__link { + padding-right: 4.8rem; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 1.6rem; + padding-left: 4.8rem; + } + + // Replace icon with right arrow + &::after { + content: "\E315"; // keyboard_arrow_right + + // Adjust for RTL languages + [dir="rtl"] & { + content: "\E314"; // keyboard_arrow_left + } + } + } + } + + // Link inside item + .md-nav__link { + position: relative; + margin-top: 0; + padding: 1.2rem 1.6rem; + + // Rotate icon + &::after { + position: absolute; + top: 50%; + right: 1.2rem; + margin-top: -1.2rem; + color: inherit; + font-size: 2.4rem; + + // Adjust for RTL languages + [dir="rtl"] & { + right: initial; + left: 1.2rem; + } + } + } + + // Table of contents inside navigation + .md-nav--secondary { + + // Set links to static to avoid unnecessary layering + .md-nav__link { + position: static; + } + + // Set nested navigation for table of contents to static + .md-nav { + position: static; + background-color: transparent; + + // 3rd level link + .md-nav__link { + padding-left: 2.8rem; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 2.8rem; + padding-left: initial; + } + } + + // 4th level link + .md-nav .md-nav__link { + padding-left: 4rem; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 4rem; + padding-left: initial; + } + } + + // 5th level link + .md-nav .md-nav .md-nav__link { + padding-left: 5.2rem; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 5.2rem; + padding-left: initial; + } + } + + // 6th level link + .md-nav .md-nav .md-nav .md-nav__link { + padding-left: 6.4rem; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 6.4rem; + padding-left: initial; + } + } + } + } + } + + // Hide nested navigation by default + .md-nav__toggle ~ & { + display: flex; + transform: translateX(100%); + transition: + transform 0.25s cubic-bezier(0.8, 0, 0.6, 1), + opacity 0.125s 0.05s; + opacity: 0; + + // Adjust for RTL languages + [dir="rtl"] & { + transform: translateX(-100%); + } + + // Just hide navigation, if browser doesn't supports 3D transforms + .no-csstransforms3d & { + display: none; + } + } + + // Expand nested navigation, if toggle is checked + .md-nav__toggle:checked ~ & { + transform: translateX(0); + transition: + transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), + opacity 0.125s 0.125s; + opacity: 1; + + // Just show navigation, if browser doesn't supports 3D transforms + .no-csstransforms3d & { + display: flex; + } + } + } + + // [tablet portrait -]: Show table of contents in drawer + @include break-to-device(tablet portrait) { + + // Show link to table of contents - higher specificity is necessary to + // display the table of contents inside the drawer + html &__link[for="__toc"] { + display: block; + padding-right: 4.8rem; + + // Unrotate icon for table of contents + &::after { + color: inherit; + content: "\E8DE"; // toc + } + + // Hide link to current item + + .md-nav__link { + display: none; + } + + // Show table of contents + & ~ .md-nav { + display: flex; + } + } + + // Adjust for RTL languages + html [dir="rtl"] &__link { + padding-right: 1.6rem; + padding-left: 4.8rem; + } + + // Repository containing source + &__source { + display: block; + padding: 0 0.4rem; + background-color: mix($md-color-primary, $md-color-black, 75%); + color: $md-color-white; + } + } + + // [screen +]: Tree-like navigation + @include break-from-device(screen) { + + // Animation is only possible if JavaScript is available, as the max-height + // property must be calculated before transitioning + &[data-md-state="animate"] { + transition: max-height 0.25s cubic-bezier(0.86, 0, 0.07, 1); + } + + // Hide nested navigation by default + .md-nav__toggle ~ & { + max-height: 0; + overflow: hidden; + + // Just hide links for accessibility if JavaScript is not available + .no-js & { + display: none; + } + } + + // Expand nested navigation, if toggle is checked + .md-nav__toggle:checked ~ &, + &[data-md-state="expand"] { + max-height: 100%; + + // Just show for accessibility links if JavaScript is not available + .no-js & { + display: block; + } + } + + // Hide titles for nested navigation + &__item--nested > .md-nav > &__title { + display: none; + } + + // Link inside item - ideally the link display method would be set to + // inline on screen, but this doesn't work with text ellipsis + &__link { + + // Item contains a nested list + .md-nav__item--nested > &::after { + display: inline-block; + transform-origin: 0.45em 0.45em; + transform-style: preserve-3d; + vertical-align: -0.125em; + + // Only animate icon when JavaScript is available, as the height can + // not be animated anyway, and better no fun than half the fun + .js & { + transition: transform 0.4s; + } + } + + // Rotate icon for expanded lists + .md-nav__item--nested .md-nav__toggle:checked ~ &::after { + transform: rotateX(180deg); + } + } + } +} diff --git a/site/assets/stylesheets/layout/_search.scss b/site/assets/stylesheets/layout/_search.scss new file mode 100644 index 000000000..f8ed05b79 --- /dev/null +++ b/site/assets/stylesheets/layout/_search.scss @@ -0,0 +1,622 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Variables +// ---------------------------------------------------------------------------- + +// Active (toggled) search +$md-toggle__search--checked: + "[data-md-toggle=\"search\"]:checked ~ .md-header"; + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Search container +.md-search { + + // Hide search, if JavaScript is not available. + .no-js & { + display: none; + } + + // [tablet landscape +]: Header-embedded search + @include break-from-device(tablet landscape) { + padding: 0.4rem; + } + + // Search modal overlay + &__overlay { + opacity: 0; + z-index: 1; + + // [tablet portrait -]: Full-screen search bar + @include break-to-device(tablet portrait) { + position: absolute; + top: 0.4rem; + left: 0.4rem; + width: 3.6rem; + height: 3.6rem; + transform-origin: center; + transition: + transform 0.3s 0.1s, + opacity 0.2s 0.2s; + border-radius: 2rem; + background-color: $md-color-white; + overflow: hidden; + pointer-events: none; + + // Adjust for RTL languages + [dir="rtl"] & { + right: 0.4rem; + left: initial; + } + + // Expanded overlay + #{$md-toggle__search--checked} & { + transition: + transform 0.4s, + opacity 0.1s; + opacity: 1; + } + } + + // Set scale factors + #{$md-toggle__search--checked} & { + + // [mobile portrait -]: Scale up 45 times + @include break-to-device(mobile portrait) { + transform: scale(45); + } + + // [mobile landscape]: Scale up 60 times + @include break-at-device(mobile landscape) { + transform: scale(60); + } + + // [tablet portrait]: Scale up 75 times + @include break-at-device(tablet portrait) { + transform: scale(75); + } + } + + // [tablet landscape +]: Overlay for better focus on search + @include break-from-device(tablet landscape) { + position: fixed; + top: 0; + left: 0; + width: 0; + height: 0; + transition: + width 0s 0.25s, + height 0s 0.25s, + opacity 0.25s; + background-color: $md-color-black--light; + cursor: pointer; + + // Adjust for RTL languages + [dir="rtl"] & { + right: 0; + left: initial; + } + + // Expanded overlay + #{$md-toggle__search--checked} & { + width: 100%; + height: 100%; + transition: + width 0s, + height 0s, + opacity 0.25s; + opacity: 1; + } + } + } + + // Search modal wrapper + &__inner { + + // [tablet portrait -]: Put search modal off-canvas by default + @include break-to-device(tablet portrait) { + position: fixed; + top: 0; + left: 100%; + width: 100%; + height: 100%; + transform: translateX(5%); + transition: + right 0s 0.3s, + left 0s 0.3s, + transform 0.15s 0.15s cubic-bezier(0.4, 0, 0.2, 1), + opacity 0.15s 0.15s; + opacity: 0; + z-index: 2; + + // Active search modal + #{$md-toggle__search--checked} & { + left: 0; + transform: translateX(0); + transition: + right 0s 0s, + left 0s 0s, + transform 0.15s 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), + opacity 0.15s 0.15s; + opacity: 1; + + // Adjust for RTL languages + [dir="rtl"] & { + right: 0; + left: initial; + } + } + + // Adjust for RTL languages + html [dir="rtl"] & { + right: 100%; + left: initial; + transform: translateX(-5%); + } + } + + // [tablet landscape +]: Header-embedded search + @include break-from-device(tablet landscape) { + position: relative; + width: 23rem; + padding: 0.2rem 0; + float: right; + transition: width 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); + + // Adjust for RTL languages + [dir="rtl"] & { + float: left; + } + } + + // Set maximum width + #{$md-toggle__search--checked} & { + + // [tablet landscape]: Do not overlay title + @include break-at-device(tablet landscape) { + width: 46.8rem; + } + + // [screen +]: Match content width + @include break-from-device(screen) { + width: 68.8rem; + } + } + } + + // Search form + &__form { + position: relative; + + // [tablet landscape +]: Header-embedded search + @include break-from-device(tablet landscape) { + border-radius: 0.2rem; + } + } + + // Search input + &__input { + position: relative; + padding: 0 4.4rem 0 7.2rem; + text-overflow: ellipsis; + z-index: 2; + + // Adjust for RTL languages + [dir="rtl"] & { + padding: 0 7.2rem 0 4.4rem; + } + + // Transition on placeholder + &::placeholder { + transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); + } + + // Placeholder and icon color in active state + ~ .md-search__icon, + &::placeholder { + color: $md-color-black--light; + } + + // Remove the "x" rendered by Internet Explorer + &::-ms-clear { + display: none; + } + + // [tablet portrait -]: Full-screen search bar + @include break-to-device(tablet portrait) { + width: 100%; + height: 4.8rem; + font-size: 1.8rem; + } + + // [tablet landscape +]: Header-embedded search + @include break-from-device(tablet landscape) { + width: 100%; + height: 3.6rem; + padding-left: 4.4rem; + transition: + background-color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1), + color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); + border-radius: 0.2rem; + background-color: $md-color-black--lighter; + color: inherit; + font-size: ms(0); + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 4.4rem; + } + + // Icon color + + .md-search__icon { + color: inherit; + } + + // Placeholder color + &::placeholder { + color: $md-color-white--light; + } + + // Hovered search field + &:hover { + background-color: $md-color-white--lightest; + } + + // Set light background on active search field + #{$md-toggle__search--checked} & { + border-radius: 0.2rem 0.2rem 0 0; + background-color: $md-color-white; + color: $md-color-black; + text-overflow: none; + + // Placeholder and icon color in active state + + .md-search__icon, + &::placeholder { + color: $md-color-black--light; + } + } + } + } + + // Icons + &__icon { + position: absolute; + transition: + color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1), + opacity 0.25s; + font-size: $md-icon-size; + cursor: pointer; + z-index: 2; + + // Hovered icon + &:hover { + opacity: 0.7; + } + + // Search icon + &[for="__search"] { + top: 0.6rem; + left: 1rem; + + // Adjust for RTL languages + [dir="rtl"] & { + right: 1rem; + left: initial; + } + + // Set search icon on pseudo class, so it can be overridden for mobile + // and tablet when the search is rendered in an overlay + &::before { + content: "\E8B6"; // search + } + + // [tablet portrait -]: Full-screen search bar + @include break-to-device(tablet portrait) { + top: 1.2rem; + left: 1.6rem; + + // Show back arrow instead of search icon + &[for="__search"]::before { + content: "\E5C4"; // arrow_back + + // Adjust for RTL languages + [dir="rtl"] & { + content: "\E5C8"; // arrow_forward + } + } + } + } + + // Reset button + &[type="reset"] { + top: 0.6rem; + right: 1rem; + transform: scale(0.125); + transition: + transform 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), + opacity 0.15s; + opacity: 0; + + // Adjust for RTL languages + [dir="rtl"] & { + right: initial; + left: 1rem; + } + + // [tablet portrait -]: Full-screen search bar + @include break-to-device(tablet portrait) { + top: 1.2rem; + right: 1.6rem; + } + + // Show reset button if search is active and input non-empty + #{$md-toggle__search--checked} .md-search__input:valid ~ & { + transform: scale(1); + opacity: 1; + + // Hovered icon + &:hover { + opacity: 0.7; + } + } + } + } + + // Search output container + &__output { + position: absolute; + width: 100%; + border-radius: 0 0 0.2rem 0.2rem; + overflow: hidden; + z-index: 1; + + // [tablet portrait -]: Full-screen search bar + @include break-to-device(tablet portrait) { + top: 4.8rem; + bottom: 0; + } + + // [tablet landscape +]: Header-embedded search + @include break-from-device(tablet landscape) { + top: 3.8rem; + transition: opacity 0.4s; + opacity: 0; + + // Show search output in active state + #{$md-toggle__search--checked} & { + @include z-depth(6); + + opacity: 1; + } + } + } + + // Wrapper for scrolling on overflow + &__scrollwrap { + height: 100%; + background-color: $md-color-white; + box-shadow: 0 0.1rem 0 $md-color-black--lightest inset; + overflow-y: auto; + -webkit-overflow-scrolling: touch; + + // [tablet landscape]: Set absolute width to omit unnecessary reflow + @include break-at-device(tablet landscape) { + width: 46.8rem; + } + + // [screen +]: Set absolute width to omit unnecessary reflow + @include break-from-device(screen) { + width: 68.8rem; + } + + // [tablet landscape +]: Limit height to viewport + @include break-from-device(tablet landscape) { + max-height: 0; + + // Expand in active state + #{$md-toggle__search--checked} & { + max-height: 75vh; + } + + // Override native scrollbar styles + &::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; + } + + // Style scrollbar thumb + &::-webkit-scrollbar-thumb { + background-color: $md-color-black--lighter; + + // Hovered scrollbar thumb + &:hover { + background-color: $md-color-accent; + } + } + } + } +} + +// Search result +.md-search-result { + color: $md-color-black; + word-break: break-word; + + // Search metadata + &__meta { + padding: 0 1.6rem; + background-color: $md-color-black--lightest; + color: $md-color-black--light; + font-size: ms(-1); + line-height: 3.6rem; + + // [tablet landscape +]: Increase left indent + @include break-from-device(tablet landscape) { + padding-left: 4.4rem; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 4.4rem; + padding-left: initial; + } + } + } + + // List of items + &__list { + margin: 0; + padding: 0; + border-top: 0.1rem solid $md-color-black--lightest; + list-style: none; + } + + // List item + &__item { + box-shadow: 0 -0.1rem 0 $md-color-black--lightest; + } + + // Link inside item + &__link { + display: block; + transition: background 0.25s; + outline: 0; + overflow: hidden; + + // Active or hovered link + &[data-md-state="active"], + &:hover { + background-color: transparentize($md-color-accent, 0.9); + + // Slightly transparent icon + .md-search-result__article::before { + opacity: 0.7; + } + } + + // Add a little spacing on the teaser of the last link + &:last-child .md-search-result__teaser { + margin-bottom: 1.2rem; + } + } + + // Article - document or section + &__article { + position: relative; + padding: 0 1.6rem; + overflow: auto; + + // [tablet landscape +]: Increase left indent + @include break-from-device(tablet landscape) { + padding-left: 4.4rem; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 4.4rem; + padding-left: 1.6rem; + } + } + + // Document + &--document { + + // Icon + &::before { + @extend %md-icon, %md-icon__button; + + position: absolute; + left: 0; + margin: 0.2rem; + transition: opacity 0.25s; + color: $md-color-black--light; + content: "\E880"; // find_in_page + + // Adjust for RTL languages + [dir="rtl"] & { + right: 0; + left: initial; + } + + // [tablet portrait -]: Hide page icon + @include break-to-device(tablet portrait) { + display: none; + } + } + + // Title + .md-search-result__title { + margin: 1.1rem 0; + font-size: ms(0); + font-weight: 400; + line-height: 1.4; + } + } + } + + // Title + &__title { + margin: 0.5em 0; + font-size: ms(-1); + font-weight: 700; + line-height: 1.4; + } + + // stylelint-disable value-no-vendor-prefix, property-no-vendor-prefix + + // Teaser + &__teaser { + display: -webkit-box; + max-height: 3.3rem; + margin: 0.5em 0; + color: $md-color-black--light; + font-size: ms(-1); + line-height: 1.4; + text-overflow: ellipsis; + overflow: hidden; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + + // [mobile -]: Increase number of lines + @include break-to-device(mobile) { + max-height: 5rem; + -webkit-line-clamp: 3; + } + + // [tablet landscape]: Increase number of lines + @include break-at-device(tablet landscape) { + max-height: 5rem; + -webkit-line-clamp: 3; + } + } + + // stylelint-enable value-no-vendor-prefix, property-no-vendor-prefix + + // Search term highlighting + em { + font-style: normal; + font-weight: 700; + text-decoration: underline; + } +} diff --git a/site/assets/stylesheets/layout/_sidebar.scss b/site/assets/stylesheets/layout/_sidebar.scss new file mode 100644 index 000000000..262323e63 --- /dev/null +++ b/site/assets/stylesheets/layout/_sidebar.scss @@ -0,0 +1,174 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Variables +// ---------------------------------------------------------------------------- + +// Active (toggled) drawer +$md-toggle__drawer--checked: + "[data-md-toggle=\"drawer\"]:checked ~ .md-container"; + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Sidebar container +.md-sidebar { + position: absolute; + width: 24.2rem; + padding: 2.4rem 0; + overflow: hidden; + + // Hide for print + @media print { + display: none; + } + + // Lock sidebar to container height (account for fixed header) + &[data-md-state="lock"] { + position: fixed; + top: 4.8rem; + } + + // [tablet -]: Convert navigation to drawer + @include break-to-device(tablet) { + + // Render primary sidebar as a slideout container + &--primary { + position: fixed; + top: 0; + left: -24.2rem; + width: 24.2rem; + height: 100%; + transform: translateX(0); + transition: + transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), + box-shadow 0.25s; + background-color: $md-color-white; + z-index: 3; + + // Adjust for RTL languages + [dir="rtl"] & { + right: -24.2rem; + left: initial; + } + + // Just hide drawer, if browser doesn't support 3D transforms + .no-csstransforms3d & { + display: none; + } + + // Expanded drawer + #{$md-toggle__drawer--checked} & { + @include z-depth(8); + + transform: translateX(24.2rem); + + // Adjust for RTL languages + [dir="rtl"] & { + transform: translateX(-24.2rem); + } + + // Just show drawer, if browser doesn't support 3D transforms + .no-csstransforms3d & { + display: block; + } + } + + // Hide overflow for nested navigation + .md-sidebar__scrollwrap { + overflow: hidden; + } + } + } + + // Secondary sidebar with table of contents + &--secondary { + display: none; + + // [tablet landscape +]: Show table of contents next to body copy + @include break-from-device(tablet landscape) { + display: block; + margin-left: 100%; + transform: translate(-100%, 0); + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 100%; + margin-left: initial; + transform: translate(100%, 0); + } + } + + // [screen +]: Limit to grid + @include break-from-device(screen) { + margin-left: 122rem; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 122rem; + margin-left: initial; + } + } + } + + // Wrapper for scrolling on overflow + &__scrollwrap { + max-height: 100%; + margin: 0 0.4rem; + overflow-y: auto; + // Hack: putting the scroll wrapper on the GPU massively reduces jitter + // when locking the sidebars into place + backface-visibility: hidden; + + // [tablet -]: Adjust margins + @include break-to-device(tablet) { + + // Stretch scrollwrap for primary sidebar + .md-sidebar--primary & { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + margin: 0; + } + } + + // Override native scrollbar styles + &::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; + } + + // Style scrollbar thumb + &::-webkit-scrollbar-thumb { + background-color: $md-color-black--lighter; + + // Hovered scrollbar thumb + &:hover { + background-color: $md-color-accent; + } + } + } +} diff --git a/site/assets/stylesheets/layout/_source.scss b/site/assets/stylesheets/layout/_source.scss new file mode 100644 index 000000000..91ef7ca82 --- /dev/null +++ b/site/assets/stylesheets/layout/_source.scss @@ -0,0 +1,234 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Keyframes +// ---------------------------------------------------------------------------- + +// Show source facts +@keyframes md-source__facts--done { + 0% { + height: 0; + } + + 100% { + height: 1.3rem; + } +} + +// Show source fact +@keyframes md-source__fact--done { + 0% { + transform: translateY(100%); + opacity: 0; + } + + 50% { + opacity: 0; + } + + 100% { + transform: translateY(0%); + opacity: 1; + } +} + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Source container +.md-source { + display: block; + padding-right: 1.2rem; + transition: opacity 0.25s; + font-size: 1.3rem; + line-height: 1.2; + white-space: nowrap; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: initial; + padding-left: 1.2rem; + } + + // Hovered source container + &:hover { + opacity: 0.7; + } + + // Necessary for vertical alignment + &::after { + display: inline-block; + height: 4.8rem; + content: ""; + vertical-align: middle; + } + + // Repository platform icon + &__icon { + display: inline-block; + width: 4.8rem; + height: 4.8rem; + content: ""; + vertical-align: middle; + + // Align SVG, do not scale, as this will incur strange formatting bugs + // in Internet Explorer and Edge + svg { + width: 2.4rem; + height: 2.4rem; + margin-top: 1.2rem; + margin-left: 1.2rem; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 1.2rem; + margin-left: initial; + } + } + + // Correct alignment, if icon is present + + .md-source__repository { + margin-left: -4.4rem; + padding-left: 4rem; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: -4.4rem; + margin-left: initial; + padding-right: 4rem; + padding-left: initial; + } + } + } + + // Repository name + &__repository { + display: inline-block; + max-width: 100%; + margin-left: 1.2rem; + font-weight: 700; + text-overflow: ellipsis; + overflow: hidden; + vertical-align: middle; + } + + // Source facts (statistics etc.) + &__facts { + margin: 0; + padding: 0; + font-size: 1.1rem; + font-weight: 700; + list-style-type: none; + opacity: 0.75; + overflow: hidden; + + // Show after the data was loaded + [data-md-state="done"] & { + animation: md-source__facts--done 0.25s ease-in; + } + } + + // Fact + &__fact { + float: left; + + // Adjust for RTL languages + [dir="rtl"] & { + float: right; + } + + // Show after the data was loaded + [data-md-state="done"] & { + animation: md-source__fact--done 0.4s ease-out; + } + + // Middle dot before fact + &::before { + margin: 0 0.2rem; + content: "\00B7"; + } + + // Remove middle dot on first fact + &:first-child::before { + display: none; + } + } +} + +// Source file +.md-source-file { + display: inline-block; + margin: 1em 0.5em 1em 0; + padding-right: 0.5rem; + border-radius: 0.2rem; + background-color: $md-color-black--lightest; + font-size: ms(-1); + list-style-type: none; + cursor: pointer; + overflow: hidden; + + // Icon + &::before { + @extend %md-icon; + + display: inline-block; + margin-right: 0.5rem; + padding: 0.5rem; + background-color: $md-color-black--lighter; + color: $md-color-white; + font-size: ms(0); + content: "\E86F"; // code + vertical-align: middle; + } + + // Some properties need to be set with higher specificity due to the default + // styling of text links inside typesetted content + html & { + transition: + background 0.4s, + color 0.4s, + box-shadow 0.4s cubic-bezier(0.4, 0, 0.2, 1); + + // Icon + &::before { + transition: inherit; + } + } + + // Color needs even higher specifity because custom color palettes are set + // using the body and override text links inside typesetted content + html body .md-typeset & { + color: $md-color-black--light; + } + + // Hovered source file + &:hover { + @include z-depth-focus; + + // Icon + &::before { + background-color: $md-color-accent; + } + } +} diff --git a/site/assets/stylesheets/layout/_tabs.scss b/site/assets/stylesheets/layout/_tabs.scss new file mode 100644 index 000000000..63aab9fe8 --- /dev/null +++ b/site/assets/stylesheets/layout/_tabs.scss @@ -0,0 +1,178 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Tabs with outline +.md-tabs { + width: 100%; + transition: background 0.25s; + background-color: $md-color-primary; + color: $md-color-white; + overflow: auto; + + // [tablet -]: Hide tabs for tablet and below, as they don't make any sense + @include break-to-device(tablet) { + display: none; + } + + // Hide for print + @media print { + display: none; + } + + // List of items + &__list { + margin: 0; + margin-left: 0.4rem; + padding: 0; + list-style: none; + white-space: nowrap; + } + + // List item + &__item { + display: inline-block; + height: 4.8rem; + padding-right: 1.2rem; + padding-left: 1.2rem; + } + + // Link inside item - could be defined as block elements and aligned via + // line height, but this would imply more repaints when scrolling + &__link { + display: block; + margin-top: 1.6rem; + transition: + transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), + opacity 0.25s; + font-size: 1.4rem; + opacity: 0.7; + + // Active or hovered link + &--active, + &:hover { + color: inherit; + opacity: 1; + } + + // Delay transitions by a small amount + @for $i from 2 through 16 { + .md-tabs__item:nth-child(#{$i}) & { + transition-delay: 0.02s * ($i - 1); + } + } + } + + // Fade-out tabs background upon scrolling + &[data-md-state="hidden"] { + pointer-events: none; + + // Hide tabs upon scrolling - disable transition to minimizes repaints whilte + // scrolling down, while scrolling up seems to be okay + .md-tabs__link { + transform: translateY(50%); + transition: + color 0.25s, + transform 0s 0.4s, + opacity 0.1s; + opacity: 0; + } + } + + // [screen +]: Adjust main navigation styles + @include break-from-device(screen) { + + // Hide 1st level nested items, as they are listed in the tabs by setting + // font-size to zero, as we need to preserve bottom padding + ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item--nested { + font-size: 0; + visibility: hidden; + } + + // We're on the 2nd+ level + &--active ~ .md-main { + + // Adjust 1st level styles + .md-nav--primary { + + // Show title and remove spacing + .md-nav__title { + display: block; + padding: 0; + } + + // Hide site title + .md-nav__title--site { + display: none; + } + + // Show 1st level navigation always expanded + .no-js & .md-nav { + display: block; + } + + // Hide 1st level normal items + & > .md-nav__list > .md-nav__item { + font-size: 0; + visibility: hidden; + + // Reset font-size for nested items and induce margin collapse + &--nested { + display: none; + font-size: 1.4rem; + overflow: auto; + visibility: visible; + + // Hide nested links + > .md-nav__link { + display: none; + } + } + + // Show 1st level active nested items + &--active { + display: block; + } + } + } + + // Always expand nested navigation on 2nd level + .md-nav[data-md-level="1"] { + max-height: initial; + overflow: visible; + + // Remove left spacing on 2nd level items + > .md-nav__list > .md-nav__item { + padding-left: 0; + } + + // Hide titles from 2nd level on + .md-nav .md-nav__title { + display: none; + } + } + } + } +} diff --git a/site/concepts/index.html b/site/concepts/index.html new file mode 100644 index 000000000..51ef94ac9 --- /dev/null +++ b/site/concepts/index.html @@ -0,0 +1,1273 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Concepts - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Concepts

+ +

Intra-Domain Routing

+

Intra-Domain Routing(IDR) offers a mechanism for user segmentation. For a small or medium size company a single domain may be sufficient, but for a multinational or an IP telephony service provider, it may not.

+

For a small company with less than 50 users, you may define a domain sip.domain.com. Regardless of how many offices they have, chances are that they still need to communicate with each other, and therefore we keep them in the same domain. Needless to say, that in a company this size you are not going to run out usernames.

+

A multinational company like Walmart have thousands of stores that operate independently. In such case, you will need a multi-domain setting. For example, you may define the domains sip.0001.walmart.com and sip.0002.walmart.com, and... you get the idea.

+

Double Agents

+

+

+

Yes, you can have double Agents, or Agents that exist in a multi-domain setup. All you need to do is include the domain in the Agent's spec.domain[*] list. In the example before, john can send or receive calls from both domains, while the rest of the Agents are only allowed to call within the domain.

+

Perhaps, could this "double agent" be the operator at a remote office?

+

Single Domain Example

+

The following yaml configuration shows a simple setup, involving one Domain and two Agents:

+

Domain configuration

+
- apiVersion: v1beta1
+  kind: Domain
+  metadata:
+    name: Local Office
+  spec:
+    context:
+      domainUri: sip.local
+
+ +

Agents configuration

+
- apiVersion: v1beta1
+  kind: Agent
+  metadata:
+    name: John Doe
+  spec:
+    credentials:
+      username: john
+      secret: '1234'
+    domains: [sip.local]
+- kind: Agent
+  apiVersion: v1beta1
+  metadata:
+    name: Janie Doe
+  spec:
+    credentials:
+      username: janie
+      secret: '1234'
+    domains: [sip.local]
+
+ +

And voila! That's all the configuration you need for intra-domain communication. For calls outside the domain, see "Domain Egress Routing" section and to receive calls from the PSTN check section "Domain Ingress Routing"

+
+

To setup your sip devices use information found in config/agents.yml. Also, you must use the Host/IP of Routr server as +the OUTBOUND PROXY of your sip device.

+
+

Routing Rules

+

The following rules apply to Intra-Domain Routing:

+
    +
  • Agents can only call other Agents in the same Domain
  • +
  • Agents must belong to a Domain
  • +
  • Agents Are not allowed to send a Digest username different than the username in the From-Header
  • +
+

Domain Ingress Routing

+

The process of receiving a call from PSTN to a domain is known in Routr as Domain Ingress Routing(DIR) and it is done using Gateway. Gateways are defined in the yaml file config/gateways.yml. The following example shows a typical Gateway configuration.

+
- apiVersion: v1beta1
+  kind: Gateway
+  metadata:
+    name: Plain Old Phone Service Provider
+  spec:
+    regService:
+      host: sip.provider.net
+      credentials:
+        username: 'gwuser'
+        secret: gwsecret
+      transport: udp
+      registries: [sip.nyc.provider.net]     # This are additional registrars within the providers network
+
+ +

You also need to define DIDs. Incoming calls from a DID will be routed to an existing Agent or Peer using the Address Of Record(AOR). The AOR must be available in the location service at the time of the call or the call will be rejected.

+

Please examine the following example:

+
- apiVersion: v1beta1
+  kind: DID
+  metadata:
+    gwRef: dd50baa4
+    geoInfo:
+      city: Columbus, GA
+      country: USA
+      countryISOCode: US
+  spec:
+    location:
+      telUri: 'tel:17066041487'
+      aorLink: 'sip:john@sip.local'      # This is the sip uri of an agent that is spected to be logged in
+
+ +

Easy right? Any incoming call from this Gateway and DID will be routed to "Jhon Doe" @ Ocean New York.

+

Routing Rules

+

As mention before, the path of an inbound PSTN call is determined by the spec.location block of a DID resource. +The aorLink refers to an Address of Record(Agent or Peer) that is available in the location service.

+

Domain Egress Routing

+

Domain Egress Routing(DER) is the way that Routr deals with a call request to a callee that exist in the Public Switched Telephone Network(PSTN) and not in the callers domain. The Egress Policy consists in a rule and a didRef, and it is defined in the spec.context section of Domains resources.

+

The rule and didRef are defined as follows:

+
    +
  • +

    rule is a regex to match callee in the call request. The location service will resort to this only after a search in the caller's Domain first.

    +
  • +
  • +

    didRef is the identifier of the DID that will to route the call. This DID must already exist and have a parent Gateway.

    +
  • +
+

Routing Rules

+

Agents can only perform outbound calls using the Egress Policy of their own Domains.

+

Peers Routing

+

Peers are very similar to Agents but they are not bound to any Domain, and they are usually collocated in the same network with Routr. A common case will be peering with Asterisk, where Asterisk acts as a Media Server and Routr is used for signaling.

+

Peers can perform inbound/outbound signaling within the network without any especial consideration since they exist inside the Location Service just like Agents. So it is possible to perform signaling from Peer to Peer, Peer to Agent.

+

The same is true for Inbound from the PSTN. For example, we can redirect incoming calls from the PSTN using the spec.location settings in the dids.yml configuration file.

+

Routing Rules

+

Agents are not allowed to call Peers.

+
+

A future version of the Peer resource will feature a spec.acceptFrom.* field to allow calls from Domains or specific Agents.

+
+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/configuration/agents/index.html b/site/configuration/agents/index.html new file mode 100644 index 000000000..c408dac42 --- /dev/null +++ b/site/configuration/agents/index.html @@ -0,0 +1,1022 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Agents Configuration - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Agents Configuration

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/configuration/dids/index.html b/site/configuration/dids/index.html new file mode 100644 index 000000000..cfd9611cf --- /dev/null +++ b/site/configuration/dids/index.html @@ -0,0 +1,1022 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Virtual Numbers(DIDs) Configuration - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Virtual Numbers(DIDs) Configuration

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/configuration/domains/index.html b/site/configuration/domains/index.html new file mode 100644 index 000000000..7deef451b --- /dev/null +++ b/site/configuration/domains/index.html @@ -0,0 +1,1022 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Domains Configuration - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Domains Configuration

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/configuration/gateways/index.html b/site/configuration/gateways/index.html new file mode 100644 index 000000000..9f71ba3b1 --- /dev/null +++ b/site/configuration/gateways/index.html @@ -0,0 +1,1022 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Carriers(Gateways) Configuration - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Carriers(Gateways) Configuration

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/configuration/general/datasource/index.html b/site/configuration/general/datasource/index.html new file mode 100644 index 000000000..be75f1c12 --- /dev/null +++ b/site/configuration/general/datasource/index.html @@ -0,0 +1,1024 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Datasource Setting - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Datasource Setting

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/configuration/general/logging/index.html b/site/configuration/general/logging/index.html new file mode 100644 index 000000000..c9336582a --- /dev/null +++ b/site/configuration/general/logging/index.html @@ -0,0 +1,1024 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Logging - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Logging

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/configuration/general/restful-api/index.html b/site/configuration/general/restful-api/index.html new file mode 100644 index 000000000..a7913a672 --- /dev/null +++ b/site/configuration/general/restful-api/index.html @@ -0,0 +1,1024 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Restful API - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Restful API

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/configuration/general/signaling-security/index.html b/site/configuration/general/signaling-security/index.html new file mode 100644 index 000000000..6147c1428 --- /dev/null +++ b/site/configuration/general/signaling-security/index.html @@ -0,0 +1,1024 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Signaling Security(TLS) - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Signaling Security(TLS)

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/configuration/general/transport/index.html b/site/configuration/general/transport/index.html new file mode 100644 index 000000000..bd7682b3c --- /dev/null +++ b/site/configuration/general/transport/index.html @@ -0,0 +1,1024 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Transport Settings - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Transport Settings

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/configuration/peers/index.html b/site/configuration/peers/index.html new file mode 100644 index 000000000..0e9c3c588 --- /dev/null +++ b/site/configuration/peers/index.html @@ -0,0 +1,1022 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Peers Configuration - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Peers Configuration

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/configuration/users/index.html b/site/configuration/users/index.html new file mode 100644 index 000000000..374ac0675 --- /dev/null +++ b/site/configuration/users/index.html @@ -0,0 +1,1022 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Users Configuration - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Users Configuration

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/guides/basic-setup/index.html b/site/guides/basic-setup/index.html new file mode 100644 index 000000000..885aa38b5 --- /dev/null +++ b/site/guides/basic-setup/index.html @@ -0,0 +1,1329 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Basic Setup - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + + + +
+
+ + + + + +

Basic Setup

+ +

This is a step-by-step guide on VoIP setup at home or at the office. For calls to the PSTN you will need to have a sip provider like voip.ms or didlogic.com.

+

Content

+ +

Requirements

+

This tutorial assumes the following:

+
    +
  • Two SIP phones connected to the same LAN
  • +
  • A fresh installation of Routr
  • +
  • SIP providers such as voip.ms or didlogic.com
  • +
+

Setting up the Server

+

A set of sample configuration converting this scenario can be found at basic sample files. You might overwrite the files in the config folder if you wish to skip this section.

+

Configuring the Gateway

+

To configure the Gateway you must consult your sip provider and obtain the credentials and registration host. The key fields for the configuration are metadata.ref, spec.regService.host and spec.regService.credentials. Here is an example:

+
- apiVersion: v1beta1
+  kind: Gateway
+  metadata:
+    name: Provider Inc
+  spec:
+    regService:
+      host: sip.provider.net
+      credentials:
+        username: 'youruser'
+        secret: 'yoursecret'
+      transport: udp
+
+ +

Configuring the DID

+

To configure your DID or virtual number, you must open and edit the file config/dids.yml. Notice in the example below, how your reference the Gateway by using the field metadata.geRef. The key field while configuring DIDs are spec.location.telUrl and spec.location.aorLink. Keep in mind that the value in spec.location.telUrl must be formatted exactly as sent by the provider.

+
- apiVersion: v1beta1
+  kind: DID
+  metadata:
+    gwRef: gweef506
+    geoInfo:
+      city: Columbus, GA
+      country: USA
+      countryISOCode: US
+  spec:
+    location:
+      telUrl: 'tel:17066041487'
+      aorLink: 'sip:1001@sip.local'
+
+ +

Creating a new Domain and EgressPolicy

+

Routr is a Domain centric Sip Server. A Domain is used to group several Agents in the same context. The Domain URI can be an arbitrary name but we recommend using a fully qualified domain name (FQDN). You will also need to setup and EgressPolicy to allow calls outside the Domain. Here is how the file config/domains.yml needs to look like:

+
- apiVersion: v1beta1
+  kind: Domain
+  metadata:
+    name: Local Office
+  spec:
+    context:
+      domainUri: sip.local
+      egressPolicy:
+        rule: .*
+        didRef: dd50baa4
+
+ +

Creating the Agents

+

We will now create the Agents 1001 and 1002. Keep in mind that field spec.credentials.username can be alphanumeric, so john or john001 is also acceptable.

+

Pay close attention to the credentials block since it contains the username and secret for both Agents.

+
- apiVersion: v1beta1
+  kind: Agent
+  metadata:
+    name: John Doe
+  spec:
+    credentials:
+      username: '1001'
+      secret: '1234'
+    domains: [sip.local]
+- apiVersion: v1beta1
+  kind: Agent
+  metadata:
+    name: Janie Doe
+  spec:
+    credentials:
+      username: '1002'
+      secret: '1234'
+    domains: [sip.local]
+
+ +

To verify your configuration, start the server by issuing the command routr. In a separate window use the following commands:

+
    +
  • rctl get gateway
  • +
  • rctl get did
  • +
  • rctl get domain
  • +
  • rctl get agents
  • +
+

Your output should be as follows:

+

Starting the Server

+

+

Verifying the Configuration

+

+

Configuring the Sip devices

+
+

We are using "Telephone" for this example. You might use any softphone you wish, just keep in mind that the configuration will look slightly different.

+
+

Configure your softphone using the information you gather in the last step. Start by completing only the required information: username, domain, password. Also, In the advanced section use the server's IP as your Registry Server and Proxy. Here is how mine looks like:

+

+

+
+

Make sure to check the box "Use this account" to register your device

+
+

If everything went well we just need to confirm that both softphones have registered correctly. Conveniently you can use the .rctl locate to obtain a list of "online" devices. This may seem like a lot of information. But what's relevant here is that both 1001 and 1002 are present in the location service and therefore can reach each other.

+

+

Making calls

+

This is a pretty easy step. If everything went well you will be able to call devices inside and outside your domain. Simply use the destination URI (eg.: 1001@sip.local or 7853178060@sip.local).

+

What’s Next?

+

You can check out the wiki to see more examples. If you have any questions start an issue or contact us via:

+ + + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/guides/benchmarking/index.html b/site/guides/benchmarking/index.html new file mode 100644 index 000000000..4c53f1e9c --- /dev/null +++ b/site/guides/benchmarking/index.html @@ -0,0 +1,1003 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Benchmarking - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Benchmarking

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/guides/routr-as-asterisk-frontend/index.html b/site/guides/routr-as-asterisk-frontend/index.html new file mode 100644 index 000000000..0e05a1c2f --- /dev/null +++ b/site/guides/routr-as-asterisk-frontend/index.html @@ -0,0 +1,1236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Routr as Asterisk frontend - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Routr as Asterisk frontend

+ +

This guide explores the use case of using Asterisk merely as a Media Server and a more specialized software, like Routr, to take care of the signaling and resource management. In other words, Asterisk will be in charge of the ivrs, voice mail, call recording, while Routr deals with connecting Agents, Peers, and Gateways. The following illustration depicts our scenario:

+

+

Content

+ +

Requirements

+

This tutorial assumes the following:

+
    +
  • You have a SIP phone connected to the same LAN where Routr and Asterisk are in.
  • +
  • If using a hardware phone, this can reach Asterisk and Routr and the other way around
  • +
  • You have a fresh installation of Routr and Asterisk
  • +
+
+

Before starting this guide make sure to have a fresh installation of Routr server.

+
+

Configuration Overview

+

With a fresh installation of Routr you will have most of the configuration you need to follow this tutorial. We, however, need to make some minor changes to configuration files to run our scenario.

+

The first file we will examine and change is config/peers.yml. Make note of the username and secret for the Peer "ast" since we will be using this to configure Asterisk. Also, search for the field spec.device and change it to match the Agents domain(sip.local). The file now will look similar to this:

+

config/peers.yml

+
- apiVersion: v1beta1
+  kind: Peer
+  metadata:
+    name: Asterisk PBX
+  spec:
+    device: 'sip.local'
+    credentials:
+      username: ast
+      secret: '1234'
+
+ +

Head to the console and run the command rctl -- get peers to confirm that the Peer exist. The result should be as follows:

+

+

Next, we focus our attention to domains.yml and agents.yml. With a fresh installation, we don't need to make any changes to this files. However, you could run the commands get domains and get agents to ensure that both, the Agent and the Domain, exist on the server. Your output should look similar to:

+

+

Use the information in agents.yml to configure your SIP phone. The relevant information is found in spec.credentials. Mine looks like this:

+

+

+
+

Make the adjustments based on your prefer SIP phone.

+
+

You can verify that your device registered correctly with Routr by running the locate command:

+

+

Configuring Asterisk

+

Using PJSIP

+

Backup your pjsip.conf and pjsip_wizard.conf. Update your pjsip.conf with the following:

+
[transport-tcp]
+type=transport
+protocol=tcp
+bind=0.0.0.0:6060
+
+ +

Then, in your pjsip_wizard.conf:

+
[routr]
+type = wizard
+sends_auth = yes
+sends_registrations = yes
+remote_hosts = 192.168.1.2
+outbound_auth/username = ast
+outbound_auth/password = 1234
+registration/retry_interval = 10
+registration/expiration = 900
+endpoint/allow = ulaw
+endpoint/allow = alaw
+endpoint/allow = opus
+endpoint/context = default
+transport = transport-tcp
+
+ +

Using the "old" Chan SIP

+

First backup your sip.conf. Then, replace your configuration and edit the file to reflect the following:

+
[general]
+udpbindaddr=0.0.0.0:6060
+context=default
+register => ast:1234@192.168.1.2:5060/1001    ; This information must match the credentials in `config/peers.yml`
+
+ +

Configuring the Dialplan

+

We are going to use a very simple dialplan to play a sound file. Again, make a backup of your configuration and replace its content with this:

+
[default]
+exten => 1001,1,Answer
+exten => 1001,n,Playback(tt-monkeys)
+exten => 1001,n,Hangup
+
+ +

Restart your Asterisk and check the location service. A new device will appear.

+

+

Calling Asterisk from John's device

+

We can now call ast@sip.local and if everything went well listen to a group of really annoying monkeys :).

+

What’s Next?

+

You can check out the wiki to see more examples. If you have any questions start an issue or contact us via:

+ + + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/guides/routr-as-freeswitch-frontend/index.html b/site/guides/routr-as-freeswitch-frontend/index.html new file mode 100644 index 000000000..db08e66ff --- /dev/null +++ b/site/guides/routr-as-freeswitch-frontend/index.html @@ -0,0 +1,1236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Routr as FreeSWITCH frontend - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Routr as FreeSWITCH frontend

+ +

This guide explores the use case of using Asterisk merely as a Media Server and a more specialized software, like Routr, to take care of the signaling and resource management. In other words, Asterisk will be in charge of the ivrs, voice mail, call recording, while Routr deals with connecting Agents, Peers, and Gateways. The following illustration depicts our scenario:

+

+

Content

+ +

Requirements

+

This tutorial assumes the following:

+
    +
  • You have a SIP phone connected to the same LAN where Routr and Asterisk are in.
  • +
  • If using a hardware phone, this can reach Asterisk and Routr and the other way around
  • +
  • You have a fresh installation of Routr and Asterisk
  • +
+
+

Before starting this guide make sure to have a fresh installation of Routr server.

+
+

Configuration Overview

+

With a fresh installation of Routr you will have most of the configuration you need to follow this tutorial. We, however, need to make some minor changes to configuration files to run our scenario.

+

The first file we will examine and change is config/peers.yml. Make note of the username and secret for the Peer "ast" since we will be using this to configure Asterisk. Also, search for the field spec.device and change it to match the Agents domain(sip.local). The file now will look similar to this:

+

config/peers.yml

+
- apiVersion: v1beta1
+  kind: Peer
+  metadata:
+    name: Asterisk PBX
+  spec:
+    device: 'sip.local'
+    credentials:
+      username: ast
+      secret: '1234'
+
+ +

Head to the console and run the command rctl -- get peers to confirm that the Peer exist. The result should be as follows:

+

+

Next, we focus our attention to domains.yml and agents.yml. With a fresh installation, we don't need to make any changes to this files. However, you could run the commands get domains and get agents to ensure that both, the Agent and the Domain, exist on the server. Your output should look similar to:

+

+

Use the information in agents.yml to configure your SIP phone. The relevant information is found in spec.credentials. Mine looks like this:

+

+

+
+

Make the adjustments based on your prefer SIP phone.

+
+

You can verify that your device registered correctly with Routr by running the locate command:

+

+

Configuring Asterisk

+

Using PJSIP

+

Backup your pjsip.conf and pjsip_wizard.conf. Update your pjsip.conf with the following:

+
[transport-tcp]
+type=transport
+protocol=tcp
+bind=0.0.0.0:6060
+
+ +

Then, in your pjsip_wizard.conf:

+
[routr]
+type = wizard
+sends_auth = yes
+sends_registrations = yes
+remote_hosts = 192.168.1.2
+outbound_auth/username = ast
+outbound_auth/password = 1234
+registration/retry_interval = 10
+registration/expiration = 900
+endpoint/allow = ulaw
+endpoint/allow = alaw
+endpoint/allow = opus
+endpoint/context = default
+transport = transport-tcp
+
+ +

Using the "old" Chan SIP

+

First backup your sip.conf. Then, replace your configuration and edit the file to reflect the following:

+
[general]
+udpbindaddr=0.0.0.0:6060
+context=default
+register => ast:1234@192.168.1.2:5060/1001    ; This information must match the credentials in `config/peers.yml`
+
+ +

Configuring the Dialplan

+

We are going to use a very simple dialplan to play a sound file. Again, make a backup of your configuration and replace its content with this:

+
[default]
+exten => 1001,1,Answer
+exten => 1001,n,Playback(tt-monkeys)
+exten => 1001,n,Hangup
+
+ +

Restart your Asterisk and check the location service. A new device will appear.

+

+

Calling Asterisk from John's device

+

We can now call ast@sip.local and if everything went well listen to a group of really annoying monkeys :).

+

What’s Next?

+

You can check out the wiki to see more examples. If you have any questions start an issue or contact us via:

+ + + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/guides/running-on-kubernetes/index.html b/site/guides/running-on-kubernetes/index.html new file mode 100644 index 000000000..8f3d70e75 --- /dev/null +++ b/site/guides/running-on-kubernetes/index.html @@ -0,0 +1,1022 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Running on Kubernetes - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Running on Kubernetes

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/guides/running-with-docker-or-compose/index.html b/site/guides/running-with-docker-or-compose/index.html new file mode 100644 index 000000000..91f4a828a --- /dev/null +++ b/site/guides/running-with-docker-or-compose/index.html @@ -0,0 +1,1022 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Running with Docker or Compose - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Running with Docker or Compose

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/guides/securing-the-signaling-path/index.html b/site/guides/securing-the-signaling-path/index.html new file mode 100644 index 000000000..8c72baef6 --- /dev/null +++ b/site/guides/securing-the-signaling-path/index.html @@ -0,0 +1,1221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Securing the Signaling Path - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + + + +
+
+ + + + + +

Securing the Signaling Path

+ +

Follow this guide to secure the signaling between your endpoints and Routr. Keep in mind that Routr will only secure the signaling and that the endpoints are ultimately responsible for securing the media.

+
+

For this guide we will use a fictitious domain name to demonstrate the process of securing the signaling path

+
+

+

Creating a Java Keystore(.JKS) Certificate

+

Routr needs a keystore (.jks) in order to properly handling the certificates. The following steps will create a valid keystore file using a self-signed method or using the free Let's Encrypt service.

+

Creating a self-signed Certificate

+

Perhaps the easiest way to create a valid certificate for Routr is using a self-signed certificate. To generate the certificate change into etc/certs in your Routr installation and run the following script:

+
keytool -genkey -keyalg RSA \
+ -noprompt \
+ -alias routr \
+ -keystore domain-certs.jks \
+ -storepass changeit \
+ -keypass changeit \
+ -validity 365 \
+ -keysize 2048 \
+ -dname "CN=sip.ocean.com, OU=OSS, O=Your Company Inc, L=Sanford, ST=NC, C=US" \
+ -ext SAN=dns:sip.ocean.com,dns:localhost,ip:127.0.0.1
+
+ +

Remember to adjust the values to match your project's information.

+
+

WSS will not work with a self-signed certificate. However, you can add a security exception by using https instead of wss in your browser's search bar and then accepting the security certificate.

+
+

Creating a Certificate using Let’s Encrypt

+

The recommended way to create a valid certificate for Routr is using the free service Let's Encrypt. Please go to https://letsencrypt.org/ for details on how to install the required tooling. To generate the certificate, use the following steps:

+

1. Create keys

+
certbot certonly --standalone -d sip.ocean.com --email admin@sip.ocean.com
+
+ +

Change to the directory where the certificates were created(normally at /etc/letsencrypt/live/sip.ocean.com).

+

2. Create a PKCS12 file containing full chain and private key

+
openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out pkcs.p12 -name domains-cert.jks
+
+ +

Please make note of the password since you will need it in the following step and also for your settings in Routr.

+

3. Convert PKCS12 to Keystore

+
keytool -importkeystore -srckeystore keystore.pkcs12 -srcstoretype PKCS12 -destkeystore domains-cert.jks
+
+ +

Installing the Certificate in Routr

+

To enable secure signaling in Routr, copy your certificate in etc/certs and edit the file config/config.yml to look like this:

+
apiVersion: v1beta1
+metadata:
+  userAgent: Routr v1.0
+spec:
+  securityContext:
+    keyStore: etc/certs/domains-cert.jks
+    trustStore: etc/certs/domains-cert.jks
+    keyStorePassword: 'changeit'
+    trustStorePassword: 'changeit'
+    keyStoreType: 'jks'
+    debugging: true                  # Enabled debug only for testing
+  transport:
+    - protocol: tls
+      port: 5061
+...
+
+ +

With the property spec.securityContext.debugging set to true you can get some valuable information about the status of the configuration. You can also test your configuration using the following command:

+
openssl s_client -host 192.168.1.2 -port 5061    # Remember to use Routr's IP
+
+ +

Setting up the Sip Phones

+
+

For the purpose of this guide, we are using Blink Pro.

+
+

Go to the account that you want to secure, select Advanced -> Sip Signaling and change the parameter Primary Proxy to ${proxyHost}:${proxyPort};transport=tls. See the example in the following image:

+

+

If everything went well you should see a green padlock like the one in the image bellow:

+

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/index.html b/site/index.html new file mode 100644 index 000000000..601df2651 --- /dev/null +++ b/site/index.html @@ -0,0 +1,982 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Welcome

+

Use the left-hand nav to find topics of interest.

+ + + + + + + + + +
+
+
+
+ + + + +
+ + + + + + +
+ +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/introduction/community/index.html b/site/introduction/community/index.html new file mode 100644 index 000000000..23baf34e4 --- /dev/null +++ b/site/introduction/community/index.html @@ -0,0 +1,1164 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Community - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Community

+ +

Routr is developed in the open. Here are some of the channels we use to communicate and contribute:

+

IRC: #routr on irc.freenode.net (for the easiest start, join via Riot)

+

(The IRC channel connects our Gitter and Slack communities)

+

User mailing lists:

+
    +
  • routr-announce – for announcements like new releases
  • +
  • routr-users – for discussions around Routr usage and community support
  • +
+

Twitter: @Fonoster

+

Issue tracker: Use the GitHub issue tracker for the various Routr repositories to file bugs and features request. If you need support, please send your questions to the routr-users mailing list rather than filing a GitHub issue.

+
+

Please do not ask individual project members for support. Use the channels above instead, where the whole community can help you and benefit from the solutions provided. If community support is insufficient for your situation, please refer to the Commercial Support section below.

+
+

Contributing

+

We welcome community contributions! Please see the CONTRIBUTING.md file in the respective Routr repository for instructions on how to submit changes. If you are planning on making more elaborate or controversial changes, please discuss them on the mailing list before sending a pull request.

+

Development mailing list: routr-developers – for discussions around Routr development

+

Developer Summits

+

We strive to be as open and public as possible. Technical discussions happen on the development list, our in-person meeting notes are public, and we have public calls. Below, you can find links to our developer summits at JConfDominicana 2019. These deveolper summits are open to join upon request as long as we have capacity. Preference is given to friendly projects and companies, plus diversity. Attendees are free not to be listed in the public meeting notes.

+

2019 developer summit notes (Come back to see updated link)

+

Code of Conduct

+

To make Routr a welcoming and harassment-free experience for everyone, we follow the Contributor Covenant Code of Conduct.

+

Commercial Support

+

This is a list of third-party companies and individuals who provide products or services related to Routr. Routr is an independent open source project which does not endorse any company. The list is provided in alphabetical order.

+

Pedro Sanders (independent contractor)

+

Acknowledgements

+

Routr was initially started by Pedro Sanders. The majority of its development has been sponsored by Fonoster.

+

The Routr logo was contributed by Pedro Sanders.

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/introduction/comparison/index.html b/site/introduction/comparison/index.html new file mode 100644 index 000000000..9de998f8c --- /dev/null +++ b/site/introduction/comparison/index.html @@ -0,0 +1,1022 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Comparison to Alternatives - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Comparison to Alternatives

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/introduction/faq/index.html b/site/introduction/faq/index.html new file mode 100644 index 000000000..4995d1980 --- /dev/null +++ b/site/introduction/faq/index.html @@ -0,0 +1,1133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FAQ - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

FAQ

+ +

Here is a list of common questions we get.

+

1. How do I change the server's password?

+

If you are using the files_data_provider then you must change the password in the users.yml file. For the redis_data_provider follow this steps:

+

First run the command redis-cli smembers users to obtain the reference to the user. Here is an example:

+

$ redis-cli smembers users
+1) "5aa69ead8fd6861d92385bac"
+
+Then, retrieve the document for reference running redis-cli get {REF}. For example

+
$ redis-cli get 5aa69ead8fd6861d92385bac
+"{\"apiVersion\":\"v1beta1\",\"kind\":\"User\",\"metadata\":{\"name\":\"Ctl\",\"ref\":\"5aa69ead8fd6861d92385bac\"},\"spec\":{\"credentials\":{\"username\":\"admin\",\"secret\":\"oldpass\"}}}"
+
+ +

Finally, search and change the old password and update your document using redis-cli set {REF} {DOCUMENT}. Like this:

+
$ redis-cli set 5aa69ead8fd6861d92385bac
+"{\"apiVersion\":\"v1beta1\",\"kind\":\"User\",\"metadata\":{\"name\":\"Ctl\",\"ref\":\"5aa69ead8fd6861d92385bac\"},\"spec\":{\"credentials\":{\"username\":\"admin\",\"secret\":\"newpass\"}}}"
+
+ +
+

A new token will be issued after your next login with rctl

+
+

2. How can I use rctl from a remote host?

+

By default Routr installs a certificate that only allows for connections using the localhost or 127.0.0.1. To use rctl tool from a remote host, you must generate a certificate that accepts connections to the desired domain name or ip and update the spec.restService section of the config.yml.

+

Here is an example using a self-signed certificate(usually enough).

+
keytool -genkey -keyalg RSA \
+-noprompt \
+-alias routr \
+-keystore api-cert.jks \
+-storepass changeit \
+-keypass changeit \
+-validity 365 \
+-keysize 2048 \
+-dname "CN=domain.com, OU=OSS, O=Your Company Inc, L=Sanford, ST=NC, C=US" \
+-ext SAN=dns:your.domain.com,dns:localhost,ip:127.0.0.1
+
+ +
+

Remember to place the certificate in the etc/certs folder

+
+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/introduction/glossary/index.html b/site/introduction/glossary/index.html new file mode 100644 index 000000000..fc8aea444 --- /dev/null +++ b/site/introduction/glossary/index.html @@ -0,0 +1,1072 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Glossary - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Glossary

+ +

This following table features some important concepts, including the different routing types implemented by the server.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ConceptDescription
UserUsers perform administrative actions on the server
AgentAgents represent SIP endpoints such as softphones and IP phones
DomainEnables the creation of isolated groups of Agents
PeerSimilar to Agents but without Domain boundaries
GatewaySIP entity that allows call termination
DIDRoutes and translate calls between the PSTN and Routr
Intra-Domain RoutingRouting type for calling within the same Domain
Domain Ingress RoutingCalling from the PSTN to an Agent or Peer
Domain Egress RoutingCalling from an Agent to the PSTN thru a Gateway
Peer Egress RoutingSimilar to DER but applies only to Peers
+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/introduction/installation/index.html b/site/introduction/installation/index.html new file mode 100644 index 000000000..a3c24b6c4 --- /dev/null +++ b/site/introduction/installation/index.html @@ -0,0 +1,1184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Installation - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Installation

+ +

There are no special requirements to install the server. Just download, decompress, and move the folder to a location of your choice.

+

Download the Server

+ + + + + + + + + + + + + + + + + + + + + + + + + +
PlatformDownload
Linuxtar.gz
macOStar.gz
Windowstar.gz, zip
Dockerimg
+

Or Build from Source

+
+

Building from source requires of Java 1.8+, Gradle, and NPM

+
+
git clone https://github.com/fonoster/routr
+cd routr
+npm i
+npm run pack
+
+ +

Running with Docker

+
docker pull fonoster/routr
+docker run -it \
+    -p 4567:4567 \
+    -p 5060:5060 \
+    -p 5060:5060/udp \
+    -p 5061-5063:5061-5063 \
+    -e ROUTR_EXTERN_ADDR=${your host address} \
+    fonoster/routr
+
+ +

Running in any other Plattform

+

To start the server just run the script ./routr at the root of this +project. Your output will look similar to this:

+
$ ./routr
+[INFO ] Starting Routr
+[INFO ] Listening @ 172.18.0.4:5060 [udp]
+[INFO ] Listening @ 172.18.0.4:5060 [tcp]
+[INFO ] Listening @ 172.18.0.4:5061 [tls]
+[INFO ] Starting Location service
+[INFO ] Starting Registry service
+[INFO ] Starting Restful service on port 4567
+
+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/introduction/media/index.html b/site/introduction/media/index.html new file mode 100644 index 000000000..36d01f610 --- /dev/null +++ b/site/introduction/media/index.html @@ -0,0 +1,1022 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Media - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Media

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/introduction/overview/index.html b/site/introduction/overview/index.html new file mode 100644 index 000000000..daab7bd53 --- /dev/null +++ b/site/introduction/overview/index.html @@ -0,0 +1,1089 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Overview - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + + + +

Overview

+ +

Routr is a lightweight sip proxy, location server, and registrar that provides a reliable and scalable SIP infrastructure for telephony carriers, communication service providers, and integrators. It also provides with capabilities that are suitable for the enterprise and personal needs. To get involved in the development of this project please contact us at @fonoster.

+

Features

+
    +
  • Proxy
  • +
  • Registrar Service
  • +
  • Location Service
  • +
  • Call Forking
  • +
  • Multi-Tenancy/Multi-Domain
  • +
  • Access to the PSTN Using SIP Gateways
  • +
  • Transport: TCP, UDP, TLS, WebSocket
  • +
  • Data Sources: Redis, RESTful API, Files
  • +
  • Security
      +
    • Digest SIP User Authentication
    • +
    • Domain Access Control List (DACL)
    • +
    • RESTful service secured with TLS and JWT tokens
    • +
    +
  • +
  • Rest API
  • +
  • Command Line Tool for Admin Operations
  • +
  • Routing Capabilities
      +
    • Intra-Domain Routing (IDR)
    • +
    • Domain Ingress Routing(DIR)
    • +
    • Domain Egress Routing (DER)
    • +
    • Peer Egress Routing (PER)
    • +
    +
  • +
+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/introduction/roadmap/index.html b/site/introduction/roadmap/index.html new file mode 100644 index 000000000..63d514c32 --- /dev/null +++ b/site/introduction/roadmap/index.html @@ -0,0 +1,1022 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Roadmap - Documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +
+ +
+ + + + +
+
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + +

Roadmap

+ +

Coming soon!

+ + + + + + + + + +
+
+
+
+ + + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/site/search/search_index.json b/site/search/search_index.json new file mode 100644 index 000000000..50c9cea54 --- /dev/null +++ b/site/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["en"],"prebuild_index":false,"separator":"[\\s\\-]+"},"docs":[{"location":"","text":"Welcome Use the left-hand nav to find topics of interest.","title":"Welcome"},{"location":"#welcome","text":"Use the left-hand nav to find topics of interest.","title":"Welcome"},{"location":"concepts/","text":"Intra-Domain Routing Intra-Domain Routing(IDR) offers a mechanism for user segmentation. For a small or medium size company a single domain may be sufficient, but for a multinational or an IP telephony service provider, it may not. For a small company with less than 50 users, you may define a domain sip.domain.com . Regardless of how many offices they have, chances are that they still need to communicate with each other, and therefore we keep them in the same domain. Needless to say, that in a company this size you are not going to run out usernames. A multinational company like Walmart have thousands of stores that operate independently. In such case, you will need a multi-domain setting. For example, you may define the domains sip.0001.walmart.com and sip.0002.walmart.com , and... you get the idea. Double Agents Yes, you can have double Agents, or Agents that exist in a multi-domain setup. All you need to do is include the domain in the Agent's spec.domain[*] list. In the example before, john can send or receive calls from both domains, while the rest of the Agents are only allowed to call within the domain. Perhaps, could this \"double agent\" be the operator at a remote office? Single Domain Example The following yaml configuration shows a simple setup, involving one Domain and two Agents: Domain configuration - apiVersion : v1beta1 kind : Domain metadata : name : Local Office spec : context : domainUri : sip.local Agents configuration - apiVersion : v1beta1 kind : Agent metadata : name : John Doe spec : credentials : username : john secret : 1234 domains : [ sip.local ] - kind : Agent apiVersion : v1beta1 metadata : name : Janie Doe spec : credentials : username : janie secret : 1234 domains : [ sip.local ] And voila! That's all the configuration you need for intra-domain communication. For calls outside the domain, see \"Domain Egress Routing\" section and to receive calls from the PSTN check section \"Domain Ingress Routing\" To setup your sip devices use information found in config/agents.yml . Also, you must use the Host/IP of Routr server as the OUTBOUND PROXY of your sip device. Routing Rules The following rules apply to Intra-Domain Routing: Agents can only call other Agents in the same Domain Agents must belong to a Domain Agents Are not allowed to send a Digest username different than the username in the From-Header Domain Ingress Routing The process of receiving a call from PSTN to a domain is known in Routr as Domain Ingress Routing(DIR) and it is done using Gateway. Gateways are defined in the yaml file config/gateways.yml . The following example shows a typical Gateway configuration. - apiVersion : v1beta1 kind : Gateway metadata : name : Plain Old Phone Service Provider spec : regService : host : sip.provider.net credentials : username : gwuser secret : gwsecret transport : udp registries : [ sip.nyc.provider.net ] # This are additional registrars within the providers network You also need to define DIDs. Incoming calls from a DID will be routed to an existing Agent or Peer using the Address Of Record(AOR). The AOR must be available in the location service at the time of the call or the call will be rejected. Please examine the following example: - apiVersion : v1beta1 kind : DID metadata : gwRef : dd50baa4 geoInfo : city : Columbus, GA country : USA countryISOCode : US spec : location : telUri : tel:17066041487 aorLink : sip:john@sip.local # This is the sip uri of an agent that is spected to be logged in Easy right? Any incoming call from this Gateway and DID will be routed to \"Jhon Doe\" @ Ocean New York. Routing Rules As mention before, the path of an inbound PSTN call is determined by the spec.location block of a DID resource. The aorLink refers to an Address of Record(Agent or Peer) that is available in the location service . Domain Egress Routing Domain Egress Routing(DER) is the way that Routr deals with a call request to a callee that exist in the Public Switched Telephone Network(PSTN) and not in the callers domain. The Egress Policy consists in a rule and a didRef , and it is defined in the spec.context section of Domains resources. The rule and didRef are defined as follows: rule is a regex to match callee in the call request. The location service will resort to this only after a search in the caller's Domain first. didRef is the identifier of the DID that will to route the call. This DID must already exist and have a parent Gateway. Routing Rules Agents can only perform outbound calls using the Egress Policy of their own Domains. Peers Routing Peers are very similar to Agents but they are not bound to any Domain, and they are usually collocated in the same network with Routr. A common case will be peering with Asterisk, where Asterisk acts as a Media Server and Routr is used for signaling. Peers can perform inbound/outbound signaling within the network without any especial consideration since they exist inside the Location Service just like Agents. So it is possible to perform signaling from Peer to Peer, Peer to Agent. The same is true for Inbound from the PSTN. For example, we can redirect incoming calls from the PSTN using the spec.location settings in the dids.yml configuration file. Routing Rules Agents are not allowed to call Peers. A future version of the Peer resource will feature a spec.acceptFrom.* field to allow calls from Domains or specific Agents.","title":"Concepts"},{"location":"concepts/#intra-domain-routing","text":"Intra-Domain Routing(IDR) offers a mechanism for user segmentation. For a small or medium size company a single domain may be sufficient, but for a multinational or an IP telephony service provider, it may not. For a small company with less than 50 users, you may define a domain sip.domain.com . Regardless of how many offices they have, chances are that they still need to communicate with each other, and therefore we keep them in the same domain. Needless to say, that in a company this size you are not going to run out usernames. A multinational company like Walmart have thousands of stores that operate independently. In such case, you will need a multi-domain setting. For example, you may define the domains sip.0001.walmart.com and sip.0002.walmart.com , and... you get the idea.","title":"Intra-Domain Routing"},{"location":"concepts/#double-agents","text":"Yes, you can have double Agents, or Agents that exist in a multi-domain setup. All you need to do is include the domain in the Agent's spec.domain[*] list. In the example before, john can send or receive calls from both domains, while the rest of the Agents are only allowed to call within the domain. Perhaps, could this \"double agent\" be the operator at a remote office?","title":"Double Agents"},{"location":"concepts/#single-domain-example","text":"The following yaml configuration shows a simple setup, involving one Domain and two Agents: Domain configuration - apiVersion : v1beta1 kind : Domain metadata : name : Local Office spec : context : domainUri : sip.local Agents configuration - apiVersion : v1beta1 kind : Agent metadata : name : John Doe spec : credentials : username : john secret : 1234 domains : [ sip.local ] - kind : Agent apiVersion : v1beta1 metadata : name : Janie Doe spec : credentials : username : janie secret : 1234 domains : [ sip.local ] And voila! That's all the configuration you need for intra-domain communication. For calls outside the domain, see \"Domain Egress Routing\" section and to receive calls from the PSTN check section \"Domain Ingress Routing\" To setup your sip devices use information found in config/agents.yml . Also, you must use the Host/IP of Routr server as the OUTBOUND PROXY of your sip device. Routing Rules The following rules apply to Intra-Domain Routing: Agents can only call other Agents in the same Domain Agents must belong to a Domain Agents Are not allowed to send a Digest username different than the username in the From-Header","title":"Single Domain Example"},{"location":"concepts/#domain-ingress-routing","text":"The process of receiving a call from PSTN to a domain is known in Routr as Domain Ingress Routing(DIR) and it is done using Gateway. Gateways are defined in the yaml file config/gateways.yml . The following example shows a typical Gateway configuration. - apiVersion : v1beta1 kind : Gateway metadata : name : Plain Old Phone Service Provider spec : regService : host : sip.provider.net credentials : username : gwuser secret : gwsecret transport : udp registries : [ sip.nyc.provider.net ] # This are additional registrars within the providers network You also need to define DIDs. Incoming calls from a DID will be routed to an existing Agent or Peer using the Address Of Record(AOR). The AOR must be available in the location service at the time of the call or the call will be rejected. Please examine the following example: - apiVersion : v1beta1 kind : DID metadata : gwRef : dd50baa4 geoInfo : city : Columbus, GA country : USA countryISOCode : US spec : location : telUri : tel:17066041487 aorLink : sip:john@sip.local # This is the sip uri of an agent that is spected to be logged in Easy right? Any incoming call from this Gateway and DID will be routed to \"Jhon Doe\" @ Ocean New York. Routing Rules As mention before, the path of an inbound PSTN call is determined by the spec.location block of a DID resource. The aorLink refers to an Address of Record(Agent or Peer) that is available in the location service .","title":"Domain Ingress Routing"},{"location":"concepts/#domain-egress-routing","text":"Domain Egress Routing(DER) is the way that Routr deals with a call request to a callee that exist in the Public Switched Telephone Network(PSTN) and not in the callers domain. The Egress Policy consists in a rule and a didRef , and it is defined in the spec.context section of Domains resources. The rule and didRef are defined as follows: rule is a regex to match callee in the call request. The location service will resort to this only after a search in the caller's Domain first. didRef is the identifier of the DID that will to route the call. This DID must already exist and have a parent Gateway. Routing Rules Agents can only perform outbound calls using the Egress Policy of their own Domains.","title":"Domain Egress Routing"},{"location":"concepts/#peers-routing","text":"Peers are very similar to Agents but they are not bound to any Domain, and they are usually collocated in the same network with Routr. A common case will be peering with Asterisk, where Asterisk acts as a Media Server and Routr is used for signaling. Peers can perform inbound/outbound signaling within the network without any especial consideration since they exist inside the Location Service just like Agents. So it is possible to perform signaling from Peer to Peer, Peer to Agent. The same is true for Inbound from the PSTN. For example, we can redirect incoming calls from the PSTN using the spec.location settings in the dids.yml configuration file. Routing Rules Agents are not allowed to call Peers. A future version of the Peer resource will feature a spec.acceptFrom.* field to allow calls from Domains or specific Agents.","title":"Peers Routing"},{"location":"administration/cli/","text":"rctl is a command line interface for running commands against a Routr server. This overview covers rctl syntax, describes the command operations and provides common examples. For details about each command, including all the supported flags and subcommands, see the rctl reference documentation. This tool is part of Routr installation. Syntax Use the following syntax to run rctl commands from your terminal window: rctl COMMAND [REF] [flags] where COMMAND , subcommand REF , and flags are: COMMAND : Specifies the operation that you want to perform on one or more resources. For example: create, get, delete, locate(loc). subcommand : Specifies the resource type. Resource types are case-sensitive and you can specify the singular, plural, or abbreviated forms. For example, the following commands produce the same output: $ rctl get gateway gweef506 $ rctl get gateways gweef506 $ rctl get gw gweef506 REF : Specifies the reference to the resource. References are case-sensitive. If the reference is omitted, details for all resources are displayed. For example: $ rctl get agents . flags : Specifies optional flags. For example, you can use the --filter to further reduce the output of get command. The --filter flag uses JsonPath to perform the filtering. The root is always '$' so all you need to add is the path to the property and the filter operators. For example: # This will return all the DIDs in Gateway gweef506 ./rctl get dids --filter @.metadata.gwRef== gweef506 If you need help, just run rctl --help from the terminal window. $ ./rctl -h usage: rctl [ -h ] COMMAND ... rctl controls the Routr server named arguments: -h, --help show this help message and exit Basic Commands: COMMAND get display a list of resources create ( crea ) creates new resource ( s ) apply apply changes over existing resource ( s ) delete ( del ) delete an existing resource ( s ) locate ( loc ) locate sip device ( s ) registry ( reg ) shows gateways registrations system ( sys ) display a list of resources login sets connection info More information at https://github.com/fonoster/routr/wiki Important : Some commands (ie.: create, delete) are not available in the default implementation of the resources modules. Only persistent implementations will allow such command. Examples: Common operations Use the following set of examples to help you familiarize yourself with running the commonly used rctl operations: rctl locate or rctl loc - Locate a sip device registered on the Routr server // Locate all Sip Devices registered against a Routr server $ rctl loc rctl registry or rctl reg - Shows Gateways current registration // Shows the registry $ rctl reg rctl get - List one or more resources. // List all dids $ rctl get dids // List all dids that belong to gateway reference gweef506 $ rctl get dids --filter @.metadata.ref== gweef506 // List did by reference $ rctl get dids dd50baa4 // List all agents $ rctl get agents rctl create - create a new resource. // Create a new gateway(s) using a .yaml or .yml file $ rctl create -f new-gateway.yaml rctl apply - update an existing resource(s) // Update an existing resource(s) .yaml or .yml. $ rctl apply -f new-gateway.yaml rctl delete - delete a resource. // Delete all did for gateway reference gweef506 $ rctl delete dids --filter @.metadata.gwRef== gweef506 // Delete a single agent (using delete alias) $ rctl del agent ag3f77f6 Cheat Sheet Create, delete, and update are only available in some implementations of the resources module. Request and store token # Request authentication for subsecuent commands $ rctl login https://127.0.0.1/api/{apiVersion} -u admin -p changeit Showing the Registry # Shows all the Gateways that are currently available $ rctl registry # Shows only current registrations. You may use `reg` for short Locating Sip Devices # Find all sip devices available at the location service $ rctl locate # This list will not include did-ingress-routes or domain-egress-routes Creating Resources # Create new peers and agents $ rctl create -f asterisk.yaml # Create Peer in file asterisk.yaml $ rctl create -f agents-list.yaml # Create Agents in file agents-list.yaml Finding Resources # Get DIDs $ rctl get dids # List all available DIDs $ rctl get did # List all available DIDs $ rctl get did --filter @.metadata.ref== dd50baa4 # Shows DID with reference DID0001 $ rctl get did --filter @.metadata.gwRef== gweef506 # Shows DIDs with Gateway reference GW1232 # Get agents $ rctl get agents # List all Agents Deleting Resources # Delete command by refernce or filter $ rctl delete agent ag3f77f6 # Delete Agent by reference $ rctl del dids --filter @.metadata.gwRef=gweef506 # Delete DIDs using a filter Updating Resources $ rctl -- apply -f asterisk.yaml # Create Peer in file asterisk.yaml $ rctl -- apply -f agents-list.yaml # Create Agents in file agents-list.yaml","title":"Command-Line"},{"location":"administration/cli/#syntax","text":"Use the following syntax to run rctl commands from your terminal window: rctl COMMAND [REF] [flags] where COMMAND , subcommand REF , and flags are: COMMAND : Specifies the operation that you want to perform on one or more resources. For example: create, get, delete, locate(loc). subcommand : Specifies the resource type. Resource types are case-sensitive and you can specify the singular, plural, or abbreviated forms. For example, the following commands produce the same output: $ rctl get gateway gweef506 $ rctl get gateways gweef506 $ rctl get gw gweef506 REF : Specifies the reference to the resource. References are case-sensitive. If the reference is omitted, details for all resources are displayed. For example: $ rctl get agents . flags : Specifies optional flags. For example, you can use the --filter to further reduce the output of get command. The --filter flag uses JsonPath to perform the filtering. The root is always '$' so all you need to add is the path to the property and the filter operators. For example: # This will return all the DIDs in Gateway gweef506 ./rctl get dids --filter @.metadata.gwRef== gweef506 If you need help, just run rctl --help from the terminal window. $ ./rctl -h usage: rctl [ -h ] COMMAND ... rctl controls the Routr server named arguments: -h, --help show this help message and exit Basic Commands: COMMAND get display a list of resources create ( crea ) creates new resource ( s ) apply apply changes over existing resource ( s ) delete ( del ) delete an existing resource ( s ) locate ( loc ) locate sip device ( s ) registry ( reg ) shows gateways registrations system ( sys ) display a list of resources login sets connection info More information at https://github.com/fonoster/routr/wiki Important : Some commands (ie.: create, delete) are not available in the default implementation of the resources modules. Only persistent implementations will allow such command.","title":"Syntax"},{"location":"administration/cli/#examples-common-operations","text":"Use the following set of examples to help you familiarize yourself with running the commonly used rctl operations: rctl locate or rctl loc - Locate a sip device registered on the Routr server // Locate all Sip Devices registered against a Routr server $ rctl loc rctl registry or rctl reg - Shows Gateways current registration // Shows the registry $ rctl reg rctl get - List one or more resources. // List all dids $ rctl get dids // List all dids that belong to gateway reference gweef506 $ rctl get dids --filter @.metadata.ref== gweef506 // List did by reference $ rctl get dids dd50baa4 // List all agents $ rctl get agents rctl create - create a new resource. // Create a new gateway(s) using a .yaml or .yml file $ rctl create -f new-gateway.yaml rctl apply - update an existing resource(s) // Update an existing resource(s) .yaml or .yml. $ rctl apply -f new-gateway.yaml rctl delete - delete a resource. // Delete all did for gateway reference gweef506 $ rctl delete dids --filter @.metadata.gwRef== gweef506 // Delete a single agent (using delete alias) $ rctl del agent ag3f77f6","title":"Examples: Common operations"},{"location":"administration/cli/#cheat-sheet","text":"Create, delete, and update are only available in some implementations of the resources module.","title":"Cheat Sheet"},{"location":"administration/cli/#request-and-store-token","text":"# Request authentication for subsecuent commands $ rctl login https://127.0.0.1/api/{apiVersion} -u admin -p changeit","title":"Request and store token"},{"location":"administration/cli/#showing-the-registry","text":"# Shows all the Gateways that are currently available $ rctl registry # Shows only current registrations. You may use `reg` for short","title":"Showing the Registry"},{"location":"administration/cli/#locating-sip-devices","text":"# Find all sip devices available at the location service $ rctl locate # This list will not include did-ingress-routes or domain-egress-routes","title":"Locating Sip Devices"},{"location":"administration/cli/#creating-resources","text":"# Create new peers and agents $ rctl create -f asterisk.yaml # Create Peer in file asterisk.yaml $ rctl create -f agents-list.yaml # Create Agents in file agents-list.yaml","title":"Creating Resources"},{"location":"administration/cli/#finding-resources","text":"# Get DIDs $ rctl get dids # List all available DIDs $ rctl get did # List all available DIDs $ rctl get did --filter @.metadata.ref== dd50baa4 # Shows DID with reference DID0001 $ rctl get did --filter @.metadata.gwRef== gweef506 # Shows DIDs with Gateway reference GW1232 # Get agents $ rctl get agents # List all Agents","title":"Finding Resources"},{"location":"administration/cli/#deleting-resources","text":"# Delete command by refernce or filter $ rctl delete agent ag3f77f6 # Delete Agent by reference $ rctl del dids --filter @.metadata.gwRef=gweef506 # Delete DIDs using a filter","title":"Deleting Resources"},{"location":"administration/cli/#updating-resources","text":"$ rctl -- apply -f asterisk.yaml # Create Peer in file asterisk.yaml $ rctl -- apply -f agents-list.yaml # Create Agents in file agents-list.yaml","title":"Updating Resources"},{"location":"administration/webconsole/","text":"Coming soon!","title":"Web Console"},{"location":"api/reference/","text":"Coming soon!","title":"Reference"},{"location":"api/resources/","text":"Routr API version is currently v1beta1 . We will continue to improve the API, resource definition, and other artifacts until we reach a final version. We then will establish an update policy to ensure backward compatibility. Until then keep an eye on this document. General Configuration This file can be found at 'config/config.yaml' in the root of this project. Property Description Required apiVersion Indicates the version of the resource (Not yet implemented) yes metadata.userAgent Sets sip header User-Agent to the desired value No spec.bindAddr Default stack IP address No spec.externAddr IP address to advertise No spec.localnets Local networks. Use in combination with spec.externAddr No spec.recordRoute Stay within the signaling path No spec.useToAsAOR Use the TO header instead of Request URI No spec.registrarIntf Force to use received rport for registration No spec.addressInfo.[*] Custom tag with the DID information No spec.accessControlList.deny.[*] Deny incoming traffic from network list No spec.accessControlList.allow.[*] Allow incoming traffic from network list No spec.restService.bindAddr Restful service listening address No spec.restService.port Restful service port. Defaults to 4567 No spec.restService.unsecured Disabled https for restful calls. Default is false No spec.restService.keyStore Path to keyStore No spec.restService.trueStore Path to trueStore No spec.restService.keyStorePassword Password for keyStore No spec.restService.trueStorePassword Password for trueStore No spec.transport.bindAddr Overwrites spec.bindAddr for transport entry No spec.transport.port Transport port Yes spec.transport.protocol Valid values are: tcp , udp , tls , sctp , ws , wss Yes spec.securityContext.keyStore Path to keyStore Yes spec.securityContext.trustStore Path to trueStore Yes spec.securityContext.keyStorePassword Password for keyStore Yes spec.securityContext.keyStoreType KeyStore type Yes spec.securityContext.client.authType Type of client authentication. Default is Disabled . See https://goo.gl/1vKbXW for more options No spec.securityContext.client.protocols.[*] Accepted tls protocols. Default is [ TLSv1.2 , TLSv1.1 , TLSv1 ] No spec.securityContext.debugging Turns ON or OFF ssl debuging. Default is false No spec.dataSource.provider Defines data provider. Defaults to files_data_provider No spec.dataSource.parameters Parameters expecifics to data provider implementation No spec.logging.traceLevel Verbosity of the sip-stack logging. Default is 0 No Example apiVersion : v1beta1 metadata : userAgent : Routr v1.0 spec : transport : - protocol : udp port : 5060 dataSource : provider : redis_data_provider logging : traceLevel : 10 Data Providers Routr currently implements three data providers: redis_data_provider , files_data_provider and restful_data_provider . The default data provider is the files_data_provider . The docker version of the server uses redis_data_provider as its default The parameters for redis_data_provider are: Parameter Description Required host Redis host. Defaults to 'localhost' No port Redis port. The default port is 6379 No secret Password to access database No The parameters for files_data_provider are: Parameter Description Required path Path to configuration files. Defaults to 'config' folder No This implementation has the limitation that writes operations have to be performed manually on the files. The parameters for restful_data_provider are: Parameter Description Required baseUrl Endpoint base url yes username Basic authentication username yes secret Basic authentication password yes User Resource This file can be found at 'config/users.yaml' in the root of this project. Property Description Required apiVersion Indicates the version of the resource (Not yet implemented) Yes kind Defines the type of resource Yes metadata.name Friendly name for the User device Yes spec.credentials.username User's credential username Yes spec.credentials.secret User's credential secret Yes Example # Users exist in Routr to perform administrative actions on the server - apiVersion : v1beta1 kind : User metadata : name : Administrator spec : credentials : username : admin secret : changeit Agent Resource This file can be found at 'config/agents.yaml' in the root of this project. Property Description Required apiVersion Indicates the version of the resource (Not yet implemented) Yes kind Defines the type of resource Yes metadata.name Friendly name for the SIP device Yes spec.credentials.username Agent's credential username Yes spec.credentials.secret Agent's credential secret Yes spec.domains[*] Context/s in which this Agent is allowed to communicate. FQDN is recommended Yes Example # Peers and Agents can register in Routr location service - apiVersion : v1beta1 kind : Agent metadata : name : John Doe spec : credentials : username : john secret : 1234 domains : [ sip.local ] Domain Resource This file can be found at 'config/domains.yaml' in the root of this project. Property Description Required apiVersion Indicates the version of the resource (Not yet implemented) Yes kind Defines the type of resource Yes metadata.name Friendly name for the SIP domain Yes spec.context.domainUri Domain URI. FQDN is recomended Yes spec.context.egressPolicy.rule Regular expression indicating when a call will be routed via $spec.context.egressPolicy.didRef No spec.context.egressPolicy.didRef Reference to the DID that will route the call No spec.context.accessControlList.allow[*] Traffic allow for Network in list No spec.context.accessControlList.deny[*] Traffic disabled for Network in list No Access Control List Rules may be in CIDR, IP/Mask, or single IP format. Example of rules are: - 0.0.0.0/1 # all - 192.168.1.0/255.255.255.0 - 192.168.0.1/31 Example - apiVersion : v1beta1 kind : Domain metadata : name : Local Server spec : context : domainUri : sip.local egressPolicy : rule : .* didRef : DID0001 accessControlList : deny : [ 0.0.0.0/1 ] # Deny all allow : [ 192.168.0.1/31 ] Gateway Resource This file can be found at 'config/gateways.yaml' in the root of this project. Property Description Required apiVersion Indicates the version of the resource (Not yet implemented) Yes kind Defines the type of resource Yes metadata.name Friendly name for the SIP device Yes metadata.ref Reference to this resource Yes spec.credentials.username Gateway username Yes spec.credentials.secret Gateway secret Yes spec.host Gateway host Yes spec.transport Transport protocol Yes spec.registries.[*] Additional registries for ingress calls No Example # Use gateway to register with a Sip Gateways or SBCs and send # or receive calls from the PSTN - apiVersion : v1beta1 kind : Gateway metadata : name : Provider, Inc ref : GW0001 spec : host : sip.provider.com transport : tcp credentials : username : user secret : changeit DID Resource This file can be found at 'config/dids.yaml' in the root of this project. Property Description Required apiVersion Indicates the version of the resource (Not yet implemented) Yes kind Defines the type of resource Yes metadata.ref Reference to this resource Yes metadata.gwRef Reference to parent Gateway Yes metadata.geoInfo.city City of the DID No metadata.geoInfo.country Country of the DID No metadata.geoInfo.countryISOCode Country ISO code for the DID (ie.: US) No spec.location.telUrl DID URI available in the location server Yes spec.location.aorLink Address of record of SIP device for call routing Yes Example - apiVersion : v1beta1 kind : DID metadata : ref : DID0001 gwRef : GW0001 geoInfo : city : Columbus, GA country : USA countryISOCode : US spec : location : telUrl : tel:17066041487 aorLink : sip:john@sip.local Peer Resource This file can be found at 'config/peers.yaml' in the root of this project. Property Description Required apiVersion Indicates the version of the resource (Not yet implemented) Yes kind Defines the type of resource Yes metadata.name Friendly name for the SIP device Yes spec.credentials.username Peer's credential username Yes spec.credentials.secret Peer's credential secret Yes spec.device When set it will be used by the location service No spec.contactAddr When set will advertise this as the contactURI No Example # Peers and Agents can register on Routr location service - apiVersion : v1beta1 kind : Peer metadata : name : Asterisk (Media Server) spec : credentials : username : ast secret : astsecret device : astserver # If is not define the IP address will be use contactAddr : 192.168.1.2:6060 This peer can be reached using ast@astserver .","title":"Resources"},{"location":"api/resources/#general-configuration","text":"This file can be found at 'config/config.yaml' in the root of this project. Property Description Required apiVersion Indicates the version of the resource (Not yet implemented) yes metadata.userAgent Sets sip header User-Agent to the desired value No spec.bindAddr Default stack IP address No spec.externAddr IP address to advertise No spec.localnets Local networks. Use in combination with spec.externAddr No spec.recordRoute Stay within the signaling path No spec.useToAsAOR Use the TO header instead of Request URI No spec.registrarIntf Force to use received rport for registration No spec.addressInfo.[*] Custom tag with the DID information No spec.accessControlList.deny.[*] Deny incoming traffic from network list No spec.accessControlList.allow.[*] Allow incoming traffic from network list No spec.restService.bindAddr Restful service listening address No spec.restService.port Restful service port. Defaults to 4567 No spec.restService.unsecured Disabled https for restful calls. Default is false No spec.restService.keyStore Path to keyStore No spec.restService.trueStore Path to trueStore No spec.restService.keyStorePassword Password for keyStore No spec.restService.trueStorePassword Password for trueStore No spec.transport.bindAddr Overwrites spec.bindAddr for transport entry No spec.transport.port Transport port Yes spec.transport.protocol Valid values are: tcp , udp , tls , sctp , ws , wss Yes spec.securityContext.keyStore Path to keyStore Yes spec.securityContext.trustStore Path to trueStore Yes spec.securityContext.keyStorePassword Password for keyStore Yes spec.securityContext.keyStoreType KeyStore type Yes spec.securityContext.client.authType Type of client authentication. Default is Disabled . See https://goo.gl/1vKbXW for more options No spec.securityContext.client.protocols.[*] Accepted tls protocols. Default is [ TLSv1.2 , TLSv1.1 , TLSv1 ] No spec.securityContext.debugging Turns ON or OFF ssl debuging. Default is false No spec.dataSource.provider Defines data provider. Defaults to files_data_provider No spec.dataSource.parameters Parameters expecifics to data provider implementation No spec.logging.traceLevel Verbosity of the sip-stack logging. Default is 0 No Example apiVersion : v1beta1 metadata : userAgent : Routr v1.0 spec : transport : - protocol : udp port : 5060 dataSource : provider : redis_data_provider logging : traceLevel : 10","title":"General Configuration"},{"location":"api/resources/#data-providers","text":"Routr currently implements three data providers: redis_data_provider , files_data_provider and restful_data_provider . The default data provider is the files_data_provider . The docker version of the server uses redis_data_provider as its default The parameters for redis_data_provider are: Parameter Description Required host Redis host. Defaults to 'localhost' No port Redis port. The default port is 6379 No secret Password to access database No The parameters for files_data_provider are: Parameter Description Required path Path to configuration files. Defaults to 'config' folder No This implementation has the limitation that writes operations have to be performed manually on the files. The parameters for restful_data_provider are: Parameter Description Required baseUrl Endpoint base url yes username Basic authentication username yes secret Basic authentication password yes","title":"Data Providers"},{"location":"api/resources/#user-resource","text":"This file can be found at 'config/users.yaml' in the root of this project. Property Description Required apiVersion Indicates the version of the resource (Not yet implemented) Yes kind Defines the type of resource Yes metadata.name Friendly name for the User device Yes spec.credentials.username User's credential username Yes spec.credentials.secret User's credential secret Yes Example # Users exist in Routr to perform administrative actions on the server - apiVersion : v1beta1 kind : User metadata : name : Administrator spec : credentials : username : admin secret : changeit","title":"User Resource"},{"location":"api/resources/#agent-resource","text":"This file can be found at 'config/agents.yaml' in the root of this project. Property Description Required apiVersion Indicates the version of the resource (Not yet implemented) Yes kind Defines the type of resource Yes metadata.name Friendly name for the SIP device Yes spec.credentials.username Agent's credential username Yes spec.credentials.secret Agent's credential secret Yes spec.domains[*] Context/s in which this Agent is allowed to communicate. FQDN is recommended Yes Example # Peers and Agents can register in Routr location service - apiVersion : v1beta1 kind : Agent metadata : name : John Doe spec : credentials : username : john secret : 1234 domains : [ sip.local ]","title":"Agent Resource"},{"location":"api/resources/#domain-resource","text":"This file can be found at 'config/domains.yaml' in the root of this project. Property Description Required apiVersion Indicates the version of the resource (Not yet implemented) Yes kind Defines the type of resource Yes metadata.name Friendly name for the SIP domain Yes spec.context.domainUri Domain URI. FQDN is recomended Yes spec.context.egressPolicy.rule Regular expression indicating when a call will be routed via $spec.context.egressPolicy.didRef No spec.context.egressPolicy.didRef Reference to the DID that will route the call No spec.context.accessControlList.allow[*] Traffic allow for Network in list No spec.context.accessControlList.deny[*] Traffic disabled for Network in list No Access Control List Rules may be in CIDR, IP/Mask, or single IP format. Example of rules are: - 0.0.0.0/1 # all - 192.168.1.0/255.255.255.0 - 192.168.0.1/31 Example - apiVersion : v1beta1 kind : Domain metadata : name : Local Server spec : context : domainUri : sip.local egressPolicy : rule : .* didRef : DID0001 accessControlList : deny : [ 0.0.0.0/1 ] # Deny all allow : [ 192.168.0.1/31 ]","title":"Domain Resource"},{"location":"api/resources/#gateway-resource","text":"This file can be found at 'config/gateways.yaml' in the root of this project. Property Description Required apiVersion Indicates the version of the resource (Not yet implemented) Yes kind Defines the type of resource Yes metadata.name Friendly name for the SIP device Yes metadata.ref Reference to this resource Yes spec.credentials.username Gateway username Yes spec.credentials.secret Gateway secret Yes spec.host Gateway host Yes spec.transport Transport protocol Yes spec.registries.[*] Additional registries for ingress calls No Example # Use gateway to register with a Sip Gateways or SBCs and send # or receive calls from the PSTN - apiVersion : v1beta1 kind : Gateway metadata : name : Provider, Inc ref : GW0001 spec : host : sip.provider.com transport : tcp credentials : username : user secret : changeit","title":"Gateway Resource"},{"location":"api/resources/#did-resource","text":"This file can be found at 'config/dids.yaml' in the root of this project. Property Description Required apiVersion Indicates the version of the resource (Not yet implemented) Yes kind Defines the type of resource Yes metadata.ref Reference to this resource Yes metadata.gwRef Reference to parent Gateway Yes metadata.geoInfo.city City of the DID No metadata.geoInfo.country Country of the DID No metadata.geoInfo.countryISOCode Country ISO code for the DID (ie.: US) No spec.location.telUrl DID URI available in the location server Yes spec.location.aorLink Address of record of SIP device for call routing Yes Example - apiVersion : v1beta1 kind : DID metadata : ref : DID0001 gwRef : GW0001 geoInfo : city : Columbus, GA country : USA countryISOCode : US spec : location : telUrl : tel:17066041487 aorLink : sip:john@sip.local","title":"DID Resource"},{"location":"api/resources/#peer-resource","text":"This file can be found at 'config/peers.yaml' in the root of this project. Property Description Required apiVersion Indicates the version of the resource (Not yet implemented) Yes kind Defines the type of resource Yes metadata.name Friendly name for the SIP device Yes spec.credentials.username Peer's credential username Yes spec.credentials.secret Peer's credential secret Yes spec.device When set it will be used by the location service No spec.contactAddr When set will advertise this as the contactURI No Example # Peers and Agents can register on Routr location service - apiVersion : v1beta1 kind : Peer metadata : name : Asterisk (Media Server) spec : credentials : username : ast secret : astsecret device : astserver # If is not define the IP address will be use contactAddr : 192.168.1.2:6060 This peer can be reached using ast@astserver .","title":"Peer Resource"},{"location":"configuration/agents/","text":"Coming soon!","title":"Agents Configuration"},{"location":"configuration/dids/","text":"Coming soon!","title":"Virtual Numbers(DIDs) Configuration"},{"location":"configuration/domains/","text":"Coming soon!","title":"Domains Configuration"},{"location":"configuration/gateways/","text":"Coming soon!","title":"Carriers(Gateways) Configuration"},{"location":"configuration/peers/","text":"Coming soon!","title":"Peers Configuration"},{"location":"configuration/users/","text":"Coming soon!","title":"Users Configuration"},{"location":"configuration/general/datasource/","text":"Coming soon!","title":"Datasource Setting"},{"location":"configuration/general/logging/","text":"Coming soon!","title":"Logging"},{"location":"configuration/general/restful-api/","text":"Coming soon!","title":"Restful API"},{"location":"configuration/general/signaling-security/","text":"Coming soon!","title":"Signaling Security(TLS)"},{"location":"configuration/general/transport/","text":"Coming soon!","title":"Transport Settings"},{"location":"guides/basic-setup/","text":"This is a step-by-step guide on VoIP setup at home or at the office. For calls to the PSTN you will need to have a sip provider like voip.ms or didlogic.com . Content Requirements Setting up the Server Configuring the Gateway Configuring the DID Creating a new Domain and EgressPolicy Creating the Agents Configuring the Sip devices Making calls What's Next Requirements This tutorial assumes the following: Two SIP phones connected to the same LAN A fresh installation of Routr SIP providers such as voip.ms or didlogic.com Setting up the Server A set of sample configuration converting this scenario can be found at basic sample files . You might overwrite the files in the config folder if you wish to skip this section. Configuring the Gateway To configure the Gateway you must consult your sip provider and obtain the credentials and registration host . The key fields for the configuration are metadata.ref , spec.regService.host and spec.regService.credentials . Here is an example: - apiVersion: v1beta1 kind: Gateway metadata: name: Provider Inc spec: regService: host: sip.provider.net credentials: username: youruser secret: yoursecret transport: udp Configuring the DID To configure your DID or virtual number, you must open and edit the file config/dids.yml . Notice in the example below, how your reference the Gateway by using the field metadata.geRef . The key field while configuring DIDs are spec.location.telUrl and spec.location.aorLink . Keep in mind that the value in spec.location.telUrl must be formatted exactly as sent by the provider. - apiVersion: v1beta1 kind: DID metadata: gwRef: gweef506 geoInfo: city: Columbus, GA country: USA countryISOCode: US spec: location: telUrl: tel:17066041487 aorLink: sip:1001@sip.local Creating a new Domain and EgressPolicy Routr is a Domain centric Sip Server. A Domain is used to group several Agents in the same context. The Domain URI can be an arbitrary name but we recommend using a fully qualified domain name (FQDN). You will also need to setup and EgressPolicy to allow calls outside the Domain. Here is how the file config/domains.yml needs to look like: - apiVersion: v1beta1 kind: Domain metadata: name: Local Office spec: context: domainUri: sip.local egressPolicy: rule: .* didRef: dd50baa4 Creating the Agents We will now create the Agents 1001 and 1002 . Keep in mind that field spec.credentials.username can be alphanumeric, so john or john001 is also acceptable. Pay close attention to the credentials block since it contains the username and secret for both Agents. - apiVersion: v1beta1 kind: Agent metadata: name: John Doe spec: credentials: username: 1001 secret: 1234 domains: [sip.local] - apiVersion: v1beta1 kind: Agent metadata: name: Janie Doe spec: credentials: username: 1002 secret: 1234 domains: [sip.local] To verify your configuration, start the server by issuing the command routr . In a separate window use the following commands: rctl get gateway rctl get did rctl get domain rctl get agents Your output should be as follows: Starting the Server Verifying the Configuration Configuring the Sip devices We are using \"Telephone\" for this example. You might use any softphone you wish, just keep in mind that the configuration will look slightly different. Configure your softphone using the information you gather in the last step. Start by completing only the required information: username , domain , password . Also, In the advanced section use the server's IP as your Registry Server and Proxy . Here is how mine looks like: Make sure to check the box \"Use this account\" to register your device If everything went well we just need to confirm that both softphones have registered correctly. Conveniently you can use the .rctl locate to obtain a list of \"online\" devices. This may seem like a lot of information. But what's relevant here is that both 1001 and 1002 are present in the location service and therefore can reach each other. Making calls This is a pretty easy step. If everything went well you will be able to call devices inside and outside your domain. Simply use the destination URI (eg.: or ). What\u2019s Next? You can check out the wiki to see more examples. If you have any questions start an issue or contact us via: Twitter: @fonoster Email:","title":"Basic Setup"},{"location":"guides/basic-setup/#requirements","text":"This tutorial assumes the following: Two SIP phones connected to the same LAN A fresh installation of Routr SIP providers such as voip.ms or didlogic.com","title":"Requirements"},{"location":"guides/basic-setup/#setting-up-the-server","text":"A set of sample configuration converting this scenario can be found at basic sample files . You might overwrite the files in the config folder if you wish to skip this section.","title":"Setting up the Server"},{"location":"guides/basic-setup/#configuring-the-gateway","text":"To configure the Gateway you must consult your sip provider and obtain the credentials and registration host . The key fields for the configuration are metadata.ref , spec.regService.host and spec.regService.credentials . Here is an example: - apiVersion: v1beta1 kind: Gateway metadata: name: Provider Inc spec: regService: host: sip.provider.net credentials: username: youruser secret: yoursecret transport: udp","title":"Configuring the Gateway"},{"location":"guides/basic-setup/#configuring-the-did","text":"To configure your DID or virtual number, you must open and edit the file config/dids.yml . Notice in the example below, how your reference the Gateway by using the field metadata.geRef . The key field while configuring DIDs are spec.location.telUrl and spec.location.aorLink . Keep in mind that the value in spec.location.telUrl must be formatted exactly as sent by the provider. - apiVersion: v1beta1 kind: DID metadata: gwRef: gweef506 geoInfo: city: Columbus, GA country: USA countryISOCode: US spec: location: telUrl: tel:17066041487 aorLink: sip:1001@sip.local","title":"Configuring the DID"},{"location":"guides/basic-setup/#creating-a-new-domain-and-egresspolicy","text":"Routr is a Domain centric Sip Server. A Domain is used to group several Agents in the same context. The Domain URI can be an arbitrary name but we recommend using a fully qualified domain name (FQDN). You will also need to setup and EgressPolicy to allow calls outside the Domain. Here is how the file config/domains.yml needs to look like: - apiVersion: v1beta1 kind: Domain metadata: name: Local Office spec: context: domainUri: sip.local egressPolicy: rule: .* didRef: dd50baa4","title":"Creating a new Domain and EgressPolicy"},{"location":"guides/basic-setup/#creating-the-agents","text":"We will now create the Agents 1001 and 1002 . Keep in mind that field spec.credentials.username can be alphanumeric, so john or john001 is also acceptable. Pay close attention to the credentials block since it contains the username and secret for both Agents. - apiVersion: v1beta1 kind: Agent metadata: name: John Doe spec: credentials: username: 1001 secret: 1234 domains: [sip.local] - apiVersion: v1beta1 kind: Agent metadata: name: Janie Doe spec: credentials: username: 1002 secret: 1234 domains: [sip.local] To verify your configuration, start the server by issuing the command routr . In a separate window use the following commands: rctl get gateway rctl get did rctl get domain rctl get agents Your output should be as follows: Starting the Server Verifying the Configuration","title":"Creating the Agents"},{"location":"guides/basic-setup/#configuring-the-sip-devices","text":"We are using \"Telephone\" for this example. You might use any softphone you wish, just keep in mind that the configuration will look slightly different. Configure your softphone using the information you gather in the last step. Start by completing only the required information: username , domain , password . Also, In the advanced section use the server's IP as your Registry Server and Proxy . Here is how mine looks like: Make sure to check the box \"Use this account\" to register your device If everything went well we just need to confirm that both softphones have registered correctly. Conveniently you can use the .rctl locate to obtain a list of \"online\" devices. This may seem like a lot of information. But what's relevant here is that both 1001 and 1002 are present in the location service and therefore can reach each other.","title":"Configuring the Sip devices"},{"location":"guides/basic-setup/#making-calls","text":"This is a pretty easy step. If everything went well you will be able to call devices inside and outside your domain. Simply use the destination URI (eg.: or ).","title":"Making calls"},{"location":"guides/basic-setup/#whats-next","text":"You can check out the wiki to see more examples. If you have any questions start an issue or contact us via: Twitter: @fonoster Email:","title":"What\u2019s Next?"},{"location":"guides/benchmarking/","text":"Coming soon!","title":"Benchmarking"},{"location":"guides/routr-as-asterisk-frontend/","text":"This guide explores the use case of using Asterisk merely as a Media Server and a more specialized software, like Routr , to take care of the signaling and resource management. In other words, Asterisk will be in charge of the ivrs, voice mail, call recording, while Routr deals with connecting Agents, Peers, and Gateways. The following illustration depicts our scenario: Content Requirements Configuration Overview Configuring Asterisk Calling Asterisk from John\u2019s device What\u2019s Next? Requirements This tutorial assumes the following: You have a SIP phone connected to the same LAN where Routr and Asterisk are in. If using a hardware phone, this can reach Asterisk and Routr and the other way around You have a fresh installation of Routr and Asterisk Before starting this guide make sure to have a fresh installation of Routr server. Configuration Overview With a fresh installation of Routr you will have most of the configuration you need to follow this tutorial. We, however, need to make some minor changes to configuration files to run our scenario. The first file we will examine and change is config/peers.yml . Make note of the username and secret for the Peer \"ast\" since we will be using this to configure Asterisk. Also, search for the field spec.device and change it to match the Agents domain( sip.local ). The file now will look similar to this: config/peers.yml - apiVersion: v1beta1 kind: Peer metadata: name: Asterisk PBX spec: device: sip.local credentials: username: ast secret: 1234 Head to the console and run the command rctl -- get peers to confirm that the Peer exist. The result should be as follows: Next, we focus our attention to domains.yml and agents.yml . With a fresh installation, we don't need to make any changes to this files. However, you could run the commands get domains and get agents to ensure that both, the Agent and the Domain, exist on the server. Your output should look similar to: Use the information in agents.yml to configure your SIP phone. The relevant information is found in spec.credentials . Mine looks like this: Make the adjustments based on your prefer SIP phone. You can verify that your device registered correctly with Routr by running the locate command: Configuring Asterisk Using PJSIP Backup your pjsip.conf and pjsip_wizard.conf . Update your pjsip.conf with the following: [transport-tcp] type=transport protocol=tcp bind=0.0.0.0:6060 Then, in your pjsip_wizard.conf: [routr] type = wizard sends_auth = yes sends_registrations = yes remote_hosts = 192.168.1.2 outbound_auth/username = ast outbound_auth/password = 1234 registration/retry_interval = 10 registration/expiration = 900 endpoint/allow = ulaw endpoint/allow = alaw endpoint/allow = opus endpoint/context = default transport = transport-tcp Using the \"old\" Chan SIP First backup your sip.conf . Then, replace your configuration and edit the file to reflect the following: [general] udpbindaddr=0.0.0.0:6060 context=default register = ast:1234@192.168.1.2:5060/1001 ; This information must match the credentials in `config/peers.yml` Configuring the Dialplan We are going to use a very simple dialplan to play a sound file. Again, make a backup of your configuration and replace its content with this: [default] exten = 1001,1,Answer exten = 1001,n,Playback(tt-monkeys) exten = 1001,n,Hangup Restart your Asterisk and check the location service. A new device will appear. Calling Asterisk from John's device We can now call ast@sip.local and if everything went well listen to a group of really annoying monkeys :). What\u2019s Next? You can check out the wiki to see more examples. If you have any questions start an issue or contact us via: Twitter: @fonoster Email:","title":"Routr as Asterisk frontend"},{"location":"guides/routr-as-asterisk-frontend/#requirements","text":"This tutorial assumes the following: You have a SIP phone connected to the same LAN where Routr and Asterisk are in. If using a hardware phone, this can reach Asterisk and Routr and the other way around You have a fresh installation of Routr and Asterisk Before starting this guide make sure to have a fresh installation of Routr server.","title":"Requirements"},{"location":"guides/routr-as-asterisk-frontend/#configuration-overview","text":"With a fresh installation of Routr you will have most of the configuration you need to follow this tutorial. We, however, need to make some minor changes to configuration files to run our scenario. The first file we will examine and change is config/peers.yml . Make note of the username and secret for the Peer \"ast\" since we will be using this to configure Asterisk. Also, search for the field spec.device and change it to match the Agents domain( sip.local ). The file now will look similar to this: config/peers.yml - apiVersion: v1beta1 kind: Peer metadata: name: Asterisk PBX spec: device: sip.local credentials: username: ast secret: 1234 Head to the console and run the command rctl -- get peers to confirm that the Peer exist. The result should be as follows: Next, we focus our attention to domains.yml and agents.yml . With a fresh installation, we don't need to make any changes to this files. However, you could run the commands get domains and get agents to ensure that both, the Agent and the Domain, exist on the server. Your output should look similar to: Use the information in agents.yml to configure your SIP phone. The relevant information is found in spec.credentials . Mine looks like this: Make the adjustments based on your prefer SIP phone. You can verify that your device registered correctly with Routr by running the locate command:","title":"Configuration Overview"},{"location":"guides/routr-as-asterisk-frontend/#configuring-asterisk","text":"Using PJSIP Backup your pjsip.conf and pjsip_wizard.conf . Update your pjsip.conf with the following: [transport-tcp] type=transport protocol=tcp bind=0.0.0.0:6060 Then, in your pjsip_wizard.conf: [routr] type = wizard sends_auth = yes sends_registrations = yes remote_hosts = 192.168.1.2 outbound_auth/username = ast outbound_auth/password = 1234 registration/retry_interval = 10 registration/expiration = 900 endpoint/allow = ulaw endpoint/allow = alaw endpoint/allow = opus endpoint/context = default transport = transport-tcp Using the \"old\" Chan SIP First backup your sip.conf . Then, replace your configuration and edit the file to reflect the following: [general] udpbindaddr=0.0.0.0:6060 context=default register = ast:1234@192.168.1.2:5060/1001 ; This information must match the credentials in `config/peers.yml` Configuring the Dialplan We are going to use a very simple dialplan to play a sound file. Again, make a backup of your configuration and replace its content with this: [default] exten = 1001,1,Answer exten = 1001,n,Playback(tt-monkeys) exten = 1001,n,Hangup Restart your Asterisk and check the location service. A new device will appear.","title":"Configuring Asterisk"},{"location":"guides/routr-as-asterisk-frontend/#calling-asterisk-from-johns-device","text":"We can now call ast@sip.local and if everything went well listen to a group of really annoying monkeys :).","title":"Calling Asterisk from John's device"},{"location":"guides/routr-as-asterisk-frontend/#whats-next","text":"You can check out the wiki to see more examples. If you have any questions start an issue or contact us via: Twitter: @fonoster Email:","title":"What\u2019s Next?"},{"location":"guides/routr-as-freeswitch-frontend/","text":"This guide explores the use case of using Asterisk merely as a Media Server and a more specialized software, like Routr , to take care of the signaling and resource management. In other words, Asterisk will be in charge of the ivrs, voice mail, call recording, while Routr deals with connecting Agents, Peers, and Gateways. The following illustration depicts our scenario: Content Requirements Configuration Overview Configuring Asterisk Calling Asterisk from John\u2019s device What\u2019s Next? Requirements This tutorial assumes the following: You have a SIP phone connected to the same LAN where Routr and Asterisk are in. If using a hardware phone, this can reach Asterisk and Routr and the other way around You have a fresh installation of Routr and Asterisk Before starting this guide make sure to have a fresh installation of Routr server. Configuration Overview With a fresh installation of Routr you will have most of the configuration you need to follow this tutorial. We, however, need to make some minor changes to configuration files to run our scenario. The first file we will examine and change is config/peers.yml . Make note of the username and secret for the Peer \"ast\" since we will be using this to configure Asterisk. Also, search for the field spec.device and change it to match the Agents domain( sip.local ). The file now will look similar to this: config/peers.yml - apiVersion: v1beta1 kind: Peer metadata: name: Asterisk PBX spec: device: sip.local credentials: username: ast secret: 1234 Head to the console and run the command rctl -- get peers to confirm that the Peer exist. The result should be as follows: Next, we focus our attention to domains.yml and agents.yml . With a fresh installation, we don't need to make any changes to this files. However, you could run the commands get domains and get agents to ensure that both, the Agent and the Domain, exist on the server. Your output should look similar to: Use the information in agents.yml to configure your SIP phone. The relevant information is found in spec.credentials . Mine looks like this: Make the adjustments based on your prefer SIP phone. You can verify that your device registered correctly with Routr by running the locate command: Configuring Asterisk Using PJSIP Backup your pjsip.conf and pjsip_wizard.conf . Update your pjsip.conf with the following: [transport-tcp] type=transport protocol=tcp bind=0.0.0.0:6060 Then, in your pjsip_wizard.conf: [routr] type = wizard sends_auth = yes sends_registrations = yes remote_hosts = 192.168.1.2 outbound_auth/username = ast outbound_auth/password = 1234 registration/retry_interval = 10 registration/expiration = 900 endpoint/allow = ulaw endpoint/allow = alaw endpoint/allow = opus endpoint/context = default transport = transport-tcp Using the \"old\" Chan SIP First backup your sip.conf . Then, replace your configuration and edit the file to reflect the following: [general] udpbindaddr=0.0.0.0:6060 context=default register = ast:1234@192.168.1.2:5060/1001 ; This information must match the credentials in `config/peers.yml` Configuring the Dialplan We are going to use a very simple dialplan to play a sound file. Again, make a backup of your configuration and replace its content with this: [default] exten = 1001,1,Answer exten = 1001,n,Playback(tt-monkeys) exten = 1001,n,Hangup Restart your Asterisk and check the location service. A new device will appear. Calling Asterisk from John's device We can now call ast@sip.local and if everything went well listen to a group of really annoying monkeys :). What\u2019s Next? You can check out the wiki to see more examples. If you have any questions start an issue or contact us via: Twitter: @fonoster Email:","title":"Routr as FreeSWITCH frontend"},{"location":"guides/routr-as-freeswitch-frontend/#requirements","text":"This tutorial assumes the following: You have a SIP phone connected to the same LAN where Routr and Asterisk are in. If using a hardware phone, this can reach Asterisk and Routr and the other way around You have a fresh installation of Routr and Asterisk Before starting this guide make sure to have a fresh installation of Routr server.","title":"Requirements"},{"location":"guides/routr-as-freeswitch-frontend/#configuration-overview","text":"With a fresh installation of Routr you will have most of the configuration you need to follow this tutorial. We, however, need to make some minor changes to configuration files to run our scenario. The first file we will examine and change is config/peers.yml . Make note of the username and secret for the Peer \"ast\" since we will be using this to configure Asterisk. Also, search for the field spec.device and change it to match the Agents domain( sip.local ). The file now will look similar to this: config/peers.yml - apiVersion: v1beta1 kind: Peer metadata: name: Asterisk PBX spec: device: sip.local credentials: username: ast secret: 1234 Head to the console and run the command rctl -- get peers to confirm that the Peer exist. The result should be as follows: Next, we focus our attention to domains.yml and agents.yml . With a fresh installation, we don't need to make any changes to this files. However, you could run the commands get domains and get agents to ensure that both, the Agent and the Domain, exist on the server. Your output should look similar to: Use the information in agents.yml to configure your SIP phone. The relevant information is found in spec.credentials . Mine looks like this: Make the adjustments based on your prefer SIP phone. You can verify that your device registered correctly with Routr by running the locate command:","title":"Configuration Overview"},{"location":"guides/routr-as-freeswitch-frontend/#configuring-asterisk","text":"Using PJSIP Backup your pjsip.conf and pjsip_wizard.conf . Update your pjsip.conf with the following: [transport-tcp] type=transport protocol=tcp bind=0.0.0.0:6060 Then, in your pjsip_wizard.conf: [routr] type = wizard sends_auth = yes sends_registrations = yes remote_hosts = 192.168.1.2 outbound_auth/username = ast outbound_auth/password = 1234 registration/retry_interval = 10 registration/expiration = 900 endpoint/allow = ulaw endpoint/allow = alaw endpoint/allow = opus endpoint/context = default transport = transport-tcp Using the \"old\" Chan SIP First backup your sip.conf . Then, replace your configuration and edit the file to reflect the following: [general] udpbindaddr=0.0.0.0:6060 context=default register = ast:1234@192.168.1.2:5060/1001 ; This information must match the credentials in `config/peers.yml` Configuring the Dialplan We are going to use a very simple dialplan to play a sound file. Again, make a backup of your configuration and replace its content with this: [default] exten = 1001,1,Answer exten = 1001,n,Playback(tt-monkeys) exten = 1001,n,Hangup Restart your Asterisk and check the location service. A new device will appear.","title":"Configuring Asterisk"},{"location":"guides/routr-as-freeswitch-frontend/#calling-asterisk-from-johns-device","text":"We can now call ast@sip.local and if everything went well listen to a group of really annoying monkeys :).","title":"Calling Asterisk from John's device"},{"location":"guides/routr-as-freeswitch-frontend/#whats-next","text":"You can check out the wiki to see more examples. If you have any questions start an issue or contact us via: Twitter: @fonoster Email:","title":"What\u2019s Next?"},{"location":"guides/running-on-kubernetes/","text":"Coming soon!","title":"Running on Kubernetes"},{"location":"guides/running-with-docker-or-compose/","text":"Coming soon!","title":"Running with Docker or Compose"},{"location":"guides/securing-the-signaling-path/","text":"Follow this guide to secure the signaling between your endpoints and Routr . Keep in mind that Routr will only secure the signaling and that the endpoints are ultimately responsible for securing the media. For this guide we will use a fictitious domain name to demonstrate the process of securing the signaling path Creating a Java Keystore(.JKS) Certificate Routr needs a keystore (.jks) in order to properly handling the certificates. The following steps will create a valid keystore file using a self-signed method or using the free Let's Encrypt service . Creating a self-signed Certificate Perhaps the easiest way to create a valid certificate for Routr is using a self-signed certificate. To generate the certificate change into etc/certs in your Routr installation and run the following script: keytool -genkey -keyalg RSA \\ -noprompt \\ -alias routr \\ -keystore domain-certs.jks \\ -storepass changeit \\ -keypass changeit \\ -validity 365 \\ -keysize 2048 \\ -dname CN=sip.ocean.com, OU=OSS, O=Your Company Inc, L=Sanford, ST=NC, C=US \\ -ext SAN = dns:sip.ocean.com,dns:localhost,ip:127.0.0.1 Remember to adjust the values to match your project's information. WSS will not work with a self-signed certificate. However, you can add a security exception by using https instead of wss in your browser's search bar and then accepting the security certificate. Creating a Certificate using Let\u2019s Encrypt The recommended way to create a valid certificate for Routr is using the free service Let's Encrypt . Please go to https://letsencrypt.org/ for details on how to install the required tooling. To generate the certificate, use the following steps: 1. Create keys certbot certonly --standalone -d sip.ocean.com --email admin@sip.ocean.com Change to the directory where the certificates were created(normally at /etc/letsencrypt/live/sip.ocean.com). 2. Create a PKCS12 file containing full chain and private key openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out pkcs.p12 -name domains-cert.jks Please make note of the password since you will need it in the following step and also for your settings in Routr . 3. Convert PKCS12 to Keystore keytool -importkeystore -srckeystore keystore.pkcs12 -srcstoretype PKCS12 -destkeystore domains-cert.jks Installing the Certificate in Routr To enable secure signaling in Routr , copy your certificate in etc/certs and edit the file config/config.yml to look like this: apiVersion: v1beta1 metadata: userAgent: Routr v1.0 spec: securityContext: keyStore: etc/certs/domains-cert.jks trustStore: etc/certs/domains-cert.jks keyStorePassword: changeit trustStorePassword: changeit keyStoreType: jks debugging: true # Enabled debug only for testing transport: - protocol: tls port: 5061 ... With the property spec.securityContext.debugging set to true you can get some valuable information about the status of the configuration. You can also test your configuration using the following command: openssl s_client -host 192.168.1.2 -port 5061 # Remember to use Routr s IP Setting up the Sip Phones For the purpose of this guide, we are using Blink Pro . Go to the account that you want to secure, select Advanced - Sip Signaling and change the parameter Primary Proxy to ${proxyHost}:${proxyPort};transport=tls . See the example in the following image: If everything went well you should see a green padlock like the one in the image bellow:","title":"Securing the Signaling Path"},{"location":"guides/securing-the-signaling-path/#creating-a-java-keystorejks-certificate","text":"Routr needs a keystore (.jks) in order to properly handling the certificates. The following steps will create a valid keystore file using a self-signed method or using the free Let's Encrypt service .","title":"Creating a Java Keystore(.JKS) Certificate"},{"location":"guides/securing-the-signaling-path/#creating-a-self-signed-certificate","text":"Perhaps the easiest way to create a valid certificate for Routr is using a self-signed certificate. To generate the certificate change into etc/certs in your Routr installation and run the following script: keytool -genkey -keyalg RSA \\ -noprompt \\ -alias routr \\ -keystore domain-certs.jks \\ -storepass changeit \\ -keypass changeit \\ -validity 365 \\ -keysize 2048 \\ -dname CN=sip.ocean.com, OU=OSS, O=Your Company Inc, L=Sanford, ST=NC, C=US \\ -ext SAN = dns:sip.ocean.com,dns:localhost,ip:127.0.0.1 Remember to adjust the values to match your project's information. WSS will not work with a self-signed certificate. However, you can add a security exception by using https instead of wss in your browser's search bar and then accepting the security certificate.","title":"Creating a self-signed Certificate"},{"location":"guides/securing-the-signaling-path/#creating-a-certificate-using-lets-encrypt","text":"The recommended way to create a valid certificate for Routr is using the free service Let's Encrypt . Please go to https://letsencrypt.org/ for details on how to install the required tooling. To generate the certificate, use the following steps: 1. Create keys certbot certonly --standalone -d sip.ocean.com --email admin@sip.ocean.com Change to the directory where the certificates were created(normally at /etc/letsencrypt/live/sip.ocean.com). 2. Create a PKCS12 file containing full chain and private key openssl pkcs12 -export -in fullchain.pem -inkey privkey.pem -out pkcs.p12 -name domains-cert.jks Please make note of the password since you will need it in the following step and also for your settings in Routr . 3. Convert PKCS12 to Keystore keytool -importkeystore -srckeystore keystore.pkcs12 -srcstoretype PKCS12 -destkeystore domains-cert.jks","title":"Creating a Certificate using Let\u2019s Encrypt"},{"location":"guides/securing-the-signaling-path/#installing-the-certificate-in-routr","text":"To enable secure signaling in Routr , copy your certificate in etc/certs and edit the file config/config.yml to look like this: apiVersion: v1beta1 metadata: userAgent: Routr v1.0 spec: securityContext: keyStore: etc/certs/domains-cert.jks trustStore: etc/certs/domains-cert.jks keyStorePassword: changeit trustStorePassword: changeit keyStoreType: jks debugging: true # Enabled debug only for testing transport: - protocol: tls port: 5061 ... With the property spec.securityContext.debugging set to true you can get some valuable information about the status of the configuration. You can also test your configuration using the following command: openssl s_client -host 192.168.1.2 -port 5061 # Remember to use Routr s IP","title":"Installing the Certificate in Routr"},{"location":"guides/securing-the-signaling-path/#setting-up-the-sip-phones","text":"For the purpose of this guide, we are using Blink Pro . Go to the account that you want to secure, select Advanced - Sip Signaling and change the parameter Primary Proxy to ${proxyHost}:${proxyPort};transport=tls . See the example in the following image: If everything went well you should see a green padlock like the one in the image bellow:","title":"Setting up the Sip Phones"},{"location":"introduction/community/","text":"Routr is developed in the open. Here are some of the channels we use to communicate and contribute: IRC : #routr on irc.freenode.net (for the easiest start, join via Riot ) (The IRC channel connects our Gitter and Slack communities) User mailing lists: routr-announce \u2013 for announcements like new releases routr-users \u2013 for discussions around Routr usage and community support Twitter: @Fonoster Issue tracker: Use the GitHub issue tracker for the various Routr repositories to file bugs and features request. If you need support, please send your questions to the routr-users mailing list rather than filing a GitHub issue. Please do not ask individual project members for support. Use the channels above instead, where the whole community can help you and benefit from the solutions provided. If community support is insufficient for your situation, please refer to the Commercial Support section below. Contributing We welcome community contributions! Please see the CONTRIBUTING.md file in the respective Routr repository for instructions on how to submit changes. If you are planning on making more elaborate or controversial changes, please discuss them on the mailing list before sending a pull request. Development mailing list: routr-developers \u2013 for discussions around Routr development Developer Summits We strive to be as open and public as possible. Technical discussions happen on the development list, our in-person meeting notes are public, and we have public calls. Below, you can find links to our developer summits at JConfDominicana 2019. These deveolper summits are open to join upon request as long as we have capacity. Preference is given to friendly projects and companies, plus diversity. Attendees are free not to be listed in the public meeting notes. 2019 developer summit notes (Come back to see updated link) Code of Conduct To make Routr a welcoming and harassment-free experience for everyone, we follow the Contributor Covenant Code of Conduct . Commercial Support This is a list of third-party companies and individuals who provide products or services related to Routr. Routr is an independent open source project which does not endorse any company. The list is provided in alphabetical order. Pedro Sanders (independent contractor) Acknowledgements Routr was initially started by Pedro Sanders . The majority of its development has been sponsored by Fonoster . The Routr logo was contributed by Pedro Sanders.","title":"Community"},{"location":"introduction/community/#contributing","text":"We welcome community contributions! Please see the CONTRIBUTING.md file in the respective Routr repository for instructions on how to submit changes. If you are planning on making more elaborate or controversial changes, please discuss them on the mailing list before sending a pull request. Development mailing list: routr-developers \u2013 for discussions around Routr development","title":"Contributing"},{"location":"introduction/community/#developer-summits","text":"We strive to be as open and public as possible. Technical discussions happen on the development list, our in-person meeting notes are public, and we have public calls. Below, you can find links to our developer summits at JConfDominicana 2019. These deveolper summits are open to join upon request as long as we have capacity. Preference is given to friendly projects and companies, plus diversity. Attendees are free not to be listed in the public meeting notes. 2019 developer summit notes (Come back to see updated link)","title":"Developer Summits"},{"location":"introduction/community/#code-of-conduct","text":"To make Routr a welcoming and harassment-free experience for everyone, we follow the Contributor Covenant Code of Conduct .","title":"Code of Conduct"},{"location":"introduction/community/#commercial-support","text":"This is a list of third-party companies and individuals who provide products or services related to Routr. Routr is an independent open source project which does not endorse any company. The list is provided in alphabetical order. Pedro Sanders (independent contractor)","title":"Commercial Support"},{"location":"introduction/community/#acknowledgements","text":"Routr was initially started by Pedro Sanders . The majority of its development has been sponsored by Fonoster . The Routr logo was contributed by Pedro Sanders.","title":"Acknowledgements"},{"location":"introduction/comparison/","text":"Coming soon!","title":"Comparison to Alternatives"},{"location":"introduction/faq/","text":"Here is a list of common questions we get. 1. How do I change the server's password? If you are using the files_data_provider then you must change the password in the users.yml file. For the redis_data_provider follow this steps: First run the command redis-cli smembers users to obtain the reference to the user. Here is an example: $ redis-cli smembers users 1) 5aa69ead8fd6861d92385bac Then, retrieve the document for reference running redis-cli get {REF} . For example $ redis-cli get 5aa69ead8fd6861d92385bac {\\ apiVersion\\ :\\ v1beta1\\ ,\\ kind\\ :\\ User\\ ,\\ metadata\\ :{\\ name\\ :\\ Ctl\\ ,\\ ref\\ :\\ 5aa69ead8fd6861d92385bac\\ },\\ spec\\ :{\\ credentials\\ :{\\ username\\ :\\ admin\\ ,\\ secret\\ :\\ oldpass\\ }}} Finally, search and change the old password and update your document using redis-cli set {REF} {DOCUMENT} . Like this: $ redis-cli set 5aa69ead8fd6861d92385bac {\\ apiVersion\\ :\\ v1beta1\\ ,\\ kind\\ :\\ User\\ ,\\ metadata\\ :{\\ name\\ :\\ Ctl\\ ,\\ ref\\ :\\ 5aa69ead8fd6861d92385bac\\ },\\ spec\\ :{\\ credentials\\ :{\\ username\\ :\\ admin\\ ,\\ secret\\ :\\ newpass\\ }}} A new token will be issued after your next login with rctl 2. How can I use rctl from a remote host? By default Routr installs a certificate that only allows for connections using the localhost or 127.0.0.1 . To use rctl tool from a remote host, you must generate a certificate that accepts connections to the desired domain name or ip and update the spec.restService section of the config.yml . Here is an example using a self-signed certificate(usually enough). keytool -genkey -keyalg RSA \\ -noprompt \\ -alias routr \\ -keystore api-cert.jks \\ -storepass changeit \\ -keypass changeit \\ -validity 365 \\ -keysize 2048 \\ -dname CN=domain.com, OU=OSS, O=Your Company Inc, L=Sanford, ST=NC, C=US \\ -ext SAN = dns:your.domain.com,dns:localhost,ip:127.0.0.1 Remember to place the certificate in the etc/certs folder","title":"FAQ"},{"location":"introduction/faq/#1-how-do-i-change-the-servers-password","text":"If you are using the files_data_provider then you must change the password in the users.yml file. For the redis_data_provider follow this steps: First run the command redis-cli smembers users to obtain the reference to the user. Here is an example: $ redis-cli smembers users 1) 5aa69ead8fd6861d92385bac Then, retrieve the document for reference running redis-cli get {REF} . For example $ redis-cli get 5aa69ead8fd6861d92385bac {\\ apiVersion\\ :\\ v1beta1\\ ,\\ kind\\ :\\ User\\ ,\\ metadata\\ :{\\ name\\ :\\ Ctl\\ ,\\ ref\\ :\\ 5aa69ead8fd6861d92385bac\\ },\\ spec\\ :{\\ credentials\\ :{\\ username\\ :\\ admin\\ ,\\ secret\\ :\\ oldpass\\ }}} Finally, search and change the old password and update your document using redis-cli set {REF} {DOCUMENT} . Like this: $ redis-cli set 5aa69ead8fd6861d92385bac {\\ apiVersion\\ :\\ v1beta1\\ ,\\ kind\\ :\\ User\\ ,\\ metadata\\ :{\\ name\\ :\\ Ctl\\ ,\\ ref\\ :\\ 5aa69ead8fd6861d92385bac\\ },\\ spec\\ :{\\ credentials\\ :{\\ username\\ :\\ admin\\ ,\\ secret\\ :\\ newpass\\ }}} A new token will be issued after your next login with rctl","title":"1. How do I change the server's password?"},{"location":"introduction/faq/#2-how-can-i-use-rctl-from-a-remote-host","text":"By default Routr installs a certificate that only allows for connections using the localhost or 127.0.0.1 . To use rctl tool from a remote host, you must generate a certificate that accepts connections to the desired domain name or ip and update the spec.restService section of the config.yml . Here is an example using a self-signed certificate(usually enough). keytool -genkey -keyalg RSA \\ -noprompt \\ -alias routr \\ -keystore api-cert.jks \\ -storepass changeit \\ -keypass changeit \\ -validity 365 \\ -keysize 2048 \\ -dname CN=domain.com, OU=OSS, O=Your Company Inc, L=Sanford, ST=NC, C=US \\ -ext SAN = dns:your.domain.com,dns:localhost,ip:127.0.0.1 Remember to place the certificate in the etc/certs folder","title":"2. How can I use rctl from a remote host?"},{"location":"introduction/glossary/","text":"This following table features some important concepts, including the different routing types implemented by the server. Concept Description User Users perform administrative actions on the server Agent Agents represent SIP endpoints such as softphones and IP phones Domain Enables the creation of isolated groups of Agents Peer Similar to Agents but without Domain boundaries Gateway SIP entity that allows call termination DID Routes and translate calls between the PSTN and Routr Intra-Domain Routing Routing type for calling within the same Domain Domain Ingress Routing Calling from the PSTN to an Agent or Peer Domain Egress Routing Calling from an Agent to the PSTN thru a Gateway Peer Egress Routing Similar to DER but applies only to Peers","title":"Glossary"},{"location":"introduction/installation/","text":"There are no special requirements to install the server. Just download, decompress, and move the folder to a location of your choice. Download the Server Platform Download Linux tar.gz macOS tar.gz Windows tar.gz , zip Docker img Or Build from Source Building from source requires of Java 1.8+, Gradle, and NPM git clone https://github.com/fonoster/routr cd routr npm i npm run pack Running with Docker docker pull fonoster/routr docker run -it \\ -p 4567 :4567 \\ -p 5060 :5060 \\ -p 5060 :5060/udp \\ -p 5061 -5063:5061-5063 \\ -e ROUTR_EXTERN_ADDR = ${ your host address } \\ fonoster/routr Running in any other Plattform To start the server just run the script ./routr at the root of this project. Your output will look similar to this: $ ./routr [ INFO ] Starting Routr [ INFO ] Listening @ 172 .18.0.4:5060 [ udp ] [ INFO ] Listening @ 172 .18.0.4:5060 [ tcp ] [ INFO ] Listening @ 172 .18.0.4:5061 [ tls ] [ INFO ] Starting Location service [ INFO ] Starting Registry service [ INFO ] Starting Restful service on port 4567","title":"Installation"},{"location":"introduction/installation/#download-the-server","text":"Platform Download Linux tar.gz macOS tar.gz Windows tar.gz , zip Docker img","title":"Download the Server"},{"location":"introduction/installation/#or-build-from-source","text":"Building from source requires of Java 1.8+, Gradle, and NPM git clone https://github.com/fonoster/routr cd routr npm i npm run pack","title":"Or Build from Source"},{"location":"introduction/installation/#running-with-docker","text":"docker pull fonoster/routr docker run -it \\ -p 4567 :4567 \\ -p 5060 :5060 \\ -p 5060 :5060/udp \\ -p 5061 -5063:5061-5063 \\ -e ROUTR_EXTERN_ADDR = ${ your host address } \\ fonoster/routr","title":"Running with Docker"},{"location":"introduction/installation/#running-in-any-other-plattform","text":"To start the server just run the script ./routr at the root of this project. Your output will look similar to this: $ ./routr [ INFO ] Starting Routr [ INFO ] Listening @ 172 .18.0.4:5060 [ udp ] [ INFO ] Listening @ 172 .18.0.4:5060 [ tcp ] [ INFO ] Listening @ 172 .18.0.4:5061 [ tls ] [ INFO ] Starting Location service [ INFO ] Starting Registry service [ INFO ] Starting Restful service on port 4567","title":"Running in any other Plattform"},{"location":"introduction/media/","text":"Coming soon!","title":"Media"},{"location":"introduction/overview/","text":"Routr is a lightweight sip proxy, location server, and registrar that provides a reliable and scalable SIP infrastructure for telephony carriers, communication service providers, and integrators. It also provides with capabilities that are suitable for the enterprise and personal needs. To get involved in the development of this project please contact us at @fonoster . Features Proxy Registrar Service Location Service Call Forking Multi-Tenancy/Multi-Domain Access to the PSTN Using SIP Gateways Transport: TCP, UDP, TLS, WebSocket Data Sources: Redis, RESTful API, Files Security Digest SIP User Authentication Domain Access Control List (DACL) RESTful service secured with TLS and JWT tokens Rest API Command Line Tool for Admin Operations Routing Capabilities Intra-Domain Routing (IDR) Domain Ingress Routing(DIR) Domain Egress Routing (DER) Peer Egress Routing (PER)","title":"Overview"},{"location":"introduction/overview/#features","text":"Proxy Registrar Service Location Service Call Forking Multi-Tenancy/Multi-Domain Access to the PSTN Using SIP Gateways Transport: TCP, UDP, TLS, WebSocket Data Sources: Redis, RESTful API, Files Security Digest SIP User Authentication Domain Access Control List (DACL) RESTful service secured with TLS and JWT tokens Rest API Command Line Tool for Admin Operations Routing Capabilities Intra-Domain Routing (IDR) Domain Ingress Routing(DIR) Domain Egress Routing (DER) Peer Egress Routing (PER)","title":"Features"},{"location":"introduction/roadmap/","text":"Coming soon!","title":"Roadmap"}]} \ No newline at end of file diff --git a/site/sitemap.xml b/site/sitemap.xml new file mode 100644 index 000000000..688a26de0 --- /dev/null +++ b/site/sitemap.xml @@ -0,0 +1,158 @@ + + + + https://routr.io/docs/introduction/overview/ + 2018-12-31 + daily + + + https://routr.io/docs/introduction/installation/ + 2018-12-31 + daily + + + https://routr.io/docs/introduction/comparison/ + 2018-12-31 + daily + + + https://routr.io/docs/introduction/community/ + 2018-12-31 + daily + + + https://routr.io/docs/introduction/faq/ + 2018-12-31 + daily + + + https://routr.io/docs/introduction/roadmap/ + 2018-12-31 + daily + + + https://routr.io/docs/introduction/media/ + 2018-12-31 + daily + + + https://routr.io/docs/introduction/glossary/ + 2018-12-31 + daily + + + https://routr.io/docs/concepts/ + 2018-12-31 + daily + + + https://routr.io/docs/configuration/general/transport/ + 2018-12-31 + daily + + + https://routr.io/docs/configuration/general/signaling-security/ + 2018-12-31 + daily + + + https://routr.io/docs/configuration/general/restful-api/ + 2018-12-31 + daily + + + https://routr.io/docs/configuration/general/datasource/ + 2018-12-31 + daily + + + https://routr.io/docs/configuration/general/logging/ + 2018-12-31 + daily + + + https://routr.io/docs/configuration/users/ + 2018-12-31 + daily + + + https://routr.io/docs/configuration/gateways/ + 2018-12-31 + daily + + + https://routr.io/docs/configuration/dids/ + 2018-12-31 + daily + + + https://routr.io/docs/configuration/domains/ + 2018-12-31 + daily + + + https://routr.io/docs/configuration/agents/ + 2018-12-31 + daily + + + https://routr.io/docs/configuration/peers/ + 2018-12-31 + daily + + + https://routr.io/docs/administration/cli/ + 2018-12-31 + daily + + + https://routr.io/docs/administration/webconsole/ + 2018-12-31 + daily + + + https://routr.io/docs/api/reference/ + 2018-12-31 + daily + + + https://routr.io/docs/api/resources/ + 2018-12-31 + daily + + + https://routr.io/docs/guides/basic-setup/ + 2018-12-31 + daily + + + https://routr.io/docs/guides/routr-as-asterisk-frontend/ + 2018-12-31 + daily + + + https://routr.io/docs/guides/routr-as-freeswitch-frontend/ + 2018-12-31 + daily + + + https://routr.io/docs/guides/securing-the-signaling-path/ + 2018-12-31 + daily + + + https://routr.io/docs/guides/running-with-docker-or-compose/ + 2018-12-31 + daily + + + https://routr.io/docs/guides/running-on-kubernetes/ + 2018-12-31 + daily + + + https://routr.io/docs/guides/benchmarking/ + 2018-12-31 + daily + + \ No newline at end of file diff --git a/site/sitemap.xml.gz b/site/sitemap.xml.gz new file mode 100644 index 000000000..1883d3042 Binary files /dev/null and b/site/sitemap.xml.gz differ diff --git a/site/theme/assets/images/favicon.png b/site/theme/assets/images/favicon.png new file mode 100644 index 000000000..23ccc2bac Binary files /dev/null and b/site/theme/assets/images/favicon.png differ diff --git a/site/theme/assets/images/icons/bitbucket.svg b/site/theme/assets/images/icons/bitbucket.svg new file mode 100644 index 000000000..a25435af3 --- /dev/null +++ b/site/theme/assets/images/icons/bitbucket.svg @@ -0,0 +1,20 @@ + + + diff --git a/site/theme/assets/images/icons/github.svg b/site/theme/assets/images/icons/github.svg new file mode 100644 index 000000000..c009420a7 --- /dev/null +++ b/site/theme/assets/images/icons/github.svg @@ -0,0 +1,18 @@ + + + diff --git a/site/theme/assets/images/icons/gitlab.svg b/site/theme/assets/images/icons/gitlab.svg new file mode 100644 index 000000000..9e3d6f05b --- /dev/null +++ b/site/theme/assets/images/icons/gitlab.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/site/theme/assets/stylesheets/_config.scss b/site/theme/assets/stylesheets/_config.scss new file mode 100644 index 000000000..8a612f7e0 --- /dev/null +++ b/site/theme/assets/stylesheets/_config.scss @@ -0,0 +1,93 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Variables: typography +// ---------------------------------------------------------------------------- + +// Modular typographic scale +$ms-base: 1.6rem; +$ms-ratio: $major-third; + +// ---------------------------------------------------------------------------- +// Variables: breakpoints +// ---------------------------------------------------------------------------- + +// stylelint-disable unit-whitelist + +// Device-specific breakpoints +$break-devices: ( + mobile: ( + portrait: px2em(220px) px2em(479px), + landscape: px2em(480px) px2em(719px) + ), + tablet: ( + portrait: px2em(720px) px2em(959px), + landscape: px2em(960px) px2em(1219px) + ), + screen: ( + small: px2em(1220px) px2em(1599px), + medium: px2em(1600px) px2em(1999px), + large: px2em(2000px) + ) +); + +// stylelint-enable unit-whitelist + +// ---------------------------------------------------------------------------- +// Variables: base colors +// ---------------------------------------------------------------------------- + +// Primary and accent colors +$md-color-primary: $clr-indigo-500 !default; +$md-color-accent: $clr-indigo-a200 !default; + +// Shades of black +$md-color-black: hsla(0, 0%, 0%, 0.87) !default; +$md-color-black--light: hsla(0, 0%, 0%, 0.54) !default; +$md-color-black--lighter: hsla(0, 0%, 0%, 0.26) !default; +$md-color-black--lightest: hsla(0, 0%, 0%, 0.07) !default; +$md-color-black--transparent: hsla(0, 0%, 0%, 0) !default; + +// Shades of white +$md-color-white: hsla(0, 0%, 100%, 1) !default; +$md-color-white--light: hsla(0, 0%, 100%, 0.7) !default; +$md-color-white--lighter: hsla(0, 0%, 100%, 0.3) !default; +$md-color-white--lightest: hsla(0, 0%, 100%, 0.12) !default; +$md-color-white--transparent: hsla(0, 0%, 100%, 0) !default; + +// ---------------------------------------------------------------------------- +// Variables: sizing and spacing +// ---------------------------------------------------------------------------- + +// Icons +$md-icon-size: $ms-base * 1.5; +$md-icon-padding: $ms-base * 0.5; +$md-icon-margin: $ms-base * 0.25; + +// Code blocks +$md-code-background: hsla(0, 0%, 92.5%, 0.5); +$md-code-color: #37474F; + +// Keystrokes +$md-keyboard-background: #FCFCFC; +$md-keyboard-color: #555555; diff --git a/site/theme/assets/stylesheets/_shame.scss b/site/theme/assets/stylesheets/_shame.scss new file mode 100644 index 000000000..31326ac51 --- /dev/null +++ b/site/theme/assets/stylesheets/_shame.scss @@ -0,0 +1,25 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Nothing to see here, move along +// ---------------------------------------------------------------------------- diff --git a/site/theme/assets/stylesheets/application-palette.scss b/site/theme/assets/stylesheets/application-palette.scss new file mode 100644 index 000000000..48af85de4 --- /dev/null +++ b/site/theme/assets/stylesheets/application-palette.scss @@ -0,0 +1,323 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Dependencies +// ---------------------------------------------------------------------------- + +@import "modularscale"; +@import "material-color"; +@import "material-shadows"; + +// ---------------------------------------------------------------------------- +// Local imports +// ---------------------------------------------------------------------------- + +@import "helpers/break"; +@import "helpers/px2em"; + +@import "config"; + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Color tile for presentation in theme documentation +button[data-md-color-primary], +button[data-md-color-accent] { + width: 13rem; + margin-bottom: 0.4rem; + padding: 2.4rem 0.8rem 0.4rem; + transition: + background-color 0.25s, + opacity 0.25s; + border-radius: 0.2rem; + color: $md-color-white; + font-size: ms(-1); + text-align: left; + cursor: pointer; + + // Hovered color tile + &:hover { + opacity: 0.75; + } +} + +// Build primary colors +@each $name, $color in ( + "red": $clr-red-400, + "pink": $clr-pink-500, + "purple": $clr-purple-400, + "deep-purple": $clr-deep-purple-400, + "indigo": $clr-indigo-500, + "blue": $clr-blue-500, + "light-blue": $clr-light-blue-500, + "cyan": $clr-cyan-500, + "teal": $clr-teal-500, + "green": $clr-green-500, + "light-green": $clr-light-green-600, + "lime": $clr-lime-600, + "yellow": $clr-yellow-800, + "amber": $clr-amber-700, + "orange": $clr-orange-600, + "deep-orange": $clr-deep-orange-400, + "brown": $clr-brown-500, + "grey": $clr-grey-600, + "blue-grey": $clr-blue-grey-600 +) { + + // Color tile for presentation in theme documentation + button[data-md-color-primary="#{$name}"] { + background-color: $color; + } + + // Color palette + [data-md-color-primary="#{$name}"] { + + // Links in typesetted content + .md-typeset a { + color: $color; + } + + // Application header (stays always on top) + .md-header { + background-color: $color; + } + + // Hero teaser + .md-hero { + background-color: $color; + } + + // Current or active link + .md-nav__link:active, + .md-nav__link--active { + color: $color; + } + + // Reset active color for nested list titles + .md-nav__item--nested > .md-nav__link { + color: inherit; + } + + // [tablet portrait -]: Layered navigation + @include break-to-device(tablet portrait) { + + // Repository containing source + .md-nav__source { + background-color: mix($color, $md-color-black, 75%); + } + } + + // [tablet -]: Layered navigation + @include break-to-device(tablet) { + + // Site title in main navigation + html & .md-nav--primary .md-nav__title--site { + background-color: $color; + } + } + + // [screen +]: Set background color for tabs + @include break-from-device(screen) { + + // Tabs with outline + .md-tabs { + background-color: $color; + } + } + } +} + +// Color tile for presentation in theme documentation +button[data-md-color-primary="white"] { + background-color: $md-color-white; + color: $md-color-black; + box-shadow: 0 0 0.1rem $md-color-black--light inset; +} + +// Overrides for white color +[data-md-color-primary="white"] { + + // Application header (stays always on top) + .md-header { + background-color: $md-color-white; + color: $md-color-black; + } + + // Hero teaser + .md-hero { + background-color: $md-color-white; + color: $md-color-black; + + // Add a border if there are no tabs + &--expand { + border-bottom: 0.1rem solid $md-color-black--lightest; + } + } + + // [tablet portrait -]: Layered navigation + @include break-to-device(tablet portrait) { + + // Repository containing source + .md-nav__source { + background-color: $md-color-black--lightest; + color: $md-color-black; + } + } + + // [tablet portrait +]: Change color of search input + @include break-from-device(tablet landscape) { + + // Search input + .md-search__input { + background-color: $md-color-black--lightest; + + // Search input placeholder + &::placeholder { + color: $md-color-black--light; + } + } + } + + // [tablet -]: Layered navigation + @include break-to-device(tablet) { + + // Site title in main navigation + html & .md-nav--primary .md-nav__title--site { + background-color: $md-color-white; + color: $md-color-black; + } + + // Hero teaser + .md-hero { + border-bottom: 0.1rem solid $md-color-black--lightest; + } + } + + // [screen +]: Set background color for tabs + @include break-from-device(screen) { + + // Tabs with outline + .md-tabs { + border-bottom: 0.1rem solid $md-color-black--lightest; + background-color: $md-color-white; + color: $md-color-black; + } + } +} + +// Build accent colors +@each $name, $color in ( + "red": $clr-red-a400, + "pink": $clr-pink-a400, + "purple": $clr-purple-a200, + "deep-purple": $clr-deep-purple-a200, + "indigo": $clr-indigo-a200, + "blue": $clr-blue-a200, + "light-blue": $clr-light-blue-a700, + "cyan": $clr-cyan-a700, + "teal": $clr-teal-a700, + "green": $clr-green-a700, + "light-green": $clr-light-green-a700, + "lime": $clr-lime-a700, + "yellow": $clr-yellow-a700, + "amber": $clr-amber-a700, + "orange": $clr-orange-a400, + "deep-orange": $clr-deep-orange-a200 +) { + + // Color tile for presentation in theme documentation + button[data-md-color-accent="#{$name}"] { + background-color: $color; + } + + // Color palette + [data-md-color-accent="#{$name}"] { + + // Typesetted content + .md-typeset { + + // Hovered and active links + a:hover, + a:active { + color: $color; + } + + // Hovered scrollbar thumb + pre code::-webkit-scrollbar-thumb:hover, + .codehilite pre::-webkit-scrollbar-thumb:hover { + background-color: $color; + } + + // Copy to clipboard active icon + .md-clipboard:hover::before, + .md-clipboard:active::before { + color: $color; + } + + // Active or targeted back reference + .footnote li:hover .footnote-backref:hover, + .footnote li:target .footnote-backref { + color: $color; + } + + // Active, targeted or focused permalink + [id]:hover .headerlink:hover, + [id]:target .headerlink, + [id] .headerlink:focus { + color: $color; + } + } + + // Focused or hovered link + .md-nav__link:focus, + .md-nav__link:hover { + color: $color; + } + + // Search container scrollbar thumb + .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: $color; + } + + // Search result link + .md-search-result__link { + + // Active or hovered link + &[data-md-state="active"], + &:hover { + background-color: transparentize($color, 0.9); + } + } + + // Wrapper for scrolling on overflow + .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: $color; + } + + // Source file icon + .md-source-file:hover::before { + background-color: $color; + } + } +} diff --git a/site/theme/assets/stylesheets/application.scss b/site/theme/assets/stylesheets/application.scss new file mode 100644 index 000000000..e135d9381 --- /dev/null +++ b/site/theme/assets/stylesheets/application.scss @@ -0,0 +1,69 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Dependencies +// ---------------------------------------------------------------------------- + +@import "modularscale"; +@import "material-color"; +@import "material-shadows"; + +// ---------------------------------------------------------------------------- +// Local imports +// ---------------------------------------------------------------------------- + +@import "helpers/break"; +@import "helpers/px2em"; + +@import "config"; + +@import "base/reset"; +@import "base/icons"; +@import "base/typeset"; + +@import "layout/base"; +@import "layout/clipboard"; +@import "layout/content"; +@import "layout/header"; +@import "layout/hero"; +@import "layout/footer"; +@import "layout/nav"; +@import "layout/search"; +@import "layout/sidebar"; +@import "layout/source"; +@import "layout/tabs"; + +@import "extensions/admonition"; +@import "extensions/codehilite"; +@import "extensions/footnotes"; +@import "extensions/permalinks"; + +@import "extensions/pymdown/arithmatex"; +@import "extensions/pymdown/critic"; +@import "extensions/pymdown/details"; +@import "extensions/pymdown/emoji"; +@import "extensions/pymdown/inlinehilite"; +@import "extensions/pymdown/superfences"; +@import "extensions/pymdown/tasklist"; + +@import "shame"; diff --git a/site/theme/assets/stylesheets/base/_icons.scss b/site/theme/assets/stylesheets/base/_icons.scss new file mode 100644 index 000000000..aaf4e9e1d --- /dev/null +++ b/site/theme/assets/stylesheets/base/_icons.scss @@ -0,0 +1,81 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// stylelint-disable font-family-no-missing-generic-family-keyword + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Icon placeholders +%md-icon { + font-family: "Material Icons"; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: 1; + text-transform: none; + white-space: nowrap; + speak: none; + word-wrap: normal; + direction: ltr; + + // Icon rendered as button + &__button { + display: inline-block; + margin: $md-icon-margin; + padding: $md-icon-padding; + font-size: $md-icon-size; + cursor: pointer; + } +} + +// Representational classes +.md-icon { + @extend %md-icon; + + // Build representational classes + @each $ligature, $name in ( + "\E5C4": "arrow-back", // arrow_back + "\E5C8": "arrow-forward", // arrow_forward + "\E5D2": "menu", // menu + "\E8B6": "search" // search + ) { + &--#{$name}::before { + content: $ligature; + } + } + + // Adjust for RTL languages + [dir="rtl"] & { + + // Flip ligatures for arrows + @each $ligature, $name in ( + "\E5C8": "arrow-back", // arrow_forward + "\E5C4": "arrow-forward" // arrow_back + ) { + &--#{$name}::before { + content: $ligature; + } + } + } +} diff --git a/site/theme/assets/stylesheets/base/_reset.scss b/site/theme/assets/stylesheets/base/_reset.scss new file mode 100644 index 000000000..73bbd6bf2 --- /dev/null +++ b/site/theme/assets/stylesheets/base/_reset.scss @@ -0,0 +1,132 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// stylelint-disable no-duplicate-selectors + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Enforce correct box model +html { + box-sizing: border-box; +} + +// All elements shall inherit the document default +*, +*::before, +*::after { + box-sizing: inherit; +} + +// Prevent adjustments of font size after orientation changes in IE and iOS +html { + text-size-adjust: none; +} + +// Remove margin in all browsers +body { + margin: 0; +} + +// Reset horizontal rules in FF +hr { + overflow: visible; + box-sizing: content-box; +} + +// Remove gaps in underlined links in iOS >= 8 and Safari >= 8 +a { + -webkit-text-decoration-skip: objects; +} + +// Reset tap outlines on iOS and Android +a, +button, +label, +input { + -webkit-tap-highlight-color: transparent; +} + +// Reset link styles +a { + color: inherit; + text-decoration: none; +} + +// Normalize font-size in all browsers +small { + font-size: 80%; +} + +// Prevent subscript and superscript from affecting line-height +sub, +sup { + position: relative; + font-size: 80%; + line-height: 0; + vertical-align: baseline; +} + +// Correct subscript offset +sub { + bottom: -0.25em; +} + +// Correct superscript offset +sup { + top: -0.5em; +} + +// Remove borders on images +img { + border-style: none; +} + +// Reset table styles +table { + border-collapse: separate; + border-spacing: 0; +} + +// Reset table cell styles +td, +th { + font-weight: normal; + vertical-align: top; +} + +// Reset (native) button styles +button { + margin: 0; + padding: 0; + border: 0; + outline-style: none; + background: transparent; + font-size: inherit; +} + +// Reset (native) input styles +input { + border: 0; + outline: 0; +} diff --git a/site/theme/assets/stylesheets/base/_typeset.scss b/site/theme/assets/stylesheets/base/_typeset.scss new file mode 100644 index 000000000..2e89c8a55 --- /dev/null +++ b/site/theme/assets/stylesheets/base/_typeset.scss @@ -0,0 +1,492 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules: font definitions +// ---------------------------------------------------------------------------- + +// Enable font-smoothing in Webkit and FF +body { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +// Default fonts +body, +input { + color: $md-color-black; + font-feature-settings: "kern", "liga"; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} + +// Proportionally spaced fonts +pre, +code, +kbd { + color: $md-color-black; + font-feature-settings: "kern"; + font-family: "Courier New", Courier, monospace; +} + +// ---------------------------------------------------------------------------- +// Rules: typesetted content +// ---------------------------------------------------------------------------- + +// Content that is typeset - if possible, all margins, paddings and font sizes +// should be set in ems, so nested blocks (e.g. Admonition) render correctly, +// except headlines that should only appear on the top level and need to have +// consistent spacing due to layout constraints. +.md-typeset { + font-size: ms(0); + line-height: 1.6; + + // Colors should be kept when printing + -webkit-print-color-adjust: exact; + + // Default spacing + p, + ul, + ol, + blockquote { + margin: 1em 0; + } + + // 1st level headline + h1 { + margin: 0 0 4rem; + color: $md-color-black--light; + font-size: ms(3); + font-weight: 300; + letter-spacing: -0.01em; + line-height: 1.3; + } + + // 2nd level headline + h2 { + margin: 4rem 0 1.6rem; + font-size: ms(2); + font-weight: 300; + letter-spacing: -0.01em; + line-height: 1.4; + } + + // 3rd level headline + h3 { + margin: 3.2rem 0 1.6rem; + font-size: ms(1); + font-weight: 400; + letter-spacing: -0.01em; + line-height: 1.5; + } + + // 3rd level headline following an 2nd level headline + h2 + h3 { + margin-top: 1.6rem; + } + + // 4th level headline + h4 { + margin: 1.6rem 0; + font-size: ms(0); + font-weight: 700; + letter-spacing: -0.01em; + } + + // 5th and 6th level headline + h5, + h6 { + margin: 1.6rem 0; + color: $md-color-black--light; + font-size: ms(-1); + font-weight: 700; + letter-spacing: -0.01em; + } + + // Overrides for 5th level headline + h5 { + text-transform: uppercase; + } + + // Horizontal separators + hr { + margin: 1.5em 0; + border-bottom: 0.1rem dotted $md-color-black--lighter; + } + + // Links + a { + color: $md-color-primary; + word-break: break-word; + + // Also enable color transition on pseudo elements + &, + &::before { + transition: color 0.125s; + } + + // Hovered and active links + &:hover, + &:active { + color: $md-color-accent; + } + + // Add URLs for print + @media print { + + // Show link URL + &::after { + color: $md-color-black--light; + content: " [" attr(href) "]"; + } + } + } + + // Code blocks + code, + pre { + background-color: $md-code-background; + color: $md-code-color; + font-size: 85%; + direction: ltr; + + // Wrap text and hide scollbars + @media print { + white-space: pre-wrap; + } + } + + // Inline code blocks, correct relative ems for smaller font size + code { + $correct: 1 / 0.85; + + margin: 0 0.25em * $correct; + padding: 0.0625em * $correct 0; + border-radius: 0.2rem; + box-shadow: + +0.25em * $correct 0 0 $md-code-background, + -0.25em * $correct 0 0 $md-code-background; + word-break: break-word; + box-decoration-break: clone; + + // Remove box-shadows for print + @media print { + box-shadow: none; + box-decoration-break: initial; + } + } + + // Disable containing block inside headlines + h1 code, + h2 code, + h3 code, + h4 code, + h5 code, + h6 code { + margin: 0; + background-color: transparent; + box-shadow: none; + } + + // Reset code if it's inside a link + a > code { + margin: inherit; + padding: inherit; + border-radius: none; + background-color: inherit; + color: inherit; + box-shadow: none; + } + + // Unformatted code blocks + pre { + position: relative; + margin: 1em 0; + border-radius: 0.2rem; + line-height: 1.4; + -webkit-overflow-scrolling: touch; + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 1em -1.6rem; + border-radius: 0; + } + + // Actual container with code, overflowing + > code { + display: block; + margin: 0; + padding: 1.05rem 1.2rem; + background-color: transparent; + font-size: inherit; + box-shadow: none; + box-decoration-break: none; + overflow: auto; + + // [mobile -]: Increase padding to match text + @include break-to-device(mobile) { + padding: 1.05rem 1.6rem; + } + + // Override native scrollbar styles + &::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; + } + + // Style scrollbar thumb + &::-webkit-scrollbar-thumb { + background-color: $md-color-black--lighter; + + // Hovered scrollbar thumb + &:hover { + background-color: $md-color-accent; + } + } + } + } + + // Keystrokes + kbd { + $correct: 1 / 0.85; + + padding: 0 0.25em * $correct; + border: 0.1rem solid darken($md-keyboard-background, 20%); + border-radius: 0.3rem; + border-bottom-color: darken($md-keyboard-background, 25%); + background-color: $md-keyboard-background; + color: $md-keyboard-color; + font-size: 85%; + box-shadow: 0 0.1rem 0 darken($md-keyboard-background, 30%); + word-break: break-word; + } + + // Text highlighting marker + mark { + margin: 0 0.25em; + padding: 0.0625em 0; + border-radius: 0.2rem; + background-color: transparentize($clr-yellow-500, 0.5); + box-shadow: + +0.25em 0 0 transparentize($clr-yellow-500, 0.5), + -0.25em 0 0 transparentize($clr-yellow-500, 0.5); + word-break: break-word; + box-decoration-break: clone; + } + + // Abbreviations + abbr { + border-bottom: 0.1rem dotted $md-color-black--light; + text-decoration: none; + cursor: help; + } + + // Small text + small { + opacity: 0.75; + } + + // Superscript and subscript + sup, + sub { + margin-left: 0.0625em * 1 / 0.8; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 0.0625em * 1 / 0.8; + margin-left: initial; + } + } + + // Blockquotes, possibly nested + blockquote { + padding-left: 1.2rem; + border-left: 0.4rem solid $md-color-black--lighter; + color: $md-color-black--light; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 1.2rem; + padding-left: initial; + border-right: 0.4rem solid $md-color-black--lighter; + border-left: initial; + } + } + + // Unordered lists + ul { + list-style-type: disc; + } + + // Unordered and ordered lists + ul, + ol { + margin-left: 0.625em; + padding: 0; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 0.625em; + margin-left: initial; + } + + // Nested ordered lists + ol { + list-style-type: lower-alpha; + + // Triply nested ordered list + ol { + list-style-type: lower-roman; + } + } + + // List elements + li { + margin-bottom: 0.5em; + margin-left: 1.25em; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 1.25em; + margin-left: initial; + } + + // Decrease vertical spacing + p, + blockquote { + margin: 0.5em 0; + } + + // Remove margin on last element + &:last-child { + margin-bottom: 0; + } + + // Nested lists + ul, + ol { + margin: 0.5em 0 0.5em 0.625em; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 0.625em; + margin-left: initial; + } + } + } + } + + // Definition lists + dd { + margin: 1em 0 1em 1.875em; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 1.875em; + margin-left: initial; + } + } + + // Limit width to container + iframe, + img, + svg { + max-width: 100%; + } + + // Data tables + table:not([class]) { + @include z-depth(2); + + display: inline-block; + max-width: 100%; + border-radius: 0.2rem; + font-size: ms(-1); + overflow: auto; + -webkit-overflow-scrolling: touch; + + // Due to margin collapse because of the necessary inline-block hack, we + // cannot increase the bottom margin on the table, so we just increase the + // top margin on the following element + & + * { + margin-top: 1.5em; + } + + // Table headings and cells + th:not([align]), + td:not([align]) { + text-align: left; + + // Adjust for RTL languages + [dir="rtl"] & { + text-align: right; + } + } + + // Table headings + th { + min-width: 10rem; + padding: 1.2rem 1.6rem; + background-color: $md-color-black--light; + color: $md-color-white; + vertical-align: top; + } + + // Table cells + td { + padding: 1.2rem 1.6rem; + border-top: 0.1rem solid $md-color-black--lightest; + vertical-align: top; + } + + // Remove top border on first row + tr:first-child td { + border-top: 0; + } + + // Do not wrap links in tables + a { + word-break: normal; + } + } + + // Wrapper for scrolling on overflow + &__scrollwrap { + margin: 1em -1.6rem; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } + + // Data table wrapper, in case JavaScript is available + .md-typeset__table { + display: inline-block; + margin-bottom: 0.5em; + padding: 0 1.6rem; + + // Data tables + table { + display: table; + width: 100%; + margin: 0; + overflow: hidden; + } + } +} diff --git a/site/theme/assets/stylesheets/extensions/_admonition.scss b/site/theme/assets/stylesheets/extensions/_admonition.scss new file mode 100644 index 000000000..7dfeeccdf --- /dev/null +++ b/site/theme/assets/stylesheets/extensions/_admonition.scss @@ -0,0 +1,144 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Admonition extension + .admonition { + @include z-depth(2); + + position: relative; + margin: 1.5625em 0; + padding: 0 1.2rem; + border-left: 0.4rem solid $clr-blue-a200; + border-radius: 0.2rem; + font-size: ms(-1); + overflow: auto; + + // Adjust for RTL languages + [dir="rtl"] & { + border-right: 0.4rem solid $clr-blue-a200; + border-left: none; + } + + // Adjust spacing on last element + html & > :last-child { + margin-bottom: 1.2rem; + } + + // Adjust margin for nested admonition blocks + .admonition { + margin: 1em 0; + } + + // Title + > .admonition-title { + margin: 0 -1.2rem; + padding: 0.8rem 1.2rem 0.8rem 4rem; + border-bottom: 0.1rem solid transparentize($clr-blue-a200, 0.9); + background-color: transparentize($clr-blue-a200, 0.9); + font-weight: 700; + + // Adjust for RTL languages + [dir="rtl"] & { + padding: 0.8rem 4rem 0.8rem 1.2rem; + } + + // Reset spacing, if title is the only element + &:last-child { + margin-bottom: 0; + } + + // Icon + &::before { + @extend %md-icon; + + position: absolute; + left: 1.2rem; + color: $clr-blue-a200; + font-size: 2rem; + content: "\E3C9"; // edit + + // Adjust for RTL languages + [dir="rtl"] & { + right: 1.2rem; + left: initial; + } + } + } + + // Build representational classes + @each $names, $appearance in ( + abstract summary tldr: $clr-light-blue-a400 "\E8D2", // subject + info todo: $clr-cyan-a700 "\E88E", // info + tip hint important : $clr-teal-a700 "\E80E", // whatshot + success check done: $clr-green-a700 "\E876", // done + question help faq: $clr-light-green-a700 "\E887", // help + warning caution attention: $clr-orange-a400 "\E002", // warning + failure fail missing: $clr-red-a200 "\E14C", // clear + danger error: $clr-red-a400 "\E3E7", // flash_on + bug: $clr-pink-a400 "\E868", // bug_report + example: $clr-deep-purple-a400 "\E242", // format_list_numbered + quote cite: $clr-grey "\E244" // format_quote + ) { + $tint: nth($appearance, 1); + $icon: nth($appearance, 2); + + // Define base class + &%#{nth($names, 1)}, + &.#{nth($names, 1)} { + border-left-color: $tint; + + // Adjust for RTL languages + [dir="rtl"] & { + border-right-color: $tint; + } + + // Title + > .admonition-title { + border-bottom-color: 0.1rem solid transparentize($tint, 0.9); + background-color: transparentize($tint, 0.9); + + // Icon + &::before { + color: $tint; + content: $icon; + } + } + } + + // Define synonyms for base class + @if length($names) > 1 { + @for $n from 2 through length($names) { + &.#{nth($names, $n)} { + @extend .admonition%#{nth($names, 1)}; + } + } + } + } + } +} diff --git a/site/theme/assets/stylesheets/extensions/_codehilite.scss b/site/theme/assets/stylesheets/extensions/_codehilite.scss new file mode 100644 index 000000000..b2778ff16 --- /dev/null +++ b/site/theme/assets/stylesheets/extensions/_codehilite.scss @@ -0,0 +1,373 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Variables +// ---------------------------------------------------------------------------- + +// Operators +$codehilite-operator: inherit; +$codehilite-operator-word: inherit; + +// Generics +$codehilite-generic-emph: #000000; +$codehilite-generic-error: #AA0000; +$codehilite-generic-heading: #999999; +$codehilite-generic-output: #888888; +$codehilite-generic-prompt: #555555; +$codehilite-generic-strong: inherit; +$codehilite-generic-subheading: #AAAAAA; +$codehilite-generic-traceback: #AA0000; + +// Diffs +$codehilite-diff-deleted: #FFDDDD; +$codehilite-diff-inserted: #DDFFDD; + +// Keywords +$codehilite-keyword: #3B78E7; +$codehilite-keyword-constant: #A71D5D; +$codehilite-keyword-declaration: #3B78E7; +$codehilite-keyword-namespace: #3B78E7; +$codehilite-keyword-pseudo: #A71D5D; +$codehilite-keyword-reserved: #3E61A2; +$codehilite-keyword-type: #3E61A2; + +// Comments +$codehilite-comment: #999999; +$codehilite-comment-multiline: #999999; +$codehilite-comment-preproc: #666666; +$codehilite-comment-single: #999999; +$codehilite-comment-shebang: #999999; +$codehilite-comment-special: #999999; + +// Names +$codehilite-name-attribute: #C2185B; +$codehilite-name-builtin: #C2185B; +$codehilite-name-builtin-pseudo: #3E61A2; +$codehilite-name-class: #C2185B; +$codehilite-name-constant: #3E61A2; +$codehilite-name-decorator: #666666; +$codehilite-name-entity: #666666; +$codehilite-name-exception: #C2185B; +$codehilite-name-function: #C2185B; +$codehilite-name-label: #3B5179; +$codehilite-name-namespace: #EC407A; +$codehilite-name-tag: #3B78E7; +$codehilite-name-variable: #3E61A2; +$codehilite-name-variable-class: #3E61A2; +$codehilite-name-variable-instance: #3E61A2; +$codehilite-name-variable-global: #3E61A2; +$codehilite-name-extension: #EC407A; + +// Numbers +$codehilite-literal-number: #E74C3C; +$codehilite-literal-number-float: #E74C3C; +$codehilite-literal-number-hex: #E74C3C; +$codehilite-literal-number-integer: #E74C3C; +$codehilite-literal-number-integer-long: #E74C3C; +$codehilite-literal-number-oct: #E74C3C; + +// Strings +$codehilite-literal-string: #0D904F; +$codehilite-literal-string-backticks: #0D904F; +$codehilite-literal-string-char: #0D904F; +$codehilite-literal-string-doc: #999999; +$codehilite-literal-string-double: #0D904F; +$codehilite-literal-string-escape: #183691; +$codehilite-literal-string-heredoc: #183691; +$codehilite-literal-string-interpol: #183691; +$codehilite-literal-string-other: #183691; +$codehilite-literal-string-regex: #009926; +$codehilite-literal-string-single: #0D904F; +$codehilite-literal-string-symbol: #0D904F; + +// Miscellaneous +$codehilite-error: #A61717; +$codehilite-whitespace: transparent; + +// ---------------------------------------------------------------------------- +// Rules: syntax highlighting +// ---------------------------------------------------------------------------- + +// Codehilite extension +.codehilite { + + // Operators + .o { color: $codehilite-operator; } + .ow { color: $codehilite-operator-word; } + + // Generics + .ge { color: $codehilite-generic-emph; } + .gr { color: $codehilite-generic-error; } + .gh { color: $codehilite-generic-heading; } + .go { color: $codehilite-generic-output; } + .gp { color: $codehilite-generic-prompt; } + .gs { color: $codehilite-generic-strong; } + .gu { color: $codehilite-generic-subheading; } + .gt { color: $codehilite-generic-traceback; } + + // Diffs + .gd { background-color: $codehilite-diff-deleted; } + .gi { background-color: $codehilite-diff-inserted; } + + // Keywords + .k { color: $codehilite-keyword; } + .kc { color: $codehilite-keyword-constant; } + .kd { color: $codehilite-keyword-declaration; } + .kn { color: $codehilite-keyword-namespace; } + .kp { color: $codehilite-keyword-pseudo; } + .kr { color: $codehilite-keyword-reserved; } + .kt { color: $codehilite-keyword-type; } + + // Comments + .c { color: $codehilite-comment; } + .cm { color: $codehilite-comment-multiline; } + .cp { color: $codehilite-comment-preproc; } + .c1 { color: $codehilite-comment-single; } + .ch { color: $codehilite-comment-shebang; } + .cs { color: $codehilite-comment-special; } + + // Names + .na { color: $codehilite-name-attribute; } + .nb { color: $codehilite-name-builtin; } + .bp { color: $codehilite-name-builtin-pseudo; } + .nc { color: $codehilite-name-class; } + .no { color: $codehilite-name-constant; } + .nd { color: $codehilite-name-entity; } + .ni { color: $codehilite-name-entity; } + .ne { color: $codehilite-name-exception; } + .nf { color: $codehilite-name-function; } + .nl { color: $codehilite-name-label; } + .nn { color: $codehilite-name-namespace; } + .nt { color: $codehilite-name-tag; } + .nv { color: $codehilite-name-variable; } + .vc { color: $codehilite-name-variable-class; } + .vg { color: $codehilite-name-variable-global; } + .vi { color: $codehilite-name-variable-instance; } + .nx { color: $codehilite-name-extension; } + + // Numbers + .m { color: $codehilite-literal-number; } + .mf { color: $codehilite-literal-number-float; } + .mh { color: $codehilite-literal-number-hex; } + .mi { color: $codehilite-literal-number-integer; } + .il { color: $codehilite-literal-number-integer-long; } + .mo { color: $codehilite-literal-number-oct; } + + // Strings + .s { color: $codehilite-literal-string; } + .sb { color: $codehilite-literal-string-backticks; } + .sc { color: $codehilite-literal-string-char; } + .sd { color: $codehilite-literal-string-doc; } + .s2 { color: $codehilite-literal-string-double; } + .se { color: $codehilite-literal-string-escape; } + .sh { color: $codehilite-literal-string-heredoc; } + .si { color: $codehilite-literal-string-interpol; } + .sx { color: $codehilite-literal-string-other; } + .sr { color: $codehilite-literal-string-regex; } + .s1 { color: $codehilite-literal-string-single; } + .ss { color: $codehilite-literal-string-symbol; } + + // Miscellaneous + .err { color: $codehilite-error; } + .w { color: $codehilite-whitespace; } + + // Highlighted lines + .hll { + display: block; + margin: 0 -1.2rem; + padding: 0 1.2rem; + background-color: transparentize($clr-yellow-500, 0.5); + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 0 -1.6rem; + padding: 0 1.6rem; + } + } +} + +// ---------------------------------------------------------------------------- +// Rules: layout +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // If code blocks are wrapped with codehilite, the styles must be adjusted + // so the marker stretches to the whole width and the padding is respected + .codehilite { + position: relative; + margin: 1em 0; + padding: 0; + border-radius: 0.2rem; + background-color: $md-code-background; + color: $md-code-color; + line-height: 1.4; + -webkit-overflow-scrolling: touch; + + // Actual container with code, overflowing + pre, + code { + display: block; + margin: 0; + padding: 1.05rem 1.2rem; + background-color: transparent; + overflow: auto; + vertical-align: top; + + // Override native scrollbar styles + &::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; + } + + // Style scrollbar thumb + &::-webkit-scrollbar-thumb { + background-color: $md-color-black--lighter; + + // Hovered scrollbar thumb + &:hover { + background-color: $md-color-accent; + } + } + } + } + + // If not using Pygments, code will be under pre > code + pre.codehilite { + overflow: visible; + + // Actual container with code, overflowing + code { + display: block; + padding: 1.05rem 1.2rem; + overflow: auto; + } + } + + // Block with line numbers + .codehilitetable { + display: block; + margin: 1em 0; + border-radius: 0.2em; + font-size: ms(0); + overflow: hidden; + + // Set table elements to block layout, because otherwise the whole flexbox + // hacking won't work correctly + tbody, + td { + display: block; + padding: 0; + } + + // We need to use flexbox layout, because otherwise it's not possible to + // make the code container scroll while keeping the line numbers static + tr { + display: flex; + } + + // The pre tags are nested inside a table, so we need to remove the + // margin because it collapses below all the overflows + .codehilite, + .linenodiv { + margin: 0; + border-radius: 0; + } + + // Add spacing to line number container + .linenodiv { + padding: 1.05rem 1.2rem; + } + + // Disable user selection, so code can be easily copied without + // accidentally also copying the line numbers + .linenos { + background-color: $md-color-black--lightest; + color: $md-color-black--lighter; + user-select: none; + + // Reset spacings + pre { + margin: 0; + padding: 0; + background-color: transparent; + color: inherit; + text-align: right; + } + } + + // The table cell containing the code container wrapper and code should + // stretch horizontally to the remaining space + .code { + flex: 1; + overflow: hidden; + } + } + + // Full-width container + > .codehilite { + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 1em -1.6rem; + border-radius: 0; + + // Actual container with code, overflowing + pre, + code { + padding: 1.05rem 1.6rem; + } + } + } + + // Full-width container on top-level + > .codehilitetable { + box-shadow: none; + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 1em -1.6rem; + border-radius: 0; + + // Increase spacing + .codehilite > pre, + .codehilite > code, + .linenodiv { + padding: 1rem 1.6rem; + } + } + } + + // When pymdownx.superfences is enabled but codehilite is disabled, + // pymdownx.highlight will be used. When this happens, the outer + // container and tables get this class names by default. + .highlight { + @extend .codehilite; + } + + // Same as above, but for code blocks with line numbers enabled + .highlighttable { + @extend .codehilitetable; + } +} diff --git a/site/theme/assets/stylesheets/extensions/_footnotes.scss b/site/theme/assets/stylesheets/extensions/_footnotes.scss new file mode 100644 index 000000000..6b6518dfb --- /dev/null +++ b/site/theme/assets/stylesheets/extensions/_footnotes.scss @@ -0,0 +1,149 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // All footnote references + [id^="fnref:"] { + display: inline-block; + + // Targeted anchor + &:target { + margin-top: -(4.8rem + 1.2rem + 1.6rem); + padding-top: (4.8rem + 1.2rem + 1.6rem); + pointer-events: none; + } + } + + // All footnote back references + [id^="fn:"] { + + // Add spacing to anchor for offset + &::before { + display: none; + height: 0; + content: ""; + } + + // Targeted anchor + &:target::before { + display: block; + margin-top: -(4.8rem + 1.2rem + 1rem); + padding-top: (4.8rem + 1.2rem + 1rem); + pointer-events: none; + } + } + + // Footnotes extension + .footnote { + color: $md-color-black--light; + font-size: ms(-1); + + // Remove additional spacing on footnotes + ol { + margin-left: 0; + } + + // Footnote + li { + transition: color 0.25s; + + // Darken color for targeted footnote + &:target { + color: $md-color-black; + } + + // Remove spacing on first element + :first-child { + margin-top: 0; + } + + // Make back references visible on hover + &:hover .footnote-backref, + &:target .footnote-backref { + transform: translateX(0); + opacity: 1; + } + + // Active or targeted back reference + &:hover .footnote-backref:hover, + &:target .footnote-backref { + color: $md-color-accent; + } + } + } + + // Footnote reference + .footnote-ref { + display: inline-block; + pointer-events: initial; + + // Render a thin line before footnote + &::before { + display: inline; + margin: 0 0.2em; + border-left: 0.1rem solid $md-color-black--lighter; + font-size: 1.25em; + content: ""; + vertical-align: -0.5rem; + } + } + + // Footnote back reference + .footnote-backref { + @extend %md-icon; + + display: inline-block; + transform: translateX(0.5rem); + transition: + transform 0.25s 0.125s, + color 0.25s, + opacity 0.125s 0.125s; + color: $md-color-black--lighter; + // Hack: remove Unicode arrow for icon + font-size: 0; + opacity: 0; + vertical-align: text-bottom; + + // Adjust for RTL languages + [dir="rtl"] & { + transform: translateX(-0.5rem); + } + + // Back reference icon + &::before { + display: inline-block; + font-size: 1.6rem; + content: "\E31B"; // keyboard_return + + // Adjust for RTL languages + [dir="rtl"] & { + transform: scaleX(-1) + } + } + } +} diff --git a/site/theme/assets/stylesheets/extensions/_permalinks.scss b/site/theme/assets/stylesheets/extensions/_permalinks.scss new file mode 100644 index 000000000..ef0b89ae7 --- /dev/null +++ b/site/theme/assets/stylesheets/extensions/_permalinks.scss @@ -0,0 +1,99 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Permalinks extension + .headerlink { + display: inline-block; + margin-left: 1rem; + transform: translate(0, 0.5rem); + transition: + transform 0.25s 0.25s, + color 0.25s, + opacity 0.125s 0.25s; + opacity: 0; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 1rem; + margin-left: initial; + } + + // Higher specificity for color due to palettes integration + html body & { + color: $md-color-black--lighter; + } + + // Hide for print + @media print { + display: none; + } + } + + // Correct anchor offset for link blurring + @each $level, $delta in ( + h1: 0.9rem, + h2: 0.8rem, + h3: 0.9rem, + h4: 0.9rem, + h5: 1.1rem, + h6: 1.1rem + ) { + #{$level}[id] { + + // Un-targeted anchor + &::before { + display: block; + margin-top: -$delta; + padding-top: $delta; + content: ""; + } + + // Targeted anchor (48px from header, 12px from sidebar offset) + &:target::before { + margin-top: -(4.8rem + 1.2rem + $delta); + padding-top: (4.8rem + 1.2rem + $delta); + } + + // Make permalink visible on hover + &:hover .headerlink, + &:target .headerlink, + & .headerlink:focus { + transform: translate(0, 0); + opacity: 1; + } + + // Active or targeted permalink + &:hover .headerlink:hover, + &:target .headerlink, + & .headerlink:focus { + color: $md-color-accent; + } + } + } +} diff --git a/site/theme/assets/stylesheets/extensions/pymdown/_arithmatex.scss b/site/theme/assets/stylesheets/extensions/pymdown/_arithmatex.scss new file mode 100644 index 000000000..2ad22cbe7 --- /dev/null +++ b/site/theme/assets/stylesheets/extensions/pymdown/_arithmatex.scss @@ -0,0 +1,54 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// stylelint-disable selector-class-pattern + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // MathJax integration - add padding to omit vertical scrollbar + .MJXc-display { + margin: 0.75em 0; + padding: 0.75em 0; + overflow: auto; + -webkit-overflow-scrolling: touch; + } + + // Stretch top-level containers + > p > .MJXc-display { + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 0.75em -1.6rem; + padding: 0.25em 1.6rem; + } + } + + // Remove outline on tab index + .MathJax_CHTML { + outline: 0; + } +} diff --git a/site/theme/assets/stylesheets/extensions/pymdown/_critic.scss b/site/theme/assets/stylesheets/extensions/pymdown/_critic.scss new file mode 100644 index 000000000..4aba7ebf2 --- /dev/null +++ b/site/theme/assets/stylesheets/extensions/pymdown/_critic.scss @@ -0,0 +1,93 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Deletions, additions and comments + del.critic, + ins.critic, + .critic.comment { + margin: 0 0.25em; + padding: 0.0625em 0; + border-radius: 0.2rem; + box-decoration-break: clone; + } + + // Deletion + del.critic { + background-color: $codehilite-diff-deleted; // TODO: dependent on order of inclusion + box-shadow: + +0.25em 0 0 $codehilite-diff-deleted, + -0.25em 0 0 $codehilite-diff-deleted; + } + + // Addition + ins.critic { + background-color: $codehilite-diff-inserted; // TODO: dependent on order of inclusion + box-shadow: + +0.25em 0 0 $codehilite-diff-inserted, + -0.25em 0 0 $codehilite-diff-inserted; + } + + // Comment + .critic.comment { + background-color: $md-code-background; // TODO: rename, centralize somehow + color: $md-code-color; + box-shadow: + +0.25em 0 0 $md-code-background, + -0.25em 0 0 $md-code-background; + + // Icon + &::before { + @extend %md-icon; + + padding-right: 0.125em; + color: $md-color-black--lighter; + content: "\E0B7"; // chat + vertical-align: -0.125em; + } + } + + // Block + .critic.block { + display: block; + margin: 1em 0; + padding-right: 1.6rem; + padding-left: 1.6rem; + box-shadow: none; + + // Decrease spacing on first element + :first-child { + margin-top: 0.5em; + } + + // Decrease spacing on last element + :last-child { + margin-bottom: 0.5em; + } + } +} diff --git a/site/theme/assets/stylesheets/extensions/pymdown/_details.scss b/site/theme/assets/stylesheets/extensions/pymdown/_details.scss new file mode 100644 index 000000000..ee8d29909 --- /dev/null +++ b/site/theme/assets/stylesheets/extensions/pymdown/_details.scss @@ -0,0 +1,109 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Details extension + details { + @extend .admonition; + + display: block; + padding-top: 0; + + // Rotate title icon + &[open] > summary::after { + transform: rotate(180deg); + } + + // Remove bottom spacing + &:not([open]) { + padding-bottom: 0; + + // Remove bottom border if block is closed + > summary { + border-bottom: none; + } + } + + // Increase spacing to the right - scoped here for higher specificity + summary { + padding-right: 4rem; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-left: 4rem; + } + } + + // Manually hide and show, if browser doesn't support details + .no-details &:not([open]) { + + // Hide all nested tags ... + > * { + display: none; + } + + // ... but show title + summary { + display: block; + } + } + } + + // Title + summary { + @extend .admonition-title; + + // Hack: set to block, so Firefox doesn't render marker + display: block; + outline: none; + cursor: pointer; + + // Remove default details marker + &::-webkit-details-marker { + display: none; + } + + // Icon + &::after { + @extend %md-icon; + + position: absolute; + top: 0.8rem; + right: 1.2rem; + color: $md-color-black--lighter; + font-size: 2rem; + content: "\E313"; // keyboard_arrow_down + + // Adjust for RTL languages + [dir="rtl"] & { + right: initial; + left: 1.2rem; + } + } + } +} diff --git a/site/theme/assets/stylesheets/extensions/pymdown/_emoji.scss b/site/theme/assets/stylesheets/extensions/pymdown/_emoji.scss new file mode 100644 index 000000000..f2cd14ab7 --- /dev/null +++ b/site/theme/assets/stylesheets/extensions/pymdown/_emoji.scss @@ -0,0 +1,35 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Correct alignment of emojis + .emojione { + width: 2rem; + vertical-align: text-top; + } +} diff --git a/site/theme/assets/stylesheets/extensions/pymdown/_inlinehilite.scss b/site/theme/assets/stylesheets/extensions/pymdown/_inlinehilite.scss new file mode 100644 index 000000000..3f2d236ec --- /dev/null +++ b/site/theme/assets/stylesheets/extensions/pymdown/_inlinehilite.scss @@ -0,0 +1,37 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Qualified class selector to distinguish inline code from code blocks + code.codehilite { + $correct: 1 / 0.85; + + margin: 0 0.25em * $correct; + padding: 0.0625em * $correct 0; + } +} diff --git a/site/theme/assets/stylesheets/extensions/pymdown/_superfences.scss b/site/theme/assets/stylesheets/extensions/pymdown/_superfences.scss new file mode 100644 index 000000000..c3dde1aff --- /dev/null +++ b/site/theme/assets/stylesheets/extensions/pymdown/_superfences.scss @@ -0,0 +1,100 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Tabbed code block content + .superfences-content { + display: none; + order: 99; + width: 100%; + background-color: $md-color-white; + + // Actual content + > * { + margin: 0; + border-radius: 0 + } + } + + // Tabbed code block container + .superfences-tabs { + display: flex; + position: relative; + flex-wrap: wrap; + margin: 1em 0; + border: 0.1rem solid $md-color-black--lightest; + border-radius: 0.2em; + + // Hide radio buttons + > input { + display: none; + + // Active tab label + &:checked + label { + font-weight: 700; + + // Show code tab content + & + .superfences-content { + display: block; + } + } + } + + // Tab label + > label { + width: auto; + padding: 1.2rem 1.2rem; + transition: color 0.125s; + font-size: ms(-1); + cursor: pointer; + + // Hovered tab label + html &:hover { + color: $md-color-accent; + } + } + } + + // Full-width container on top-level + > .superfences-tabs { + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 1em -1.6rem; + border: 0; + border-top: 0.1rem solid $md-color-black--lightest; + border-radius: 0; + + // Actual container with code, overflowing + pre, + code { + padding: 1.05rem 1.6rem; + } + } + } +} diff --git a/site/theme/assets/stylesheets/extensions/pymdown/_tasklist.scss b/site/theme/assets/stylesheets/extensions/pymdown/_tasklist.scss new file mode 100644 index 000000000..be6ae8f44 --- /dev/null +++ b/site/theme/assets/stylesheets/extensions/pymdown/_tasklist.scss @@ -0,0 +1,83 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Remove list icon on task items + .task-list-item { + position: relative; + list-style-type: none; + + // Make checkbox items align with normal list items, but position + // everything in ems for correct layout at smaller font sizes + [type="checkbox"] { + position: absolute; + top: 0.45em; + left: -2em; + + // Adjust for RTL languages + [dir="rtl"] & { + right: -2em; + left: initial; + } + } + } + + // Wrapper for list controls, in case custom checkboxes are enabled + .task-list-control { + + // Checkbox icon in unchecked state + .task-list-indicator::before { + @extend %md-icon; + + position: absolute; + top: 0.15em; + left: -1.25em; + color: $md-color-black--lighter; + font-size: 1.25em; + content: "\E835"; // check_box_outline_blank + vertical-align: -0.25em; + + // Adjust for RTL languages + [dir="rtl"] & { + right: -1.25em; + left: initial; + } + } + + // Checkbox icon in checked state + [type="checkbox"]:checked + .task-list-indicator::before { + content: "\E834"; // check_box + } + + // Hide original checkbox behind icon + [type="checkbox"] { + opacity: 0; + z-index: -1; + } + } +} diff --git a/site/theme/assets/stylesheets/helpers/_break.scss b/site/theme/assets/stylesheets/helpers/_break.scss new file mode 100644 index 000000000..eee7aa32b --- /dev/null +++ b/site/theme/assets/stylesheets/helpers/_break.scss @@ -0,0 +1,250 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Variables +// ---------------------------------------------------------------------------- + +/// +/// Device-specific breakpoints +/// +/// @example +/// $break-devices: ( +/// mobile: ( +/// portrait: 220px 479px, +/// landscape: 480px 719px +/// ), +/// tablet: ( +/// portrait: 720px 959px, +/// landscape: 960px 1219px +/// ), +/// screen: ( +/// small: 1220px 1599px, +/// medium: 1600px 1999px, +/// large: 2000px +/// ) +/// ); +/// +/// @group helpers +/// @access private +/// @type Map +/// +$break-devices: () !default; + +// ---------------------------------------------------------------------------- +// Helpers +// ---------------------------------------------------------------------------- + +/// +/// Choose minimum and maximum device widths +/// +/// @group helpers +/// @access private +/// @param {Map} $devices Map of devices +/// @return {List} Minimum and maximum width +/// +@function break-select-min-max($devices) { + $min: 1000000; + $max: 0; + @each $key, $value in $devices { + @while type-of($value) == map { + $value: break-select-min-max($value); + } + @if type-of($value) == list { + @each $number in $value { + @if type-of($number) == number { + $min: min($number, $min); + @if $max != null { + $max: max($number, $max); + } + } @else { + @error "Invalid number: #{$number}"; + } + } + } @elseif type-of($value) == number { + $min: min($value, $min); + $max: null; + } @else { + @error "Invalid value: #{$value}"; + } + } + @return $min, $max; +} + +/// +/// Select minimum and maximum widths for a device breakpoint +/// +/// @group helpers +/// @access private +/// @param {String} $device Device +/// @return {List} Minimum and maximum width +/// +@function break-select-device($device) { + $current: $break-devices; + @for $n from 1 through length($device) { + @if type-of($current) == map { + $current: map-get($current, nth($device, $n)); + } @else { + @error "Invalid device map: #{$devices}"; + } + } + @if type-of($current) == list or type-of($current) == number { + $current: (default: $current); + } + @return break-select-min-max($current); +} + +// ---------------------------------------------------------------------------- +// Mixins +// ---------------------------------------------------------------------------- + +/// +/// A minimum-maximum media query breakpoint +/// +/// @group helpers +/// @access public +/// @param {Number|List} $breakpoint Number or number pair +/// +@mixin break-at($breakpoint) { + @if type-of($breakpoint) == number { + @media only screen and (min-width: $breakpoint) { + @content; + } + } @elseif type-of($breakpoint) == list { + $min: nth($breakpoint, 1); + $max: nth($breakpoint, 2); + @if type-of($min) == number and type-of($max) == number { + @media only screen and (min-width: $min) and (max-width: $max) { + @content; + } + } @else { + @error "Invalid breakpoint: #{$breakpoint}"; + } + } @else { + @error "Invalid breakpoint: #{$breakpoint}"; + } +} + +/// +/// An orientation media query breakpoint +/// +/// @group helpers +/// @access public +/// @param {String} $breakpoint Orientation +/// +@mixin break-at-orientation($breakpoint) { + @if type-of($breakpoint) == string { + @media only screen and (orientation: $breakpoint) { + @content; + } + } @else { + @error "Invalid breakpoint: #{$breakpoint}"; + } +} + +/// +/// A maximum-aspect-ratio media query breakpoint +/// +/// @group helpers +/// @access public +/// @param {Number} $breakpoint Ratio +/// +@mixin break-at-ratio($breakpoint) { + @if type-of($breakpoint) == number { + @media only screen and (max-aspect-ratio: $breakpoint) { + @content; + } + } @else { + @error "Invalid breakpoint: #{$breakpoint}"; + } +} + +/// +/// A minimum-maximum media query device breakpoint +/// +/// @group helpers +/// @access public +/// @param {String|List} $breakpoint Device +/// +@mixin break-at-device($device) { + @if type-of($device) == string { + $device: $device,; + } + @if type-of($device) == list { + $breakpoint: break-select-device($device); + @if nth($breakpoint, 2) != null { + $min: nth($breakpoint, 1); + $max: nth($breakpoint, 2); + @media only screen and (min-width: $min) and (max-width: $max) { + @content; + } + } @else { + @error "Invalid device: #{$device}"; + } + } @else { + @error "Invalid device: #{$device}"; + } +} + +/// +/// A minimum media query device breakpoint +/// +/// @group helpers +/// @access public +/// @param {String|List} $breakpoint Device +/// +@mixin break-from-device($device) { + @if type-of($device) == string { + $device: $device,; + } + @if type-of($device) == list { + $breakpoint: break-select-device($device); + $min: nth($breakpoint, 1); + @media only screen and (min-width: $min) { + @content; + } + } @else { + @error "Invalid device: #{$device}"; + } +} + +/// +/// A maximum media query device breakpoint +/// +/// @group helpers +/// @access public +/// @param {String|List} $breakpoint Device +/// +@mixin break-to-device($device) { + @if type-of($device) == string { + $device: $device,; + } + @if type-of($device) == list { + $breakpoint: break-select-device($device); + $max: nth($breakpoint, 2); + @media only screen and (max-width: $max) { + @content; + } + } @else { + @error "Invalid device: #{$device}"; + } +} diff --git a/site/theme/assets/stylesheets/helpers/_px2em.scss b/site/theme/assets/stylesheets/helpers/_px2em.scss new file mode 100644 index 000000000..2ca50e111 --- /dev/null +++ b/site/theme/assets/stylesheets/helpers/_px2em.scss @@ -0,0 +1,46 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Helpers +// ---------------------------------------------------------------------------- + +/// +/// Convert font size in px to em. +/// +/// @group helpers +/// @access public +/// @param {Number} $size Font size in px +/// @param {Number} $base Base font size +/// @return {Number} Font size in em +/// +@function px2em($size, $base: 16px) { + @if unit($size) == px { + @if unit($base) == px { + @return ($size / $base) * 1em; + } @else { + @error "Invalid base: #{$base} - unit must be 'px'"; + } + } @else { + @error "Invalid size: #{$size} - unit must be 'px'"; + } +} diff --git a/site/theme/assets/stylesheets/layout/_base.scss b/site/theme/assets/stylesheets/layout/_base.scss new file mode 100644 index 000000000..38510f0cf --- /dev/null +++ b/site/theme/assets/stylesheets/layout/_base.scss @@ -0,0 +1,245 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Variables +// ---------------------------------------------------------------------------- + +// Active (toggled) drawer +$md-toggle__drawer--checked: + "[data-md-toggle=\"drawer\"]:checked ~"; + +// ---------------------------------------------------------------------------- +// Rules: base grid and containers +// ---------------------------------------------------------------------------- + +// Stretch container to viewport and set base font-size to 10px for simple +// calculations base on relative ems (rems) +html { + height: 100%; + font-size: 62.5%; + // Hack: some browsers on some operating systems don't account for scroll + // bars when firing media queries, so we need to do this for safety. This + // currently impacts the table of contents component between 1220 and 1234px + // and is to current knowledge not fixable. + overflow-x: hidden; + + // [screen medium +]: Set base font-size to 11px + @include break-from-device(screen medium) { + font-size: 68.75%; + } + + // [screen large +]: Set base font-size to 12px + @include break-from-device(screen large) { + font-size: 75%; + } +} + +// Stretch body to container and leave room for footer +body { + position: relative; + height: 100%; + + // [tablet portrait -]: Lock body to disable scroll bubbling + @include break-to-device(tablet portrait) { + + // Lock body to viewport height (e.g. in search mode) + &[data-md-state="lock"] { + overflow: hidden; + + // Hide container on iOS, or the body will not be locked correctly + .ios & .md-container { + display: none; + } + } + } +} + +// Horizontal separators +hr { + display: block; + height: 0.1rem; + padding: 0; + border: 0; +} + +// Inline SVG container +.md-svg { + display: none; +} + +// Template-wide grid +.md-grid { + max-width: 122rem; + margin-right: auto; + margin-left: auto; +} + +// Prevent collapse of margin when setting margin on child element +.md-container, +.md-main { + overflow: auto; +} + +// Content wrapper - use display: table to make variable-height sticky footers +// work and fixed table-layout for IE, see http://bit.ly/2hZohXL +.md-container { + display: table; + width: 100%; + height: 100%; + padding-top: 4.8rem; + table-layout: fixed; +} + +// The main content should stretch to maximum height in the table +.md-main { + display: table-row; + height: 100%; + + // Increase top spacing of content area to give typography more room + &__inner { + height: 100%; + padding-top: 2.4rem + 0.6rem; + // Hack: induce margin-collapse, because otherwise the sidebar height is + // not calculated correctly and the overflow property on this element must + // be left in initial state for targetted link offsets to work properly + padding-bottom: 0.1rem; + } +} + +// ---------------------------------------------------------------------------- +// Rules: navigational elements +// ---------------------------------------------------------------------------- + +// Toggle checkbox +.md-toggle { + display: none; +} + +// Overlay below expanded drawer +.md-overlay { + position: fixed; + top: 0; + width: 0; + height: 0; + transition: + width 0s 0.25s, + height 0s 0.25s, + opacity 0.25s; + background-color: $md-color-black--light; + opacity: 0; + z-index: 3; + + // [tablet -]: Trigger overlay + @include break-to-device(tablet) { + + // Expanded drawer + #{$md-toggle__drawer--checked} & { + width: 100%; + height: 100%; + transition: + width 0s, + height 0s, + opacity 0.25s; + opacity: 1; + } + } +} + +// ---------------------------------------------------------------------------- +// Rules: flexible elements, implemented with table layout +// ---------------------------------------------------------------------------- + +// Flexible layout container +.md-flex { + display: table; + + // Flexible layout container cell/element + &__cell { + display: table-cell; + position: relative; + vertical-align: top; + + // Shrink to minimum width + &--shrink { + width: 0%; + } + + // Stretch to maximum width + &--stretch { + display: table; + width: 100%; + table-layout: fixed; + } + } + + // Apply ellipsis in case of overflowing text + &__ellipsis { + display: table-cell; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } +} + +// ---------------------------------------------------------------------------- +// Rules: skip link +// ---------------------------------------------------------------------------- + +// Skip link +.md-skip { + position: fixed; + width: 0.1rem; + height: 0.1rem; + margin: 1rem; + padding: 0.6rem 1rem; + clip: rect(0.1rem); + transform: translateY(0.8rem); + border-radius: 0.2rem; + background-color: $md-color-black; + color: $md-color-white; + font-size: ms(-1); + opacity: 0; + overflow: hidden; + + // Show skip link on focus + &:focus { + width: auto; + height: auto; + clip: auto; + transform: translateX(0); + transition: + transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), + opacity 0.175s 0.075s; + opacity: 1; + z-index: 10; + } +} + +// ---------------------------------------------------------------------------- +// Rules: print styles +// ---------------------------------------------------------------------------- + +// Add margins to page +@page { + margin: 25mm; +} diff --git a/site/theme/assets/stylesheets/layout/_clipboard.scss b/site/theme/assets/stylesheets/layout/_clipboard.scss new file mode 100644 index 000000000..c2d84f38f --- /dev/null +++ b/site/theme/assets/stylesheets/layout/_clipboard.scss @@ -0,0 +1,117 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Copy to clipboard +.md-clipboard { + position: absolute; + top: 0.6rem; + right: 0.6rem; + width: 2.8rem; + height: 2.8rem; + border-radius: 0.2rem; + font-size: 1.6rem; + cursor: pointer; + z-index: 1; + // Hack: put everything on the GPU to omit flickering + backface-visibility: hidden; + + // Hide for print + @media print { + display: none; + } + + // Icon + &::before { + @extend %md-icon; + + transition: + color 0.25s, + opacity 0.25s; + color: $md-color-black--lightest; + content: "\E14D"; // content_copy + + // Show on container hover + pre:hover &, + .codehilite:hover & { + color: $md-color-black--light; + } + } + + // Focused or hovered icon + &:focus::before, + &:hover::before { + color: $md-color-accent; + } + + // Message + &__message { + display: block; + position: absolute; + top: 0; + right: 3.4rem; + padding: 0.6rem 1rem; + transform: translateX(0.8rem); + transition: + transform 0.25s cubic-bezier(0.9, 0.1, 0.9, 0), + opacity 0.175s; + border-radius: 0.2rem; + background-color: $md-color-black--light; + color: $md-color-white; + font-size: ms(-1); + white-space: nowrap; + opacity: 0; + pointer-events: none; + + // Active message + &--active { + transform: translateX(0); + transition: + transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), + opacity 0.175s 0.075s; + opacity: 1; + pointer-events: initial; + } + + // Inject content from ARIA label + &::before { + content: attr(aria-label); + } + + // Paint a nice speech bubble + &::after { + display: block; + position: absolute; + top: 50%; + right: -0.4rem; + width: 0; + margin-top: -0.4rem; + border-width: 0.4rem 0 0.4rem 0.4rem; + border-style: solid; + border-color: transparent $md-color-black--light; + content: ""; + } + } +} diff --git a/site/theme/assets/stylesheets/layout/_content.scss b/site/theme/assets/stylesheets/layout/_content.scss new file mode 100644 index 000000000..61e9fb8e8 --- /dev/null +++ b/site/theme/assets/stylesheets/layout/_content.scss @@ -0,0 +1,95 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Content container +.md-content { + + // [tablet landscape +]: Add space for table of contents + @include break-from-device(tablet landscape) { + margin-right: 24.2rem; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: initial; + margin-left: 24.2rem; + } + } + + // [screen +]: Add space for table of contents + @include break-from-device(screen) { + margin-left: 24.2rem; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 24.2rem; + } + } + + // Define spacing + &__inner { + margin: 0 1.6rem 2.4rem; + padding-top: 1.2rem; + + // [screen +]: Increase horizontal spacing + @include break-from-device(screen) { + margin-right: 2.4rem; + margin-left: 2.4rem; + } + + // Hack: add pseudo element for spacing, as the overflow of the content + // container may not be hidden due to an imminent offset error on targets + &::before { + display: block; + height: 0.8rem; + content: ""; + } + + // Hack: remove bottom spacing of last element, due to margin collapse + > :last-child { + margin-bottom: 0; + } + } + + // Icons + &__icon { + @extend %md-icon__button; + + position: relative; + margin: 0.8rem 0; + padding: 0; + float: right; + + // Override default link color for icons + .md-typeset & { + color: $md-color-black--lighter; + } + + // Hide for print + @media print { + display: none; + } + } +} diff --git a/site/theme/assets/stylesheets/layout/_footer.scss b/site/theme/assets/stylesheets/layout/_footer.scss new file mode 100644 index 000000000..2446d81f2 --- /dev/null +++ b/site/theme/assets/stylesheets/layout/_footer.scss @@ -0,0 +1,199 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Application footer +.md-footer { + + // Hide for print + @media print { + display: none; + } +} + +// Navigation within footer +.md-footer-nav { + background-color: $md-color-black; + color: $md-color-white; + + // Set spacing + &__inner { + padding: 0.4rem; + overflow: auto; + } + + // Links to previous and next page + &__link { + padding-top: 2.8rem; + padding-bottom: 0.8rem; + transition: opacity 0.25s; + + // [tablet +]: Set proportional width + @include break-from-device(tablet) { + width: 50%; + } + + // Hovered link + &:hover { + opacity: 0.7; + } + + // Link to previous page + &--prev { + width: 25%; + float: left; + + // Adjust for RTL languages + [dir="rtl"] & { + float: right; + } + + // Title + .md-footer-nav__title { + + // [mobile -]: Hide title for previous page + @include break-to-device(mobile) { + display: none; + } + } + } + + // Link to next page + &--next { + width: 75%; + float: right; + text-align: right; + + // Adjust for RTL languages + [dir="rtl"] & { + float: left; + text-align: left; + } + } + } + + // Icon buttons + &__button { + @extend %md-icon__button; + + transition: background 0.25s; + } + + // Link title - set line height to match icon for correct alignment + &__title { + position: relative; + padding: 0 2rem; + font-size: 1.8rem; + line-height: 4.8rem; + } + + // Link direction + &__direction { + position: absolute; + right: 0; + left: 0; + margin-top: -2rem; + padding: 0 2rem; + color: $md-color-white--light; + font-size: 1.5rem; + } +} + +// Non-navigational information +.md-footer-meta { + background-color: opacify($md-color-black, 0.025); + + // Set spacing + &__inner { + padding: 0.4rem; + overflow: auto; + } + + // Use a decent color for non-hovered links and ensure specificity + html &.md-typeset a { + color: $md-color-white--light; + + // Focused or hovered link + &:focus, + &:hover { + color: $md-color-white; + } + } +} + +// Copyright and theme information +.md-footer-copyright { + margin: 0 1.2rem; + padding: 0.8rem 0; + color: $md-color-white--lighter; + font-size: ms(-1); + + // [tablet portrait +]: Show next to social media links + @include break-from-device(tablet portrait) { + max-width: 75%; + float: left; + + // Adjust for RTL languages + [dir="rtl"] & { + float: right; + } + } + + // Highlight copyright information + &__highlight { + color: $md-color-white--light; + } +} + +// Social media links +.md-footer-social { + margin: 0 0.8rem; + padding: 0.4rem 0 1.2rem; + + // [tablet portrait +]: Show next to copyright information + @include break-from-device(tablet portrait) { + padding: 1.2rem 0; + float: right; + + // Adjust for RTL languages + [dir="rtl"] & { + float: left; + } + } + + // Link with icon + &__link { + display: inline-block; + width: 3.2rem; + height: 3.2rem; + font-size: 1.6rem; + text-align: center; + + // Adjust line-height to match height for correct alignment + &::before { + line-height: 1.9; + } + } +} diff --git a/site/theme/assets/stylesheets/layout/_header.scss b/site/theme/assets/stylesheets/layout/_header.scss new file mode 100644 index 000000000..79333359e --- /dev/null +++ b/site/theme/assets/stylesheets/layout/_header.scss @@ -0,0 +1,216 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Application header (stays always on top) +.md-header { + position: fixed; + top: 0; + right: 0; + left: 0; + height: 4.8rem; + transition: + background-color 0.25s, + color 0.25s; + background-color: $md-color-primary; + color: $md-color-white; + box-shadow: none; + z-index: 2; + // Hack: putting the header on the GPU avoids unnecessary repaints + backface-visibility: hidden; + + // Always show shadow, in case JavaScript is not available + .no-js & { + transition: none; + box-shadow: none; + } + + // Show and animate shadow + &[data-md-state="shadow"] { + transition: + background-color 0.25s, + color 0.25s, + box-shadow 0.25s; + box-shadow: + 0 0 0.4rem rgba(0, 0, 0, 0.1), + 0 0.4rem 0.8rem rgba(0, 0, 0, 0.2); + } + + // Hide for print + @media print { + display: none; + } +} + +// Navigation within header +.md-header-nav { + padding: 0 0.4rem; + + // Icon buttons + &__button { + @extend %md-icon__button; + + position: relative; + transition: opacity 0.25s; + z-index: 1; + + // Hovered icon + &:hover { + opacity: 0.7; + } + + // Set correct display on image or icon + &.md-logo * { + display: block; + } + + // Hide search icon, if JavaScript is not available. + .no-js &.md-icon--search { + display: none; + } + + // [tablet landscape +]: Hide the search icon + @include break-from-device(tablet landscape) { + + // Search icon + &.md-icon--search { + display: none; + } + } + + // [tablet -]: Hide the home icon or logo + @include break-to-device(tablet) { + + // Home icon or logo + &.md-icon--home, + &.md-logo { + display: none; + } + } + + // [screen +]: Hide the menu icon + @include break-from-device(screen) { + + // Menu icon + &.md-icon--menu { + display: none; + } + } + } + + // Header topics + &__topic { + display: block; + position: absolute; + transition: + transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), + opacity 0.15s; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + + // Page title + & + & { + transform: translateX(2.5rem); + transition: + transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1), + opacity 0.15s; + opacity: 0; + z-index: -1; + pointer-events: none; + + // Adjust for RTL languages + [dir="rtl"] & { + transform: translateX(-2.5rem); + } + } + + // Induce ellipsis, if no JavaScript is available + .no-js & { + position: initial; + } + + // Hide page title as it is invisible anyway and will overflow the header + .no-js & + & { + display: none; + } + } + + // Header title - set line height to match icon for correct alignment + &__title { + padding: 0 2rem; + font-size: 1.8rem; + line-height: 4.8rem; + + // Show page title + &[data-md-state="active"] .md-header-nav__topic { + transform: translateX(-2.5rem); + transition: + transform 0.4s cubic-bezier(1, 0.7, 0.1, 0.1), + opacity 0.15s; + opacity: 0; + z-index: -1; + pointer-events: none; + + // Adjust for RTL languages + [dir="rtl"] & { + transform: translateX(2.5rem); + } + + // Page title + & + .md-header-nav__topic { + transform: translateX(0); + transition: + transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), + opacity 0.15s; + opacity: 1; + z-index: 0; + pointer-events: initial; + } + } + } + + // Repository containing source + &__source { + display: none; + + // [tablet landscape +]: Show the reposistory from tablet + @include break-from-device(tablet landscape) { + display: block; + width: 23rem; + max-width: 23rem; + margin-left: 2.8rem; + padding-right: 1.2rem; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 2.8rem; + margin-left: initial; + padding-right: initial; + padding-left: 1.2rem; + } + } + } +} diff --git a/site/theme/assets/stylesheets/layout/_hero.scss b/site/theme/assets/stylesheets/layout/_hero.scss new file mode 100644 index 000000000..d8d588b55 --- /dev/null +++ b/site/theme/assets/stylesheets/layout/_hero.scss @@ -0,0 +1,65 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Hero teaser +.md-hero { + transition: background 0.25s; + background-color: $md-color-primary; + color: $md-color-white; + font-size: ms(1); + overflow: hidden; + + // Inner wrapper + &__inner { + margin-top: 2rem; + padding: 1.6rem 1.6rem 0.8rem; + transition: + transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), + opacity 0.25s; + transition-delay: 0.1s; + + // [tablet -]: Compensate for missing tabs + @include break-to-device(tablet) { + margin-top: 4.8rem; + margin-bottom: 2.4rem; + } + + // Fade-out tabs background upon scrolling + [data-md-state="hidden"] & { + pointer-events: none; + transform: translateY(1.25rem); + transition: + transform 0s 0.4s, + opacity 0.1s 0s; + opacity: 0; + } + + // Adjust bottom spacing if there are no tabs + .md-hero--expand & { + margin-bottom: 2.4rem; + } + } +} diff --git a/site/theme/assets/stylesheets/layout/_nav.scss b/site/theme/assets/stylesheets/layout/_nav.scss new file mode 100644 index 000000000..969a45622 --- /dev/null +++ b/site/theme/assets/stylesheets/layout/_nav.scss @@ -0,0 +1,525 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Navigation container +.md-nav { + font-size: 1.4rem; + line-height: 1.3; + + // List title + &__title { + display: block; + padding: 0 1.2rem; + font-weight: 700; + text-overflow: ellipsis; + overflow: hidden; + + // Icon, hidden by default + &::before { + @extend %md-icon, %md-icon__button; + + display: none; + content: "\E5C4"; // arrow_back + + // Adjust for RTL languages + [dir="rtl"] & { + content: "\E5C8"; // arrow_forward + } + } + + // Hide button by default + .md-nav__button { + display: none; + } + } + + // List of items + &__list { + margin: 0; + padding: 0; + list-style: none; + } + + // List item + &__item { + padding: 0 1.2rem; + + // Add bottom spacing to last item + &:last-child { + padding-bottom: 1.2rem; + } + + // 2nd+ level items + & & { + padding-right: 0; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 1.2rem; + padding-left: 0; + } + + // Remove bottom spacing for nested items + &:last-child { + padding-bottom: 0; + } + } + } + + // Button with logo + &__button { + @extend %md-icon, %md-icon__button; + + // Stretch image + img { + width: 100%; + height: auto; + } + } + + // Link inside item + &__link { + display: block; + margin-top: 0.625em; + transition: color 0.125s; + text-overflow: ellipsis; + cursor: pointer; + overflow: hidden; + + // Icon + &::after { + @extend %md-icon; + + // Item contains a nested list + .md-nav__item--nested > & { + content: "\E313"; // keyboard_arrow_down + } + } + + // Hide link to table of contents by default - this will only match the + // table of contents inside the drawer below and including tablet portrait + html &[for="__toc"] { + display: none; + + // Hide table of contents by default + & ~ .md-nav { + display: none; + } + + // Hide icon for current item + + .md-nav__link::after { + display: none; + } + } + + // Blurred link + &[data-md-state="blur"] { + color: $md-color-black--light; + } + + // Active link + &:active, + &--active { + color: $md-color-primary; + } + + // Reset active color for nested list titles + .md-nav__item--nested > & { + color: inherit; + } + + // Focused or hovered link + &:focus, + &:hover { + color: $md-color-accent; + } + } + + // Repository containing source + &__source { + display: none; + } + + // [tablet -]: Layered navigation + @include break-to-device(tablet) { + background-color: $md-color-white; + + // Stretch primary navigation to drawer + &--primary, + &--primary .md-nav { + display: flex; + position: absolute; + top: 0; + right: 0; + left: 0; + flex-direction: column; + height: 100%; + z-index: 1; + } + + // Adjust styles for primary navigation + &--primary { + + // List title and item + .md-nav__title, + .md-nav__item { + font-size: 1.6rem; + line-height: 1.5; + } + + // List title - higher specificity is necessary to ensure that the title + // inside the drawer is always styled accordingly + html & .md-nav__title { + position: relative; + height: 11.2rem; + padding: 6rem 1.6rem 0.4rem; + background-color: $md-color-black--lightest; + color: $md-color-black--light; + font-weight: 400; + line-height: 4.8rem; + white-space: nowrap; + cursor: pointer; + + // Icon + &::before { + display: block; + position: absolute; + top: 0.4rem; + left: 0.4rem; + width: 4rem; + height: 4rem; + color: $md-color-black--light; + } + + // Main lists + ~ .md-nav__list { + background-color: $md-color-white; + box-shadow: 0 0.1rem 0 $md-color-black--lightest inset; + + // Remove border for first list item + & > .md-nav__item:first-child { + border-top: 0; + } + } + + // Site title in main navigation + &--site { + position: relative; + background-color: $md-color-primary; + color: $md-color-white; + + // Site logo + .md-nav__button { + display: block; + position: absolute; + top: 0.4rem; + left: 0.4rem; + width: 6.4rem; + height: 6.4rem; + font-size: 4.8rem; + } + + // Hide back arrow icon + &::before { + display: none; + } + } + } + + // Adjust for RTL languages + html [dir="rtl"] & .md-nav__title { + + // Icon + &::before { + right: 0.4rem; + left: initial; + } + + // Site title in main navigation + &--site .md-nav__button { + right: 0.4rem; + left: initial; + } + } + + // List of items + .md-nav__list { + flex: 1; + overflow-y: auto; + } + + // List item + .md-nav__item { + padding: 0; + border-top: 0.1rem solid $md-color-black--lightest; + + // Adjust for RTL languages + [dir="rtl"] & { + padding: 0; + } + + // Increase spacing to account for icon + &--nested > .md-nav__link { + padding-right: 4.8rem; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 1.6rem; + padding-left: 4.8rem; + } + + // Replace icon with right arrow + &::after { + content: "\E315"; // keyboard_arrow_right + + // Adjust for RTL languages + [dir="rtl"] & { + content: "\E314"; // keyboard_arrow_left + } + } + } + } + + // Link inside item + .md-nav__link { + position: relative; + margin-top: 0; + padding: 1.2rem 1.6rem; + + // Rotate icon + &::after { + position: absolute; + top: 50%; + right: 1.2rem; + margin-top: -1.2rem; + color: inherit; + font-size: 2.4rem; + + // Adjust for RTL languages + [dir="rtl"] & { + right: initial; + left: 1.2rem; + } + } + } + + // Table of contents inside navigation + .md-nav--secondary { + + // Set links to static to avoid unnecessary layering + .md-nav__link { + position: static; + } + + // Set nested navigation for table of contents to static + .md-nav { + position: static; + background-color: transparent; + + // 3rd level link + .md-nav__link { + padding-left: 2.8rem; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 2.8rem; + padding-left: initial; + } + } + + // 4th level link + .md-nav .md-nav__link { + padding-left: 4rem; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 4rem; + padding-left: initial; + } + } + + // 5th level link + .md-nav .md-nav .md-nav__link { + padding-left: 5.2rem; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 5.2rem; + padding-left: initial; + } + } + + // 6th level link + .md-nav .md-nav .md-nav .md-nav__link { + padding-left: 6.4rem; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 6.4rem; + padding-left: initial; + } + } + } + } + } + + // Hide nested navigation by default + .md-nav__toggle ~ & { + display: flex; + transform: translateX(100%); + transition: + transform 0.25s cubic-bezier(0.8, 0, 0.6, 1), + opacity 0.125s 0.05s; + opacity: 0; + + // Adjust for RTL languages + [dir="rtl"] & { + transform: translateX(-100%); + } + + // Just hide navigation, if browser doesn't supports 3D transforms + .no-csstransforms3d & { + display: none; + } + } + + // Expand nested navigation, if toggle is checked + .md-nav__toggle:checked ~ & { + transform: translateX(0); + transition: + transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), + opacity 0.125s 0.125s; + opacity: 1; + + // Just show navigation, if browser doesn't supports 3D transforms + .no-csstransforms3d & { + display: flex; + } + } + } + + // [tablet portrait -]: Show table of contents in drawer + @include break-to-device(tablet portrait) { + + // Show link to table of contents - higher specificity is necessary to + // display the table of contents inside the drawer + html &__link[for="__toc"] { + display: block; + padding-right: 4.8rem; + + // Unrotate icon for table of contents + &::after { + color: inherit; + content: "\E8DE"; // toc + } + + // Hide link to current item + + .md-nav__link { + display: none; + } + + // Show table of contents + & ~ .md-nav { + display: flex; + } + } + + // Adjust for RTL languages + html [dir="rtl"] &__link { + padding-right: 1.6rem; + padding-left: 4.8rem; + } + + // Repository containing source + &__source { + display: block; + padding: 0 0.4rem; + background-color: mix($md-color-primary, $md-color-black, 75%); + color: $md-color-white; + } + } + + // [screen +]: Tree-like navigation + @include break-from-device(screen) { + + // Animation is only possible if JavaScript is available, as the max-height + // property must be calculated before transitioning + &[data-md-state="animate"] { + transition: max-height 0.25s cubic-bezier(0.86, 0, 0.07, 1); + } + + // Hide nested navigation by default + .md-nav__toggle ~ & { + max-height: 0; + overflow: hidden; + + // Just hide links for accessibility if JavaScript is not available + .no-js & { + display: none; + } + } + + // Expand nested navigation, if toggle is checked + .md-nav__toggle:checked ~ &, + &[data-md-state="expand"] { + max-height: 100%; + + // Just show for accessibility links if JavaScript is not available + .no-js & { + display: block; + } + } + + // Hide titles for nested navigation + &__item--nested > .md-nav > &__title { + display: none; + } + + // Link inside item - ideally the link display method would be set to + // inline on screen, but this doesn't work with text ellipsis + &__link { + + // Item contains a nested list + .md-nav__item--nested > &::after { + display: inline-block; + transform-origin: 0.45em 0.45em; + transform-style: preserve-3d; + vertical-align: -0.125em; + + // Only animate icon when JavaScript is available, as the height can + // not be animated anyway, and better no fun than half the fun + .js & { + transition: transform 0.4s; + } + } + + // Rotate icon for expanded lists + .md-nav__item--nested .md-nav__toggle:checked ~ &::after { + transform: rotateX(180deg); + } + } + } +} diff --git a/site/theme/assets/stylesheets/layout/_search.scss b/site/theme/assets/stylesheets/layout/_search.scss new file mode 100644 index 000000000..f8ed05b79 --- /dev/null +++ b/site/theme/assets/stylesheets/layout/_search.scss @@ -0,0 +1,622 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Variables +// ---------------------------------------------------------------------------- + +// Active (toggled) search +$md-toggle__search--checked: + "[data-md-toggle=\"search\"]:checked ~ .md-header"; + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Search container +.md-search { + + // Hide search, if JavaScript is not available. + .no-js & { + display: none; + } + + // [tablet landscape +]: Header-embedded search + @include break-from-device(tablet landscape) { + padding: 0.4rem; + } + + // Search modal overlay + &__overlay { + opacity: 0; + z-index: 1; + + // [tablet portrait -]: Full-screen search bar + @include break-to-device(tablet portrait) { + position: absolute; + top: 0.4rem; + left: 0.4rem; + width: 3.6rem; + height: 3.6rem; + transform-origin: center; + transition: + transform 0.3s 0.1s, + opacity 0.2s 0.2s; + border-radius: 2rem; + background-color: $md-color-white; + overflow: hidden; + pointer-events: none; + + // Adjust for RTL languages + [dir="rtl"] & { + right: 0.4rem; + left: initial; + } + + // Expanded overlay + #{$md-toggle__search--checked} & { + transition: + transform 0.4s, + opacity 0.1s; + opacity: 1; + } + } + + // Set scale factors + #{$md-toggle__search--checked} & { + + // [mobile portrait -]: Scale up 45 times + @include break-to-device(mobile portrait) { + transform: scale(45); + } + + // [mobile landscape]: Scale up 60 times + @include break-at-device(mobile landscape) { + transform: scale(60); + } + + // [tablet portrait]: Scale up 75 times + @include break-at-device(tablet portrait) { + transform: scale(75); + } + } + + // [tablet landscape +]: Overlay for better focus on search + @include break-from-device(tablet landscape) { + position: fixed; + top: 0; + left: 0; + width: 0; + height: 0; + transition: + width 0s 0.25s, + height 0s 0.25s, + opacity 0.25s; + background-color: $md-color-black--light; + cursor: pointer; + + // Adjust for RTL languages + [dir="rtl"] & { + right: 0; + left: initial; + } + + // Expanded overlay + #{$md-toggle__search--checked} & { + width: 100%; + height: 100%; + transition: + width 0s, + height 0s, + opacity 0.25s; + opacity: 1; + } + } + } + + // Search modal wrapper + &__inner { + + // [tablet portrait -]: Put search modal off-canvas by default + @include break-to-device(tablet portrait) { + position: fixed; + top: 0; + left: 100%; + width: 100%; + height: 100%; + transform: translateX(5%); + transition: + right 0s 0.3s, + left 0s 0.3s, + transform 0.15s 0.15s cubic-bezier(0.4, 0, 0.2, 1), + opacity 0.15s 0.15s; + opacity: 0; + z-index: 2; + + // Active search modal + #{$md-toggle__search--checked} & { + left: 0; + transform: translateX(0); + transition: + right 0s 0s, + left 0s 0s, + transform 0.15s 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), + opacity 0.15s 0.15s; + opacity: 1; + + // Adjust for RTL languages + [dir="rtl"] & { + right: 0; + left: initial; + } + } + + // Adjust for RTL languages + html [dir="rtl"] & { + right: 100%; + left: initial; + transform: translateX(-5%); + } + } + + // [tablet landscape +]: Header-embedded search + @include break-from-device(tablet landscape) { + position: relative; + width: 23rem; + padding: 0.2rem 0; + float: right; + transition: width 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); + + // Adjust for RTL languages + [dir="rtl"] & { + float: left; + } + } + + // Set maximum width + #{$md-toggle__search--checked} & { + + // [tablet landscape]: Do not overlay title + @include break-at-device(tablet landscape) { + width: 46.8rem; + } + + // [screen +]: Match content width + @include break-from-device(screen) { + width: 68.8rem; + } + } + } + + // Search form + &__form { + position: relative; + + // [tablet landscape +]: Header-embedded search + @include break-from-device(tablet landscape) { + border-radius: 0.2rem; + } + } + + // Search input + &__input { + position: relative; + padding: 0 4.4rem 0 7.2rem; + text-overflow: ellipsis; + z-index: 2; + + // Adjust for RTL languages + [dir="rtl"] & { + padding: 0 7.2rem 0 4.4rem; + } + + // Transition on placeholder + &::placeholder { + transition: color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); + } + + // Placeholder and icon color in active state + ~ .md-search__icon, + &::placeholder { + color: $md-color-black--light; + } + + // Remove the "x" rendered by Internet Explorer + &::-ms-clear { + display: none; + } + + // [tablet portrait -]: Full-screen search bar + @include break-to-device(tablet portrait) { + width: 100%; + height: 4.8rem; + font-size: 1.8rem; + } + + // [tablet landscape +]: Header-embedded search + @include break-from-device(tablet landscape) { + width: 100%; + height: 3.6rem; + padding-left: 4.4rem; + transition: + background-color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1), + color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); + border-radius: 0.2rem; + background-color: $md-color-black--lighter; + color: inherit; + font-size: ms(0); + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 4.4rem; + } + + // Icon color + + .md-search__icon { + color: inherit; + } + + // Placeholder color + &::placeholder { + color: $md-color-white--light; + } + + // Hovered search field + &:hover { + background-color: $md-color-white--lightest; + } + + // Set light background on active search field + #{$md-toggle__search--checked} & { + border-radius: 0.2rem 0.2rem 0 0; + background-color: $md-color-white; + color: $md-color-black; + text-overflow: none; + + // Placeholder and icon color in active state + + .md-search__icon, + &::placeholder { + color: $md-color-black--light; + } + } + } + } + + // Icons + &__icon { + position: absolute; + transition: + color 0.25s cubic-bezier(0.1, 0.7, 0.1, 1), + opacity 0.25s; + font-size: $md-icon-size; + cursor: pointer; + z-index: 2; + + // Hovered icon + &:hover { + opacity: 0.7; + } + + // Search icon + &[for="__search"] { + top: 0.6rem; + left: 1rem; + + // Adjust for RTL languages + [dir="rtl"] & { + right: 1rem; + left: initial; + } + + // Set search icon on pseudo class, so it can be overridden for mobile + // and tablet when the search is rendered in an overlay + &::before { + content: "\E8B6"; // search + } + + // [tablet portrait -]: Full-screen search bar + @include break-to-device(tablet portrait) { + top: 1.2rem; + left: 1.6rem; + + // Show back arrow instead of search icon + &[for="__search"]::before { + content: "\E5C4"; // arrow_back + + // Adjust for RTL languages + [dir="rtl"] & { + content: "\E5C8"; // arrow_forward + } + } + } + } + + // Reset button + &[type="reset"] { + top: 0.6rem; + right: 1rem; + transform: scale(0.125); + transition: + transform 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), + opacity 0.15s; + opacity: 0; + + // Adjust for RTL languages + [dir="rtl"] & { + right: initial; + left: 1rem; + } + + // [tablet portrait -]: Full-screen search bar + @include break-to-device(tablet portrait) { + top: 1.2rem; + right: 1.6rem; + } + + // Show reset button if search is active and input non-empty + #{$md-toggle__search--checked} .md-search__input:valid ~ & { + transform: scale(1); + opacity: 1; + + // Hovered icon + &:hover { + opacity: 0.7; + } + } + } + } + + // Search output container + &__output { + position: absolute; + width: 100%; + border-radius: 0 0 0.2rem 0.2rem; + overflow: hidden; + z-index: 1; + + // [tablet portrait -]: Full-screen search bar + @include break-to-device(tablet portrait) { + top: 4.8rem; + bottom: 0; + } + + // [tablet landscape +]: Header-embedded search + @include break-from-device(tablet landscape) { + top: 3.8rem; + transition: opacity 0.4s; + opacity: 0; + + // Show search output in active state + #{$md-toggle__search--checked} & { + @include z-depth(6); + + opacity: 1; + } + } + } + + // Wrapper for scrolling on overflow + &__scrollwrap { + height: 100%; + background-color: $md-color-white; + box-shadow: 0 0.1rem 0 $md-color-black--lightest inset; + overflow-y: auto; + -webkit-overflow-scrolling: touch; + + // [tablet landscape]: Set absolute width to omit unnecessary reflow + @include break-at-device(tablet landscape) { + width: 46.8rem; + } + + // [screen +]: Set absolute width to omit unnecessary reflow + @include break-from-device(screen) { + width: 68.8rem; + } + + // [tablet landscape +]: Limit height to viewport + @include break-from-device(tablet landscape) { + max-height: 0; + + // Expand in active state + #{$md-toggle__search--checked} & { + max-height: 75vh; + } + + // Override native scrollbar styles + &::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; + } + + // Style scrollbar thumb + &::-webkit-scrollbar-thumb { + background-color: $md-color-black--lighter; + + // Hovered scrollbar thumb + &:hover { + background-color: $md-color-accent; + } + } + } + } +} + +// Search result +.md-search-result { + color: $md-color-black; + word-break: break-word; + + // Search metadata + &__meta { + padding: 0 1.6rem; + background-color: $md-color-black--lightest; + color: $md-color-black--light; + font-size: ms(-1); + line-height: 3.6rem; + + // [tablet landscape +]: Increase left indent + @include break-from-device(tablet landscape) { + padding-left: 4.4rem; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 4.4rem; + padding-left: initial; + } + } + } + + // List of items + &__list { + margin: 0; + padding: 0; + border-top: 0.1rem solid $md-color-black--lightest; + list-style: none; + } + + // List item + &__item { + box-shadow: 0 -0.1rem 0 $md-color-black--lightest; + } + + // Link inside item + &__link { + display: block; + transition: background 0.25s; + outline: 0; + overflow: hidden; + + // Active or hovered link + &[data-md-state="active"], + &:hover { + background-color: transparentize($md-color-accent, 0.9); + + // Slightly transparent icon + .md-search-result__article::before { + opacity: 0.7; + } + } + + // Add a little spacing on the teaser of the last link + &:last-child .md-search-result__teaser { + margin-bottom: 1.2rem; + } + } + + // Article - document or section + &__article { + position: relative; + padding: 0 1.6rem; + overflow: auto; + + // [tablet landscape +]: Increase left indent + @include break-from-device(tablet landscape) { + padding-left: 4.4rem; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: 4.4rem; + padding-left: 1.6rem; + } + } + + // Document + &--document { + + // Icon + &::before { + @extend %md-icon, %md-icon__button; + + position: absolute; + left: 0; + margin: 0.2rem; + transition: opacity 0.25s; + color: $md-color-black--light; + content: "\E880"; // find_in_page + + // Adjust for RTL languages + [dir="rtl"] & { + right: 0; + left: initial; + } + + // [tablet portrait -]: Hide page icon + @include break-to-device(tablet portrait) { + display: none; + } + } + + // Title + .md-search-result__title { + margin: 1.1rem 0; + font-size: ms(0); + font-weight: 400; + line-height: 1.4; + } + } + } + + // Title + &__title { + margin: 0.5em 0; + font-size: ms(-1); + font-weight: 700; + line-height: 1.4; + } + + // stylelint-disable value-no-vendor-prefix, property-no-vendor-prefix + + // Teaser + &__teaser { + display: -webkit-box; + max-height: 3.3rem; + margin: 0.5em 0; + color: $md-color-black--light; + font-size: ms(-1); + line-height: 1.4; + text-overflow: ellipsis; + overflow: hidden; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; + + // [mobile -]: Increase number of lines + @include break-to-device(mobile) { + max-height: 5rem; + -webkit-line-clamp: 3; + } + + // [tablet landscape]: Increase number of lines + @include break-at-device(tablet landscape) { + max-height: 5rem; + -webkit-line-clamp: 3; + } + } + + // stylelint-enable value-no-vendor-prefix, property-no-vendor-prefix + + // Search term highlighting + em { + font-style: normal; + font-weight: 700; + text-decoration: underline; + } +} diff --git a/site/theme/assets/stylesheets/layout/_sidebar.scss b/site/theme/assets/stylesheets/layout/_sidebar.scss new file mode 100644 index 000000000..262323e63 --- /dev/null +++ b/site/theme/assets/stylesheets/layout/_sidebar.scss @@ -0,0 +1,174 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Variables +// ---------------------------------------------------------------------------- + +// Active (toggled) drawer +$md-toggle__drawer--checked: + "[data-md-toggle=\"drawer\"]:checked ~ .md-container"; + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Sidebar container +.md-sidebar { + position: absolute; + width: 24.2rem; + padding: 2.4rem 0; + overflow: hidden; + + // Hide for print + @media print { + display: none; + } + + // Lock sidebar to container height (account for fixed header) + &[data-md-state="lock"] { + position: fixed; + top: 4.8rem; + } + + // [tablet -]: Convert navigation to drawer + @include break-to-device(tablet) { + + // Render primary sidebar as a slideout container + &--primary { + position: fixed; + top: 0; + left: -24.2rem; + width: 24.2rem; + height: 100%; + transform: translateX(0); + transition: + transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), + box-shadow 0.25s; + background-color: $md-color-white; + z-index: 3; + + // Adjust for RTL languages + [dir="rtl"] & { + right: -24.2rem; + left: initial; + } + + // Just hide drawer, if browser doesn't support 3D transforms + .no-csstransforms3d & { + display: none; + } + + // Expanded drawer + #{$md-toggle__drawer--checked} & { + @include z-depth(8); + + transform: translateX(24.2rem); + + // Adjust for RTL languages + [dir="rtl"] & { + transform: translateX(-24.2rem); + } + + // Just show drawer, if browser doesn't support 3D transforms + .no-csstransforms3d & { + display: block; + } + } + + // Hide overflow for nested navigation + .md-sidebar__scrollwrap { + overflow: hidden; + } + } + } + + // Secondary sidebar with table of contents + &--secondary { + display: none; + + // [tablet landscape +]: Show table of contents next to body copy + @include break-from-device(tablet landscape) { + display: block; + margin-left: 100%; + transform: translate(-100%, 0); + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 100%; + margin-left: initial; + transform: translate(100%, 0); + } + } + + // [screen +]: Limit to grid + @include break-from-device(screen) { + margin-left: 122rem; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 122rem; + margin-left: initial; + } + } + } + + // Wrapper for scrolling on overflow + &__scrollwrap { + max-height: 100%; + margin: 0 0.4rem; + overflow-y: auto; + // Hack: putting the scroll wrapper on the GPU massively reduces jitter + // when locking the sidebars into place + backface-visibility: hidden; + + // [tablet -]: Adjust margins + @include break-to-device(tablet) { + + // Stretch scrollwrap for primary sidebar + .md-sidebar--primary & { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + margin: 0; + } + } + + // Override native scrollbar styles + &::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; + } + + // Style scrollbar thumb + &::-webkit-scrollbar-thumb { + background-color: $md-color-black--lighter; + + // Hovered scrollbar thumb + &:hover { + background-color: $md-color-accent; + } + } + } +} diff --git a/site/theme/assets/stylesheets/layout/_source.scss b/site/theme/assets/stylesheets/layout/_source.scss new file mode 100644 index 000000000..91ef7ca82 --- /dev/null +++ b/site/theme/assets/stylesheets/layout/_source.scss @@ -0,0 +1,234 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Keyframes +// ---------------------------------------------------------------------------- + +// Show source facts +@keyframes md-source__facts--done { + 0% { + height: 0; + } + + 100% { + height: 1.3rem; + } +} + +// Show source fact +@keyframes md-source__fact--done { + 0% { + transform: translateY(100%); + opacity: 0; + } + + 50% { + opacity: 0; + } + + 100% { + transform: translateY(0%); + opacity: 1; + } +} + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Source container +.md-source { + display: block; + padding-right: 1.2rem; + transition: opacity 0.25s; + font-size: 1.3rem; + line-height: 1.2; + white-space: nowrap; + + // Adjust for RTL languages + [dir="rtl"] & { + padding-right: initial; + padding-left: 1.2rem; + } + + // Hovered source container + &:hover { + opacity: 0.7; + } + + // Necessary for vertical alignment + &::after { + display: inline-block; + height: 4.8rem; + content: ""; + vertical-align: middle; + } + + // Repository platform icon + &__icon { + display: inline-block; + width: 4.8rem; + height: 4.8rem; + content: ""; + vertical-align: middle; + + // Align SVG, do not scale, as this will incur strange formatting bugs + // in Internet Explorer and Edge + svg { + width: 2.4rem; + height: 2.4rem; + margin-top: 1.2rem; + margin-left: 1.2rem; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: 1.2rem; + margin-left: initial; + } + } + + // Correct alignment, if icon is present + + .md-source__repository { + margin-left: -4.4rem; + padding-left: 4rem; + + // Adjust for RTL languages + [dir="rtl"] & { + margin-right: -4.4rem; + margin-left: initial; + padding-right: 4rem; + padding-left: initial; + } + } + } + + // Repository name + &__repository { + display: inline-block; + max-width: 100%; + margin-left: 1.2rem; + font-weight: 700; + text-overflow: ellipsis; + overflow: hidden; + vertical-align: middle; + } + + // Source facts (statistics etc.) + &__facts { + margin: 0; + padding: 0; + font-size: 1.1rem; + font-weight: 700; + list-style-type: none; + opacity: 0.75; + overflow: hidden; + + // Show after the data was loaded + [data-md-state="done"] & { + animation: md-source__facts--done 0.25s ease-in; + } + } + + // Fact + &__fact { + float: left; + + // Adjust for RTL languages + [dir="rtl"] & { + float: right; + } + + // Show after the data was loaded + [data-md-state="done"] & { + animation: md-source__fact--done 0.4s ease-out; + } + + // Middle dot before fact + &::before { + margin: 0 0.2rem; + content: "\00B7"; + } + + // Remove middle dot on first fact + &:first-child::before { + display: none; + } + } +} + +// Source file +.md-source-file { + display: inline-block; + margin: 1em 0.5em 1em 0; + padding-right: 0.5rem; + border-radius: 0.2rem; + background-color: $md-color-black--lightest; + font-size: ms(-1); + list-style-type: none; + cursor: pointer; + overflow: hidden; + + // Icon + &::before { + @extend %md-icon; + + display: inline-block; + margin-right: 0.5rem; + padding: 0.5rem; + background-color: $md-color-black--lighter; + color: $md-color-white; + font-size: ms(0); + content: "\E86F"; // code + vertical-align: middle; + } + + // Some properties need to be set with higher specificity due to the default + // styling of text links inside typesetted content + html & { + transition: + background 0.4s, + color 0.4s, + box-shadow 0.4s cubic-bezier(0.4, 0, 0.2, 1); + + // Icon + &::before { + transition: inherit; + } + } + + // Color needs even higher specifity because custom color palettes are set + // using the body and override text links inside typesetted content + html body .md-typeset & { + color: $md-color-black--light; + } + + // Hovered source file + &:hover { + @include z-depth-focus; + + // Icon + &::before { + background-color: $md-color-accent; + } + } +} diff --git a/site/theme/assets/stylesheets/layout/_tabs.scss b/site/theme/assets/stylesheets/layout/_tabs.scss new file mode 100644 index 000000000..63aab9fe8 --- /dev/null +++ b/site/theme/assets/stylesheets/layout/_tabs.scss @@ -0,0 +1,178 @@ +//// +/// Copyright (c) 2016-2018 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Tabs with outline +.md-tabs { + width: 100%; + transition: background 0.25s; + background-color: $md-color-primary; + color: $md-color-white; + overflow: auto; + + // [tablet -]: Hide tabs for tablet and below, as they don't make any sense + @include break-to-device(tablet) { + display: none; + } + + // Hide for print + @media print { + display: none; + } + + // List of items + &__list { + margin: 0; + margin-left: 0.4rem; + padding: 0; + list-style: none; + white-space: nowrap; + } + + // List item + &__item { + display: inline-block; + height: 4.8rem; + padding-right: 1.2rem; + padding-left: 1.2rem; + } + + // Link inside item - could be defined as block elements and aligned via + // line height, but this would imply more repaints when scrolling + &__link { + display: block; + margin-top: 1.6rem; + transition: + transform 0.4s cubic-bezier(0.1, 0.7, 0.1, 1), + opacity 0.25s; + font-size: 1.4rem; + opacity: 0.7; + + // Active or hovered link + &--active, + &:hover { + color: inherit; + opacity: 1; + } + + // Delay transitions by a small amount + @for $i from 2 through 16 { + .md-tabs__item:nth-child(#{$i}) & { + transition-delay: 0.02s * ($i - 1); + } + } + } + + // Fade-out tabs background upon scrolling + &[data-md-state="hidden"] { + pointer-events: none; + + // Hide tabs upon scrolling - disable transition to minimizes repaints whilte + // scrolling down, while scrolling up seems to be okay + .md-tabs__link { + transform: translateY(50%); + transition: + color 0.25s, + transform 0s 0.4s, + opacity 0.1s; + opacity: 0; + } + } + + // [screen +]: Adjust main navigation styles + @include break-from-device(screen) { + + // Hide 1st level nested items, as they are listed in the tabs by setting + // font-size to zero, as we need to preserve bottom padding + ~ .md-main .md-nav--primary > .md-nav__list > .md-nav__item--nested { + font-size: 0; + visibility: hidden; + } + + // We're on the 2nd+ level + &--active ~ .md-main { + + // Adjust 1st level styles + .md-nav--primary { + + // Show title and remove spacing + .md-nav__title { + display: block; + padding: 0; + } + + // Hide site title + .md-nav__title--site { + display: none; + } + + // Show 1st level navigation always expanded + .no-js & .md-nav { + display: block; + } + + // Hide 1st level normal items + & > .md-nav__list > .md-nav__item { + font-size: 0; + visibility: hidden; + + // Reset font-size for nested items and induce margin collapse + &--nested { + display: none; + font-size: 1.4rem; + overflow: auto; + visibility: visible; + + // Hide nested links + > .md-nav__link { + display: none; + } + } + + // Show 1st level active nested items + &--active { + display: block; + } + } + } + + // Always expand nested navigation on 2nd level + .md-nav[data-md-level="1"] { + max-height: initial; + overflow: visible; + + // Remove left spacing on 2nd level items + > .md-nav__list > .md-nav__item { + padding-left: 0; + } + + // Hide titles from 2nd level on + .md-nav .md-nav__title { + display: none; + } + } + } + } +} diff --git a/site/theme/partials/footer.html b/site/theme/partials/footer.html new file mode 100644 index 000000000..2f319a07c --- /dev/null +++ b/site/theme/partials/footer.html @@ -0,0 +1,82 @@ +{% import "partials/language.html" as lang with context %} + + + diff --git a/site/theme/partials/header.html b/site/theme/partials/header.html new file mode 100644 index 000000000..2170c4ccb --- /dev/null +++ b/site/theme/partials/header.html @@ -0,0 +1,164 @@ + + + + + +
+ + + Demo + Community + About + + + +
+ + + + +
+ + + +