├── .prettierignore ├── .prettierrc ├── .gitignore ├── docs ├── ishihara.jpg ├── style.css ├── script.js └── index.html ├── src ├── types.ts ├── sim-matrix.ts ├── index.ts └── util.ts ├── tsconfig.json ├── CHANGELOG.md ├── rollup.config.js ├── LICENSE ├── package.json ├── README.md └── pnpm-lock.yaml /.prettierignore: -------------------------------------------------------------------------------- 1 | dist 2 | docs/colorblind.umd.js 3 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": false, 3 | "singleQuote": true 4 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .vscode 4 | *.code-workspace 5 | -------------------------------------------------------------------------------- /docs/ishihara.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluwy/colorblind/HEAD/docs/ishihara.jpg -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | export type RGB = { 2 | r: number 3 | g: number 4 | b: number 5 | } 6 | 7 | export type LMS = { 8 | l: number 9 | m: number 10 | s: number 11 | } 12 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2015", 4 | "emitDeclarationOnly": true, 5 | "declaration": true, 6 | "declarationDir": "dist", 7 | "strict": true, 8 | "esModuleInterop": true, 9 | "forceConsistentCasingInFileNames": true 10 | }, 11 | "include": ["src"], 12 | "exclude": ["node_modules"] 13 | } 14 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 1.0.3 - 2020-10-22 4 | 5 | ### Changed 6 | 7 | - Sanitize input and output RGB 8 | 9 | ## 1.0.2 - 2020-07-28 10 | 11 | ### Fixed 12 | 13 | - Internal code refactoring 14 | 15 | ## 1.0.1 - 2020-07-02 16 | 17 | ### Changed 18 | 19 | - Change output file names for better CDN naming 20 | 21 | ## 1.0.0 - 2020-06-28 22 | 23 | Initial release 24 | -------------------------------------------------------------------------------- /src/sim-matrix.ts: -------------------------------------------------------------------------------- 1 | // prettier-ignore 2 | export const protanopiaSim = [ 3 | 0.0, 1.05118294, -0.05116099, 4 | 0.0, 1.0, 0.0, 5 | 0.0, 0.0, 1.0, 6 | ] 7 | 8 | // prettier-ignore 9 | export const deuteranopiaSim = [ 10 | 1.0, 0.0, 0.0, 11 | 0.9513092, 0.0, 0.04866992, 12 | 0.0, 0.0, 1.0, 13 | ] 14 | 15 | // prettier-ignore 16 | export const tritanopiaSim = [ 17 | 1.0, 0.0, 0.0, 18 | 0.0, 1.0, 0.0, 19 | -0.86744736, 1.86727089, 0.0, 20 | ] 21 | 22 | // prettier-ignore 23 | export const achromatopsiaSim = [ 24 | 0.212656, 0.715158, 0.072186, 25 | ] 26 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import typescript from '@rollup/plugin-typescript' 2 | import { terser } from 'rollup-plugin-terser' 3 | import pkg from './package.json' 4 | import tsconfig from './tsconfig.json' 5 | 6 | const { 7 | declaration, 8 | declarationDir, 9 | ...compilerOptions 10 | } = tsconfig.compilerOptions 11 | 12 | export default { 13 | input: 'src/index.ts', 14 | output: [ 15 | { format: 'cjs', file: pkg.main }, 16 | { format: 'es', file: pkg.module }, 17 | { format: 'umd', file: pkg.browser, name: 'colorblind' }, 18 | ], 19 | plugins: [ 20 | typescript({ 21 | tsconfig: false, 22 | ...compilerOptions, 23 | }), 24 | terser(), 25 | ], 26 | } 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Bjorn Lu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@bjornlu/colorblind", 3 | "description": "Simulate color blindness", 4 | "version": "1.0.3", 5 | "main": "dist/colorblind.cjs.js", 6 | "module": "dist/colorblind.esm.js", 7 | "browser": "dist/colorblind.min.js", 8 | "types": "dist/index.d.ts", 9 | "files": [ 10 | "dist" 11 | ], 12 | "author": { 13 | "name": "Bjorn Lu", 14 | "url": "https://bjornlu.com" 15 | }, 16 | "license": "MIT", 17 | "homepage": "https://github.com/bluwy/colorblind", 18 | "repository": { 19 | "type": "git", 20 | "url": "https://github.com/bluwy/colorblind.git" 21 | }, 22 | "bugs": { 23 | "url": "https://github.com/bluwy/colorblind/issues" 24 | }, 25 | "keywords": [ 26 | "color", 27 | "blindness", 28 | "simulation", 29 | "protanopia", 30 | "deuteranopia", 31 | "tritanopia", 32 | "achromatopsia" 33 | ], 34 | "scripts": { 35 | "clean": "rm -rf dist", 36 | "build": "rollup -c && tsc", 37 | "format": "prettier --write '**/*.{ts,md,html,css,js}'", 38 | "prepublishOnly": "pnpm clean && pnpm build" 39 | }, 40 | "devDependencies": { 41 | "@rollup/plugin-typescript": "^6.0.0", 42 | "@types/node": "^14.14.2", 43 | "prettier": "^2.1.2", 44 | "rollup": "^2.32.1", 45 | "rollup-plugin-terser": "^7.0.2", 46 | "ts-node": "^9.0.0", 47 | "tslib": "^2.0.3", 48 | "typescript": "^4.0.3" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { RGB } from './types' 2 | import { 3 | protanopiaSim, 4 | deuteranopiaSim, 5 | tritanopiaSim, 6 | achromatopsiaSim, 7 | } from './sim-matrix' 8 | import { 9 | convertLmsToMatrix, 10 | convertLmsToRgb, 11 | convertMatrixToLms, 12 | convertMatrixToRgb, 13 | convertRgbToLms, 14 | convertRgbToMatrix, 15 | multiplyMatrix3x1And3x1, 16 | multiplyMatrix3x3And3x1, 17 | sanitizeRgb, 18 | } from './util' 19 | 20 | export type Deficiency = 21 | | 'protanopia' 22 | | 'deuteranopia' 23 | | 'tritanopia' 24 | | 'achromatopsia' 25 | 26 | export function simulate(rgb: RGB, deficiency: Deficiency) { 27 | switch (deficiency) { 28 | case 'protanopia': 29 | return simulateDichromatic(rgb, protanopiaSim) 30 | case 'deuteranopia': 31 | return simulateDichromatic(rgb, deuteranopiaSim) 32 | case 'tritanopia': 33 | return simulateDichromatic(rgb, tritanopiaSim) 34 | case 'achromatopsia': 35 | return simulateMonochromatic(rgb, achromatopsiaSim) 36 | default: 37 | throw new Error('Invalid color deficiency provided') 38 | } 39 | } 40 | 41 | export function simulateDichromatic(rgb: RGB, simMatrix: Array) { 42 | const lms = convertRgbToLms(sanitizeRgb(rgb)) 43 | const lmsMatrix = convertLmsToMatrix(lms) 44 | const simLmsMatrix = multiplyMatrix3x3And3x1(simMatrix, lmsMatrix) 45 | const simLms = convertMatrixToLms(simLmsMatrix) 46 | const simRgb = convertLmsToRgb(simLms) 47 | 48 | return sanitizeRgb(simRgb) 49 | } 50 | 51 | export function simulateMonochromatic(rgb: RGB, simMatrix: Array) { 52 | const rgbMatrix = convertRgbToMatrix(sanitizeRgb(rgb)) 53 | const simRgbValue = multiplyMatrix3x1And3x1(rgbMatrix, simMatrix)[0] 54 | const simRgbMetrix = Array(3).fill(simRgbValue) 55 | const simRgb = convertMatrixToRgb(simRgbMetrix) 56 | 57 | return sanitizeRgb(simRgb) 58 | } 59 | -------------------------------------------------------------------------------- /docs/style.css: -------------------------------------------------------------------------------- 1 | *, 2 | *::before, 3 | *::after { 4 | box-sizing: border-box; 5 | } 6 | 7 | html { 8 | text-align: center; 9 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, 10 | Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 11 | } 12 | 13 | canvas { 14 | border: 1px solid black; 15 | max-width: 100%; 16 | } 17 | 18 | label > div { 19 | margin-bottom: 0.3rem; 20 | } 21 | 22 | .options-section { 23 | display: flex; 24 | flex-direction: column; 25 | justify-content: center; 26 | margin: 0 1rem; 27 | } 28 | 29 | .options-section__img, 30 | .options-section__select { 31 | text-align: left; 32 | margin-bottom: 1rem; 33 | } 34 | 35 | .canvas-section { 36 | display: flex; 37 | justify-content: center; 38 | flex-direction: column; 39 | } 40 | 41 | .canvas-section__original { 42 | margin-bottom: 1rem; 43 | } 44 | 45 | #default-img { 46 | display: none; 47 | } 48 | 49 | @media (min-width: 500px) { 50 | .options-section { 51 | flex-direction: row; 52 | } 53 | 54 | .options-section__select { 55 | text-align: right; 56 | } 57 | } 58 | 59 | @media (min-width: 870px) { 60 | .canvas-section { 61 | flex-direction: row; 62 | } 63 | 64 | .canvas-section__original { 65 | margin-bottom: 0; 66 | margin-right: 1rem; 67 | } 68 | } 69 | 70 | .github-corner:hover .octo-arm { 71 | animation: octocat-wave 560ms ease-in-out; 72 | } 73 | 74 | @keyframes octocat-wave { 75 | 0%, 76 | 100% { 77 | transform: rotate(0); 78 | } 79 | 20%, 80 | 60% { 81 | transform: rotate(-25deg); 82 | } 83 | 40%, 84 | 80% { 85 | transform: rotate(10deg); 86 | } 87 | } 88 | 89 | @media (max-width: 500px) { 90 | .github-corner:hover .octo-arm { 91 | animation: none; 92 | } 93 | .github-corner .octo-arm { 94 | animation: octocat-wave 560ms ease-in-out; 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/util.ts: -------------------------------------------------------------------------------- 1 | import { LMS, RGB } from './types' 2 | 3 | // prettier-ignore 4 | const rgbToLmsMatrix = [ 5 | 0.31399022, 0.63951294, 0.04649755, 6 | 0.15537241, 0.75789446, 0.08670142, 7 | 0.01775239, 0.10944209, 0.87256922, 8 | ] 9 | 10 | // prettier-ignore 11 | const lmsToRgbMatrix = [ 12 | 5.47221206, -4.6419601, 0.16963708, 13 | -1.1252419, 2.29317094, -0.1678952, 14 | 0.02980165, -0.19318073, 1.16364789, 15 | ] 16 | 17 | export function multiplyMatrix3x3And3x1(a: Array, b: Array) { 18 | return [ 19 | a[0] * b[0] + a[1] * b[1] + a[2] * b[2], 20 | a[3] * b[0] + a[4] * b[1] + a[5] * b[2], 21 | a[6] * b[0] + a[7] * b[1] + a[8] * b[2], 22 | ] 23 | } 24 | 25 | export function multiplyMatrix3x1And3x1(a: Array, b: Array) { 26 | return [a[0] * b[0] + a[1] * b[1] + a[2] * b[2]] 27 | } 28 | 29 | export function convertRgbToLms(rgb: RGB) { 30 | const rgbMatrix = convertRgbToMatrix(rgb) 31 | const lmsMatrix = multiplyMatrix3x3And3x1(rgbToLmsMatrix, rgbMatrix) 32 | const lms = convertMatrixToLms(lmsMatrix) 33 | 34 | return lms 35 | } 36 | 37 | export function convertLmsToRgb(lms: LMS) { 38 | const lmsMatrix = convertLmsToMatrix(lms) 39 | const rgbMatrix = multiplyMatrix3x3And3x1(lmsToRgbMatrix, lmsMatrix) 40 | const rgb = convertMatrixToRgb(rgbMatrix) 41 | 42 | return rgb 43 | } 44 | 45 | export function convertRgbToMatrix(rgb: RGB) { 46 | return [rgb.r / 255, rgb.g / 255, rgb.b / 255] 47 | } 48 | 49 | export function convertLmsToMatrix(lms: LMS) { 50 | return [lms.l, lms.m, lms.s] 51 | } 52 | 53 | export function convertMatrixToRgb(m: Array): RGB { 54 | return { r: m[0] * 255, g: m[1] * 255, b: m[2] * 255 } 55 | } 56 | 57 | export function convertMatrixToLms(m: Array): LMS { 58 | return { l: m[0], m: m[1], s: m[2] } 59 | } 60 | 61 | export function sanitizeRgb(rgb: RGB): RGB { 62 | return { 63 | r: sanitizeRgbProperty(rgb.r), 64 | g: sanitizeRgbProperty(rgb.g), 65 | b: sanitizeRgbProperty(rgb.b), 66 | } 67 | } 68 | 69 | function sanitizeRgbProperty(v: number) { 70 | return Math.round(Math.min(Math.max(v, 0), 255)) 71 | } 72 | -------------------------------------------------------------------------------- /docs/script.js: -------------------------------------------------------------------------------- 1 | window.addEventListener('load', async () => { 2 | const srcCanvas = document.getElementById('src') 3 | const imgInput = document.getElementById('img-input') 4 | const deficiencySelect = document.getElementById('deficiency') 5 | 6 | imgInput.addEventListener('input', async () => { 7 | const url = URL.createObjectURL(imgInput.files[0]) 8 | await canvasLoadImage(srcCanvas, url) 9 | processImage(deficiencySelect.value) 10 | }) 11 | 12 | deficiencySelect.addEventListener('change', () => { 13 | processImage(deficiencySelect.value) 14 | }) 15 | 16 | await canvasLoadImage(srcCanvas, './ishihara.jpg') 17 | processImage(deficiencySelect.value) 18 | }) 19 | 20 | function processImage(deficiency) { 21 | const srcCanvas = document.getElementById('src') 22 | const distCanvas = document.getElementById('dist') 23 | const srcContext = srcCanvas.getContext('2d') 24 | const distContext = distCanvas.getContext('2d') 25 | 26 | const imageData = srcContext.getImageData( 27 | 0, 28 | 0, 29 | srcCanvas.width, 30 | srcCanvas.height 31 | ) 32 | 33 | const data = imageData.data 34 | 35 | for (let i = 0; i < data.length; i += 4) { 36 | const r = data[i] 37 | const g = data[i + 1] 38 | const b = data[i + 2] 39 | 40 | const simColor = colorblind.simulate({ r, g, b }, deficiency) 41 | 42 | data[i] = simColor.r 43 | data[i + 1] = simColor.g 44 | data[i + 2] = simColor.b 45 | } 46 | 47 | setCanvasSize(distCanvas, srcCanvas.width, srcCanvas.height) 48 | distContext.clearRect(0, 0, distCanvas.width, distCanvas.height) 49 | distContext.putImageData(imageData, 0, 0) 50 | } 51 | 52 | async function loadImage(src) { 53 | return new Promise((resolve, reject) => { 54 | const img = new Image() 55 | img.onload = () => resolve(img) 56 | img.src = src 57 | }) 58 | } 59 | 60 | // Set canvas size but maintain it's original width 61 | function setCanvasSize(canvas, width, height) { 62 | canvas.height = (height / width) * canvas.offsetWidth 63 | } 64 | 65 | async function canvasLoadImage(canvas, src) { 66 | const context = canvas.getContext('2d') 67 | const img = await loadImage(src) 68 | setCanvasSize(canvas, img.naturalWidth, img.naturalHeight) 69 | context.clearRect(0, 0, canvas.width, canvas.height) 70 | context.drawImage(img, 0, 0, canvas.width, canvas.height) 71 | } 72 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Colorblind JS 9 | 10 | 14 | 15 | 16 | 17 |
18 |

Colorblind

19 |
20 |
21 | 25 |
26 |
27 | 30 | 36 |
37 |
38 |
39 |
40 |
Original
41 | 42 |
43 |
44 |
Simulated
45 | 46 |
47 |
48 | Ishihara test image 49 | 54 | 81 | 82 |
83 | 84 | 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Colorblind 2 | 3 | [![package version](https://img.shields.io/npm/v/@bjornlu/colorblind)](https://www.npmjs.com/package/@bjornlu/colorblind) 4 | [![npm downloads](https://img.shields.io/npm/dm/@bjornlu/colorblind)](https://www.npmjs.com/package/@bjornlu/colorblind) 5 | 6 | A zero-dependencies color blindness simulation library. 7 | 8 | It is based on the [color blindness simulation research](https://ixora.io/projects/colorblindness/color-blindness-simulation-research/) and its [Processing library](https://github.com/hx2A/ColorBlindness) by [hx2A](https://github.com/hx2A). 9 | 10 | [**Demo**](https://bluwy.github.io/colorblind) 11 | 12 | ## Install 13 | 14 | ```bash 15 | $ npm install @bjornlu/colorblind 16 | ``` 17 | 18 | or with CDN for direct browser usage, such as: 19 | 20 | ```html 21 | 22 | 23 | 24 | 25 | 26 | ``` 27 | 28 | The CDN version sets a global `colorblind` object, e.g. `colorblind.simulate(...)`. 29 | 30 | ## Usage 31 | 32 | ```js 33 | import { simulate } from '@bjornlu/colorblind' 34 | 35 | simulate({ r: 120, g: 50, b: 30 }, 'protanopia') 36 | // => { r: 62, g: 62, b: 30 } 37 | ``` 38 | 39 | The color deficiency can be set to: 40 | 41 | | Deficiency | Description | 42 | | ----------------- | ----------- | 43 | | `'protanopia'` | No red | 44 | | `'deuteranopia'` | No green | 45 | | `'tritanopia'` | No blue | 46 | | `'achromatopsia'` | No color | 47 | 48 | ## Advanced 49 | 50 | The library also exports two functions: 51 | 52 | 1. `simulateDichromatic(rgb: RGB, simMatrix: Array): RGB` 53 | 2. `simulateMonochromatic(rgb: RGB, simMatrix: Array): RGB` 54 | 55 | You would almost never used this unless you need to perform custom color simulation. 56 | 57 | `simulateDichromatic()` accepts a simulation matrix represented as an array of 9 numbers, while `simulateMonochromatic()` accepts array of 3 numbers. 58 | 59 | Check out the [research](https://ixora.io/projects/colorblindness/color-blindness-simulation-research/) for how to calculate simulation matrices. 60 | 61 | ## Additional Notes 62 | 63 | - The library makes no assumption of the color's gamma, hence gamma correction must be applied or removed manually where needed. 64 | - The algorithm does not use daltonization to calculate the result values. 65 | 66 | ## Contributing 67 | 68 | PRs are welcomed for any typos or documentation issues. Edits on the simulation algorithm must be backed up with research and is preferred to be discussed in an issue first. 69 | 70 | ## Prior Research 71 | 72 | The library was actually planned to be a rewrite of [color-blind](https://github.com/skratchdot/color-blind) to remove the [onecolor](https://github.com/One-com/one-color) dependency and to add typings. In the process of understanding how the code works, I found that the [original reference](https://galactic.ink/sphere/js/Color.Blind.js) was outdated and has a [newer version](https://galactic.ink/labs/Color-Vision/Javascript/Color.Vision.Simulate.js). 73 | 74 | I also found out about the [LMS version](https://galactic.ink/labs/Color-Vision/Javascript/Color.Vision.Daltonize.js) of the daltonize implementation, which happens to be the same technique used in the [color blindness simulation research](https://ixora.io/projects/colorblindness/color-blindness-simulation-research/). The only difference was the simulation matrix used for the color deficiencies and its post color correction calculations. 75 | 76 | I finally decided to follow the algorithm from the research since it's the only source I found that backs up how the values were calculated. So this means that this library does not use daltonization to calculate the colors. 77 | 78 | Since I'm no expert in this field, I would highly appreciate validation on the implementation and whether daltonization would be the better choice. 79 | 80 | ## License 81 | 82 | MIT 83 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | devDependencies: 2 | '@rollup/plugin-typescript': 6.0.0_281a8bb8822fd7dcdaae9096124d239e 3 | '@types/node': 14.14.2 4 | prettier: 2.1.2 5 | rollup: 2.32.1 6 | rollup-plugin-terser: 7.0.2_rollup@2.32.1 7 | ts-node: 9.0.0_typescript@4.0.3 8 | tslib: 2.0.3 9 | typescript: 4.0.3 10 | lockfileVersion: 5.1 11 | packages: 12 | /@babel/code-frame/7.10.4: 13 | dependencies: 14 | '@babel/highlight': 7.10.4 15 | dev: true 16 | resolution: 17 | integrity: sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== 18 | /@babel/helper-validator-identifier/7.10.4: 19 | dev: true 20 | resolution: 21 | integrity: sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== 22 | /@babel/highlight/7.10.4: 23 | dependencies: 24 | '@babel/helper-validator-identifier': 7.10.4 25 | chalk: 2.4.2 26 | js-tokens: 4.0.0 27 | dev: true 28 | resolution: 29 | integrity: sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== 30 | /@rollup/plugin-typescript/6.0.0_281a8bb8822fd7dcdaae9096124d239e: 31 | dependencies: 32 | '@rollup/pluginutils': 3.1.0_rollup@2.32.1 33 | resolve: 1.18.1 34 | rollup: 2.32.1 35 | tslib: 2.0.3 36 | typescript: 4.0.3 37 | dev: true 38 | engines: 39 | node: '>=8.0.0' 40 | peerDependencies: 41 | rollup: ^2.14.0 42 | tslib: '*' 43 | typescript: '>=3.4.0' 44 | resolution: 45 | integrity: sha512-Y5U2L4eaF3wUSgCZRMdvNmuzWkKMyN3OwvhAdbzAi5sUqedaBk/XbzO4T7RlViDJ78MOPhwAIv2FtId/jhMtbg== 46 | /@rollup/pluginutils/3.1.0_rollup@2.32.1: 47 | dependencies: 48 | '@types/estree': 0.0.39 49 | estree-walker: 1.0.1 50 | picomatch: 2.2.2 51 | rollup: 2.32.1 52 | dev: true 53 | engines: 54 | node: '>= 8.0.0' 55 | peerDependencies: 56 | rollup: ^1.20.0||^2.0.0 57 | resolution: 58 | integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== 59 | /@types/estree/0.0.39: 60 | dev: true 61 | resolution: 62 | integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== 63 | /@types/node/14.14.2: 64 | dev: true 65 | resolution: 66 | integrity: sha512-jeYJU2kl7hL9U5xuI/BhKPZ4vqGM/OmK6whiFAXVhlstzZhVamWhDSmHyGLIp+RVyuF9/d0dqr2P85aFj4BvJg== 67 | /ansi-styles/3.2.1: 68 | dependencies: 69 | color-convert: 1.9.3 70 | dev: true 71 | engines: 72 | node: '>=4' 73 | resolution: 74 | integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 75 | /arg/4.1.3: 76 | dev: true 77 | resolution: 78 | integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== 79 | /buffer-from/1.1.1: 80 | dev: true 81 | resolution: 82 | integrity: sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== 83 | /chalk/2.4.2: 84 | dependencies: 85 | ansi-styles: 3.2.1 86 | escape-string-regexp: 1.0.5 87 | supports-color: 5.5.0 88 | dev: true 89 | engines: 90 | node: '>=4' 91 | resolution: 92 | integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 93 | /color-convert/1.9.3: 94 | dependencies: 95 | color-name: 1.1.3 96 | dev: true 97 | resolution: 98 | integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 99 | /color-name/1.1.3: 100 | dev: true 101 | resolution: 102 | integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 103 | /commander/2.20.3: 104 | dev: true 105 | resolution: 106 | integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 107 | /diff/4.0.2: 108 | dev: true 109 | engines: 110 | node: '>=0.3.1' 111 | resolution: 112 | integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== 113 | /escape-string-regexp/1.0.5: 114 | dev: true 115 | engines: 116 | node: '>=0.8.0' 117 | resolution: 118 | integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 119 | /estree-walker/1.0.1: 120 | dev: true 121 | resolution: 122 | integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== 123 | /fsevents/2.1.3: 124 | dev: true 125 | engines: 126 | node: ^8.16.0 || ^10.6.0 || >=11.0.0 127 | optional: true 128 | os: 129 | - darwin 130 | resolution: 131 | integrity: sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== 132 | /function-bind/1.1.1: 133 | dev: true 134 | resolution: 135 | integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 136 | /has-flag/3.0.0: 137 | dev: true 138 | engines: 139 | node: '>=4' 140 | resolution: 141 | integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 142 | /has-flag/4.0.0: 143 | dev: true 144 | engines: 145 | node: '>=8' 146 | resolution: 147 | integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 148 | /has/1.0.3: 149 | dependencies: 150 | function-bind: 1.1.1 151 | dev: true 152 | engines: 153 | node: '>= 0.4.0' 154 | resolution: 155 | integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 156 | /is-core-module/2.0.0: 157 | dependencies: 158 | has: 1.0.3 159 | dev: true 160 | resolution: 161 | integrity: sha512-jq1AH6C8MuteOoBPwkxHafmByhL9j5q4OaPGdbuD+ZtQJVzH+i6E3BJDQcBA09k57i2Hh2yQbEG8yObZ0jdlWw== 162 | /jest-worker/26.5.0: 163 | dependencies: 164 | '@types/node': 14.14.2 165 | merge-stream: 2.0.0 166 | supports-color: 7.2.0 167 | dev: true 168 | engines: 169 | node: '>= 10.13.0' 170 | resolution: 171 | integrity: sha512-kTw66Dn4ZX7WpjZ7T/SUDgRhapFRKWmisVAF0Rv4Fu8SLFD7eLbqpLvbxVqYhSgaWa7I+bW7pHnbyfNsH6stug== 172 | /js-tokens/4.0.0: 173 | dev: true 174 | resolution: 175 | integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== 176 | /make-error/1.3.6: 177 | dev: true 178 | resolution: 179 | integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== 180 | /merge-stream/2.0.0: 181 | dev: true 182 | resolution: 183 | integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== 184 | /path-parse/1.0.6: 185 | dev: true 186 | resolution: 187 | integrity: sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== 188 | /picomatch/2.2.2: 189 | dev: true 190 | engines: 191 | node: '>=8.6' 192 | resolution: 193 | integrity: sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== 194 | /prettier/2.1.2: 195 | dev: true 196 | engines: 197 | node: '>=10.13.0' 198 | hasBin: true 199 | resolution: 200 | integrity: sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg== 201 | /randombytes/2.1.0: 202 | dependencies: 203 | safe-buffer: 5.2.1 204 | dev: true 205 | resolution: 206 | integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== 207 | /resolve/1.18.1: 208 | dependencies: 209 | is-core-module: 2.0.0 210 | path-parse: 1.0.6 211 | dev: true 212 | resolution: 213 | integrity: sha512-lDfCPaMKfOJXjy0dPayzPdF1phampNWr3qFCjAu+rw/qbQmr5jWH5xN2hwh9QKfw9E5v4hwV7A+jrCmL8yjjqA== 214 | /rollup-plugin-terser/7.0.2_rollup@2.32.1: 215 | dependencies: 216 | '@babel/code-frame': 7.10.4 217 | jest-worker: 26.5.0 218 | rollup: 2.32.1 219 | serialize-javascript: 4.0.0 220 | terser: 5.3.7 221 | dev: true 222 | peerDependencies: 223 | rollup: ^2.0.0 224 | resolution: 225 | integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== 226 | /rollup/2.32.1: 227 | dev: true 228 | engines: 229 | node: '>=10.0.0' 230 | hasBin: true 231 | optionalDependencies: 232 | fsevents: 2.1.3 233 | resolution: 234 | integrity: sha512-Op2vWTpvK7t6/Qnm1TTh7VjEZZkN8RWgf0DHbkKzQBwNf748YhXbozHVefqpPp/Fuyk/PQPAnYsBxAEtlMvpUw== 235 | /safe-buffer/5.2.1: 236 | dev: true 237 | resolution: 238 | integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 239 | /serialize-javascript/4.0.0: 240 | dependencies: 241 | randombytes: 2.1.0 242 | dev: true 243 | resolution: 244 | integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== 245 | /source-map-support/0.5.19: 246 | dependencies: 247 | buffer-from: 1.1.1 248 | source-map: 0.6.1 249 | dev: true 250 | resolution: 251 | integrity: sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== 252 | /source-map/0.6.1: 253 | dev: true 254 | engines: 255 | node: '>=0.10.0' 256 | resolution: 257 | integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 258 | /source-map/0.7.3: 259 | dev: true 260 | engines: 261 | node: '>= 8' 262 | resolution: 263 | integrity: sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== 264 | /supports-color/5.5.0: 265 | dependencies: 266 | has-flag: 3.0.0 267 | dev: true 268 | engines: 269 | node: '>=4' 270 | resolution: 271 | integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 272 | /supports-color/7.2.0: 273 | dependencies: 274 | has-flag: 4.0.0 275 | dev: true 276 | engines: 277 | node: '>=8' 278 | resolution: 279 | integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 280 | /terser/5.3.7: 281 | dependencies: 282 | commander: 2.20.3 283 | source-map: 0.7.3 284 | source-map-support: 0.5.19 285 | dev: true 286 | engines: 287 | node: ^10.0.0 || ^11.0.0 || ^12.0.0 || >=14.0.0 288 | hasBin: true 289 | resolution: 290 | integrity: sha512-lJbKdfxWvjpV330U4PBZStCT9h3N9A4zZVA5Y4k9sCWXknrpdyxi1oMsRKLmQ/YDMDxSBKIh88v0SkdhdqX06w== 291 | /ts-node/9.0.0_typescript@4.0.3: 292 | dependencies: 293 | arg: 4.1.3 294 | diff: 4.0.2 295 | make-error: 1.3.6 296 | source-map-support: 0.5.19 297 | typescript: 4.0.3 298 | yn: 3.1.1 299 | dev: true 300 | engines: 301 | node: '>=10.0.0' 302 | hasBin: true 303 | peerDependencies: 304 | typescript: '>=2.7' 305 | resolution: 306 | integrity: sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg== 307 | /tslib/2.0.3: 308 | dev: true 309 | resolution: 310 | integrity: sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ== 311 | /typescript/4.0.3: 312 | dev: true 313 | engines: 314 | node: '>=4.2.0' 315 | hasBin: true 316 | resolution: 317 | integrity: sha512-tEu6DGxGgRJPb/mVPIZ48e69xCn2yRmCgYmDugAVwmJ6o+0u1RI18eO7E7WBTLYLaEVVOhwQmcdhQHweux/WPg== 318 | /yn/3.1.1: 319 | dev: true 320 | engines: 321 | node: '>=6' 322 | resolution: 323 | integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== 324 | specifiers: 325 | '@rollup/plugin-typescript': ^6.0.0 326 | '@types/node': ^14.14.2 327 | prettier: ^2.1.2 328 | rollup: ^2.32.1 329 | rollup-plugin-terser: ^7.0.2 330 | ts-node: ^9.0.0 331 | tslib: ^2.0.3 332 | typescript: ^4.0.3 333 | --------------------------------------------------------------------------------