merge master -> multi-class-comma

pull/3419/head
Richard Harris 6 years ago
commit 55287e5f73

@ -22,14 +22,7 @@ module.exports = {
'arrow-spacing': 2,
'no-inner-declarations': 0,
'require-atomic-updates': 'off',
'@typescript-eslint/indent': [
'error',
'tab',
{
SwitchCase: 1,
ignoredNodes: ['TemplateLiteral']
}
],
'@typescript-eslint/indent': 'off',
'@typescript-eslint/camelcase': 'off',
'@typescript-eslint/no-use-before-define': 'off',
'@typescript-eslint/array-type': ['error', 'array-simple'],

@ -0,0 +1,25 @@
name: CI
on: [push, pull_request]
jobs:
Tests:
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [8, 10, 12]
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- run: git config --global core.autocrlf false
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm test
env:
CI: true
Lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- run: 'npm i && npm run lint'

@ -1,20 +0,0 @@
language: node_js
node_js:
- "8"
- "10"
- "12"
env:
global:
- BUILD_TIMEOUT=20000
addons:
apt:
packages:
- xvfb
install:
- export DISPLAY=':99.0'
- Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
- npm ci || npm install
after_success: npm run codecov

@ -1,5 +1,98 @@
# Svelte changelog
## 3.14.1
* Deconflict block method names with other variables ([#3900](https://github.com/sveltejs/svelte/issues/3900))
* Fix entity encoding issue in text nodes with constant expressions ([#3911](https://github.com/sveltejs/svelte/issues/3911))
* Make code for unknown prop warnings compatible with older js engines ([#3914](https://github.com/sveltejs/svelte/issues/3914))
## 3.14.0
* Add `loopGuardTimeout` option that augments `for`/`while` loops to prevent infinite loops, primarily for use in the REPL ([#3887](https://github.com/sveltejs/svelte/pull/3887))
* Keep component bindings in sync when changed in reactive statements ([#3382](https://github.com/sveltejs/svelte/issues/3382))
* Update attributes before bindings ([#3857](https://github.com/sveltejs/svelte/issues/3857))
* Prevent variable naming conflict ([#3899](https://github.com/sveltejs/svelte/issues/3899))
## 3.13.0
* New structured code generation, which eliminates a number of edge cases and obscure bugs ([#3539](https://github.com/sveltejs/svelte/pull/3539))
Also:
* Fix `{#each}` context not shadowing outer scope when using `bind:` ([#1565](https://github.com/sveltejs/svelte/issues/1565))
* Fix edge cases in matching selectors against elements ([#1710](https://github.com/sveltejs/svelte/issues/1710))
* Fix several bugs related to interaction of `{...spread}` attributes with other features ([#2721](https://github.com/sveltejs/svelte/issues/2721), [#2916](https://github.com/sveltejs/svelte/issues/2916), [#3421](https://github.com/sveltejs/svelte/issues/3421), [#3681](https://github.com/sveltejs/svelte/issues/3681), [#3764](https://github.com/sveltejs/svelte/issues/3764), [#3790](https://github.com/sveltejs/svelte/issues/3790))
* Allow exiting a reactive block early with `break $` ([#2828](https://github.com/sveltejs/svelte/issues/2828))
* Fix binding to props that have been renamed with `export { ... as ... }` ([#3508](https://github.com/sveltejs/svelte/issues/3508))
* Fix application of style scoping class in cases of ambiguity ([#3544](https://github.com/sveltejs/svelte/issues/3544))
* Check attributes have changed before setting them to avoid image flicker ([#3579](https://github.com/sveltejs/svelte/pull/3579))
* Fix generating malformed code for `{@debug}` tags with no dependencies ([#3588](https://github.com/sveltejs/svelte/issues/3588))
* Fix generated code in specific case involving compound ifs and child components ([#3595](https://github.com/sveltejs/svelte/issues/3595))
* Fix `bind:this` binding to a store ([#3591](https://github.com/sveltejs/svelte/issues/3591))
* Use safer `HTMLElement` check before extending class ([#3608](https://github.com/sveltejs/svelte/issues/3608))
* Add `location` as a known global ([#3619](https://github.com/sveltejs/svelte/pull/3619))
* Support `{#await}` with `{:catch}` but no `{:then}` ([#3623](https://github.com/sveltejs/svelte/issues/3623))
* Clean up dead code emitted for `<slot/>`s ([#3631](https://github.com/sveltejs/svelte/issues/3631))
* Fix tracking of dependencies of compound assignments in reactive statements ([#3634](https://github.com/sveltejs/svelte/issues/3634))
* Flush changes in newly attached block when using `{#await}` ([#3660](https://github.com/sveltejs/svelte/issues/3660))
* Throw exception immediately when calling `createEventDispatcher()` after component instantiation ([#3667](https://github.com/sveltejs/svelte/pull/3667))
* Fix globals shadowing contextual template scope ([#3674](https://github.com/sveltejs/svelte/issues/3674))
* Fix `<svelte:window>` bindings to stores ([#3832](https://github.com/sveltejs/svelte/issues/3832))
* Deconflict generated var names with builtins ([#3724](https://github.com/sveltejs/svelte/issues/3724))
* Allow spring/tweened values to be initially undefined ([#3761](https://github.com/sveltejs/svelte/issues/3761))
* Warn if using `<svelte:options tag="...">` without `customElement: true` option ([#3782](https://github.com/sveltejs/svelte/pull/3782))
* Add `Event` to list of known globals ([#3810](https://github.com/sveltejs/svelte/pull/3810))
* Throw helpful error on empty CSS declaration ([#3801](https://github.com/sveltejs/svelte/issues/3801))
* Support `easing` param on `fade` transition ([#3823](https://github.com/sveltejs/svelte/pull/3823))
* Generate valid names from filenames with unicode characters ([#3845](https://github.com/sveltejs/svelte/issues/3845))
* Don't generate any code for markup-less components ([#2200](https://github.com/sveltejs/svelte/issues/2200))
* Deconflict with internal name `block` ([#3854](https://github.com/sveltejs/svelte/issues/3854))
* Set attributes before bindings, to prevent erroneous assignments to `input.files` ([#3828](https://github.com/sveltejs/svelte/issues/3828))
* Smarter unused CSS detection ([#3825](https://github.com/sveltejs/svelte/pull/3825))
* Allow dynamic event handlers ([#3040](https://github.com/sveltejs/svelte/issues/3040))
* Prevent erroneous `"undefined"` class name ([#3876](https://github.com/sveltejs/svelte/pull/3876))
* Prevent resetting of `src` attribute unless changed ([#3579](https://github.com/sveltejs/svelte/pull/3579))
* Prevent hydration of void element 'children' ([#3882](https://github.com/sveltejs/svelte/issues/3882))
* Hoist globals even if mentioned in `<script>` block ([#3745](https://github.com/sveltejs/svelte/pull/3745))
## 3.12.1
* Escape `@` symbols in props, again ([#3545](https://github.com/sveltejs/svelte/issues/3545))
## 3.12.0
* Fire events on `document` in development to facilitate dev tooling ([#3005](https://github.com/sveltejs/svelte/pull/3005))
* Remove old props when the keys in spread props are removed ([#2282](https://github.com/sveltejs/svelte/issues/2282))
## 3.11.0
* `$capture_state` and `$inject_state` HMR hooks in dev mode ([#3148](https://github.com/sveltejs/svelte/pull/3148))
* Allow unclosed tags inside if/each/etc blocks ([#2807](https://github.com/sveltejs/svelte/issues/2807))
* Invalidate unreferenced store values inside `<script>` ([#3537](https://github.com/sveltejs/svelte/issues/3537))
* Print `null` text when hydrating ([#3379](https://github.com/sveltejs/svelte/pull/3379))
## 3.10.1
* Preserve reactivity inside if block heads etc ([#3512](https://github.com/sveltejs/svelte/issues/3512))
* Fix store bindings inside each blocks ([#3455](https://github.com/sveltejs/svelte/issues/3455))
* Generate correct code for if-else blocks with static conditions ([#3505](https://github.com/sveltejs/svelte/issues/3505))
* Avoid generating unnecessary component update code ([#3526](https://github.com/sveltejs/svelte/issues/3526))
* Make `bind:currentTime` more reliable ([#3524](https://github.com/sveltejs/svelte/issues/3524))
* Prevent errors when setting spread props on SVG elements ([#3522](https://github.com/sveltejs/svelte/issues/3522))
## 3.10.0
* Add `blur` transition ([#3477](https://github.com/sveltejs/svelte/pull/3477))
* Prevent `<input type="number">` edge case with spread props ([#3426](https://github.com/sveltejs/svelte/issues/3426))
* Robustify cyclical dependency detection, improve errors ([#3459](https://github.com/sveltejs/svelte/issues/3459))
## 3.9.2
* Fix handling of additional @-rules in style blocks ([#2995](https://github.com/sveltejs/svelte/pull/2995))
* Fix if blocks with complex but static conditions ([#3447](https://github.com/sveltejs/svelte/issues/3447))
## 3.9.1
* Only update style properties if necessary ([#3433](https://github.com/sveltejs/svelte/issues/3433))

@ -0,0 +1,138 @@
# Contributing to Svelte
Svelte is a new way to build web applications. It's a compiler that takes your declarative components and converts them into efficient JavaScript that surgically updates the DOM.
The [Open Source Guides](https://opensource.guide/) website has a collection of resources for individuals, communities, and companies who want to learn how to run and contribute to an open source project. Contributors and people new to open source alike will find the following guides especially useful:
* [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)
* [Building Welcoming Communities](https://opensource.guide/building-community/)
## Get involved
There are many ways to contribute to Svelte, and many of them do not involve writing any code. Here's a few ideas to get started:
- Simply start using Svelte. Go through the [Getting Started](https://svelte.dev/blog/the-easiest-way-to-get-started) guide. Does everything work as expected? If not, we're always looking for improvements. Let us know by [opening an issue](#reporting-new-issues).
- Look through the [open issues](https://github.com/sveltejs/svelte/issues). Provide workarounds, ask for clarification, or suggest labels. Help [triage issues](#triaging-issues-and-pull-requests).
- If you find an issue you would like to fix, [open a pull request](#your-first-pull-request).
- Read through our [tutorials](https://svelte.dev/tutorial/basics). If you find anything that is confusing or can be improved, you can make edits by clicking "Edit this chapter" at the bottom left of the tutorial page.
- Take a look at the [features requested](https://github.com/sveltejs/svelte/labels/enhancement) by others in the community and consider opening a pull request if you see something you want to work on.
Contributions are very welcome. If you think you need help planning your contribution, please ping us on Discord at [svelte.dev/chat](https://svelte.dev/chat) and let us know you are looking for a bit of help.
### Triaging issues and pull requests
One great way you can contribute to the project without writing any code is to help triage issues and pull requests as they come in.
- Ask for more information if you believe the issue does not provide all the details required to solve it.
- Suggest [labels](https://github.com/sveltejs/svelte/labels) that can help categorize issues.
- Flag issues that are stale or that should be closed.
- Ask for test plans and review code.
## Bugs
We use [GitHub issues](https://github.com/sveltejs/svelte/issues) for our public bugs. If you would like to report a problem, take a look around and see if someone already opened an issue about it. If you a are certain this is a new, unreported bug, you can submit a [bug report](#reporting-new-issues).
If you have questions about using Svelte, contact us on Discord at [svelte.dev/chat](https://svelte.dev/chat), and we will do our best to answer your questions.
If you see anything you'd like to be implemented, create a [feature request issue](https://github.com/sveltejs/svelte/issues/new?template=feature_request.md)
## Reporting new issues
When [opening a new issue](https://github.com/sveltejs/svelte/issues/new/choose), always make sure to fill out the issue template. **This step is very important!** Not doing so may result in your issue not being managed in a timely fashion. Don't take this personally if this happens, and feel free to open a new issue once you've gathered all the information required by the template.
- **One issue, one bug:** Please report a single bug per issue.
- **Provide reproduction steps:** List all the steps necessary to reproduce the issue. The person reading your bug report should be able to follow these steps to reproduce your issue with minimal effort. If possible, use the [REPL](https://svelte.dev/repl) to create your reproduction.
## Installation
1. Ensure you have [npm](https://www.npmjs.com/get-npm) installed.
1. After cloning the repository, run `npm install` in the root of the repository.
1. To start a development server, run `npm run dev`.
## Pull requests
### Your first pull request
So you have decided to contribute code back to upstream by opening a pull request. You've invested a good chunk of time, and we appreciate it. We will do our best to work with you and get the PR looked at.
Working on your first Pull Request? You can learn how from this free video series:
[**How to Contribute to an Open Source Project on GitHub**](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github)
### Proposing a change
If you would like to request a new feature or enhancement but are not yet thinking about opening a pull request, you can also file an issue with [feature template](https://github.com/sveltejs/svelte/issues/new?template=feature_request.md).
If you're only fixing a bug, it's fine to submit a pull request right away but we still recommend to file an issue detailing what you're fixing. This is helpful in case we don't accept that specific fix but want to keep track of the issue.
### Sending a pull request
Small pull requests are much easier to review and more likely to get merged. Make sure the PR does only one thing, otherwise please split it.
Please make sure the following is done when submitting a pull request:
1. Fork [the repository](https://github.com/sveltejs/svelte) and create your branch from `master`.
1. Describe your **test plan** in your pull request description. Make sure to test your changes.
1. Make sure your code lints (`npm run lint`).
1. Make sure your tests pass (`npm run test`).
All pull requests should be opened against the `master` branch.
#### Test plan
A good test plan has the exact commands you ran and their output, provides screenshots or videos if the pull request changes UI.
- If you've changed APIs, update the documentation.
#### Writing tests
All tests are located in `/test` folder.
Test samples are kept in `/test/xxx/samples` folder.
#### Running tests
1. To run test, run `npm run test`
1. To run test for a specific feature, you can use the `-g` (aka `--grep`) option. For example, to only run test involving transitions, run `npm run test -- -g transition`.
##### Running solo test
1. To run only one test, rename the test sample folder to end with `.solo`. For example, to run the `test/js/samples/action` only, rename it to `test/js/samples/action.solo`.
1. To run only one test suite, rename the test suite folder to end with `.solo`. For example, to run the `test/js` test suite only, rename it to `test/js.solo`.
1. Remember to rename the test folder back. The CI will fail if there's a solo test.
##### Updating `.expected` files
1. Tests suites like `css`, `js`, `server-side-rendering` asserts that the generated output has to match the content in the `.expected` file. For example, in the `js` test suites, the generated js code is compared against the content in `expected.js`.
1. To update the content of the `.expected` file, run the test with `--update` flag. (`npm run test --update`)
#### Breaking changes
When adding a new breaking change, follow this template in your pull request:
```md
### New breaking change here
- **Who does this affect**:
- **How to migrate**:
- **Why make this breaking change**:
- **Severity (number of people affected x effort)**:
```
### What happens next?
The core Svelte team will be monitoring for pull requests. Do help us by making your pull request easy to review by following the guidelines above.
## Style guide
[Eslint](https://eslint.org) will catch most styling issues that may exist in your code. You can check the status of your code styling by simply running `npm run lint`.
### Code conventions
- `snake_case` for internal variable names and methods
- `camelCase` for public variable names and methods.
## License
By contributing to Svelte, you agree that your contributions will be licensed under its [MIT license](https://github.com/sveltejs/svelte/blob/master/LICENSE).

@ -1,6 +1,6 @@
<p>
<a href="https://svelte.dev">
<img alt="Cybernetically enhanced web apps: Svelte" src="https://svelte-assets.surge.sh/banner.png">
<img alt="Cybernetically enhanced web apps: Svelte" src="https://sveltejs.github.io/assets/banner.png">
</a>
<a href="https://www.npmjs.com/package/svelte">

@ -1,31 +0,0 @@
# http://www.appveyor.com/docs/appveyor-yml
version: "{build}"
clone_depth: 10
init:
- git config --global core.autocrlf false
environment:
matrix:
- nodejs_version: 8
- nodejs_version: 10
- nodejs_version: 12
install:
- ps: Update-NodeJsInstallation (Get-NodeJsLatestBuild $env:nodejs_version)
- npm ci || npm install
build: off
test_script:
- node --version && npm --version
- npm test
matrix:
fast_finish: false
# cache:
# - C:\Users\appveyor\AppData\Roaming\npm-cache -> package.json # npm cache
# - node_modules -> package.json # local npm modules

388
package-lock.json generated

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "3.8.1",
"version": "3.14.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -30,6 +30,16 @@
"integrity": "sha512-KioOCsSvSvXx6xUNLiJz+P+VMb7NRcePjoefOr74Y5P6lEKsiOn35eZyZzgpK4XCNJdXTDR7+zykj0lwxRvZ2g==",
"dev": true
},
"@rollup/plugin-replace": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@rollup/plugin-replace/-/plugin-replace-2.2.1.tgz",
"integrity": "sha512-dgq5ijT8fK18KTb1inenZ61ivTayV7pvbz2+ivT+VN20BOgJVM1fqoBETqGHKgFVm/J9BhR82mQyAtxfpPv1lQ==",
"dev": true,
"requires": {
"magic-string": "^0.25.2",
"rollup-pluginutils": "^2.6.0"
}
},
"@types/eslint-visitor-keys": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
@ -54,6 +64,12 @@
"integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==",
"dev": true
},
"@types/json-schema": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.3.tgz",
"integrity": "sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==",
"dev": true
},
"@types/mocha": {
"version": "5.2.7",
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz",
@ -61,9 +77,9 @@
"dev": true
},
"@types/node": {
"version": "8.10.50",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.50.tgz",
"integrity": "sha512-+ZbcUwJdaBgOZpwXeT0v+gHC/jQbEfzoc9s4d0rN0JIKeQbuTrT+A2n1aQY6LpZjrLXJT7avVUqiCecCJeeZxA==",
"version": "8.10.53",
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.53.tgz",
"integrity": "sha512-aOmXdv1a1/vYUn1OT1CED8ftbkmmYbKhKGSyMDeJiidLvKRKvZUQOdXwG/wcNY7T1Qb0XTlVdiYjIq00U7pLrQ==",
"dev": true
},
"@types/resolve": {
@ -76,48 +92,82 @@
}
},
"@typescript-eslint/eslint-plugin": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.11.0.tgz",
"integrity": "sha512-mXv9ccCou89C8/4avKHuPB2WkSZyY/XcTQUXd5LFZAcLw1I3mWYVjUu6eS9Ja0QkP/ClolbcW9tb3Ov/pMdcqw==",
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.13.0.tgz",
"integrity": "sha512-WQHCozMnuNADiqMtsNzp96FNox5sOVpU8Xt4meaT4em8lOG1SrOv92/mUbEHQVh90sldKSfcOc/I0FOb/14G1g==",
"dev": true,
"requires": {
"@typescript-eslint/experimental-utils": "1.11.0",
"@typescript-eslint/experimental-utils": "1.13.0",
"eslint-utils": "^1.3.1",
"functional-red-black-tree": "^1.0.1",
"regexpp": "^2.0.1",
"tsutils": "^3.7.0"
},
"dependencies": {
"@typescript-eslint/experimental-utils": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz",
"integrity": "sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.3",
"@typescript-eslint/typescript-estree": "1.13.0",
"eslint-scope": "^4.0.0"
}
},
"@typescript-eslint/typescript-estree": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz",
"integrity": "sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw==",
"dev": true,
"requires": {
"lodash.unescape": "4.0.1",
"semver": "5.5.0"
}
}
}
},
"@typescript-eslint/experimental-utils": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-1.11.0.tgz",
"integrity": "sha512-7LbfaqF6B8oa8cp/315zxKk8FFzosRzzhF8Kn/ZRsRsnpm7Qcu25cR/9RnAQo5utZ2KIWVgaALr+ZmcbG47ruw==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.1.0.tgz",
"integrity": "sha512-ZJGLYXa4nxjNzomaEk1qts38B/vludg2LOM7dRc7SppEKsMPTS1swaTKS/pom+x4d/luJGoG00BDIss7PR1NQA==",
"dev": true,
"requires": {
"@typescript-eslint/typescript-estree": "1.11.0",
"@types/json-schema": "^7.0.3",
"@typescript-eslint/typescript-estree": "2.1.0",
"eslint-scope": "^4.0.0"
}
},
"@typescript-eslint/parser": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-1.11.0.tgz",
"integrity": "sha512-5xBExyXaxVyczrZvbRKEXvaTUFFq7gIM9BynXukXZE0zF3IQP/FxF4mPmmh3gJ9egafZFqByCpPTFm3dk4SY7Q==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.1.0.tgz",
"integrity": "sha512-0+hzirRJoqE1T4lSSvCfKD+kWjIpDWfbGBiisK5CENcr+22pPkHB2sfV1giON+UxHV4A08SSrQonZk7X2zIQdw==",
"dev": true,
"requires": {
"@types/eslint-visitor-keys": "^1.0.0",
"@typescript-eslint/experimental-utils": "1.11.0",
"@typescript-eslint/typescript-estree": "1.11.0",
"@typescript-eslint/experimental-utils": "2.1.0",
"@typescript-eslint/typescript-estree": "2.1.0",
"eslint-visitor-keys": "^1.0.0"
}
},
"@typescript-eslint/typescript-estree": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-1.11.0.tgz",
"integrity": "sha512-fquUHF5tAx1sM2OeRCC7wVxFd1iMELWMGCzOSmJ3pLzArj9+kRixdlC4d5MncuzXpjEqc6045p3KwM0o/3FuUA==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.1.0.tgz",
"integrity": "sha512-482ErJJ7QYghBh+KA9G+Fwcuk/PLTy+9NBMz8S+6UFrUUnVvHRNAL7I70kdws2te0FBYEZW7pkDaXoT+y8UARw==",
"dev": true,
"requires": {
"glob": "^7.1.4",
"is-glob": "^4.0.1",
"lodash.unescape": "4.0.1",
"semver": "5.5.0"
"semver": "^6.2.0"
},
"dependencies": {
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
},
"abab": {
@ -127,15 +177,9 @@
"dev": true
},
"acorn": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.0.tgz",
"integrity": "sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw==",
"dev": true
},
"acorn-dynamic-import": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz",
"integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==",
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz",
"integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==",
"dev": true
},
"acorn-globals": {
@ -146,12 +190,20 @@
"requires": {
"acorn": "^6.0.1",
"acorn-walk": "^6.0.1"
},
"dependencies": {
"acorn": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz",
"integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==",
"dev": true
}
}
},
"acorn-jsx": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz",
"integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==",
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz",
"integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==",
"dev": true
},
"acorn-walk": {
@ -161,25 +213,13 @@
"dev": true
},
"agadoo": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/agadoo/-/agadoo-1.0.1.tgz",
"integrity": "sha512-rEOSqXQ3ABoxmgvxqEvUfS7mcMJBqRhcMbmJq4j+EpCXN0P1cFHYQT66V7rYSu0C+3jialSk58yHTBqzY0m+Sw==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/agadoo/-/agadoo-1.1.0.tgz",
"integrity": "sha512-MiTXQ3As5jARRXa0eZF+ObtzsseQurCXOc1RB19NOGDsimEvoT8DB8iQiC0zAGTfsF/nBhzEle+eV9UpXyWnbw==",
"dev": true,
"requires": {
"rollup": "^0.64.1",
"rollup": "^1",
"rollup-plugin-virtual": "^1.0.1"
},
"dependencies": {
"rollup": {
"version": "0.64.1",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-0.64.1.tgz",
"integrity": "sha512-+ThdVXrvonJdOTzyybMBipP0uz605Z8AnzWVY3rf+cSGnLO7uNkJBlN+9jXqWOomkvumXfm/esmBpA5d53qm7g==",
"dev": true,
"requires": {
"@types/estree": "0.0.39",
"@types/node": "*"
}
}
}
},
"agent-base": {
@ -459,6 +499,18 @@
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"dev": true
},
"code-red": {
"version": "0.0.21",
"resolved": "https://registry.npmjs.org/code-red/-/code-red-0.0.21.tgz",
"integrity": "sha512-luUVxyGNwTU/lG+lY+pitXHJzgDvFa0WfxA4Nsd7uk/S366mHY8B86pwAcyRcKY9BE/HvryVNXCR691Q5ry+Ww==",
"dev": true,
"requires": {
"acorn": "^7.1.0",
"is-reference": "^1.1.4",
"periscopic": "^2.0.1",
"sourcemap-codec": "^1.4.6"
}
},
"codecov": {
"version": "3.5.0",
"resolved": "https://registry.npmjs.org/codecov/-/codecov-3.5.0.tgz",
@ -762,13 +814,20 @@
"resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
"integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=",
"dev": true
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"optional": true
}
}
},
"eslint": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.1.0.tgz",
"integrity": "sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ==",
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-6.3.0.tgz",
"integrity": "sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
@ -778,9 +837,9 @@
"debug": "^4.0.1",
"doctrine": "^3.0.0",
"eslint-scope": "^5.0.0",
"eslint-utils": "^1.3.1",
"eslint-visitor-keys": "^1.0.0",
"espree": "^6.0.0",
"eslint-utils": "^1.4.2",
"eslint-visitor-keys": "^1.1.0",
"espree": "^6.1.1",
"esquery": "^1.0.1",
"esutils": "^2.0.2",
"file-entry-cache": "^5.0.1",
@ -824,9 +883,9 @@
},
"dependencies": {
"semver": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
}
}
@ -1059,9 +1118,9 @@
}
},
"eslint-plugin-svelte3": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-svelte3/-/eslint-plugin-svelte3-2.6.0.tgz",
"integrity": "sha512-HtoVRGo/Bjkv/S+OyPZFL/O8kwLAQpWvW4QJMP9BKDyBkrAPMlEdXCLPMFAOH4cEJmkdfgJIWuTNwOPX8W571A==",
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-svelte3/-/eslint-plugin-svelte3-2.7.3.tgz",
"integrity": "sha512-p6HhxyICX9x/x+8WSy6AVk2bmv9ayoznoTSyCvK47th/k/07ksuJixMwbGX9qxJVAmPBaYMjEIMSEZtJHPIN7w==",
"dev": true
},
"eslint-scope": {
@ -1075,26 +1134,29 @@
}
},
"eslint-utils": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz",
"integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==",
"dev": true
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz",
"integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==",
"dev": true,
"requires": {
"eslint-visitor-keys": "^1.0.0"
}
},
"eslint-visitor-keys": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz",
"integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
"integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
"dev": true
},
"espree": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/espree/-/espree-6.0.0.tgz",
"integrity": "sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q==",
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz",
"integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==",
"dev": true,
"requires": {
"acorn": "^6.0.7",
"acorn-jsx": "^5.0.0",
"eslint-visitor-keys": "^1.0.0"
"acorn": "^7.0.0",
"acorn-jsx": "^5.0.2",
"eslint-visitor-keys": "^1.1.0"
}
},
"esprima": {
@ -1128,9 +1190,9 @@
"dev": true
},
"estree-walker": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
"integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.8.1.tgz",
"integrity": "sha512-H6cJORkqvrNziu0KX2hqOMAlA2CiuAxHeGJXSIoKA/KLv229Dw806J3II6mKTm5xiDX1At1EXCfsOQPB+tMB+g==",
"dev": true
},
"esutils": {
@ -1443,6 +1505,14 @@
"optimist": "^0.6.1",
"source-map": "^0.6.1",
"uglify-js": "^3.1.4"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
}
}
},
"har-schema": {
@ -1581,9 +1651,9 @@
"dev": true
},
"inquirer": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz",
"integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==",
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz",
"integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==",
"dev": true,
"requires": {
"ansi-escapes": "^3.2.0",
@ -1700,9 +1770,9 @@
"dev": true
},
"is-reference": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.3.tgz",
"integrity": "sha512-W1iHHv/oyBb2pPxkBxtaewxa1BC58Pn5J0hogyCdefwUIvb6R+TGbAcIa4qPNYLqLhb3EnOgUf2MQkkF76BcKw==",
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.1.4.tgz",
"integrity": "sha512-uJA/CDPO3Tao3GTrxYn6AwkM4nUPJiGGYu5+cB8qbC7WGFlrKZbiRo7SFKxUAEpFUfiHofWCXBUNhvYJMh+6zw==",
"dev": true,
"requires": {
"@types/estree": "0.0.39"
@ -1844,6 +1914,12 @@
"xml-name-validator": "^3.0.0"
},
"dependencies": {
"acorn": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz",
"integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==",
"dev": true
},
"ws": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.1.1.tgz",
@ -2646,6 +2722,15 @@
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
"dev": true
},
"periscopic": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/periscopic/-/periscopic-2.0.1.tgz",
"integrity": "sha512-twJ8e4RatllMAcbmBqKj8cvZ94HtqSzbb8hJoGj4iSCcCHXxKb06HRxOq4heyq2x/6mKynJDvTTreHCz+m6lJw==",
"dev": true,
"requires": {
"is-reference": "^1.1.4"
}
},
"pify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
@ -2774,9 +2859,9 @@
"dev": true
},
"puppeteer": {
"version": "1.18.1",
"resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.18.1.tgz",
"integrity": "sha512-luUy0HPSuWPsPZ1wAp6NinE0zgetWtudf5zwZ6dHjMWfYpTQcmKveFRox7VBNhQ98OjNA9PQ9PzQyX8k/KrxTg==",
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.19.0.tgz",
"integrity": "sha512-2S6E6ygpoqcECaagDbBopoSOPDv0pAZvTbnBgUY+6hq0/XDFDOLEMNlHF/SKJlzcaZ9ckiKjKDuueWI3FN/WXw==",
"dev": true,
"requires": {
"debug": "^4.1.0",
@ -2840,14 +2925,6 @@
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
},
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
}
}
},
"regexpp": {
@ -2981,28 +3058,28 @@
}
},
"rollup": {
"version": "1.16.6",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-1.16.6.tgz",
"integrity": "sha512-oM3iKkzPCq9Da95wCnNfS8YlNZjgCD5c/TceKnJIthI9FOeJqnO3PUr/C5Suv9Kjzh0iphKL02PLeja3A5AMIA==",
"version": "1.21.4",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-1.21.4.tgz",
"integrity": "sha512-Pl512XVCmVzgcBz5h/3Li4oTaoDcmpuFZ+kdhS/wLreALz//WuDAMfomD3QEYl84NkDu6Z6wV9twlcREb4qQsw==",
"dev": true,
"requires": {
"@types/estree": "0.0.39",
"@types/node": "^12.0.10",
"acorn": "^6.1.1"
"@types/node": "^12.7.5",
"acorn": "^7.0.0"
},
"dependencies": {
"@types/node": {
"version": "12.0.12",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.12.tgz",
"integrity": "sha512-Uy0PN4R5vgBUXFoJrKryf5aTk3kJ8Rv3PdlHjl6UaX+Cqp1QE0yPQ68MPXGrZOfG7gZVNDIJZYyot0B9ubXUrQ==",
"version": "12.7.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.5.tgz",
"integrity": "sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w==",
"dev": true
}
}
},
"rollup-plugin-commonjs": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.0.1.tgz",
"integrity": "sha512-x0PcCVdEc4J8igv1qe2vttz8JKAKcTs3wfIA3L8xEty3VzxgORLrzZrNWaVMc+pBC4U3aDOb9BnWLAQ8J11vkA==",
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-commonjs/-/rollup-plugin-commonjs-10.1.0.tgz",
"integrity": "sha512-jlXbjZSQg8EIeAAvepNwhJj++qJWNJw1Cl0YnOqKtP5Djx+fFGkp3WRh+W0ASCaFG5w1jhmzDxgu3SJuVxPF4Q==",
"dev": true,
"requires": {
"estree-walker": "^0.6.1",
@ -3010,6 +3087,14 @@
"magic-string": "^0.25.2",
"resolve": "^1.11.0",
"rollup-pluginutils": "^2.8.1"
},
"dependencies": {
"estree-walker": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
"integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
"dev": true
}
}
},
"rollup-plugin-json": {
@ -3034,16 +3119,6 @@
"rollup-pluginutils": "^2.8.1"
}
},
"rollup-plugin-replace": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-replace/-/rollup-plugin-replace-2.2.0.tgz",
"integrity": "sha512-/5bxtUPkDHyBJAKketb4NfaeZjL5yLZdeUihSfbF2PQMz+rSTEb8ARKoOl3UBT4m7/X+QOXJo3sLTcq+yMMYTA==",
"dev": true,
"requires": {
"magic-string": "^0.25.2",
"rollup-pluginutils": "^2.6.0"
}
},
"rollup-plugin-sucrase": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/rollup-plugin-sucrase/-/rollup-plugin-sucrase-2.1.0.tgz",
@ -3077,6 +3152,14 @@
"dev": true,
"requires": {
"estree-walker": "^0.6.1"
},
"dependencies": {
"estree-walker": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz",
"integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==",
"dev": true
}
}
},
"run-async": {
@ -3089,9 +3172,9 @@
}
},
"rxjs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz",
"integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==",
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz",
"integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==",
"dev": true,
"requires": {
"tslib": "^1.9.0"
@ -3163,19 +3246,27 @@
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
"dev": true
},
"source-map-support": {
"version": "0.5.12",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz",
"integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
"version": "0.5.13",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
"integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
"dev": true,
"requires": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
}
}
},
"sourcemap-codec": {
@ -3263,14 +3354,6 @@
"dev": true,
"requires": {
"safe-buffer": "~5.1.0"
},
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
}
}
},
"strip-ansi": {
@ -3328,9 +3411,9 @@
"dev": true
},
"table": {
"version": "5.4.5",
"resolved": "https://registry.npmjs.org/table/-/table-5.4.5.tgz",
"integrity": "sha512-oGa2Hl7CQjfoaogtrOHEJroOcYILTx7BZWLGsJIlzoWmB2zmguhNfPJZsWPKYek/MgCxfco54gEi31d1uN2hFA==",
"version": "5.4.6",
"resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
"integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
"dev": true,
"requires": {
"ajv": "^6.10.2",
@ -3438,9 +3521,9 @@
"dev": true
},
"tsutils": {
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.14.0.tgz",
"integrity": "sha512-SmzGbB0l+8I0QwsPgjooFRaRvHLBLNYM8SeQ0k6rtNDru5sCGeLJcZdwilNndN+GysuFjF5EIYgN8GfFG6UeUw==",
"version": "3.17.1",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz",
"integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==",
"dev": true,
"requires": {
"tslib": "^1.8.1"
@ -3477,9 +3560,9 @@
"dev": true
},
"typescript": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.2.tgz",
"integrity": "sha512-7KxJovlYhTX5RaRbUdkAXN1KUZ8PwWlTzQdHV6xNqvuFOs7+WBo10TQUqT19Q/Jz2hk5v9TQDIhyLhhJY4p5AA==",
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz",
"integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==",
"dev": true
},
"uglify-js": {
@ -3491,6 +3574,15 @@
"requires": {
"commander": "~2.20.0",
"source-map": "~0.6.1"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"optional": true
}
}
},
"uri-js": {
@ -3521,9 +3613,9 @@
"dev": true
},
"v8-compile-cache": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz",
"integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
"integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==",
"dev": true
},
"v8-to-istanbul": {
@ -3535,14 +3627,6 @@
"@types/istanbul-lib-coverage": "^2.0.1",
"convert-source-map": "^1.6.0",
"source-map": "^0.7.3"
},
"dependencies": {
"source-map": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
"dev": true
}
}
},
"validate-npm-package-license": {

@ -1,6 +1,6 @@
{
"name": "svelte",
"version": "3.9.1",
"version": "3.14.1",
"description": "Cybernetically enhanced web apps",
"module": "index.mjs",
"main": "index",
@ -56,40 +56,41 @@
},
"homepage": "https://github.com/sveltejs/svelte#README",
"devDependencies": {
"@rollup/plugin-replace": "^2.2.1",
"@types/mocha": "^5.2.7",
"@types/node": "=8",
"@typescript-eslint/eslint-plugin": "^1.11.0",
"@typescript-eslint/parser": "^1.11.0",
"acorn": "^6.2.0",
"acorn-dynamic-import": "^4.0.0",
"agadoo": "^1.0.1",
"@types/node": "^8.10.53",
"@typescript-eslint/eslint-plugin": "^1.13.0",
"@typescript-eslint/parser": "^2.1.0",
"acorn": "^7.1.0",
"agadoo": "^1.1.0",
"c8": "^5.0.1",
"code-red": "0.0.21",
"codecov": "^3.5.0",
"css-tree": "1.0.0-alpha22",
"eslint": "^6.1.0",
"eslint": "^6.3.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-svelte3": "^2.6.0",
"estree-walker": "^0.6.1",
"is-reference": "^1.1.3",
"eslint-plugin-svelte3": "^2.7.3",
"estree-walker": "^0.8.1",
"is-reference": "^1.1.4",
"jsdom": "^15.1.1",
"kleur": "^3.0.3",
"locate-character": "^2.0.5",
"magic-string": "^0.25.3",
"mocha": "^6.2.0",
"puppeteer": "^1.18.1",
"rollup": "^1.16.6",
"rollup-plugin-commonjs": "^10.0.1",
"periscopic": "^2.0.1",
"puppeteer": "^1.19.0",
"rollup": "^1.21.4",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-json": "^4.0.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-sucrase": "^2.1.0",
"rollup-plugin-typescript": "^1.0.1",
"rollup-plugin-virtual": "^1.0.1",
"source-map": "^0.6.1",
"source-map-support": "^0.5.12",
"source-map": "^0.7.3",
"source-map-support": "^0.5.13",
"tiny-glob": "^0.2.6",
"tslib": "^1.10.0",
"typescript": "^3.5.2"
"typescript": "^3.5.3"
},
"nyc": {
"include": [

@ -1,5 +1,5 @@
import fs from 'fs';
import replace from 'rollup-plugin-replace';
import replace from '@rollup/plugin-replace';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import json from 'rollup-plugin-json';
@ -20,8 +20,7 @@ const ts_plugin = is_publish
const external = id => id.startsWith('svelte/');
const inlined_estree = fs.readFileSync('./node_modules/estree-walker/index.d.ts', 'utf-8').replace(/declare.*\{((.|[\n\r])+)\}/m, '$1');
fs.writeFileSync(`./compiler.d.ts`, `export { compile, parse, preprocess, VERSION } from './types/compiler/index';\n${inlined_estree}`);
fs.writeFileSync(`./compiler.d.ts`, `export { compile, parse, preprocess, VERSION } from './types/compiler/index';`);
export default [
/* runtime */

@ -2,7 +2,12 @@ NODE_ENV=
PORT=
BASEURL=
DATABASE_URL=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
MAPBOX_ACCESS_TOKEN=
PGHOST=hostname
PGPORT=port
PGUSER=username
PGPASSWORD=password
PGDATABASE=database_name

@ -47,6 +47,12 @@ module.exports = {
},
settings: {
'import/core-modules': ['svelte'],
'svelte3/compiler': require('svelte/compiler')
'svelte3/compiler': (() => {
try {
return require('svelte/compiler');
} catch (e) {
return null;
}
})()
}
};

@ -6,28 +6,64 @@ authorURL: https://twitter.com/Rich_Harris
draft: true
---
*Coming soon* This post will walk you through setting up your editor so that recognises Svelte files:
*__Coming soon__*
This post will walk you through setting up your editor so that recognises Svelte files:
* eslint-plugin-svelte3
* svelte-vscode
* associating .svelte files with HTML in VSCode, Sublime, Atom, etc etc etc
* associating .svelte files with HTML in VSCode, Sublime, etc.
## Atom
To treat `*.svelte` files as HTML, open *__Edit → Config...__* and add the following lines to your `core` section:
```cson
"*":
core:
customFileTypes:
"text.html.basic": [
"svelte"
]
```
## Vim/Neovim
To treat all `*.svelte` files as HTML, add the following line to your `init.vim`:
```bash
```
au! BufNewFile,BufRead *.svelte set ft=html
```
To temporarily turn on HTML syntax highlighting for the current buffer, use:
```bash
```
:set ft=html
```
To set the filetype for a single file, use a [modeline](https://vim.fandom.com/wiki/Modeline_magic):
```bash
```
<!-- vim: set ft=html :-->
```
## Visual Studio Code
To treat `*.svelte` files as HTML, add the following lines to your `settings.json` file:
```cson
"files.associations": {
"*.svelte": "html"
}
```
## JetBrains WebStorm
To treat `*.svelte` files as HTML in WebStorm, you need to create a new file type association. Please refer to the [JetBrains website](https://www.jetbrains.com/help/webstorm/creating-and-registering-file-types.html) to see how.
## Sublime Text 3
Open any `.svelte` file.
Go to *__View → Syntax → Open all with current extension as... → HTML__*.

@ -318,7 +318,9 @@ If you don't care about the pending state, you can also omit the initial block.
---
In a text expression, characters like `<` and `>` are escaped. With HTML expressions, they're not.
In a text expression, characters like `<` and `>` are escaped; however, with HTML expressions, they're not.
The expression should be valid standalone HTML — `{@html "<div>"}content{@html "</div>"}` will *not* work, because `</div>` is not valid HTML.
> Svelte does not sanitize expressions before injecting HTML. If the data comes from an untrusted source, you must sanitize it, or you are exposing your users to an XSS vulnerability.
@ -568,9 +570,10 @@ Media elements (`<audio>` and `<video>`) have their own set of bindings — four
* `seekable` (readonly) — ditto
* `played` (readonly) — ditto
...and three *two-way* bindings:
...and four *two-way* bindings:
* `currentTime` — the current point in the video, in seconds
* `playbackRate` — how fast to play the video, where 1 is 'normal'
* `paused` — this one should be self-explanatory
* `volume` — a value between 0 and 1
@ -1153,7 +1156,7 @@ bind:property={variable}
---
You can bind to component props using the same mechanism.
You can bind to component props using the same syntax as for elements.
```html
<Keypad bind:value={pin}/>
@ -1388,7 +1391,7 @@ As with `<svelte:window>`, this element allows you to add listeners to events on
---
This element makes it possible to insert elements into `document.head`. During server-side rendering, `head` content exposed separately to the main `html` content.
This element makes it possible to insert elements into `document.head`. During server-side rendering, `head` content is exposed separately to the main `html` content.
```html
<svelte:head>

@ -184,7 +184,7 @@ dispatch: ((name: string, detail?: any) => void) = createEventDispatcher();
---
Creates an event dispatcher that can be used to dispatch [component events](docs#Component_events). Event dispatchers are functions that can take two arguments: `name` and `detail`.
Creates an event dispatcher that can be used to dispatch [component events](docs#on_component_event). Event dispatchers are functions that can take two arguments: `name` and `detail`.
Component events created with `createEventDispatcher` create a [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent). These events do not [bubble](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture) and are not cancellable with `event.preventDefault()`. The `detail` argument corresponds to the [CustomEvent.detail](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail) property and can contain any type of data.
@ -433,6 +433,19 @@ Out of the box, Svelte will interpolate between two numbers, two arrays or two o
---
If the initial value is `undefined` or `null`, the first value change will take effect immediately. This is useful when you have tweened values that are based on props, and don't want any motion when the component first renders.
```js
const size = tweened(undefined, {
duration: 300,
easing: cubicOut
});
$: $size = big ? 100 : 10;
```
---
The `interpolate` option allows you to tween between *any* arbitrary values. It must be an `(a, b) => t => value` function, where `a` is the starting value, `b` is the target value, `t` is a number between 0 and 1, and `value` is the result. For example, we can use the [d3-interpolate](https://github.com/d3/d3-interpolate) package to smoothly interpolate between two colours.
```html
@ -493,6 +506,15 @@ Both `set` and `update` can take a second argument — an object with `hard` or
</script>
```
---
If the initial value is `undefined` or `null`, the first value change will take effect immediately, just as with `tweened` values (see above).
```js
const size = spring();
$: $size = big ? 100 : 10;
```
### `svelte/transition`
The `svelte/transition` module exports six functions: `fade`, `fly`, `slide`, `scale`, `draw` and `crossfade`. They are for use with svelte [`transitions`](docs#Transitions).
@ -532,6 +554,42 @@ You can see the `fade` transition in action in the [transition tutorial](tutoria
{/if}
```
#### `blur`
```sv
transition:blur={params}
```
```sv
in:blur={params}
```
```sv
out:blur={params}
```
---
Animates a `blur` filter alongside an element's opacity.
`blur` accepts the following parameters:
* `delay` (`number`, default 0) — milliseconds before starting
* `duration` (`number`, default 400) — milliseconds the transition lasts
* `easing` (`function`, default `cubicInOut`) — an [easing function](docs#svelte_easing)
* `opacity` (`number`, default 0) - the opacity value to animate out to and in from
* `amount` (`number`, default 5) - the size of the blur in pixels
```html
<script>
import { blur } from 'svelte/transition';
</script>
{#if condition}
<div transition:blur="{{amount: 10}}">
fades in and out
</div>
{/if}
```
#### `fly`
```sv
@ -660,7 +718,7 @@ out:draw={params}
Animates the stroke of an SVG element, like a snake in a tube. `in` transitions begin with the path invisible and draw the path to the screen over time. `out` transitions start in a visible state and gradually erase the path. `draw` only works with elements that have a `getTotalLength` method, like `<path>` and `<polyline>`.
`scale` accepts the following parameters:
`draw` accepts the following parameters:
* `delay` (`number`, default 0) — milliseconds before starting
* `speed` (`number`, default undefined) - the speed of the animation, see below.
@ -909,7 +967,7 @@ app.count += 1;
---
Svelte components can also be compiled to custom elements (aka web components) using the `customElements: true` compiler option. You should specify a tag name for the component using the `<svelte:options>` [element](docs#svelte_options).
Svelte components can also be compiled to custom elements (aka web components) using the `customElement: true` compiler option. You should specify a tag name for the component using the `<svelte:options>` [element](docs#svelte_options).
```html
<svelte:options tag="my-element">
@ -983,8 +1041,12 @@ Unlike client-side components, server-side components don't have a lifespan afte
A server-side component exposes a `render` method that can be called with optional props. It returns an object with `head`, `html`, and `css` properties, where `head` contains the contents of any `<svelte:head>` elements encountered.
You can import a Svelte component directly into Node using [`svelte/register`](docs#svelte_register).
```js
const App = require('./App.svelte');
require('svelte/register');
const App = require('./App.svelte').default;
const { head, html, css } = App.render({
answer: 42

@ -53,6 +53,7 @@ The following options can be passed to the compiler. None are required:
| `tag` | string | null
| `accessors` | boolean | `false`
| `css` | boolean | `true`
| `loopGuardTimeout` | number | 0
| `preserveComments` | boolean | `false`
| `preserveWhitespace` | boolean | `false`
| `outputFilename` | string | `null`
@ -73,6 +74,7 @@ The following options can be passed to the compiler. None are required:
| `customElement` | `false` | If `true`, tells the compiler to generate a custom element constructor instead of a regular Svelte component.
| `tag` | `null` | A `string` that tells Svelte what tag name to register the custom element with. It must be a lowercase alphanumeric string with at least one hyphen, e.g. `"my-element"`.
| `css` | `true` | If `true`, styles will be included in the JavaScript class and injected at runtime. It's recommended that you set this to `false` and use the CSS that is statically generated, as it will result in smaller JavaScript bundles and better performance.
| `loopGuardTimeout` | 0 | A `number` that tells Svelte to break the loop if it blocks the thread for more than `loopGuardTimeout` ms. This is useful to prevent infinite loops. **Only available when `dev: true`**
| `preserveComments` | `false` | If `true`, your HTML comments will be preserved during server-side rendering. By default, they are stripped out.
| `preserveWhitespace` | `false` | If `true`, whitespace inside and between elements is kept as you typed it, rather than optimised by Svelte.
| `outputFilename` | `null` | A `string` used for your JavaScript sourcemap.
@ -315,7 +317,7 @@ walk(ast: Node, {
---
The `walk` function provides a way to walk to abstract syntax trees generated by the parser, using the compiler's own built-in instance of [estree-walker](https://github.com/Rich-Harris/estree-walker).
The `walk` function provides a way to walk the abstract syntax trees generated by the parser, using the compiler's own built-in instance of [estree-walker](https://github.com/Rich-Harris/estree-walker).
The walker takes an abstract syntax tree to walk and an object with two optional methods: `enter` and `leave`. For each node, `enter` is called (if present). Then, unless `this.skip()` is called during `enter`, each of the children are traversed, and then `leave` is called on the node.

@ -14,7 +14,7 @@
showControlsTimeout = setTimeout(() => showControls = false, 2500);
showControls = true;
if (e.which !== 1) return; // mouse not down
if (!(e.buttons & 1)) return; // mouse not down
if (!duration) return; // video not loaded yet
const { left, right } = this.getBoundingClientRect();
@ -109,8 +109,8 @@
<div>
<video
poster="http://svelte-assets.surge.sh/caminandes-llamigos.jpg"
src="http://svelte-assets.surge.sh/caminandes-llamigos.mp4"
poster="http://sveltejs.github.io/assets/caminandes-llamigos.jpg"
src="http://sveltejs.github.io/assets/caminandes-llamigos.mp4"
on:mousemove={handleMousemove}
on:mousedown={handleMousedown}
bind:currentTime={time}

@ -2,9 +2,6 @@
import { onMount } from 'svelte';
let canvas;
let running = false;
const r = Math.random();
onMount(() => {
const ctx = canvas.getContext('2d');
@ -46,8 +43,8 @@
width: 100%;
height: 100%;
background-color: #666;
-webkit-mask: url(logo-mask.svg) 50% 50% no-repeat;
mask: url(logo-mask.svg) 50% 50% no-repeat;
-webkit-mask: url(svelte-logo-mask.svg) 50% 50% no-repeat;
mask: url(svelte-logo-mask.svg) 50% 50% no-repeat;
}
</style>

@ -10,7 +10,7 @@
let selected = null;
let loading = null;
const ASSETS = `https://svelte-assets.surge.sh/crossfade`;
const ASSETS = `https://sveltejs.github.io/assets/crossfade`;
const load = image => {
const timeout = setTimeout(() => loading = image, 100);

@ -109,7 +109,11 @@
</style>
<div class='board'>
<input class="new-todo" placeholder="what needs to be done?" on:keydown="{event => event.which === 13 && add(this)}">
<input
class="new-todo"
placeholder="what needs to be done?"
on:keydown="{event => event.which === 13 && add(event.target)}"
>
<div class='left'>
<h2>todo</h2>

@ -33,7 +33,7 @@
font-family: 'Overpass';
letter-spacing: 0.12em;
color: #676778;
font-weight: 100;
font-weight: 400;
}
.centered span {
@ -71,4 +71,4 @@
toggle me
</label>
<link href="https://fonts.googleapis.com/css?family=Overpass:100" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Overpass:100,400" rel="stylesheet">

@ -1,9 +1,56 @@
<script>
import { createEventDispatcher } from 'svelte';
import { createEventDispatcher, onDestroy } from 'svelte';
const dispatch = createEventDispatcher();
const close = () => dispatch('close');
let modal;
const handle_keydown = e => {
if (e.key === 'Escape') {
close();
return;
}
if (e.key === 'Tab') {
// trap focus
const nodes = modal.querySelectorAll('*');
const tabbable = Array.from(nodes).filter(n => n.tabIndex >= 0);
let index = tabbable.indexOf(document.activeElement);
if (index === -1 && e.shiftKey) index = 0;
index += tabbable.length + (e.shiftKey ? -1 : 1);
index %= tabbable.length;
tabbable[index].focus();
e.preventDefault();
}
};
const previously_focused = typeof document !== 'undefined' && document.activeElement;
if (previously_focused) {
onDestroy(() => {
previously_focused.focus();
});
}
</script>
<svelte:window on:keydown={handle_keydown}/>
<div class="modal-background" on:click={close}></div>
<div class="modal" role="dialog" aria-modal="true" bind:this={modal}>
<slot name="header"></slot>
<hr>
<slot></slot>
<hr>
<!-- svelte-ignore a11y-autofocus -->
<button autofocus on:click={close}>close modal</button>
</div>
<style>
.modal-background {
position: fixed;
@ -32,14 +79,3 @@
display: block;
}
</style>
<div class='modal-background' on:click='{() => dispatch("close")}'></div>
<div class='modal'>
<slot name='header'></slot>
<hr>
<slot></slot>
<hr>
<button on:click='{() => dispatch("close")}'>close modal</button>
</div>

@ -8,7 +8,7 @@
<!-- https://musopen.org/music/9862-the-blue-danube-op-314/ -->
<AudioPlayer
src="tutorial/music/strauss.mp3"
src="https://sveltejs.github.io/assets/music/strauss.mp3"
title="The Blue Danube Waltz"
composer="Johann Strauss"
performer="European Archive"
@ -16,7 +16,7 @@
<!-- https://musopen.org/music/43775-the-planets-op-32/ -->
<AudioPlayer
src="tutorial/music/holst.mp3"
src="https://sveltejs.github.io/assets/music/holst.mp3"
title="Mars, the Bringer of War"
composer="Gustav Holst"
performer="USAF Heritage of America Band"
@ -24,7 +24,7 @@
<!-- https://musopen.org/music/8010-3-gymnopedies/ -->
<AudioPlayer
src="tutorial/music/satie.mp3"
src="https://sveltejs.github.io/assets/music/satie.mp3"
title="Gymnopédie no. 1"
composer="Erik Satie"
performer="Prodigal Procrastinator"
@ -32,7 +32,7 @@
<!-- https://musopen.org/music/2567-symphony-no-5-in-c-minor-op-67/ -->
<AudioPlayer
src="tutorial/music/beethoven.mp3"
src="https://sveltejs.github.io/assets/music/beethoven.mp3"
title="Symphony no. 5 in Cm, Op. 67 - I. Allegro con brio"
composer="Ludwig van Beethoven"
performer="European Archive"
@ -40,7 +40,7 @@
<!-- https://musopen.org/music/43683-requiem-in-d-minor-k-626/ -->
<AudioPlayer
src="tutorial/music/mozart.mp3"
src="https://sveltejs.github.io/assets/music/mozart.mp3"
title="Requiem in D minor, K. 626 - III. Sequence - Lacrymosa"
composer="Wolfgang Amadeus Mozart"
performer="Markus Staab"

@ -2,18 +2,9 @@
<script>
let people = [
{
first: 'Hans',
last: 'Emil'
},
{
first: 'Max',
last: 'Mustermann'
},
{
first: 'Roman',
last: 'Tisch'
}
{ first: 'Hans', last: 'Emil' },
{ first: 'Max', last: 'Mustermann' },
{ first: 'Roman', last: 'Tisch' }
];
let prefix = '';
@ -39,7 +30,9 @@
}
function update() {
people[i] = { first, last };
selected.first = first;
selected.last = last;
people = people;
}
function remove() {

@ -30,3 +30,12 @@ function addNumber() {
numbers[numbers.length] = numbers.length + 1;
}
```
A simple rule of thumb: the name of the updated variable must appear on the left hand side of the assignment. For example this...
```js
const foo = obj.foo;
foo.bar = 'baz';
```
...won't update references to `obj.foo.bar`, unless you follow it up with `obj = obj`.

@ -4,13 +4,13 @@ title: Keyed each blocks
By default, when you modify the value of an `each` block, it will add and remove items at the *end* of the block, and update any values that have changed. That might not be what you want.
It's easier to show why than to explain. Click the 'Remove first thing' button a few times, and notice that it's removing `<Thing>` components from the end and updating the `value` for those that remain. Instead, we'd like to remove the first `<Thing>` component and leave the rest unaffected.
It's easier to show why than to explain. Click the 'Remove first thing' button a few times, and notice that it's removing `<Thing>` components from the end and updating the `color` for those that remain. Instead, we'd like to remove the first `<Thing>` component and leave the rest unaffected.
To do that, we specify a unique identifier for the `each` block:
```html
{#each things as thing (thing.id)}
<Thing value={thing.value}/>
<Thing current={thing.color}/>
{/each}
```

@ -14,7 +14,7 @@
showControlsTimeout = setTimeout(() => showControls = false, 2500);
showControls = true;
if (e.which !== 1) return; // mouse not down
if (!(e.buttons & 1)) return; // mouse not down
if (!duration) return; // video not loaded yet
const { left, right } = this.getBoundingClientRect();
@ -109,8 +109,8 @@
<div>
<video
poster="https://svelte-assets.surge.sh/caminandes-llamigos.jpg"
src="https://svelte-assets.surge.sh/caminandes-llamigos.mp4"
poster="https://sveltejs.github.io/assets/caminandes-llamigos.jpg"
src="https://sveltejs.github.io/assets/caminandes-llamigos.mp4"
on:mousemove={handleMousemove}
on:mousedown={handleMousedown}
></video>

@ -14,7 +14,7 @@
showControlsTimeout = setTimeout(() => showControls = false, 2500);
showControls = true;
if (e.which !== 1) return; // mouse not down
if (!(e.buttons & 1)) return; // mouse not down
if (!duration) return; // video not loaded yet
const { left, right } = this.getBoundingClientRect();
@ -109,8 +109,8 @@
<div>
<video
poster="https://svelte-assets.surge.sh/caminandes-llamigos.jpg"
src="https://svelte-assets.surge.sh/caminandes-llamigos.mp4"
poster="https://sveltejs.github.io/assets/caminandes-llamigos.jpg"
src="https://sveltejs.github.io/assets/caminandes-llamigos.mp4"
on:mousemove={handleMousemove}
on:mousedown={handleMousedown}
bind:currentTime={time}

@ -8,8 +8,8 @@ On line 116, add `currentTime={time}`, `duration` and `paused` bindings:
```html
<video
poster="https://svelte-assets.surge.sh/caminandes-llamigos.jpg"
src="https://svelte-assets.surge.sh/caminandes-llamigos.mp4"
poster="https://sveltejs.github.io/assets/caminandes-llamigos.jpg"
src="https://sveltejs.github.io/assets/caminandes-llamigos.mp4"
on:mousemove={handleMousemove}
on:mousedown={handleMousedown}
bind:currentTime={time}

@ -8,6 +8,7 @@
<style>
input { display: block; }
div { display: inline-block; }
span { word-break: break-all; }
</style>
<input type=range bind:value={size}>

@ -8,6 +8,7 @@
<style>
input { display: block; }
div { display: inline-block; }
span { word-break: break-all; }
</style>
<input type=range bind:value={size}>

@ -43,8 +43,8 @@
width: 100%;
height: 100%;
background-color: #666;
-webkit-mask: url(logo-mask.svg) 50% 50% no-repeat;
mask: url(logo-mask.svg) 50% 50% no-repeat;
-webkit-mask: url(svelte-logo-mask.svg) 50% 50% no-repeat;
mask: url(svelte-logo-mask.svg) 50% 50% no-repeat;
}
</style>

@ -43,8 +43,8 @@
width: 100%;
height: 100%;
background-color: #666;
-webkit-mask: url(logo-mask.svg) 50% 50% no-repeat;
mask: url(logo-mask.svg) 50% 50% no-repeat;
-webkit-mask: url(svelte-logo-mask.svg) 50% 50% no-repeat;
mask: url(svelte-logo-mask.svg) 50% 50% no-repeat;
}
</style>

@ -88,6 +88,7 @@
background-color: #0074D9;
color: white;
border-radius: 1em 1em 0 1em;
word-break: break-all;
}
</style>

@ -88,6 +88,7 @@
background-color: #0074D9;
color: white;
border-radius: 1em 1em 0 1em;
word-break: break-all;
}
</style>

@ -28,7 +28,7 @@ Clicking the buttons causes the progress bar to animate to its new value. It's a
</script>
```
> The `svelte/easing` module contains the [Penner easing equations](http://robertpenner.com/easing/), or you can supply your own `p => t` function where `p` and `t` are both values between 0 and 1.
> The `svelte/easing` module contains the [Penner easing equations](https://web.archive.org/web/20190805215728/http://robertpenner.com/easing/), or you can supply your own `p => t` function where `p` and `t` are both values between 0 and 1.
The full set of options available to `tweened`:

@ -3,7 +3,6 @@
import flash from './flash.js';
export let todo;
export let toggle;
let div;

@ -5,7 +5,6 @@
import flash from './flash.js';
export let todo;
export let toggle;
let div;

@ -4,7 +4,7 @@
<!-- https://musopen.org/music/9862-the-blue-danube-op-314/ -->
<AudioPlayer
src="tutorial/music/strauss.mp3"
src="https://sveltejs.github.io/assets/music/strauss.mp3"
title="The Blue Danube Waltz"
composer="Johann Strauss"
performer="European Archive"
@ -12,7 +12,7 @@
<!-- https://musopen.org/music/43775-the-planets-op-32/ -->
<AudioPlayer
src="tutorial/music/holst.mp3"
src="https://sveltejs.github.io/assets/music/holst.mp3"
title="Mars, the Bringer of War"
composer="Gustav Holst"
performer="USAF Heritage of America Band"
@ -20,7 +20,7 @@
<!-- https://musopen.org/music/8010-3-gymnopedies/ -->
<AudioPlayer
src="tutorial/music/satie.mp3"
src="https://sveltejs.github.io/assets/music/satie.mp3"
title="Gymnopédie no. 1"
composer="Erik Satie"
performer="Prodigal Procrastinator"
@ -28,7 +28,7 @@
<!-- https://musopen.org/music/2567-symphony-no-5-in-c-minor-op-67/ -->
<AudioPlayer
src="tutorial/music/beethoven.mp3"
src="https://sveltejs.github.io/assets/music/beethoven.mp3"
title="Symphony no. 5 in Cm, Op. 67 - I. Allegro con brio"
composer="Ludwig van Beethoven"
performer="European Archive"
@ -36,7 +36,7 @@
<!-- https://musopen.org/music/43683-requiem-in-d-minor-k-626/ -->
<AudioPlayer
src="tutorial/music/mozart.mp3"
src="https://sveltejs.github.io/assets/music/mozart.mp3"
title="Requiem in D minor, K. 626 - III. Sequence - Lacrymosa"
composer="Wolfgang Amadeus Mozart"
performer="Markus Staab"

@ -4,7 +4,7 @@
<!-- https://musopen.org/music/9862-the-blue-danube-op-314/ -->
<AudioPlayer
src="tutorial/music/strauss.mp3"
src="https://sveltejs.github.io/assets/music/strauss.mp3"
title="The Blue Danube Waltz"
composer="Johann Strauss"
performer="European Archive"
@ -12,7 +12,7 @@
<!-- https://musopen.org/music/43775-the-planets-op-32/ -->
<AudioPlayer
src="tutorial/music/holst.mp3"
src="https://sveltejs.github.io/assets/music/holst.mp3"
title="Mars, the Bringer of War"
composer="Gustav Holst"
performer="USAF Heritage of America Band"
@ -20,7 +20,7 @@
<!-- https://musopen.org/music/8010-3-gymnopedies/ -->
<AudioPlayer
src="tutorial/music/satie.mp3"
src="https://sveltejs.github.io/assets/music/satie.mp3"
title="Gymnopédie no. 1"
composer="Erik Satie"
performer="Prodigal Procrastinator"
@ -28,7 +28,7 @@
<!-- https://musopen.org/music/2567-symphony-no-5-in-c-minor-op-67/ -->
<AudioPlayer
src="tutorial/music/beethoven.mp3"
src="https://sveltejs.github.io/assets/music/beethoven.mp3"
title="Symphony no. 5 in Cm, Op. 67 - I. Allegro con brio"
composer="Ludwig van Beethoven"
performer="European Archive"
@ -36,7 +36,7 @@
<!-- https://musopen.org/music/43683-requiem-in-d-minor-k-626/ -->
<AudioPlayer
src="tutorial/music/mozart.mp3"
src="https://sveltejs.github.io/assets/music/mozart.mp3"
title="Requiem in D minor, K. 626 - III. Sequence - Lacrymosa"
composer="Wolfgang Amadeus Mozart"
performer="Markus Staab"

@ -8,7 +8,7 @@
<!-- https://musopen.org/music/9862-the-blue-danube-op-314/ -->
<AudioPlayer
src="tutorial/music/strauss.mp3"
src="https://sveltejs.github.io/assets/music/strauss.mp3"
title="The Blue Danube Waltz"
composer="Johann Strauss"
performer="European Archive"
@ -16,7 +16,7 @@
<!-- https://musopen.org/music/43775-the-planets-op-32/ -->
<AudioPlayer
src="tutorial/music/holst.mp3"
src="https://sveltejs.github.io/assets/music/holst.mp3"
title="Mars, the Bringer of War"
composer="Gustav Holst"
performer="USAF Heritage of America Band"
@ -24,7 +24,7 @@
<!-- https://musopen.org/music/8010-3-gymnopedies/ -->
<AudioPlayer
src="tutorial/music/satie.mp3"
src="https://sveltejs.github.io/assets/music/satie.mp3"
title="Gymnopédie no. 1"
composer="Erik Satie"
performer="Prodigal Procrastinator"
@ -32,7 +32,7 @@
<!-- https://musopen.org/music/2567-symphony-no-5-in-c-minor-op-67/ -->
<AudioPlayer
src="tutorial/music/beethoven.mp3"
src="https://sveltejs.github.io/assets/music/beethoven.mp3"
title="Symphony no. 5 in Cm, Op. 67 - I. Allegro con brio"
composer="Ludwig van Beethoven"
performer="European Archive"
@ -40,7 +40,7 @@
<!-- https://musopen.org/music/43683-requiem-in-d-minor-k-626/ -->
<AudioPlayer
src="tutorial/music/mozart.mp3"
src="https://sveltejs.github.io/assets/music/mozart.mp3"
title="Requiem in D minor, K. 626 - III. Sequence - Lacrymosa"
composer="Wolfgang Amadeus Mozart"
performer="Markus Staab"

@ -8,7 +8,7 @@
<!-- https://musopen.org/music/9862-the-blue-danube-op-314/ -->
<AudioPlayer
src="tutorial/music/strauss.mp3"
src="https://sveltejs.github.io/assets/music/strauss.mp3"
title="The Blue Danube Waltz"
composer="Johann Strauss"
performer="European Archive"
@ -16,7 +16,7 @@
<!-- https://musopen.org/music/43775-the-planets-op-32/ -->
<AudioPlayer
src="tutorial/music/holst.mp3"
src="https://sveltejs.github.io/assets/music/holst.mp3"
title="Mars, the Bringer of War"
composer="Gustav Holst"
performer="USAF Heritage of America Band"
@ -24,7 +24,7 @@
<!-- https://musopen.org/music/8010-3-gymnopedies/ -->
<AudioPlayer
src="tutorial/music/satie.mp3"
src="https://sveltejs.github.io/assets/music/satie.mp3"
title="Gymnopédie no. 1"
composer="Erik Satie"
performer="Prodigal Procrastinator"
@ -32,7 +32,7 @@
<!-- https://musopen.org/music/2567-symphony-no-5-in-c-minor-op-67/ -->
<AudioPlayer
src="tutorial/music/beethoven.mp3"
src="https://sveltejs.github.io/assets/music/beethoven.mp3"
title="Symphony no. 5 in Cm, Op. 67 - I. Allegro con brio"
composer="Ludwig van Beethoven"
performer="European Archive"
@ -40,7 +40,7 @@
<!-- https://musopen.org/music/43683-requiem-in-d-minor-k-626/ -->
<AudioPlayer
src="tutorial/music/mozart.mp3"
src="https://sveltejs.github.io/assets/music/mozart.mp3"
title="Requiem in D minor, K. 626 - III. Sequence - Lacrymosa"
composer="Wolfgang Amadeus Mozart"
performer="Markus Staab"

File diff suppressed because it is too large Load Diff

@ -14,7 +14,7 @@
},
"dependencies": {
"@polka/redirect": "^1.0.0-next.0",
"@polka/send": "^1.0.0-next.3",
"@polka/send": "^1.0.0-next.6",
"cookie": "^0.4.0",
"devalue": "^2.0.0",
"do-not-zip": "^1.0.0",
@ -22,32 +22,32 @@
"httpie": "^1.1.2",
"jsonwebtoken": "^8.5.1",
"marked": "^0.7.0",
"pg": "^7.12.0",
"polka": "^1.0.0-next.4",
"pg": "^7.12.1",
"polka": "^1.0.0-next.6",
"prismjs": "^1.17.1",
"sirv": "^0.4.2",
"yootils": "0.0.16"
},
"devDependencies": {
"@babel/core": "^7.5.5",
"@babel/core": "^7.6.0",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-transform-runtime": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"@babel/runtime": "^7.5.5",
"@babel/plugin-transform-runtime": "^7.6.0",
"@babel/preset-env": "^7.6.0",
"@babel/runtime": "^7.6.0",
"@sindresorhus/slugify": "^0.9.1",
"@sveltejs/site-kit": "^1.1.1",
"@sveltejs/svelte-repl": "^0.1.8",
"degit": "^2.1.3",
"dotenv": "^8.0.0",
"@sveltejs/site-kit": "^1.1.4",
"@sveltejs/svelte-repl": "^0.1.13",
"degit": "^2.1.4",
"dotenv": "^8.1.0",
"esm": "^3.2.25",
"jimp": "^0.6.4",
"jimp": "^0.8.0",
"mocha": "^6.2.0",
"node-fetch": "^2.6.0",
"node-pg-migrate": "^3.21.1",
"node-pg-migrate": "^3.22.0",
"npm-run-all": "^4.1.5",
"rollup": "^1.17.0",
"rollup": "^1.21.2",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-commonjs": "^10.0.1",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-json": "^4.0.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-replace": "^2.2.0",
@ -55,7 +55,7 @@
"rollup-plugin-terser": "^5.1.1",
"sapper": "^0.27.8",
"shelljs": "^0.8.3",
"svelte": "^3.6.9"
"svelte": "^3.12.0"
},
"engines": {
"node": ">=10.0.0"

@ -13,6 +13,9 @@ const mode = process.env.NODE_ENV;
const dev = mode === 'development';
const legacy = !!process.env.SAPPER_LEGACY_BUILD;
const onwarn = (warning, onwarn) => (warning.code === 'CIRCULAR_DEPENDENCY' && /[/\\]@sapper[/\\]/.test(warning.message)) || onwarn(warning);
const dedupe = importee => importee === 'svelte' || importee.startsWith('svelte/');
export default {
client: {
input: config.client.input(),
@ -28,7 +31,10 @@ export default {
hydratable: true,
emitCss: true
}),
resolve(),
resolve({
browser: true,
dedupe
}),
commonjs(),
json(),
@ -53,6 +59,7 @@ export default {
module: true
})
],
onwarn
},
server: {
@ -67,7 +74,9 @@ export default {
generate: 'ssr',
dev
}),
resolve(),
resolve({
dedupe
}),
commonjs(),
json()
],
@ -78,6 +87,7 @@ export default {
require('module').builtinModules || Object.keys(process.binding('natives'))
)
],
onwarn
},
serviceworker: {

@ -38,7 +38,7 @@
{#each labels as label, index}
<button
class:selected={offset === index}
on:click={() => {offset = index}}
on:click={() => offset = index}
>
{label}
</button>

@ -45,30 +45,43 @@
</style>
<div class="logos">
<a target="_blank" rel="noopener" href="https://bekchy.com"><img src="organisations/bekchy.png" alt="Bekchy logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://beyonk.com"><img src="organisations/beyonk.svg" alt="Beyonk logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://buydotstar.com"><img src="organisations/buydotstar.svg" alt="buy.* logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://chess.com" style="background-color: rgb(49,46,43);"><img src="organisations/chess.svg" alt="Chess.com logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://comigosaude.com.br"><img src="organisations/comigo.svg" alt="Comigo logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://datawrapper.de"><img src="organisations/datawrapper.svg" alt="Datawrapper logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://db.nomics.world" style="background-color: rgb(15,39,47);"><picture><source type="image/webp" srcset="organisations/dbnomics.webp"><img src="organisations/dbnomics.jpg" alt="DBNomics logo" loading="lazy"></picture></a>
<a target="_blank" rel="noopener" href="https://deck.nl"><img src="organisations/deck.svg" alt="Deck logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://dextra.com.br/pt/"><img src="organisations/dextra.png" alt="Dextra logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://www.entriwise.com/"><img src="organisations/entriwise.png" alt="Entriwise logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://www.entur.org/about-entur/" style="background-color: rgb(25, 25, 84);"><img src="organisations/entur.svg" alt="Entur logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://from-now-on.com"><img src="organisations/from-now-on.png" alt="From-Now-On logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://fusioncharts.com"><img src="organisations/fusioncharts.svg" alt="FusionCharts logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://godaddy.com"><img src="organisations/godaddy.svg" alt="GoDaddy logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://www.grainger.com"><img src="organisations/grainger.svg" alt="Grainger logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="http://healthtree.org/"><img src="organisations/healthtree.png" alt="HealthTree logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://itslearning.com"><img src="organisations/itslearning.svg" alt="itslearning logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://jacoux.com"><img src="organisations/jacoux.png" alt="Jacoux logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://www.metrovias.com.ar/"><img src="organisations/metrovias.svg" alt="Metrovias logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="http://mustlab.ru"><img src="organisations/mustlab.png" alt="Mustlab logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://www.nesta.org.uk"><img src="organisations/nesta.svg" alt="Nesta logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://www.nonkositelecoms.com"><img src="organisations/nonkosi.svg" alt="Nonkosi Telecoms logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://www.nzz.ch"><img src="organisations/nzz.svg" alt="Neue Zürcher Zeitung logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://nytimes.com"><img src="organisations/nyt.svg" alt="The New York Times logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://oberonspace.xyz"><img src="organisations/oberonspace.svg" alt="OberonSPACE logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://ofof.nl"><img src="organisations/ofof.png" alt="Ofof logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://openstate.eu"><img src="organisations/open-state-foundation.svg" alt="Open State Foundation logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://panascais.net"><img src="organisations/panascais.svg" alt="Panascais logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://pankod.com"><img src="organisations/pankod.svg" alt="Pankod logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://razorpay.com"><img src="organisations/razorpay.svg" alt="Razorpay logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://sp.nl"><img src="organisations/socialist-party.svg" alt="Socialist Party logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://sqltribe.com"><img src="organisations/sqltribe.svg" alt="SQL Tribe logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://www.stone.co"><img src="organisations/stone.svg" alt="Stone Payments logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://www.strixengine.com"><img src="organisations/strixcloud.svg" alt="Strix Cloud logo" loading="lazy"><span>Strix Cloud</span></a>
<a target="_blank" rel="noopener" href="https://sucuri.net" style="background-color: rgb(93, 93, 93);"><img src="organisations/sucuri.png" alt="Sucuri logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://thunderdome.dev"><img src="organisations/thunderdome.svg" alt="Thunderdome logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://m.tokopedia.com"><img src="organisations/tokopedia.png" alt="Tokopedia logo" srcset="organisations/tokopedia.2x.png 2x, organisations/tokopedia.3x.png 3x" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://m.tokopedia.com"><img src="organisations/tokopedia.svg" alt="Tokopedia logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://webdesq.net"><img src="organisations/webdesq.svg" alt="Webdesq logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://zevvle.com/"><img src="organisations/zevvle.svg" alt="Zevvle logo" loading="lazy"></a>
<a target="_blank" rel="noopener" href="https://github.com/sveltejs/svelte/blob/master/site/src/routes/_components/WhosUsingSvelte.svelte" class="add-yourself"><span>+ your company?</span></a>

@ -4,7 +4,7 @@
let offset = null;
if (user) {
var url = 'apps.json';
let url = 'apps.json';
if (page.query.offset) {
url += `?offset=${encodeURIComponent(page.query.offset)}`;
}
@ -50,9 +50,9 @@
<h1>Your apps</h1>
<div class="user">
<img class="avatar" alt="{user.name} avatar" src="{user.avatar}">
<img class="avatar" alt="{user.name || user.username} avatar" src="{user.avatar}">
<span>
{user.name}
{user.name || user.username}
(<a on:click|preventDefault={logout} href="auth/logout">log out</a>)
</span>
</div>

@ -1,6 +1,6 @@
export const oauth = 'https://github.com/login/oauth';
export const baseurl = process.env.BASEURL;
export const secure = baseurl.startsWith('https:');
export const secure = baseurl && baseurl.startsWith('https:');
export const client_id = process.env.GITHUB_CLIENT_ID;
export const client_secret = process.env.GITHUB_CLIENT_SECRET;

@ -1,11 +1,10 @@
import fs from 'fs';
import path from 'path';
import { extract_frontmatter, langs, link_renderer } from '@sveltejs/site-kit/utils/markdown.js';
import { extract_frontmatter, link_renderer } from '@sveltejs/site-kit/utils/markdown.js';
import marked from 'marked';
import { makeSlugProcessor } from '../../utils/slug';
import { highlight } from '../../utils/highlight';
import { SLUG_PRESERVE_UNICODE } from '../../../config';
import PrismJS from 'prismjs';
import 'prismjs/components/prism-bash';
const makeSlug = makeSlugProcessor(SLUG_PRESERVE_UNICODE);
@ -32,16 +31,7 @@ export default function get_posts() {
renderer.link = link_renderer;
renderer.code = (source, lang) => {
const plang = langs[lang];
const highlighted = PrismJS.highlight(
source,
PrismJS.languages[plang],
lang,
);
return `<pre class='language-${plang}'><code>${highlighted}</code></pre>`;
};
renderer.code = highlight;
renderer.heading = (text, level, rawtext) => {
const fragment = makeSlug(rawtext);

@ -1,28 +1,10 @@
import fs from 'fs';
import path from 'path';
import { SLUG_PRESERVE_UNICODE, SLUG_SEPARATOR } from '../../../config';
import { extract_frontmatter, extract_metadata, langs, link_renderer } from '@sveltejs/site-kit/utils/markdown.js';
import { extract_frontmatter, extract_metadata, link_renderer } from '@sveltejs/site-kit/utils/markdown.js';
import { make_session_slug_processor } from '@sveltejs/site-kit/utils/slug';
import { highlight } from '../../utils/highlight';
import marked from 'marked';
import PrismJS from 'prismjs';
import 'prismjs/components/prism-bash';
const escaped = {
'"': '&quot;',
"'": '&#39;',
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
};
const unescaped = Object.keys(escaped).reduce(
(unescaped, key) => ((unescaped[escaped[key]] = key), unescaped),
{}
);
function unescape(str) {
return String(str).replace(/&.+?;/g, match => unescaped[match] || match);
}
const blockTypes = [
'blockquote',
@ -90,14 +72,7 @@ export default function() {
if (meta && meta.hidden) return '';
const plang = langs[lang];
const highlighted = PrismJS.highlight(
source,
PrismJS.languages[plang],
lang
);
const html = `<div class='${className}'>${prefix}<pre class='language-${plang}'><code>${highlighted}</code></pre></div>`;
const html = `<div class='${className}'>${prefix}${highlight(source, lang)}</div>`;
if (block_open) {
block_open = false;

@ -140,12 +140,12 @@
if (imports.length > 0) {
const idx = files.findIndex(({ path }) => path === 'package.json');
const pkg = JSON.parse(files[idx].data);
const deps = {};
const { devDependencies } = pkg;
imports.forEach(mod => {
const match = /^(@[^/]+\/)?[^@/]+/.exec(mod);
deps[match[0]] = 'latest';
devDependencies[match[0]] = 'latest';
});
pkg.dependencies = deps;
pkg.devDependencies = devDependencies;
files[idx].data = JSON.stringify(pkg, null, ' ');
}

@ -95,7 +95,8 @@ export async function patch(req, res) {
const { user } = req;
if (!user) return;
let id, uid = req.params.id;
let id;
const uid = req.params.id;
try {
const [row] = await query(`select * from gists where uid = $1 limit 1`, [uid]);
@ -110,7 +111,9 @@ export async function patch(req, res) {
try {
const obj = await body(req);
obj.updated_at = 'now()';
let k, cols=[], vals=[];
let k;
const cols = [];
const vals = [];
for (k in obj) {
cols.push(k);
vals.push(k === 'files' ? JSON.stringify(obj[k]) : obj[k]);

@ -1,9 +1,9 @@
import * as fs from 'fs';
import * as path from 'path';
import marked from 'marked';
import PrismJS from 'prismjs';
import send from '@polka/send';
import { extract_frontmatter, extract_metadata, langs, link_renderer } from '@sveltejs/site-kit/utils/markdown';
import { extract_frontmatter, extract_metadata, link_renderer } from '@sveltejs/site-kit/utils/markdown';
import { highlight } from '../../../utils/highlight';
const cache = new Map();
@ -57,14 +57,7 @@ function get_tutorial(slug) {
}
}
const plang = langs[lang];
const highlighted = PrismJS.highlight(
source,
PrismJS.languages[plang],
lang
);
return `<div class='${className}'>${prefix}<pre class='language-${plang}'><code>${highlighted}</code></pre></div>`;
return `<div class='${className}'>${prefix}${highlight(source, lang)}</div>`;
};
let html = marked(content, { renderer });

@ -18,7 +18,6 @@
import { getContext } from 'svelte';
import ScreenToggle from '../../../components/ScreenToggle.svelte';
import { Icon } from '@sveltejs/site-kit';
import TableOfContents from './_TableOfContents.svelte';
import {
@ -219,17 +218,17 @@
}
.show {
background: rgba(0,0,0,.4);
background: var(--prime);
padding: .3em .7em;
border-radius: var(--border-r);
top: .1em;
position: relative;
font-size: var(--h5);
font-weight: 300;
color: rgba(255,255,255,0.7);
}
.show:hover {
background: rgba(0,0,0,.65);
color: white;
}

@ -14,9 +14,11 @@ const app = polka({
}
});
app.use(
authenticate(),
if (process.env.PGHOST) {
app.use(authenticate());
}
app.use(
sirv('static', {
dev: process.env.NODE_ENV === 'development',
setHeaders(res) {

@ -1,8 +1,7 @@
import { Pool } from 'pg';
export const DB = new Pool({
connectionString: process.env.DATABASE_URL
});
// Uses `PG*` ENV vars
export const DB = process.env.PGHOST ? new Pool() : null;
export function query(text, values=[]) {
return DB.query(text, values).then(r => r.rows);

@ -0,0 +1,14 @@
import { langs } from '@sveltejs/site-kit/utils/markdown.js';
import PrismJS from 'prismjs';
import 'prismjs/components/prism-bash';
export function highlight(source, lang) {
const plang = langs[lang] || '';
const highlighted = plang ? PrismJS.highlight(
source,
PrismJS.languages[plang],
lang,
) : source.replace(/[&<>]/g, c => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;' })[c]);
return `<pre class='language-${plang}'><code>${highlighted}</code></pre>`;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 103 124">
<path style="fill:black" d='M96.33,20.61C85.38,4.93,63.74.28,48.09,10.25L20.61,27.77A31.46,31.46,0,0,0,6.37,48.88,33.22,33.22,0,0,0,9.64,70.2,31.52,31.52,0,0,0,4.93,82a33.61,33.61,0,0,0,5.73,25.41c11,15.68,32.6,20.33,48.25,10.36l27.48-17.52a31.48,31.48,0,0,0,14.24-21.11A33.22,33.22,0,0,0,97.36,57.8,31.52,31.52,0,0,0,102.07,46a33.57,33.57,0,0,0-5.74-25.41
M45.41,108.86A21.81,21.81,0,0,1,22,100.18,20.2,20.2,0,0,1,18.53,84.9a19,19,0,0,1,.65-2.57l.52-1.58,1.41,1a35.32,35.32,0,0,0,10.75,5.37l1,.31-.1,1a6.2,6.2,0,0,0,1.11,4.08A6.57,6.57,0,0,0,41,95.19a6,6,0,0,0,1.68-.74L70.11,76.94a5.76,5.76,0,0,0,2.59-3.83,6.09,6.09,0,0,0-1-4.6,6.58,6.58,0,0,0-7.06-2.62,6.21,6.21,0,0,0-1.69.74L52.43,73.31a19.88,19.88,0,0,1-5.58,2.45,21.82,21.82,0,0,1-23.43-8.68A20.2,20.2,0,0,1,20,51.8a19,19,0,0,1,8.56-12.7L56,21.59a19.88,19.88,0,0,1,5.58-2.45A21.81,21.81,0,0,1,85,27.82,20.2,20.2,0,0,1,88.47,43.1a19,19,0,0,1-.65,2.57l-.52,1.58-1.41-1a35.32,35.32,0,0,0-10.75-5.37l-1-.31.1-1a6.2,6.2,0,0,0-1.11-4.08,6.57,6.57,0,0,0-7.06-2.62,6,6,0,0,0-1.68.74L36.89,51.06a5.71,5.71,0,0,0-2.58,3.83,6,6,0,0,0,1,4.6,6.58,6.58,0,0,0,7.06,2.62,6.21,6.21,0,0,0,1.69-.74l10.48-6.68a19.88,19.88,0,0,1,5.58-2.45,21.82,21.82,0,0,1,23.43,8.68A20.2,20.2,0,0,1,87,76.2a19,19,0,0,1-8.56,12.7L51,106.41a19.88,19.88,0,0,1-5.58,2.45' />
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg viewBox="0 0 257 60" xmlns="http://www.w3.org/2000/svg">
<style>
.logo {
font-size: 60px;
text-align: center;
font-family: "Times New Roman", Times, serif;
}
</style>
<text x="65" y="46" class="logo">buy.*</text>
</svg>

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="523" height="158"><rect id="backgroundrect" width="100%" height="100%" x="0" y="0" fill="none" stroke="none"/><style>.st0{fill:#fff}</style><g class="currentLayer"><path class="st0" d="M21.1 18.7v27.6h53.3V65H21.1v26.7h60.1v18.7H0V0h81.2v18.7H21.1z" id="svg_1"/><path d="M195.9 156.4H0v-18.7h195.9v18.7z" id="svg_2" fill="#ff5959"/><path class="st0" d="M193.7 110.2l-72.4-65.5v65.5h-21.1V0h2.3l72.4 66.7V0H196v110.2h-2.3z" id="svg_3"/><path class="st0" d="M299.8 64.9h-31.5v91.5h-21.1V64.9h-31.5V46.2h84.2v18.7z" id="svg_4"/><path class="st0" d="M363.1 158.4c-7.1 0-13.6-1.1-19.4-3.3-5.8-2.2-10.8-5.3-14.9-9.3-4.1-4-7.3-8.9-9.6-14.6-2.3-5.7-3.4-12.1-3.4-19.1V46.3h21.1V112c0 5.5.9 10.1 2.7 13.7 1.8 3.6 4 6.5 6.7 8.6 2.7 2.1 5.5 3.6 8.6 4.4 3.1.8 5.8 1.2 8.2 1.2 2.4 0 5.1-.4 8.2-1.2 3.1-.8 5.9-2.3 8.6-4.4 2.7-2.1 4.9-5 6.7-8.6 1.8-3.6 2.7-8.2 2.7-13.7V46.2h21.1V112c0 7-1.1 13.4-3.3 19.1-2.2 5.7-5.4 10.6-9.5 14.6s-9.1 7.1-14.9 9.3c-5.8 2.3-12.4 3.4-19.6 3.4z" id="svg_5"/><path class="st0" d="M451.2 121.4v35.1h-21.1V46.2h50.1c5.6 0 10.8.9 15.5 2.8 4.7 1.9 8.7 4.5 12 7.8 3.3 3.4 5.9 7.4 7.8 12 1.9 4.7 2.8 9.8 2.8 15.3 0 4.1-.6 8.1-1.7 12-1.1 3.9-2.6 7.4-4.6 10.5-2 3.1-4.4 5.8-7.2 8.1-2.9 2.3-6 3.8-9.4 4.7l27.4 37h-25.1l-25.5-35.1h-21zm0-18.4h24c4.4 0 8-.6 10.9-1.7 2.9-1.1 5.1-2.6 6.8-4.4 1.7-1.8 2.8-3.8 3.4-6.1.6-2.3.9-4.5.9-6.9 0-2.7-.4-5.2-1.3-7.5s-2.2-4.3-3.9-6c-1.8-1.7-4-3.1-6.8-4.1-2.8-1-6.1-1.5-10-1.5h-24V103z" id="svg_6"/></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="735px" height="115px" viewBox="0 0 735 115" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 51.1 (57501) - http://www.bohemiancoding.com/sketch -->
<title>logo colour</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-3" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="concept-one-rough-test-copy" transform="translate(-23.000000, -11.000000)" fill="#373C8B">
<g id="logo-colour">
<path d="M185.446,92 L185.446,24.638 L226.131,24.638 L226.131,34.732 L197.394,34.732 L197.394,53.787 L221.805,53.787 L221.805,63.881 L197.394,63.881 L197.394,92 L185.446,92 Z M234.268,73.151 L234.268,41.427 L246.113,41.427 L246.113,71.606 C246.113,79.949 248.482,83.039 253.941,83.039 C258.37,83.039 261.357,80.979 265.168,76.035 L265.168,41.427 L277.013,41.427 L277.013,92 L267.331,92 L266.404,84.584 L266.095,84.584 C261.666,89.837 256.722,93.236 249.821,93.236 C239.006,93.236 234.268,85.923 234.268,73.151 Z M287.004,86.232 L292.566,78.61 C297.098,82.112 301.424,84.275 306.574,84.275 C312.033,84.275 314.608,81.7 314.608,78.198 C314.608,73.975 309.149,72.121 303.793,70.061 C297.098,67.589 289.579,63.778 289.579,55.332 C289.579,46.474 296.686,40.191 308.016,40.191 C315.02,40.191 320.685,43.075 324.805,46.268 L319.346,53.478 C315.844,50.903 312.239,49.152 308.222,49.152 C303.175,49.152 300.806,51.521 300.806,54.714 C300.806,58.628 305.853,60.276 311.312,62.233 C318.213,64.808 325.835,68.104 325.835,77.58 C325.835,86.232 318.934,93.236 306.162,93.236 C299.261,93.236 291.948,90.249 287.004,86.232 Z M342.418,32.569 C338.195,32.569 335.105,29.788 335.105,25.874 C335.105,21.857 338.195,19.076 342.418,19.076 C346.641,19.076 349.731,21.857 349.731,25.874 C349.731,29.788 346.641,32.569 342.418,32.569 Z M336.444,92 L336.444,41.427 L348.289,41.427 L348.289,92 L336.444,92 Z M360.134,66.765 C360.134,49.873 371.567,40.191 384.133,40.191 C396.802,40.191 408.235,49.873 408.235,66.765 C408.235,83.554 396.802,93.236 384.133,93.236 C371.567,93.236 360.134,83.554 360.134,66.765 Z M372.288,66.765 C372.288,76.859 376.717,83.554 384.133,83.554 C391.549,83.554 396.081,76.859 396.081,66.765 C396.081,56.568 391.549,49.873 384.133,49.873 C376.717,49.873 372.288,56.568 372.288,66.765 Z M419.977,92 L419.977,41.427 L429.762,41.427 L430.586,48.225 L430.998,48.225 C435.53,43.796 440.68,40.191 447.581,40.191 C458.396,40.191 463.134,47.504 463.134,60.276 L463.134,92 L451.289,92 L451.289,61.821 C451.289,53.478 448.92,50.388 443.358,50.388 C438.929,50.388 436.045,52.551 431.822,56.671 L431.822,92 L419.977,92 Z M474.979,58.525 C474.979,36.483 488.781,23.402 506.085,23.402 C514.325,23.402 521.02,27.419 525.243,31.951 L518.651,39.367 C515.149,35.968 511.338,33.805 506.188,33.805 C495.167,33.805 487.236,43.075 487.236,58.216 C487.236,73.563 494.549,82.833 505.776,82.833 C511.75,82.833 516.179,80.361 519.99,76.138 L526.582,83.451 C521.123,89.734 514.119,93.236 505.57,93.236 C488.472,93.236 474.979,80.876 474.979,58.525 Z M536.676,92 L536.676,19.282 L548.521,19.282 L548.521,38.028 L548.109,47.813 C552.332,43.796 557.379,40.191 564.28,40.191 C575.095,40.191 579.833,47.504 579.833,60.276 L579.833,92 L567.988,92 L567.988,61.821 C567.988,53.478 565.619,50.388 560.057,50.388 C555.628,50.388 552.744,52.551 548.521,56.671 L548.521,92 L536.676,92 Z M591.987,78.404 C591.987,67.589 601.051,61.924 621.754,59.658 C621.651,54.302 619.385,49.77 612.587,49.77 C607.54,49.77 602.802,52.036 598.373,54.714 L594.047,46.783 C599.609,43.281 606.716,40.191 614.75,40.191 C627.419,40.191 633.599,47.916 633.599,62.027 L633.599,92 L623.917,92 L622.99,86.438 L622.681,86.438 C618.149,90.249 612.999,93.236 607.025,93.236 C598.167,93.236 591.987,87.262 591.987,78.404 Z M603.523,77.477 C603.523,82.009 606.51,83.966 610.733,83.966 C614.853,83.966 618.046,81.906 621.754,78.404 L621.754,67.074 C608.055,68.825 603.523,72.43 603.523,77.477 Z M648.019,92 L648.019,41.427 L657.804,41.427 L658.628,50.388 L659.04,50.388 C662.645,43.796 668.001,40.191 673.357,40.191 C675.932,40.191 677.58,40.5 679.125,41.221 L677.065,51.521 C675.314,51.006 673.975,50.697 671.812,50.697 C667.795,50.697 662.954,53.478 659.864,61.1 L659.864,92 L648.019,92 Z M688.189,74.902 L688.189,50.8 L680.979,50.8 L680.979,41.942 L688.807,41.427 L690.249,27.625 L700.137,27.625 L700.137,41.427 L713.012,41.427 L713.012,50.8 L700.137,50.8 L700.137,74.902 C700.137,80.876 702.403,83.76 707.244,83.76 C708.995,83.76 711.055,83.245 712.497,82.627 L714.557,91.382 C711.776,92.309 708.274,93.236 704.257,93.236 C692.515,93.236 688.189,85.82 688.189,74.902 Z M718.574,86.232 L724.136,78.61 C728.668,82.112 732.994,84.275 738.144,84.275 C743.603,84.275 746.178,81.7 746.178,78.198 C746.178,73.975 740.719,72.121 735.363,70.061 C728.668,67.589 721.149,63.778 721.149,55.332 C721.149,46.474 728.256,40.191 739.586,40.191 C746.59,40.191 752.255,43.075 756.375,46.268 L750.916,53.478 C747.414,50.903 743.809,49.152 739.792,49.152 C734.745,49.152 732.376,51.521 732.376,54.714 C732.376,58.628 737.423,60.276 742.882,62.233 C749.783,64.808 757.405,68.104 757.405,77.58 C757.405,86.232 750.504,93.236 737.732,93.236 C730.831,93.236 723.518,90.249 718.574,86.232 Z" id="FusionCharts"></path>
<rect id="Rectangle-2-Copy-4" x="23.4041667" y="22.8571429" width="23.4041667" height="68.5714286"></rect>
<rect id="Rectangle-2-Copy-5" x="57.0833333" y="56.5714286" width="23.975" height="34.8571429"></rect>
<rect id="Rectangle-2-Copy-6" x="91.9041667" y="11.4285714" width="22.2625" height="80"></rect>
<rect id="Rectangle-2-Copy-7" x="91.9041667" y="101.714286" width="22.2625" height="23.4285714"></rect>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.7 KiB

@ -0,0 +1 @@
<svg viewBox="0 0 122 29" xmlns="http://www.w3.org/2000/svg" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><g fill-rule="nonzero"><path d="M91.431 1.26l-.55 3.392h1.185l-1.481 9.084H89.38l-.582 3.58h12.676l.912-5.608h-4.08l-.315 2.028H94.83l.47-2.865h3.483l.624-3.863h-3.49l.375-2.356h2.98l-.26 1.634h3.965l.813-5.027M68.414 1.26l-.543 3.392h1.182l-.744 4.585-4.152-7.978h-5.365l-.54 3.393h1.19l-1.48 9.084h-1.184l-.572 3.58h6.71l.573-3.58h-1.19l.865-5.413 4.539 8.994h3.583l2.051-12.665h1.191l.548-3.393M37.499 1.26l-.545 3.392h1.191l-4.632 9.084h-1.175l-.587 3.58h6.703l.589-3.58H37.84l.597-1.326h4.15l.168 1.326h-1.187l-.577 3.58 6.891-.002.582-3.578H47.27L45.155 1.259H37.5zm4.36 3.99l.333 3.78H40.23M27.38 7.89c-.772.71-1.974.433-3.023.48l.571-3.515c1.19.027 2.826-.335 3.267 1.024.104.775-.168 1.507-.815 2.011zm1.064 2.971c.794-.187 1.481-.669 2.128-1.234 1.462-1.34 2.274-3.287 1.688-5.296-.561-1.884-2.542-2.943-4.38-3.069h-7.957l-.54 3.391h1.184l-1.471 9.084h-1.198l-.577 3.58h6.491l.587-3.58h-.904l.342-2.142 3.19 5.723h3.993l.586-3.58h-1.492M55.496 17.31l.574-3.578H54.88l1.48-9.084h1.185l.54-3.392h-6.885l-.55 3.392h1.184l-1.465 9.084h-1.194l-.576 3.585M112.25 7.886c-.772.711-1.973.435-3.024.482l.572-3.518c1.19.03 2.827-.333 3.267 1.027.103.774-.17 1.506-.815 2.01zm1.063 2.973c.795-.189 1.482-.67 2.128-1.235 1.463-1.34 2.275-3.288 1.689-5.296-.562-1.885-2.543-2.943-4.38-3.07h-7.959l-.538 3.393h1.184l-1.472 9.084h-1.198l-.576 3.58h6.491l.586-3.58h-.904l.343-2.143 3.19 5.723h3.993l.586-3.58h-1.494"/><path d="M25.076 20.897l-1.157 7.157h90.227l1.163-7.157H25.076zM8.546 20.897H6.942l-1.157 7.157H7.39l1.157-7.157zM13.74 20.897h-2.258l-1.156 7.157h2.258l1.156-7.157zM3.35 20.897h-.949l-1.156 7.157h.95l1.156-7.157zM24.13 20.897h-3.565l-1.156 7.157h3.566l1.155-7.157zM18.935 20.897h-2.912l-1.156 7.157h2.912l1.156-7.157z" fill="#ed1b2d"/><path d="M120.652 15.57a1.605 1.605 0 0 1-1.621 1.615 1.61 1.61 0 0 1-1.614-1.62c0-.89.707-1.62 1.625-1.62.922 0 1.614.735 1.61 1.624zm.16.005a1.764 1.764 0 0 0-1.781-1.79c-.956 0-1.774.754-1.774 1.78 0 1.056.848 1.78 1.77 1.78 1.006 0 1.779-.785 1.784-1.77zm-2.494-1.13v2.224h.325v-1.034h.159c.32.006.498.045.562.376.011.054.046.304.057.354.02.105.04.205.089.304h.374c-.101-.199-.114-.319-.165-.644-.045-.269-.12-.4-.359-.49.274-.044.5-.225.5-.535a.535.535 0 0 0-.34-.505c-.134-.05-.26-.05-.518-.05h-.684zm.33.25h.304c.268 0 .378 0 .473.084a.321.321 0 0 1 .106.246c0 .356-.37.35-.509.35h-.375M15.144 1.24h3.308l-.878 5.45h-3.76c-.21-.879-1.108-1.707-1.986-1.896-1.61-.356-3.259.209-4.283 1.506-1.127 1.574-1.629 4.22-.564 5.938.732 1.153 2.141 1.58 3.458 1.37 1.024-.187 2.057-1.098 2.496-2.062l-4.191-.003.524-3.262h8.83l-1.465 9.04H13.23l.21-1.023c-.402.535-1.48 1.445-4.138 1.445-3.356 0-7.024-2.848-7.024-7.873 0-4.136 3.119-9.155 8.654-9.136 1.41.006 2.992.361 4.013 1.34M86.611 1.24h3.308l-.878 5.45H85.28c-.208-.879-1.107-1.707-1.985-1.896-1.61-.356-3.258.209-4.282 1.506-1.128 1.574-1.63 4.22-.565 5.938.732 1.153 2.141 1.58 3.458 1.37 1.025-.187 2.057-1.098 2.496-2.062l-4.191-.003.524-3.262h8.83l-1.465 9.04h-3.402l.208-1.023c-.4.535-1.478 1.445-4.137 1.445-3.356 0-7.024-2.848-7.024-7.873 0-4.136 3.12-9.155 8.654-9.136 1.41.006 2.993.361 4.013 1.34"/></g></svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 187.09 22.97"><defs><style>.cls-1{fill:#606463;}.cls-1,.cls-2,.cls-3{fill-rule:evenodd;}.cls-2{fill:#fff;}.cls-3{fill:#fcc14f;}</style></defs><title>Asset 1</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><polygon class="cls-1" points="187.09 0 0 0 0 22.97 187.09 22.97 187.09 0 187.09 0"/><path class="cls-2" d="M147.91,10.73a6.74,6.74,0,0,0-1.44-4.25,12.93,12.93,0,0,0-4.1-3.38,14.42,14.42,0,0,0-5.69,3.24,5.79,5.79,0,0,0-2.09,4.39,6.13,6.13,0,0,0,2.09,4.39,16,16,0,0,0,5.62,3.24,13.57,13.57,0,0,0,4.18-3.46,6.69,6.69,0,0,0,1.44-4.18Z"/><path class="cls-2" d="M153.53,4.75a18.74,18.74,0,0,1,6.12,4.61,9.65,9.65,0,0,1,2.16,5.91,9.3,9.3,0,0,1-.5,3.1,15.6,15.6,0,0,0,5.62-3.24,6.11,6.11,0,0,0,2.16-4.39c0-2.52-1.73-4.68-5-6.48A25.83,25.83,0,0,0,151.8,1.58l-5.69.5H146a21.19,21.19,0,0,1,7.49,2.66Z"/><path class="cls-2" d="M144.82,2.38l-1.51.36a16.1,16.1,0,0,1,6,4.46,9.08,9.08,0,0,1,2.23,6,9.5,9.5,0,0,1-2.74,6.48l3,.14,3-.14a8.43,8.43,0,0,0,2.09-5.47,9.55,9.55,0,0,0-3.31-6.91,21.9,21.9,0,0,0-8.79-4.9Z"/><polygon class="cls-3" points="35.93 5.62 36.01 5.62 33.05 18.22 36.29 18.22 39.61 2.95 34.49 2.95 28.45 13.97 28.45 13.97 27.36 2.95 22.32 2.95 19.08 18.22 21.96 18.22 24.77 5.62 24.84 5.62 26.07 18.22 28.95 18.22 35.93 5.62 35.93 5.62"/><path class="cls-3" d="M45.58,8.86a1.67,1.67,0,0,1,1.87,1.87l-.07.79h-5A6,6,0,0,1,43.5,9.58a3.08,3.08,0,0,1,2.09-.72ZM50.26,11A4.18,4.18,0,0,0,49,7.78,5.16,5.16,0,0,0,45.66,6.7,6,6,0,0,0,41,8.79a7.26,7.26,0,0,0-1.87,4.82,4.63,4.63,0,0,0,1.51,3.74,6.05,6.05,0,0,0,4,1.22,10.6,10.6,0,0,0,3.6-.72l.36-2.3a7.77,7.77,0,0,1-3.46.79c-2.09,0-3.1-.94-3.1-2.81H50A10.83,10.83,0,0,0,50.26,11Z"/><path class="cls-3" d="M56.39,9.15H59L59.48,7H56.82l.72-3.38L54.37,4.68,53.86,7H51.78l-.5,2.16h2.16L52.57,13a9.61,9.61,0,0,0-.36,2.59c0,2,1.15,3,3.38,3l1.58-.36.5-2.23-1.44.29c-.72,0-1.08-.36-1.08-1.15L55.31,14l1.08-4.9Z"/><path class="cls-3" d="M66.61,9.51l1.08.14.65-2.88L67.19,6.7a3.11,3.11,0,0,0-1.94.72,4.23,4.23,0,0,0-1.37,1.66H63.8l.36-2.16H61.43l-2.3,11.31h3l1-5a6,6,0,0,1,1.08-2.45,2.85,2.85,0,0,1,2.45-1.22Z"/><path class="cls-3" d="M74.6,9c1.51,0,2.3.86,2.3,2.66a5.32,5.32,0,0,1-.86,3,3,3,0,0,1-2.59,1.58c-1.51,0-2.3-.94-2.3-2.66a5.73,5.73,0,0,1,.86-3.1A3,3,0,0,1,74.6,9Zm3.89-1a5.26,5.26,0,0,0-3.74-1.3,6.52,6.52,0,0,0-6.63,6.7,5.26,5.26,0,0,0,1.3,3.74,5.22,5.22,0,0,0,3.82,1.44,6.68,6.68,0,0,0,4.82-1.94,6.79,6.79,0,0,0,1.87-5A4.73,4.73,0,0,0,78.49,8Z"/><polygon class="cls-3" points="92.46 6.99 89.3 6.99 84.9 15.27 84.83 15.27 83.68 6.99 80.65 6.99 82.6 18.22 85.84 18.22 92.46 6.99 92.46 6.99"/><polygon class="cls-3" points="91.89 18.22 94.84 18.22 97.29 6.91 94.33 6.91 91.89 18.22 91.89 18.22"/><path class="cls-3" d="M105.07,13a7.53,7.53,0,0,1-1,2.38,2.84,2.84,0,0,1-2.3.94,2.09,2.09,0,0,1-1-.22,1,1,0,0,1-.5-.94c0-1.44,1.22-2.16,3.82-2.16Zm.36-1.73h-1.08a13.64,13.64,0,0,0-4.46.58,3.37,3.37,0,0,0-2.45,3.38,2.88,2.88,0,0,0,1,2.45,3.93,3.93,0,0,0,2.52.86,4.68,4.68,0,0,0,3.6-2.09h.07l-.29,1.73h2.45l.79-4.25a30.31,30.31,0,0,0,.58-3.82,3.25,3.25,0,0,0-1.3-2.74,5.64,5.64,0,0,0-3.1-.72,10.51,10.51,0,0,0-3.82.72l-.43,2.38a7.94,7.94,0,0,1,3.67-.94c1.51,0,2.3.5,2.3,1.44l-.07,1Z"/><path class="cls-3" d="M117.74,9.36l.65-2.16a11.13,11.13,0,0,0-3.24-.5,6.83,6.83,0,0,0-3.31.79,3.14,3.14,0,0,0-1.51,2.81A3.26,3.26,0,0,0,112.19,13l1.3.94a1.48,1.48,0,0,1,.65,1.15c0,.86-.72,1.22-2,1.22a5.41,5.41,0,0,1-2.81-.86l-.65,2.38a7.22,7.22,0,0,0,3.46.72,6.79,6.79,0,0,0,3.46-.86,3.31,3.31,0,0,0,1.66-3q0-1.51-1.94-2.81l-1.3-.94a1.25,1.25,0,0,1-.65-.94c0-.79.65-1.15,1.94-1.15a8.72,8.72,0,0,1,2.45.5Z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="800px" height="160px" viewBox="0 0 800 160" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 49.3 (51167) - http://www.bohemiancoding.com/sketch -->
<title>Dark</title>
<desc>Created with Sketch.</desc>
<defs>
<polygon id="path-1" points="0.321905678 0.275424046 91.2854215 0.275424046 91.2854215 120.758046 0.321905678 120.758046"></polygon>
<polygon id="path-3" points="0.000265185374 0.245106383 217.001549 0.245106383 217.001549 160 0.000265185374 160"></polygon>
</defs>
<g id="Dark" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Logo">
<path d="M275.066842,101.866245 L298.520492,101.866245 C310.08215,101.866245 318.670431,93.9910625 318.670431,83.3267532 C318.670431,72.8265103 310.08215,64.951328 299.015612,64.951328 L275.066842,64.951328 L275.066842,101.866245 Z M275.066842,120.405359 L275.066842,156 L252.439024,156 L252.439024,46.4122137 L304.466487,46.4122137 C325.111926,46.4122137 341.463415,61.6703793 341.463415,83.3267532 C341.463415,105.147193 325.442259,120.405359 303.970608,120.405359 L275.066842,120.405359 Z" id="Fill-1" fill="#2C3E50"></path>
<path d="M412.210747,116.169033 C412.210747,103.600873 402.12157,93.5132706 389.551448,93.5132706 C376.981707,93.5132706 366.727134,103.600873 366.727134,116.169033 C366.727134,128.737573 376.981707,138.990166 389.551448,138.990166 C402.12157,138.990166 412.210747,128.737573 412.210747,116.169033 M385.581936,73.5038168 C397.325456,73.5038168 409.564405,79.4571558 413.86471,89.0486465 L414.360899,89.0486465 L415.187881,75.6536337 L435.365854,75.6536337 L435.365854,156 L415.187881,156 L414.360899,143.45517 L413.86471,143.45517 C409.398629,153.377402 396.663491,159 385.581936,159 C365.07279,159 343.902439,141.801465 343.902439,116.169033 C343.902439,90.5369813 365.238567,73.5038168 385.581936,73.5038168 Z" id="Fill-3" fill="#2C3E50"></path>
<path d="M442.682927,75.6460779 L462.812052,75.6460779 L464.131994,88.9940123 L464.46198,88.9940123 C469.411765,79.4362321 479.971306,73.5038168 490.860832,73.5038168 C512.804499,73.5038168 526.829268,90.3123268 526.829268,111.899348 L526.829268,156 L504.059879,156 L504.059879,114.206777 C504.059879,103.001104 495.810238,93.7729023 484.756098,93.7729023 C474.196557,93.7729023 465.451937,103.165893 465.451937,114.701145 L465.451937,156 L442.682927,156 L442.682927,75.6460779 Z" id="Fill-5" fill="#2C3E50"></path>
<polygon id="Fill-7" fill="#2C3E50" points="534.146341 38.0839695 557.050183 38.0839695 557.050183 107.0289 557.382123 107.0289 588.086549 75.7649175 616.632984 75.7649175 579.621704 112.788055 617.914429 156 589.206787 156 557.382123 118.547209 557.050183 118.547209 557.050183 156 534.146341 156"></polygon>
<path d="M680.792588,117.169033 C680.792588,104.766624 670.354166,94.5132706 657.92702,94.5132706 C645.499874,94.5132706 635.061071,104.766624 635.061071,117.169033 C635.061071,129.737573 645.499874,139.990166 657.92702,139.990166 C670.354166,139.990166 680.792588,129.737573 680.792588,117.169033 M612.195122,117.169033 C612.195122,93.686418 632.741337,74.5038168 657.92702,74.5038168 C683.112322,74.5038168 703.658537,93.686418 703.658537,117.169033 C703.658537,140.652028 683.112322,160 657.92702,160 C632.741337,160 612.195122,140.652028 612.195122,117.169033" id="Fill-9" fill="#2C3E50"></path>
<g id="Group-13" transform="translate(708.536585, 37.862595)">
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<g id="Clip-12"></g>
<path d="M68.5035169,78.1861569 C68.5035169,65.6940195 58.4330533,55.6674355 45.8862463,55.6674355 C33.3398188,55.6674355 23.1042658,65.6940195 23.1042658,78.1861569 C23.1042658,90.6786721 33.3398188,100.869248 45.8862463,100.869248 C58.4330533,100.869248 68.5035169,90.6786721 68.5035169,78.1861569 Z M91.2854974,0.275424046 L91.2854974,118.137405 L71.3027701,118.137405 L70.3195021,105.307245 L69.9893229,105.307245 C65.5319047,115.169458 52.6549185,120.758046 41.5942971,120.758046 C20.6275428,120.758046 0.321905678,103.663542 0.321905678,78.1861569 C0.321905678,52.7091492 20.6275428,35.7790156 41.0986489,35.7790156 C52.6549185,35.7790156 64.0460986,41.8607141 68.1733377,51.2298172 L68.5035169,51.2298172 L68.5035169,0.275424046 L91.2854974,0.275424046 Z" id="Fill-11" fill="#2C3E50" mask="url(#mask-2)"></path>
</g>
<g id="Group-16">
<mask id="mask-4" fill="white">
<use xlink:href="#path-3"></use>
</mask>
<g id="Clip-15"></g>
<path d="M182.173146,72.3045674 C179.882324,72.7406903 176.517879,72.4520851 172.983716,68.9373806 C169.314687,65.3250875 168.638464,63.1758676 168.732794,61.9972388 C168.784695,61.348539 169.590479,61.0701466 170.049629,61.5319905 C175.829533,67.3460804 179.87058,69.6632435 182.307255,70.5770969 C183.159257,70.8959622 183.066821,72.1343546 182.173146,72.3045674 M208.714793,77.9684917 C202.438992,73.3954421 181.685963,52.03374 159.689215,34.322156 C153.250514,28.1619669 145.345717,21.3685863 135.155401,15.1705721 C77.8814213,-19.6647943 18.2991925,17.3969551 18.2991925,17.3969551 C87.7360886,-8.66299764 129.308821,27.0866005 129.308821,27.0866005 C75.6527276,7.74437825 14.4218035,29.2055603 0.000265185374,46.0547329 C6.59466777,42.4590827 32.1161082,28.8768605 77.4082548,30.8399811 C107.795468,32.6922742 125.986806,45.028539 136.685142,57.3368132 C136.950706,57.7177116 137.28143,58.1092009 137.685269,58.5131726 C137.686785,58.5150638 137.688679,58.5169551 137.690194,58.5188463 C137.66216,58.5286809 123.69712,63.5155366 106.920356,56.5572388 C106.920356,56.5572388 117.255009,72.0348747 130.948045,72.8091537 C128.986052,80.5042837 127.100584,89.4154894 125.537885,101.514969 C121.14149,137.54069 172.870822,156.693787 181.428733,159.607073 L182.620173,160.000076 C182.620173,160.000076 163.760189,141.684804 165.568375,98.8630544 C153.16717,92.9298156 152.650438,83.1274515 151.875339,80.0318487 C151.875339,80.0318487 158.334497,90.3505248 164.018177,90.8660804 C169.702236,91.6399811 175.263173,89.971896 177.453226,89.5766241 C180.489977,89.028539 188.304232,90.3505248 188.820965,96.5413522 C189.079331,104.538326 186.754034,117.178326 198.380519,122.853598 C198.380519,122.853598 195.279744,106.602061 203.547466,106.344095 C207.939694,106.85965 211.298077,106.602061 211.815189,103.764426 C212.590288,100.410856 214.140107,96.2837636 215.94905,92.1559149 C217.757235,88.0284444 218.273968,84.9332199 208.714793,77.9684917" id="Fill-14" fill="#2C3E50" mask="url(#mask-4)"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.7 KiB

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 1333.3333 266.66666"
height="266.66666"
width="1333.3333"
xml:space="preserve"
id="svg3713"
version="1.1"
sodipodi:docname="logo.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="3840"
inkscape:window-height="1506"
id="namedview36"
showgrid="false"
inkscape:zoom="2.7532502"
inkscape:cx="599.11011"
inkscape:cy="133.33333"
inkscape:window-x="-11"
inkscape:window-y="-11"
inkscape:window-maximized="1"
inkscape:current-layer="svg3713" /><metadata
id="metadata3719"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs3717"><clipPath
id="clipPath3729"
clipPathUnits="userSpaceOnUse"><path
id="path3727"
d="M 0,200 H 1000 V 0 H 0 Z" /></clipPath></defs><g
transform="matrix(1.3333333,0,0,-1.3333333,0,266.66667)"
id="g3721"
style="fill:#00a0e3;fill-opacity:1"><g
id="g3723"
style="fill:#00a0e3;fill-opacity:1"><g
clip-path="url(#clipPath3729)"
id="g3725"
style="fill:#00a0e3;fill-opacity:1"><g
transform="translate(46.9448,138.832)"
id="g3731"
style="fill:#00a0e3;fill-opacity:1"><path
id="path3733"
style="fill:#00a0e3;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0,-15.33 17.382,-19.257 37.947,-21.872 24.117,-3.178 44.677,-10.657 44.677,-35.707 0,-20.002 -15.513,-38.696 -47.667,-38.696 -19.817,0 -36.265,4.489 -50.475,14.396 -1.869,1.12 -1.869,2.053 -0.75,4.11 l 3.553,5.98 c 1.308,2.058 2.058,2.433 4.3,1.125 11.967,-8.225 27.479,-12.527 41.502,-12.527 17.2,0 35.144,5.61 35.144,25.049 0,15.518 -14.02,20.565 -38.509,23.93 -20.377,2.808 -44.119,8.975 -44.119,33.837 0,14.393 10.844,39.072 47.109,39.072 19.255,0 31.779,-5.61 45.989,-14.21 2.058,-1.12 1.68,-2.245 0.933,-4.11 L 76.081,14.58 C 74.961,12.522 73.836,11.777 71.971,13.272 60.006,21.31 47.667,25.612 34.582,25.612 6.167,25.612 0,9.72 0,0" /></g><g
transform="translate(215.9419,55.2656)"
id="g3735"
style="fill:#00a0e3;fill-opacity:1"><path
id="path3737"
style="fill:#00a0e3;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 29.537,0 51.967,26.737 51.967,54.777 0,28.227 -22.43,54.584 -51.967,54.772 -29.165,0 -51.969,-26.545 -51.969,-54.772 C -51.969,26.737 -29.165,0 0,0 m 0,122.633 c 36.827,0 66.922,-30.654 66.922,-67.856 0,-25.799 -13.458,-43.182 -29.35,-55.335 l 16.45,-22.616 c 1.312,-1.871 0.937,-2.996 -0.745,-4.115 l -7.293,-5.235 c -1.682,-1.121 -2.799,-0.746 -3.924,0.937 L 25.607,-7.1 C 17.575,-10.652 11.027,-13.084 0,-13.084 c -36.829,0 -66.924,30.664 -66.924,67.861 0,37.202 30.095,67.856 66.924,67.856" /></g><g
transform="translate(389.8018,57.5156)"
id="g3739"
style="fill:#00a0e3;fill-opacity:1"><path
id="path3741"
style="fill:#00a0e3;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 2.245,0 2.805,-0.75 2.805,-2.994 v -6.918 c 0,-2.245 -0.56,-2.99 -2.805,-2.99 h -76.084 c -2.245,0 -2.992,0.745 -2.992,2.99 v 124.878 c 0,2.24 0.747,2.99 2.992,2.99 h 8.788 c 2.239,0 2.989,-0.75 2.989,-2.99 V 0 Z" /></g><g
transform="translate(555.251,175.4717)"
id="g3743"
style="fill:#00a0e3;fill-opacity:1"><path
id="path3745"
style="fill:#00a0e3;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 2.428,0 2.803,-0.75 2.803,-2.99 v -7.48 c 0,-2.245 -0.563,-2.99 -2.803,-2.99 h -44.868 v -114.408 c 0,-2.245 -0.563,-2.99 -2.803,-2.99 h -8.975 c -2.43,0 -2.992,0.745 -2.992,2.99 V -13.46 h -44.677 c -2.428,0 -2.99,0.745 -2.99,2.99 v 7.48 c 0,2.24 0.75,2.99 2.99,2.99 z" /></g><g
transform="translate(624.9873,108.5479)"
id="g3747"
style="fill:#00a0e3;fill-opacity:1"><path
id="path3749"
style="fill:#00a0e3;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 0,0 C 22.242,0 31.962,10.652 31.962,27.664 31.962,46.358 19.252,54.209 0,54.209 H -31.779 V 0 Z m 17.007,-11.032 35.144,-49.35 c 1.495,-2.432 0,-3.553 -2.24,-3.553 h -8.787 c -2.245,0 -3.74,1.121 -5.052,2.991 L 1.678,-12.715 h -33.457 v -48.229 c 0,-2.428 -0.755,-2.991 -2.995,-2.991 h -8.788 c -2.24,0 -2.99,0.375 -2.99,2.991 V 63.934 c 0,2.24 0.75,2.99 2.99,2.99 H 0.933 c 21.309,0 45.421,-8.976 45.421,-39.26 0,-22.242 -11.959,-34.024 -29.347,-38.696" /></g><g
transform="translate(704.0635,172.4814)"
id="g3751"
style="fill:#00a0e3;fill-opacity:1"><path
id="path3753"
style="fill:#00a0e3;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 0,2.24 0.75,2.99 2.995,2.99 h 8.97 c 2.245,0 2.807,-0.75 2.807,-2.99 v -124.878 c 0,-2.245 -0.562,-2.99 -2.807,-2.99 h -8.97 c -2.245,0 -2.995,0.745 -2.995,2.99 z" /></g><g
transform="translate(807.8193,57.3232)"
id="g3755"
style="fill:#00a0e3;fill-opacity:1"><path
id="path3757"
style="fill:#00a0e3;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 22.617,0 31.962,9.162 31.962,24.862 0,12.715 -13.085,23.185 -30.284,23.185 H -37.015 V 0 Z m -0.192,60.382 c 16.08,0 27.482,8.042 27.482,20.189 0,17.2 -12.527,24.863 -31.78,24.863 H -37.015 V 60.382 Z M -48.797,-12.71 c -2.24,0 -2.99,0.563 -2.99,2.99 v 124.878 c 0,2.24 0.75,2.99 2.99,2.99 h 45.244 c 21.31,0 45.797,-8.788 45.797,-36.269 0,-16.45 -13.272,-24.112 -21.309,-27.108 V 54.589 C 28.222,52.345 47.104,44.119 47.104,23.367 47.104,-2.989 25.795,-12.71 1.12,-12.71 Z" /></g><g
transform="translate(967.2793,57.5156)"
id="g3759"
style="fill:#00a0e3;fill-opacity:1"><path
id="path3761"
style="fill:#00a0e3;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 h -71.409 v 59.553 h 68.044 c 2.245,0 2.995,0.75 2.995,2.99 v 6.917 c 0,2.245 -0.75,2.99 -2.995,2.99 H -58.482 -71.409 -86.176 V -9.912 c 0,-2.245 0.744,-2.99 2.989,-2.99 H 0 c 2.245,0 2.808,0.745 2.808,2.99 v 6.918 C 2.808,-0.75 2.245,0 0,0" /></g><g
transform="translate(967.2793,175.4717)"
id="g3763"
style="fill:#00a0e3;fill-opacity:1"><path
id="path3765"
style="fill:#00a0e3;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 h -83.187 c -2.245,0 -2.989,-0.75 -2.989,-2.99 v -9.907 H -71.409 -58.482 0 c 2.058,0 2.808,0.745 2.808,2.99 V -2.99 C 2.808,-0.75 2.058,0 0,0" /></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 111 KiB

After

Width:  |  Height:  |  Size: 111 KiB

File diff suppressed because it is too large Load Diff

@ -1,7 +1,7 @@
import deindent from './utils/deindent';
import list from '../utils/list';
import { ModuleFormat, Node } from '../interfaces';
import { stringify_props } from './utils/stringify_props';
import { ModuleFormat } from '../interfaces';
import { b, x } from 'code-red';
import { Identifier, ImportDeclaration } from 'estree';
const wrappers = { esm, cjs };
@ -11,24 +11,26 @@ interface Export {
}
export default function create_module(
code: string,
program: any,
format: ModuleFormat,
name: string,
name: Identifier,
banner: string,
sveltePath = 'svelte',
helpers: Array<{ name: string; alias: string }>,
globals: Array<{ name: string; alias: string }>,
imports: Node[],
module_exports: Export[],
source: string
): string {
helpers: Array<{ name: string; alias: Identifier }>,
globals: Array<{ name: string; alias: Identifier }>,
imports: ImportDeclaration[],
module_exports: Export[]
) {
const internal_path = `${sveltePath}/internal`;
helpers.sort((a, b) => (a.name < b.name) ? -1 : 1);
globals.sort((a, b) => (a.name < b.name) ? -1 : 1);
if (format === 'esm') {
return esm(code, name, banner, sveltePath, internal_path, helpers, globals, imports, module_exports, source);
return esm(program, name, banner, sveltePath, internal_path, helpers, globals, imports, module_exports);
}
if (format === 'cjs') return cjs(code, name, banner, sveltePath, internal_path, helpers, globals, imports, module_exports);
if (format === 'cjs') return cjs(program, name, banner, sveltePath, internal_path, helpers, globals, imports, module_exports);
throw new Error(`options.format is invalid (must be ${list(Object.keys(wrappers))})`);
}
@ -40,107 +42,164 @@ function edit_source(source, sveltePath) {
}
function esm(
code: string,
name: string,
program: any,
name: Identifier,
banner: string,
sveltePath: string,
internal_path: string,
helpers: Array<{ name: string; alias: string }>,
globals: Array<{ name: string; alias: string }>,
imports: Node[],
module_exports: Export[],
source: string
helpers: Array<{ name: string; alias: Identifier }>,
globals: Array<{ name: string; alias: Identifier }>,
imports: ImportDeclaration[],
module_exports: Export[]
) {
const internal_imports = helpers.length > 0 && (
`import ${stringify_props(helpers.map(h => h.name === h.alias ? h.name : `${h.name} as ${h.alias}`).sort())} from ${JSON.stringify(internal_path)};`
);
const internal_globals = globals.length > 0 && (
`const ${stringify_props(globals.map(g => `${g.name}: ${g.alias}`).sort())} = ${helpers.find(({ name }) => name === 'globals').alias};`
);
const user_imports = imports.length > 0 && (
imports
.map((declaration: Node) => {
const import_source = edit_source(declaration.source.value, sveltePath);
return (
source.slice(declaration.start, declaration.source.start) +
JSON.stringify(import_source) +
source.slice(declaration.source.end, declaration.end)
);
})
.join('\n')
);
return deindent`
${banner}
${internal_imports}
const import_declaration = {
type: 'ImportDeclaration',
specifiers: helpers.map(h => ({
type: 'ImportSpecifier',
local: h.alias,
imported: { type: 'Identifier', name: h.name }
})),
source: { type: 'Literal', value: internal_path }
};
const internal_globals = globals.length > 0 && {
type: 'VariableDeclaration',
kind: 'const',
declarations: [{
type: 'VariableDeclarator',
id: {
type: 'ObjectPattern',
properties: globals.map(g => ({
type: 'Property',
method: false,
shorthand: false,
computed: false,
key: { type: 'Identifier', name: g.name },
value: g.alias,
kind: 'init'
}))
},
init: helpers.find(({ name }) => name === 'globals').alias
}]
};
// edit user imports
imports.forEach(node => {
node.source.value = edit_source(node.source.value, sveltePath);
});
const exports = module_exports.length > 0 && {
type: 'ExportNamedDeclaration',
specifiers: module_exports.map(x => ({
type: 'Specifier',
local: { type: 'Identifier', name: x.name },
exported: { type: 'Identifier', name: x.as }
}))
};
program.body = b`
/* ${banner} */
${import_declaration}
${internal_globals}
${user_imports}
${imports}
${code}
${program.body}
export default ${name};
${module_exports.length > 0 && `export { ${module_exports.map(e => e.name === e.as ? e.name : `${e.name} as ${e.as}`).join(', ')} };`}`;
${exports}
`;
}
function cjs(
code: string,
name: string,
program: any,
name: Identifier,
banner: string,
sveltePath: string,
internal_path: string,
helpers: Array<{ name: string; alias: string }>,
globals: Array<{ name: string; alias: string }>,
imports: Node[],
helpers: Array<{ name: string; alias: Identifier }>,
globals: Array<{ name: string; alias: Identifier }>,
imports: ImportDeclaration[],
module_exports: Export[]
) {
const declarations = helpers.map(h => `${h.alias === h.name ? h.name : `${h.name}: ${h.alias}`}`).sort();
const internal_imports = helpers.length > 0 && (
`const ${stringify_props(declarations)} = require(${JSON.stringify(internal_path)});\n`
);
const internal_globals = globals.length > 0 && (
`const ${stringify_props(globals.map(g => `${g.name}: ${g.alias}`).sort())} = ${helpers.find(({ name }) => name === 'globals').alias};`
);
const requires = imports.map(node => {
let lhs;
if (node.specifiers[0].type === 'ImportNamespaceSpecifier') {
lhs = node.specifiers[0].local.name;
} else {
const properties = node.specifiers.map(s => {
if (s.type === 'ImportDefaultSpecifier') {
return `default: ${s.local.name}`;
}
const internal_requires = {
type: 'VariableDeclaration',
kind: 'const',
declarations: [{
type: 'VariableDeclarator',
id: {
type: 'ObjectPattern',
properties: helpers.map(h => ({
type: 'Property',
method: false,
shorthand: false,
computed: false,
key: { type: 'Identifier', name: h.name },
value: h.alias,
kind: 'init'
}))
},
init: x`require("${internal_path}")`
}]
};
const internal_globals = globals.length > 0 && {
type: 'VariableDeclaration',
kind: 'const',
declarations: [{
type: 'VariableDeclarator',
id: {
type: 'ObjectPattern',
properties: globals.map(g => ({
type: 'Property',
method: false,
shorthand: false,
computed: false,
key: { type: 'Identifier', name: g.name },
value: g.alias,
kind: 'init'
}))
},
init: helpers.find(({ name }) => name === 'globals').alias
}]
};
const user_requires = imports.map(node => ({
type: 'VariableDeclaration',
kind: 'const',
declarations: [{
type: 'VariableDeclarator',
id: node.specifiers[0].type === 'ImportNamespaceSpecifier'
? { type: 'Identifier', name: node.specifiers[0].local.name }
: {
type: 'ObjectPattern',
properties: node.specifiers.map(s => ({
type: 'Property',
method: false,
shorthand: false,
computed: false,
key: s.type === 'ImportSpecifier' ? s.imported : { type: 'Identifier', name: 'default' },
value: s.local,
kind: 'init'
}))
},
init: x`require("${edit_source(node.source.value, sveltePath)}")`
}]
}));
const exports = module_exports.map(x => b`exports.${{ type: 'Identifier', name: x.as }} = ${{ type: 'Identifier', name: x.name }};`);
program.body = b`
/* ${banner} */
return s.local.name === s.imported.name
? s.local.name
: `${s.imported.name}: ${s.local.name}`;
});
lhs = `{ ${properties.join(', ')} }`;
}
const source = edit_source(node.source.value, sveltePath);
return `const ${lhs} = require("${source}");`;
});
const exports = [`exports.default = ${name};`].concat(
module_exports.map(x => `exports.${x.as} = ${x.name};`)
);
return deindent`
${banner}
"use strict";
${internal_imports}
${internal_requires}
${internal_globals}
${requires}
${user_requires}
${code}
${program.body}
${exports}`;
exports.default = ${name};
${exports}
`;
}

@ -1,17 +1,24 @@
import MagicString from 'magic-string';
import Stylesheet from './Stylesheet';
import { gather_possible_values, UNKNOWN } from './gather_possible_values';
import { Node } from '../../interfaces';
import { CssNode } from './interfaces';
import Component from '../Component';
import Element from '../nodes/Element';
enum BlockAppliesToNode {
NotPossible,
Possible,
UnknownSelectorType
}
export default class Selector {
node: Node;
node: CssNode;
stylesheet: Stylesheet;
blocks: Block[];
local_blocks: Block[];
used: boolean;
constructor(node: Node, stylesheet: Stylesheet) {
constructor(node: CssNode, stylesheet: Stylesheet) {
this.node = node;
this.stylesheet = stylesheet;
@ -28,13 +35,13 @@ export default class Selector {
this.used = this.blocks[0].global;
}
apply(node: Node, stack: Node[]) {
const to_encapsulate: Node[] = [];
apply(node: Element, stack: Element[]) {
const to_encapsulate: any[] = [];
apply_selector(this.stylesheet, this.local_blocks.slice(), node, stack.slice(), to_encapsulate);
apply_selector(this.local_blocks.slice(), node, stack.slice(), to_encapsulate);
if (to_encapsulate.length > 0) {
to_encapsulate.filter((_, i) => i === 0 || i === to_encapsulate.length - 1).forEach(({ node, block }) => {
to_encapsulate.forEach(({ node, block }) => {
this.stylesheet.nodes_with_css_class.add(node);
block.should_encapsulate = true;
});
@ -126,7 +133,7 @@ export default class Selector {
}
}
function apply_selector(stylesheet: Stylesheet, blocks: Block[], node: Node, stack: Node[], to_encapsulate: any[]): boolean {
function apply_selector(blocks: Block[], node: Element, stack: Element[], to_encapsulate: any[]): boolean {
const block = blocks.pop();
if (!block) return false;
@ -134,49 +141,30 @@ function apply_selector(stylesheet: Stylesheet, blocks: Block[], node: Node, sta
return blocks.every(block => block.global);
}
let i = block.selectors.length;
while (i--) {
const selector = block.selectors[i];
if (selector.type === 'PseudoClassSelector' && selector.name === 'global') {
// TODO shouldn't see this here... maybe we should enforce that :global(...)
// cannot be sandwiched between non-global selectors?
switch (block_might_apply_to_node(block, node)) {
case BlockAppliesToNode.NotPossible:
return false;
}
if (selector.type === 'PseudoClassSelector' || selector.type === 'PseudoElementSelector') {
continue;
}
if (selector.type === 'ClassSelector') {
if (!attribute_matches(node, 'class', selector.name, '~=', false) && !class_matches(node, selector.name)) return false;
}
else if (selector.type === 'IdSelector') {
if (!attribute_matches(node, 'id', selector.name, '=', false)) return false;
}
else if (selector.type === 'AttributeSelector') {
if (!attribute_matches(node, selector.name.name, selector.value && unquote(selector.value), selector.matcher, selector.flags)) return false;
}
else if (selector.type === 'TypeSelector') {
// remove toLowerCase() in v2, when uppercase elements will be forbidden
if (node.name.toLowerCase() !== selector.name.toLowerCase() && selector.name !== '*') return false;
}
else {
case BlockAppliesToNode.UnknownSelectorType:
// bail. TODO figure out what these could be
to_encapsulate.push({ node, block });
return true;
}
}
if (block.combinator) {
if (block.combinator.type === 'WhiteSpace') {
while (stack.length) {
if (apply_selector(stylesheet, blocks.slice(), stack.pop(), stack, to_encapsulate)) {
for (const ancestor_block of blocks) {
if (ancestor_block.global) {
continue;
}
for (const stack_node of stack) {
if (block_might_apply_to_node(ancestor_block, stack_node) !== BlockAppliesToNode.NotPossible) {
to_encapsulate.push({ node: stack_node, block: ancestor_block });
}
}
if (to_encapsulate.length) {
to_encapsulate.push({ node, block });
return true;
}
@ -189,7 +177,7 @@ function apply_selector(stylesheet: Stylesheet, blocks: Block[], node: Node, sta
return false;
} else if (block.combinator.name === '>') {
if (apply_selector(stylesheet, blocks, stack.pop(), stack, to_encapsulate)) {
if (apply_selector(blocks, stack.pop(), stack, to_encapsulate)) {
to_encapsulate.push({ node, block });
return true;
}
@ -206,51 +194,160 @@ function apply_selector(stylesheet: Stylesheet, blocks: Block[], node: Node, sta
return true;
}
const operators = {
'=' : (value: string, flags: string) => new RegExp(`^${value}$`, flags),
'~=': (value: string, flags: string) => new RegExp(`\\b${value}\\b`, flags),
'|=': (value: string, flags: string) => new RegExp(`^${value}(-.+)?$`, flags),
'^=': (value: string, flags: string) => new RegExp(`^${value}`, flags),
'$=': (value: string, flags: string) => new RegExp(`${value}$`, flags),
'*=': (value: string, flags: string) => new RegExp(value, flags)
};
function block_might_apply_to_node(block, node): BlockAppliesToNode {
let i = block.selectors.length;
while (i--) {
const selector = block.selectors[i];
const name = typeof selector.name === 'string' && selector.name.replace(/\\(.)/g, '$1');
if (selector.type === 'PseudoClassSelector' || selector.type === 'PseudoElementSelector') {
continue;
}
if (selector.type === 'PseudoClassSelector' && name === 'global') {
// TODO shouldn't see this here... maybe we should enforce that :global(...)
// cannot be sandwiched between non-global selectors?
return BlockAppliesToNode.NotPossible;
}
if (selector.type === 'ClassSelector') {
if (!attribute_matches(node, 'class', name, '~=', false) && !node.classes.some(c => c.name === name)) return BlockAppliesToNode.NotPossible;
}
function attribute_matches(node: Node, name: string, expected_value: string, operator: string, case_insensitive: boolean) {
else if (selector.type === 'IdSelector') {
if (!attribute_matches(node, 'id', name, '=', false)) return BlockAppliesToNode.NotPossible;
}
else if (selector.type === 'AttributeSelector') {
if (!attribute_matches(node, selector.name.name, selector.value && unquote(selector.value), selector.matcher, selector.flags)) return BlockAppliesToNode.NotPossible;
}
else if (selector.type === 'TypeSelector') {
if (node.name.toLowerCase() !== name.toLowerCase() && name !== '*') return BlockAppliesToNode.NotPossible;
}
else {
return BlockAppliesToNode.UnknownSelectorType;
}
}
return BlockAppliesToNode.Possible;
}
function test_attribute(operator, expected_value, case_insensitive, value) {
if (case_insensitive) {
expected_value = expected_value.toLowerCase();
value = value.toLowerCase();
}
switch (operator) {
case '=': return value === expected_value;
case '~=': return ` ${value} `.includes(` ${expected_value} `);
case '|=': return `${value}-`.startsWith(`${expected_value}-`);
case '^=': return value.startsWith(expected_value);
case '$=': return value.endsWith(expected_value);
case '*=': return value.includes(expected_value);
default: throw new Error(`this shouldn't happen`);
}
}
function attribute_matches(node: CssNode, name: string, expected_value: string, operator: string, case_insensitive: boolean) {
const spread = node.attributes.find(attr => attr.type === 'Spread');
if (spread) return true;
if (node.bindings.some((binding: Node) => binding.name === name)) return true;
if (node.bindings.some((binding: CssNode) => binding.name === name)) return true;
const attr = node.attributes.find((attr: Node) => attr.name === name);
const attr = node.attributes.find((attr: CssNode) => attr.name === name);
if (!attr) return false;
if (attr.is_true) return operator === null;
if (attr.chunks.length > 1) return true;
if (!expected_value) return true;
const pattern = operators[operator](expected_value, case_insensitive ? 'i' : '');
if (attr.chunks.length === 1) {
const value = attr.chunks[0];
if (!value) return false;
if (value.type === 'Text') return pattern.test(value.data);
if (value.type === 'Text') return test_attribute(operator, expected_value, case_insensitive, value.data);
}
const possible_values = new Set();
gather_possible_values(value.node, possible_values);
if (possible_values.has(UNKNOWN)) return true;
for (const x of Array.from(possible_values)) { // TypeScript for-of is slightly unlike JS
if (pattern.test(x)) return true;
let prev_values = [];
for (const chunk of attr.chunks) {
const current_possible_values = new Set();
if (chunk.type === 'Text') {
current_possible_values.add(chunk.data);
} else {
gather_possible_values(chunk.node, current_possible_values);
}
return false;
// impossible to find out all combinations
if (current_possible_values.has(UNKNOWN)) return true;
if (prev_values.length > 0) {
const start_with_space = [];
const remaining = [];
current_possible_values.forEach((current_possible_value: string) => {
if (/^\s/.test(current_possible_value)) {
start_with_space.push(current_possible_value);
} else {
remaining.push(current_possible_value);
}
});
function class_matches(node, name: string) {
return node.classes.some((class_directive) => {
return new RegExp(`\\b${name}\\b`).test(class_directive.name);
if (remaining.length > 0) {
if (start_with_space.length > 0) {
prev_values.forEach(prev_value => possible_values.add(prev_value));
}
const combined = [];
prev_values.forEach((prev_value: string) => {
remaining.forEach((value: string) => {
combined.push(prev_value + value);
});
});
prev_values = combined;
start_with_space.forEach((value: string) => {
if (/\s$/.test(value)) {
possible_values.add(value);
} else {
prev_values.push(value);
}
});
continue;
} else {
prev_values.forEach(prev_value => possible_values.add(prev_value));
prev_values = [];
}
}
current_possible_values.forEach((current_possible_value: string) => {
if (/\s$/.test(current_possible_value)) {
possible_values.add(current_possible_value);
} else {
prev_values.push(current_possible_value);
}
});
if (prev_values.length < current_possible_values.size) {
prev_values.push(' ');
}
if (prev_values.length > 20) {
// might grow exponentially, bail out
return true;
}
}
prev_values.forEach(prev_value => possible_values.add(prev_value));
if (possible_values.has(UNKNOWN)) return true;
for (const value of possible_values) {
if (test_attribute(operator, expected_value, case_insensitive, value)) return true;
}
return false;
}
function unquote(value: Node) {
function unquote(value: CssNode) {
if (value.type === 'Identifier') return value.name;
const str = value.value;
if (str[0] === str[str.length - 1] && str[0] === "'" || str[0] === '"') {
@ -261,13 +358,13 @@ function unquote(value: Node) {
class Block {
global: boolean;
combinator: Node;
selectors: Node[]
combinator: CssNode;
selectors: CssNode[]
start: number;
end: number;
should_encapsulate: boolean;
constructor(combinator: Node) {
constructor(combinator: CssNode) {
this.combinator = combinator;
this.global = false;
this.selectors = [];
@ -278,7 +375,7 @@ class Block {
this.should_encapsulate = false;
}
add(selector: Node) {
add(selector: CssNode) {
if (this.selectors.length === 0) {
this.start = selector.start;
this.global = selector.type === 'PseudoClassSelector' && selector.name === 'global';
@ -289,12 +386,12 @@ class Block {
}
}
function group_selectors(selector: Node) {
function group_selectors(selector: CssNode) {
let block: Block = new Block(null);
const blocks = [block];
selector.children.forEach((child: Node) => {
selector.children.forEach((child: CssNode) => {
if (child.type === 'WhiteSpace' || child.type === 'Combinator') {
block = new Block(child);
blocks.push(block);

@ -2,14 +2,40 @@ import MagicString from 'magic-string';
import { walk } from 'estree-walker';
import Selector from './Selector';
import Element from '../nodes/Element';
import { Node, Ast } from '../../interfaces';
import { Ast, TemplateNode } from '../../interfaces';
import Component from '../Component';
import { CssNode } from './interfaces';
function remove_css_prefix(name: string): string {
return name.replace(/^-((webkit)|(moz)|(o)|(ms))-/, '');
}
const is_keyframes_node = (node: Node) => remove_css_prefix(node.name) === 'keyframes';
const is_keyframes_node = (node: CssNode) =>
remove_css_prefix(node.name) === 'keyframes';
const at_rule_has_declaration = ({ block }: CssNode): true =>
block &&
block.children &&
block.children.find((node: CssNode) => node.type === 'Declaration');
function minify_declarations(
code: MagicString,
start: number,
declarations: Declaration[]
): number {
let c = start;
declarations.forEach((declaration, i) => {
const separator = i > 0 ? ';' : '';
if ((declaration.node.start - c) > separator.length) {
code.overwrite(c, declaration.node.start, separator);
}
declaration.minify(code);
c = declaration.node.end;
});
return c;
}
// https://github.com/darkskyapp/string-hash/blob/master/index.js
function hash(str: string): string {
@ -23,14 +49,14 @@ function hash(str: string): string {
class Rule {
selectors: Selector[];
declarations: Declaration[];
node: Node;
node: CssNode;
parent: Atrule;
constructor(node: Node, stylesheet, parent?: Atrule) {
constructor(node: CssNode, stylesheet, parent?: Atrule) {
this.node = node;
this.parent = parent;
this.selectors = node.selector.children.map((node: Node) => new Selector(node, stylesheet));
this.declarations = node.block.children.map((node: Node) => new Declaration(node));
this.selectors = node.selector.children.map((node: CssNode) => new Selector(node, stylesheet));
this.declarations = node.block.children.map((node: CssNode) => new Declaration(node));
}
apply(node: Element, stack: Element[]) {
@ -64,16 +90,7 @@ class Rule {
code.remove(c, this.node.block.start);
c = this.node.block.start + 1;
this.declarations.forEach((declaration, i) => {
const separator = i > 0 ? ';' : '';
if ((declaration.node.start - c) > separator.length) {
code.overwrite(c, declaration.node.start, separator);
}
declaration.minify(code);
c = declaration.node.end;
});
c = minify_declarations(code, c, this.declarations);
code.remove(c, this.node.block.end - 1);
}
@ -101,16 +118,16 @@ class Rule {
}
class Declaration {
node: Node;
node: CssNode;
constructor(node: Node) {
constructor(node: CssNode) {
this.node = node;
}
transform(code: MagicString, keyframes: Map<string, string>) {
const property = this.node.property && remove_css_prefix(this.node.property.toLowerCase());
if (property === 'animation' || property === 'animation-name') {
this.node.value.children.forEach((block: Node) => {
this.node.value.children.forEach((block: CssNode) => {
if (block.type === 'Identifier') {
const name = block.name;
if (keyframes.has(name)) {
@ -139,12 +156,14 @@ class Declaration {
}
class Atrule {
node: Node;
node: CssNode;
children: Array<Atrule|Rule>;
declarations: Declaration[];
constructor(node: Node) {
constructor(node: CssNode) {
this.node = node;
this.children = [];
this.declarations = [];
}
apply(node: Element, stack: Element[]) {
@ -173,31 +192,40 @@ class Atrule {
let c = this.node.start + (expression_char === '(' ? 6 : 7);
if (this.node.expression.start > c) code.remove(c, this.node.expression.start);
this.node.expression.children.forEach((query: Node) => {
this.node.expression.children.forEach((query: CssNode) => {
// TODO minify queries
c = query.end;
});
code.remove(c, this.node.block.start);
} else if (is_keyframes_node(this.node)) {
let c = this.node.start + this.node.name.length + 1;
if (this.node.expression.start - c > 1) code.overwrite(c, this.node.expression.start, ' ');
c = this.node.expression.end;
if (this.node.block.start - c > 0) code.remove(c, this.node.block.start);
} else if (this.node.name === 'supports') {
let c = this.node.start + 9;
if (this.node.expression.start - c > 1) code.overwrite(c, this.node.expression.start, ' ');
this.node.expression.children.forEach((query: Node) => {
this.node.expression.children.forEach((query: CssNode) => {
// TODO minify queries
c = query.end;
});
code.remove(c, this.node.block.start);
} else {
let c = this.node.start + this.node.name.length + 1;
if (this.node.expression) {
if (this.node.expression.start - c > 1) code.overwrite(c, this.node.expression.start, ' ');
c = this.node.expression.end;
}
if (this.node.block && this.node.block.start - c > 0) {
code.remove(c, this.node.block.start);
}
}
// TODO other atrules
if (this.node.block) {
let c = this.node.block.start + 1;
if (this.declarations.length) {
c = minify_declarations(code, c, this.declarations);
// if the atrule has children, leave the last declaration semicolon alone
if (this.children.length) c++;
}
this.children.forEach(child => {
if (child.is_used(dev)) {
@ -213,7 +241,7 @@ class Atrule {
transform(code: MagicString, id: string, keyframes: Map<string, string>) {
if (is_keyframes_node(this.node)) {
this.node.expression.children.forEach(({ type, name, start, end }: Node) => {
this.node.expression.children.forEach(({ type, name, start, end }: CssNode) => {
if (type === 'Identifier') {
if (name.startsWith('-global-')) {
code.remove(start, start + 8);
@ -261,7 +289,7 @@ export default class Stylesheet {
children: Array<Rule|Atrule> = [];
keyframes: Map<string, string> = new Map();
nodes_with_css_class: Set<Node> = new Set();
nodes_with_css_class: Set<CssNode> = new Set();
constructor(source: string, ast: Ast, filename: string, dev: boolean) {
this.source = source;
@ -278,8 +306,8 @@ export default class Stylesheet {
let depth = 0;
let current_atrule: Atrule = null;
walk(ast.css, {
enter: (node: Node) => {
walk(ast.css as any, {
enter: (node: any) => {
if (node.type === 'Atrule') {
const atrule = new Atrule(node);
stack.push(atrule);
@ -291,11 +319,16 @@ export default class Stylesheet {
}
if (is_keyframes_node(node)) {
node.expression.children.forEach((expression: Node) => {
node.expression.children.forEach((expression: CssNode) => {
if (expression.type === 'Identifier' && !expression.name.startsWith('-global-')) {
this.keyframes.set(expression.name, `${this.id}-${expression.name}`);
}
});
} else if (at_rule_has_declaration(node)) {
const at_rule_declarations = node.block.children
.filter(node => node.type === 'Declaration')
.map(node => new Declaration(node));
atrule.declarations.push(...at_rule_declarations);
}
current_atrule = atrule;
@ -314,7 +347,7 @@ export default class Stylesheet {
depth += 1;
},
leave: (node: Node) => {
leave: (node: any) => {
if (node.type === 'Atrule') {
stack.pop();
current_atrule = stack[stack.length - 1];
@ -332,7 +365,7 @@ export default class Stylesheet {
if (!this.has_styles) return;
const stack: Element[] = [];
let parent: Node = node;
let parent: TemplateNode = node;
while (parent = parent.parent) {
if (parent.type === 'Element') stack.unshift(parent as Element);
}
@ -344,7 +377,7 @@ export default class Stylesheet {
}
reify() {
this.nodes_with_css_class.forEach((node: Node) => {
this.nodes_with_css_class.forEach((node: Element) => {
node.add_css_class();
});
}
@ -356,8 +389,8 @@ export default class Stylesheet {
const code = new MagicString(this.source);
walk(this.ast.css, {
enter: (node: Node) => {
walk(this.ast.css as any, {
enter: (node: any) => {
code.addSourcemapLocation(node.start);
code.addSourcemapLocation(node.end);
}

@ -1,4 +1,4 @@
import { Node } from '../../interfaces';
import { Node } from 'estree';
export const UNKNOWN = {};

@ -0,0 +1,6 @@
export interface CssNode {
type: string;
start: number;
end: number;
[prop_name: string]: any;
}

@ -24,12 +24,13 @@ const valid_options = [
'customElement',
'tag',
'css',
'loopGuardTimeout',
'preserveComments',
'preserveWhitespace'
];
function validate_options(options: CompileOptions, warnings: Warning[]) {
const { name, filename } = options;
const { name, filename, loopGuardTimeout, dev } = options;
Object.keys(options).forEach(key => {
if (valid_options.indexOf(key) === -1) {
@ -54,6 +55,16 @@ function validate_options(options: CompileOptions, warnings: Warning[]) {
toString: () => message,
});
}
if (loopGuardTimeout && !dev) {
const message = 'options.loopGuardTimeout is for options.dev = true only';
warnings.push({
code: `options-loop-guard-timeout`,
message,
filename,
toString: () => message,
});
}
}
export default function compile(source: string, options: CompileOptions = {}) {

@ -1,52 +1,49 @@
import { stringify } from '../utils/stringify';
import { string_literal } from '../utils/stringify';
import add_to_set from '../utils/add_to_set';
import Component from '../Component';
import Node from './shared/Node';
import Element from './Element';
import Text from './Text';
import Expression from './shared/Expression';
import TemplateScope from './shared/TemplateScope';
import { x } from 'code-red';
export default class Attribute extends Node {
type: 'Attribute';
type: 'Attribute' | 'Spread';
start: number;
end: number;
scope: TemplateScope;
component: Component;
parent: Element;
name: string;
is_spread: boolean;
is_true: boolean;
is_dynamic: boolean;
is_static: boolean;
is_synthetic: boolean;
should_cache: boolean;
expression?: Expression;
chunks: Array<Text | Expression>;
dependencies: Set<string>;
constructor(component, parent, scope, info) {
super(component, parent, scope, info);
this.scope = scope;
if (info.type === 'Spread') {
this.name = null;
this.is_spread = true;
this.is_true = false;
this.is_synthetic = false;
this.expression = new Expression(component, this, scope, info.expression);
this.dependencies = this.expression.dependencies;
this.chunks = null;
this.is_dynamic = true; // TODO not necessarily
this.is_static = false;
this.should_cache = false; // TODO does this mean anything here?
}
else {
this.name = info.name;
this.is_true = info.value === true;
this.is_static = true;
this.is_synthetic = info.synthetic;
this.dependencies = new Set();
@ -62,22 +59,13 @@ export default class Attribute extends Node {
add_to_set(this.dependencies, expression.dependencies);
return expression;
});
this.is_dynamic = this.dependencies.size > 0;
this.should_cache = this.is_dynamic
? this.chunks.length === 1
// @ts-ignore todo: probably error
? this.chunks[0].node.type !== 'Identifier' || scope.names.has(this.chunks[0].node.name)
: true
: false;
}
}
get_dependencies() {
if (this.is_spread) return this.expression.dynamic_dependencies();
const dependencies = new Set();
const dependencies: Set<string> = new Set();
this.chunks.forEach(chunk => {
if (chunk.type === 'Expression') {
add_to_set(dependencies, chunk.dynamic_dependencies());
@ -88,32 +76,28 @@ export default class Attribute extends Node {
}
get_value(block) {
if (this.is_true) return true;
if (this.chunks.length === 0) return `""`;
if (this.is_true) return x`true`;
if (this.chunks.length === 0) return x`""`;
if (this.chunks.length === 1) {
return this.chunks[0].type === 'Text'
? stringify((this.chunks[0] as Text).data)
// @ts-ignore todo: probably error
: this.chunks[0].render(block);
? string_literal((this.chunks[0] as Text).data)
: (this.chunks[0] as Expression).manipulate(block);
}
return (this.chunks[0].type === 'Text' ? '' : `"" + `) +
this.chunks
.map(chunk => {
if (chunk.type === 'Text') {
return stringify(chunk.data);
} else {
// @ts-ignore todo: probably error
return chunk.get_precedence() <= 13 ? `(${chunk.render()})` : chunk.render();
let expression = this.chunks
.map(chunk => chunk.type === 'Text' ? string_literal(chunk.data) : chunk.manipulate(block))
.reduce((lhs, rhs) => x`${lhs} + ${rhs}`);
if (this.chunks[0].type !== 'Text') {
expression = x`"" + ${expression}`;
}
})
.join(' + ');
return expression;
}
get_static_value() {
if (this.is_spread || this.is_dynamic) return null;
if (this.is_spread || this.dependencies.size > 0) return null;
return this.is_true
? true
@ -122,4 +106,13 @@ export default class Attribute extends Node {
? (this.chunks[0] as Text).data
: '';
}
should_cache() {
return this.is_static
? false
: this.chunks.length === 1
// @ts-ignore todo: probably error
? this.chunks[0].node.type !== 'Identifier' || this.scope.names.has(this.chunks[0].node.name)
: true;
}
}

@ -4,22 +4,24 @@ import Expression from './shared/Expression';
import Component from '../Component';
import TemplateScope from './shared/TemplateScope';
import {dimensions} from "../../utils/patterns";
import { Node as ESTreeNode } from 'estree';
// TODO this should live in a specific binding
const read_only_media_attributes = new Set([
'duration',
'buffered',
'seekable',
'played'
'played',
'seeking',
'ended'
]);
export default class Binding extends Node {
type: 'Binding';
name: string;
expression: Expression;
raw_expression: ESTreeNode; // TODO exists only for bind:this — is there a more elegant solution?
is_contextual: boolean;
obj: string;
prop: string;
is_readonly: boolean;
constructor(component: Component, parent, scope: TemplateScope, info) {
@ -34,9 +36,7 @@ export default class Binding extends Node {
this.name = info.name;
this.expression = new Expression(component, this, scope, info.expression);
let obj;
let prop;
this.raw_expression = JSON.parse(JSON.stringify(info.expression));
const { name } = get_object(this.expression.node);
this.is_contextual = scope.names.has(name);
@ -63,18 +63,6 @@ export default class Binding extends Node {
variable[this.expression.node.type === 'MemberExpression' ? 'mutated' : 'reassigned'] = true;
}
if (this.expression.node.type === 'MemberExpression') {
prop = `[✂${this.expression.node.property.start}-${this.expression.node.property.end}✂]`;
if (!this.expression.node.computed) prop = `'${prop}'`;
obj = `[✂${this.expression.node.object.start}-${this.expression.node.object.end}✂]`;
} else {
obj = 'ctx';
prop = `'${name}'`;
}
this.obj = obj;
this.prop = prop;
const type = parent.get_static_attribute_value('type');
this.is_readonly = (

@ -1,49 +1,55 @@
import Node from './shared/Node';
import ElseBlock from './ElseBlock';
import Expression from './shared/Expression';
import map_children from './shared/map_children';
import TemplateScope from './shared/TemplateScope';
import AbstractBlock from './shared/AbstractBlock';
import { Node as INode } from '../../interfaces';
import { new_tail } from '../utils/tail';
import Element from './Element';
import { x } from 'code-red';
import { Node, Identifier, RestElement } from 'estree';
interface Context {
key: INode;
key: Identifier;
name?: string;
tail: string;
modifier: (node: Node) => Node;
}
function unpack_destructuring(contexts: Context[], node: INode, tail: string) {
function unpack_destructuring(contexts: Context[], node: Node, modifier: (node: Node) => Node) {
if (!node) return;
if (node.type === 'Identifier' || node.type === 'RestIdentifier') {
if (node.type === 'Identifier' || (node as any).type === 'RestIdentifier') { // TODO is this right? not RestElement?
contexts.push({
key: node,
tail
key: node as Identifier,
modifier
});
} else if (node.type === 'ArrayPattern') {
node.elements.forEach((element, i) => {
if (element && element.type === 'RestIdentifier') {
unpack_destructuring(contexts, element, `${tail}.slice(${i})`);
if (element && (element as any).type === 'RestIdentifier') {
unpack_destructuring(contexts, element, node => x`${modifier(node)}.slice(${i})` as Node);
} else {
unpack_destructuring(contexts, element, `${tail}[${i}]`);
unpack_destructuring(contexts, element, node => x`${modifier(node)}[${i}]` as Node);
}
});
} else if (node.type === 'ObjectPattern') {
const used_properties = [];
node.properties.forEach((property) => {
if (property.kind === 'rest') {
node.properties.forEach((property, i) => {
if ((property as any).kind === 'rest') { // TODO is this right?
const replacement: RestElement = {
type: 'RestElement',
argument: property.key as Identifier
};
node.properties[i] = replacement as any;
unpack_destructuring(
contexts,
property.value,
`@object_without_properties(${tail}, ${JSON.stringify(used_properties)})`
node => x`@object_without_properties(${modifier(node)}, [${used_properties}])` as Node
);
} else {
used_properties.push(property.key.name);
used_properties.push(x`"${(property.key as Identifier).name}"`);
unpack_destructuring(contexts, property.value,`${tail}.${property.key.name}`);
unpack_destructuring(contexts, property.value, node => x`${modifier(node)}.${(property.key as Identifier).name}` as Node);
}
});
}
@ -77,7 +83,7 @@ export default class EachBlock extends AbstractBlock {
this.scope = scope.child();
this.contexts = [];
unpack_destructuring(this.contexts, info.context, new_tail());
unpack_destructuring(this.contexts, info.context, node => node);
this.contexts.forEach(context => {
this.scope.add(context.key.name, this.expression.dependencies, this);

@ -105,6 +105,7 @@ export default class Element extends Node {
animation?: Animation = null;
children: INode[];
namespace: string;
needs_manual_style_scoping: boolean;
constructor(component, parent, scope, info: any) {
super(component, parent, scope, info);
@ -150,6 +151,10 @@ export default class Element extends Node {
}
}
// Binding relies on Attribute, defer its evaluation
const order = ['Binding']; // everything else is -1
info.attributes.sort((a, b) => order.indexOf(a.type) - order.indexOf(b.type));
info.attributes.forEach(node => {
switch (node.type) {
case 'Action':
@ -201,7 +206,7 @@ export default class Element extends Node {
this.scope = scope.child();
this.lets.forEach(l => {
const dependencies = new Set([l.name]);
const dependencies = new Set([l.name.name]);
l.names.forEach(name => {
this.scope.add(name, dependencies, this);
@ -622,7 +627,9 @@ export default class Element extends Node {
name === 'seekable' ||
name === 'played' ||
name === 'volume' ||
name === 'playbackRate'
name === 'playbackRate' ||
name === 'seeking' ||
name === 'ended'
) {
if (this.name !== 'audio' && this.name !== 'video') {
component.error(binding, {
@ -743,6 +750,11 @@ export default class Element extends Node {
}
add_css_class() {
if (this.attributes.some(attr => attr.is_spread)) {
this.needs_manual_style_scoping = true;
return;
}
const { id } = this.component.stylesheet;
const class_attribute = this.attributes.find(a => a.name === 'class');

@ -1,18 +1,18 @@
import Node from './shared/Node';
import Expression from './shared/Expression';
import Component from '../Component';
import deindent from '../utils/deindent';
import Block from '../render_dom/Block';
import { sanitize } from '../../utils/names';
import { Identifier } from 'estree';
export default class EventHandler extends Node {
type: 'EventHandler';
name: string;
modifiers: Set<string>;
expression: Expression;
handler_name: string;
handler_name: Identifier;
uses_context = false;
can_make_passive = false;
reassigned?: boolean;
constructor(component: Component, parent, template_scope, info) {
super(component, parent, template_scope, info);
@ -21,7 +21,7 @@ export default class EventHandler extends Node {
this.modifiers = new Set(info.modifiers);
if (info.expression) {
this.expression = new Expression(component, this, template_scope, info.expression, true);
this.expression = new Expression(component, this, template_scope, info.expression);
this.uses_context = this.expression.uses_context;
if (/FunctionExpression/.test(info.expression.type) && info.expression.params.length === 0) {
@ -31,40 +31,22 @@ export default class EventHandler extends Node {
} else if (info.expression.type === 'Identifier') {
let node = component.node_for_declaration.get(info.expression.name);
if (node && node.type === 'VariableDeclaration') {
if (node) {
if (node.type === 'VariableDeclaration') {
// for `const handleClick = () => {...}`, we want the [arrow] function expression node
const declarator = node.declarations.find(d => d.id.name === info.expression.name);
const declarator = node.declarations.find(d => (d.id as Identifier).name === info.expression.name);
node = declarator && declarator.init;
}
if (node && /Function/.test(node.type) && node.params.length === 0) {
if (node && (node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration' || node.type === 'ArrowFunctionExpression') && node.params.length === 0) {
this.can_make_passive = true;
}
}
} else {
const name = component.get_unique_name(`${sanitize(this.name)}_handler`);
component.add_var({
name,
internal: true,
referenced: true
});
component.partly_hoisted.push(deindent`
function ${name}(event) {
@bubble($$self, event);
this.reassigned = component.var_lookup.get(info.expression.name).reassigned;
}
`);
this.handler_name = name;
}
} else {
this.handler_name = component.get_unique_name(`${sanitize(this.name)}_handler`);
}
// TODO move this? it is specific to render-dom
render(block: Block) {
if (this.expression) return this.expression.render(block);
// this.component.add_reference(this.handler_name);
return `ctx.${this.handler_name}`;
}
}

@ -90,7 +90,7 @@ export default class InlineComponent extends Node {
this.scope = scope.child();
this.lets.forEach(l => {
const dependencies = new Set([l.name]);
const dependencies = new Set([l.name.name]);
l.names.forEach(name => {
this.scope.add(name, dependencies, this);

@ -1,38 +1,51 @@
import Node from './shared/Node';
import Component from '../Component';
import { walk } from 'estree-walker';
import { Identifier } from 'estree';
const applicable = new Set(['Identifier', 'ObjectExpression', 'ArrayExpression', 'Property']);
export default class Let extends Node {
type: 'Let';
name: string;
value: string;
name: Identifier;
value: Identifier;
names: string[] = [];
constructor(component: Component, parent, scope, info) {
super(component, parent, scope, info);
this.name = info.name;
this.value = info.expression && `[✂${info.expression.start}-${info.expression.end}✂]`;
this.name = { type: 'Identifier', name: info.name };
const { names } = this;
if (info.expression) {
this.value = info.expression;
walk(info.expression, {
enter: node => {
enter(node) {
if (!applicable.has(node.type)) {
component.error(node, {
component.error(node as any, {
code: 'invalid-let',
message: `let directive value must be an identifier or an object/array pattern`
});
}
if (node.type === 'Identifier') {
this.names.push(node.name);
names.push(node.name);
}
// slightly unfortunate hack
if (node.type === 'ArrayExpression') {
(node as any).type = 'ArrayPattern';
}
if (node.type === 'ObjectExpression') {
(node as any).type = 'ObjectPattern';
}
}
});
} else {
this.names.push(this.name);
names.push(this.name.name);
}
}
}

@ -3,74 +3,24 @@ import { walk } from 'estree-walker';
import is_reference from 'is-reference';
import flatten_reference from '../../utils/flatten_reference';
import { create_scopes, Scope, extract_names } from '../../utils/scope';
import { Node } from '../../../interfaces';
import { globals , sanitize } from '../../../utils/names';
import deindent from '../../utils/deindent';
import { sanitize } from '../../../utils/names';
import Wrapper from '../../render_dom/wrappers/shared/Wrapper';
import TemplateScope from './TemplateScope';
import get_object from '../../utils/get_object';
import { nodes_match } from '../../../utils/nodes_match';
import Block from '../../render_dom/Block';
import { INode } from '../interfaces';
import is_dynamic from '../../render_dom/wrappers/shared/is_dynamic';
import { x, b, p } from 'code-red';
import { invalidate } from '../../utils/invalidate';
import { Node, FunctionExpression } from 'estree';
import { TemplateNode } from '../../../interfaces';
const binary_operators: Record<string, number> = {
'**': 15,
'*': 14,
'/': 14,
'%': 14,
'+': 13,
'-': 13,
'<<': 12,
'>>': 12,
'>>>': 12,
'<': 11,
'<=': 11,
'>': 11,
'>=': 11,
in: 11,
instanceof: 11,
'==': 10,
'!=': 10,
'===': 10,
'!==': 10,
'&': 9,
'^': 8,
'|': 7
};
const logical_operators: Record<string, number> = {
'&&': 6,
'||': 5
};
const precedence: Record<string, (node?: Node) => number> = {
Literal: () => 21,
Identifier: () => 21,
ParenthesizedExpression: () => 20,
MemberExpression: () => 19,
NewExpression: () => 19, // can be 18 (if no args) but makes no practical difference
CallExpression: () => 19,
UpdateExpression: () => 17,
UnaryExpression: () => 16,
BinaryExpression: (node: Node) => binary_operators[node.operator],
LogicalExpression: (node: Node) => logical_operators[node.operator],
ConditionalExpression: () => 4,
AssignmentExpression: () => 3,
YieldExpression: () => 2,
SpreadElement: () => 1,
SequenceExpression: () => 0
};
type Owner = Wrapper | INode;
type Owner = Wrapper | TemplateNode;
export default class Expression {
type: 'Expression' = 'Expression';
component: Component;
owner: Owner;
node: any;
snippet: string;
references: Set<string>;
dependencies: Set<string> = new Set();
contextual_dependencies: Set<string> = new Set();
@ -79,11 +29,10 @@ export default class Expression {
scope: Scope;
scope_map: WeakMap<Node, Scope>;
is_synthetic: boolean;
declarations: string[] = [];
declarations: Array<(Node | Node[])> = [];
uses_context = false;
rendered: string;
manipulated: Node;
// todo: owner type
constructor(component: Component, owner: Owner, template_scope: TemplateScope, info, lazy?: boolean) {
@ -97,8 +46,6 @@ export default class Expression {
this.node = info;
this.template_scope = template_scope;
this.owner = owner;
// @ts-ignore
this.is_synthetic = owner.is_synthetic;
const { dependencies, contextual_dependencies } = this;
@ -128,8 +75,6 @@ export default class Expression {
if (scope.has(name)) return;
if (globals.has(name) && !component.var_lookup.has(name)) return;
if (name[0] === '$' && template_scope.names.has(name.slice(1))) {
component.error(node, {
code: `contextual-store`,
@ -220,50 +165,41 @@ export default class Expression {
});
}
get_precedence() {
return this.node.type in precedence ? precedence[this.node.type](this.node) : 0;
}
// TODO move this into a render-dom wrapper?
render(block?: Block) {
if (this.rendered) return this.rendered;
manipulate(block?: Block) {
// TODO ideally we wouldn't end up calling this method
// multiple times
if (this.manipulated) return this.manipulated;
const {
component,
declarations,
scope_map: map,
template_scope,
owner,
is_synthetic
owner
} = this;
let scope = this.scope;
const { code } = component;
let function_expression;
let pending_assignments: Set<string> = new Set();
let dependencies: Set<string>;
let contextual_dependencies: Set<string>;
// rewrite code as appropriate
walk(this.node, {
enter(node: any, parent: any, key: string) {
// don't manipulate shorthand props twice
if (key === 'value' && parent.shorthand) return;
code.addSourcemapLocation(node.start);
code.addSourcemapLocation(node.end);
const node = walk(this.node, {
enter(node: any, parent: any) {
if (node.type === 'Property' && node.shorthand) {
node.value = JSON.parse(JSON.stringify(node.value));
node.shorthand = false;
}
if (map.has(node)) {
scope = map.get(node);
}
if (is_reference(node, parent)) {
const { name, nodes } = flatten_reference(node);
const { name } = flatten_reference(node);
if (scope.has(name)) return;
if (globals.has(name) && !component.var_lookup.has(name)) return;
if (function_expression) {
if (template_scope.names.has(name)) {
@ -276,17 +212,8 @@ export default class Expression {
dependencies.add(name);
component.add_reference(name); // TODO is this redundant/misplaced?
}
} else if (!is_synthetic && is_contextual(component, template_scope, name)) {
code.prependRight(node.start, key === 'key' && parent.shorthand
? `${name}: ctx.`
: 'ctx.');
}
if (node.type === 'MemberExpression') {
nodes.forEach(node => {
code.addSourcemapLocation(node.start);
code.addSourcemapLocation(node.end);
});
} else if (is_contextual(component, template_scope, name)) {
this.replace(x`#ctx.${node}`);
}
this.skip();
@ -309,73 +236,20 @@ export default class Expression {
if (map.has(node)) scope = scope.parent;
if (node === function_expression) {
if (pending_assignments.size > 0) {
if (node.type !== 'ArrowFunctionExpression') {
// this should never happen!
throw new Error(`Well that's odd`);
}
// TOOD optimisation — if this is an event handler,
// the return value doesn't matter
}
const name = component.get_unique_name(
const id = component.get_unique_name(
sanitize(get_function_name(node, owner))
);
const args = contextual_dependencies.size > 0
? [`{ ${Array.from(contextual_dependencies).join(', ')} }`]
: [];
let original_params;
if (node.params.length > 0) {
original_params = code.slice(node.params[0].start, node.params[node.params.length - 1].end);
args.push(original_params);
}
let body = code.slice(node.body.start, node.body.end).trim();
if (node.body.type !== 'BlockStatement') {
if (pending_assignments.size > 0) {
const dependencies = new Set();
pending_assignments.forEach(name => {
if (template_scope.names.has(name)) {
template_scope.dependencies_for_name.get(name).forEach(dependency => {
dependencies.add(dependency);
});
} else {
dependencies.add(name);
}
});
const insert = Array.from(dependencies).map(name => component.invalidate(name)).join('; ');
pending_assignments = new Set();
component.has_reactive_assignments = true;
body = deindent`
{
const $$result = ${body};
${insert};
return $$result;
}
`;
} else {
body = `{\n\treturn ${body};\n}`;
}
}
const fn = deindent`
${node.async && 'async '}function${node.generator && '*'} ${name}(${args.join(', ')}) ${body}
`;
const declaration = b`const ${id} = ${node}`;
if (dependencies.size === 0 && contextual_dependencies.size === 0) {
// we can hoist this out of the component completely
component.fully_hoisted.push(fn);
code.overwrite(node.start, node.end, name);
component.fully_hoisted.push(declaration);
this.replace(id as any);
component.add_var({
name,
name: id.name,
internal: true,
hoistable: true,
referenced: true
@ -384,11 +258,12 @@ export default class Expression {
else if (contextual_dependencies.size === 0) {
// function can be hoisted inside the component init
component.partly_hoisted.push(fn);
code.overwrite(node.start, node.end, `ctx.${name}`);
component.partly_hoisted.push(declaration);
this.replace(x`#ctx.${id}` as any);
component.add_var({
name,
name: id.name,
internal: true,
referenced: true
});
@ -396,91 +271,65 @@ export default class Expression {
else {
// we need a combo block/init recipe
component.partly_hoisted.push(fn);
code.overwrite(node.start, node.end, name);
(node as FunctionExpression).params.unshift({
type: 'ObjectPattern',
properties: Array.from(contextual_dependencies).map(name => p`${name}` as any)
});
component.partly_hoisted.push(declaration);
this.replace(id as any);
component.add_var({
name,
name: id.name,
internal: true,
referenced: true
});
declarations.push(deindent`
function ${name}(${original_params ? '...args' : ''}) {
return ctx.${name}(ctx${original_params ? ', ...args' : ''});
if ((node as FunctionExpression).params.length > 0) {
declarations.push(b`
function ${id}(...args) {
return #ctx.${id}(#ctx, ...args);
}
`);
} else {
declarations.push(b`
function ${id}() {
return #ctx.${id}(#ctx);
}
`);
}
if (parent && parent.method) {
code.prependRight(node.start, ': ');
}
function_expression = null;
dependencies = null;
contextual_dependencies = null;
}
if (node.type === 'AssignmentExpression') {
const names = node.left.type === 'MemberExpression'
? [get_object(node.left).name]
: extract_names(node.left);
if (node.operator === '=' && nodes_match(node.left, node.right)) {
const dirty = names.filter(name => {
return !scope.declarations.has(name);
});
if (dirty.length) component.has_reactive_assignments = true;
code.overwrite(node.start, node.end, dirty.map(n => component.invalidate(n)).join('; '));
} else {
names.forEach(name => {
if (scope.declarations.has(name)) return;
const variable = component.var_lookup.get(name);
if (variable && variable.hoistable) return;
pending_assignments.add(name);
});
if (parent && parent.type === 'Property') {
parent.method = false;
}
} else if (node.type === 'UpdateExpression') {
const { name } = get_object(node.argument);
if (scope.declarations.has(name)) return;
const variable = component.var_lookup.get(name);
if (variable && variable.hoistable) return;
pending_assignments.add(name);
}
if (/Statement/.test(node.type)) {
if (pending_assignments.size > 0) {
const has_semi = code.original[node.end - 1] === ';';
if (node.type === 'AssignmentExpression' || node.type === 'UpdateExpression') {
const assignee = node.type === 'AssignmentExpression' ? node.left : node.argument;
const insert = (
(has_semi ? ' ' : '; ') +
Array.from(pending_assignments).map(name => component.invalidate(name)).join('; ')
);
// normally (`a = 1`, `b.c = 2`), there'll be a single name
// (a or b). In destructuring cases (`[d, e] = [e, d]`) there
// may be more, in which case we need to tack the extra ones
// onto the initial function call
const names = new Set(extract_names(assignee));
if (/^(Break|Continue|Return)Statement/.test(node.type)) {
if (node.argument) {
code.overwrite(node.start, node.argument.start, `var $$result = `);
code.appendLeft(node.end, `${insert}; return $$result`);
} else {
code.prependRight(node.start, `${insert}; `);
}
} else if (parent && /(If|For(In|Of)?|While)Statement/.test(parent.type) && node.type !== 'BlockStatement') {
code.prependRight(node.start, '{ ');
code.appendLeft(node.end, `${insert}; }`);
const traced: Set<string> = new Set();
names.forEach(name => {
const dependencies = template_scope.dependencies_for_name.get(name);
if (dependencies) {
dependencies.forEach(name => traced.add(name));
} else {
code.appendLeft(node.end, `${insert};`);
traced.add(name);
}
});
component.has_reactive_assignments = true;
pending_assignments = new Set();
}
this.replace(invalidate(component, scope, node, traced));
}
}
});
@ -488,11 +337,11 @@ export default class Expression {
if (declarations.length > 0) {
block.maintain_context = true;
declarations.forEach(declaration => {
block.builders.init.add_block(declaration);
block.chunks.init.push(declaration);
});
}
return this.rendered = `[✂${this.node.start}-${this.node.end}✂]`;
return (this.manipulated = node);
}
}

@ -14,7 +14,7 @@ import Slot from '../Slot';
import Text from '../Text';
import Title from '../Title';
import Window from '../Window';
import { Node } from '../../../interfaces';
import { TemplateNode } from '../../../interfaces';
export type Children = ReturnType<typeof map_children>;
@ -40,7 +40,7 @@ function get_constructor(type) {
}
}
export default function map_children(component, parent, scope, children: Node[]) {
export default function map_children(component, parent, scope, children: TemplateNode[]) {
let last = null;
let ignores = [];

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save