From 5cab0b26694960a1b5d49a52c9b54d85b4498beb Mon Sep 17 00:00:00 2001 From: mineejo Date: Sat, 11 Nov 2023 14:37:41 +0300 Subject: [PATCH] chore: initial commit --- .github/workflows/ci.yml | 24 + .gitignore | 1 + .idea/.gitignore | 5 + .idea/codeStyles/codeStyleConfig.xml | 5 + .idea/color.iml | 12 + .idea/copyright/mit_license.xml | 6 + .idea/copyright/profiles_settings.xml | 10 + .idea/deno.xml | 7 + .idea/dictionaries/mineejo.xml | 8 + .../inspectionProfiles/profiles_settings.xml | 7 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + .idea/watcherTasks.xml | 145 ++ LICENSE | 21 + README.md | 34 + _build_npm.ts | 42 + advanced_color.ts | 131 ++ advanced_color_test.ts | 145 ++ color.ts | 49 + color/mod.ts | 4 + color/rgb.ts | 9 + color/rgb_color_wheel.ts | 1537 +++++++++++++++++ color_component.ts | 18 + color_effects/discolor.ts | 24 + color_effects/discolor_test.ts | 21 + color_effects/invert_color.ts | 22 + color_effects/invert_color_test.ts | 19 + color_effects/mix_colors.ts | 35 + color_effects/mix_colors_test.ts | 42 + color_effects/mod.ts | 7 + color_effects/subtract_colors.ts | 23 + color_effects/subtract_colors_test.ts | 13 + color_effects/summarize_colors.ts | 23 + color_effects/summarize_colors_test.ts | 17 + color_info.ts | 48 + color_info_test.ts | 12 + color_test.ts | 31 + deno.jsonc | 17 + deno.lock | 111 ++ deps.ts | 3 + dev_deps.ts | 3 + mod.ts | 7 + util.ts | 5 + 43 files changed, 2717 insertions(+) create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 .idea/.gitignore create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/color.iml create mode 100644 .idea/copyright/mit_license.xml create mode 100644 .idea/copyright/profiles_settings.xml create mode 100644 .idea/deno.xml create mode 100644 .idea/dictionaries/mineejo.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 .idea/watcherTasks.xml create mode 100644 LICENSE create mode 100644 README.md create mode 100644 _build_npm.ts create mode 100644 advanced_color.ts create mode 100644 advanced_color_test.ts create mode 100644 color.ts create mode 100644 color/mod.ts create mode 100644 color/rgb.ts create mode 100644 color/rgb_color_wheel.ts create mode 100644 color_component.ts create mode 100644 color_effects/discolor.ts create mode 100644 color_effects/discolor_test.ts create mode 100644 color_effects/invert_color.ts create mode 100644 color_effects/invert_color_test.ts create mode 100644 color_effects/mix_colors.ts create mode 100644 color_effects/mix_colors_test.ts create mode 100644 color_effects/mod.ts create mode 100644 color_effects/subtract_colors.ts create mode 100644 color_effects/subtract_colors_test.ts create mode 100644 color_effects/summarize_colors.ts create mode 100644 color_effects/summarize_colors_test.ts create mode 100644 color_info.ts create mode 100644 color_info_test.ts create mode 100644 color_test.ts create mode 100644 deno.jsonc create mode 100644 deno.lock create mode 100644 deps.ts create mode 100644 dev_deps.ts create mode 100644 mod.ts create mode 100644 util.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..b14ce9a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,24 @@ +name: ci + +on: [ push, pull_request ] + +jobs: + checks: + runs-on: ubuntu-latest + steps: + - name: clone repository + uses: actions/checkout@v3 + + - name: install deno + uses: denoland/setup-deno@v1 + with: + deno-version: 1.X + + - name: check format + run: deno fmt --check + + - name: check linting + run: deno lint + + - name: run tests + run: deno test diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6450084 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.npm diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..b58b603 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/color.iml b/.idea/color.iml new file mode 100644 index 0000000..24643cc --- /dev/null +++ b/.idea/color.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/copyright/mit_license.xml b/.idea/copyright/mit_license.xml new file mode 100644 index 0000000..4f96546 --- /dev/null +++ b/.idea/copyright/mit_license.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000..d984029 --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/deno.xml b/.idea/deno.xml new file mode 100644 index 0000000..3b8a686 --- /dev/null +++ b/.idea/deno.xml @@ -0,0 +1,7 @@ + + + + + diff --git a/.idea/dictionaries/mineejo.xml b/.idea/dictionaries/mineejo.xml new file mode 100644 index 0000000..60d3b69 --- /dev/null +++ b/.idea/dictionaries/mineejo.xml @@ -0,0 +1,8 @@ + + + + chalkpot + mineejo + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..dd4c951 --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..3743e72 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/watcherTasks.xml b/.idea/watcherTasks.xml new file mode 100644 index 0000000..ed877ef --- /dev/null +++ b/.idea/watcherTasks.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c1ad1e7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 mineejo + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..58c0e38 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +# Color + +Color is a tool for creating [RGB] color by range and by HSL without leaving RGB +space. With `additional tools`, `unlimited development` and `no dependencies`. + +[Read documentation, API...] + +[RGB]: https://en.wikipedia.org/wiki/RGB_color_model +[Read documentation, API...]: https://deno.land/x/chalkpot_color/mod.ts + +## Installation + +`CommonJS` (script directory) and `ModuleJS` (esm directory) support for +`Node.js`, see [NPM page] for installation command. Also support for `Yarn` and +other package managers or CDNs like `UNPKG`. For `Deno` reference see +[module page], or use CDN like `esm.sh`. + +[NPM page]: https://www.npmjs.com/package/@chalkpot/color +[module page]: https://deno.land/x/chalkpot_color + +## Related + +- [colors](https://github.com/chalkpot/colors) - Colors is JSON with the names + of colors, their values and localization. Colors are based on HTML color names + and CSS keywords. + +## Contributing + +Pull requests are welcome. For major changes, please open an issue first to +discuss what you would like to change. + +## License + +[MIT](https://choosealicense.com/licenses/mit/) diff --git a/_build_npm.ts b/_build_npm.ts new file mode 100644 index 0000000..45eee8c --- /dev/null +++ b/_build_npm.ts @@ -0,0 +1,42 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { build, emptyDir } from "https://deno.land/x/dnt@0.38.1/mod.ts"; + +const outDir = "./.npm"; + +await emptyDir(outDir); + +await build({ + entryPoints: ["./mod.ts"], + outDir: outDir, + shims: { + deno: true, + }, + test: true, + package: { + name: "@chalkpot/color", + version: Deno.args[0], + description: + "Color is a tool for creating [RGB] color by range and by HSL without leaving RGB space.", + author: "mineejo", + license: "MIT", + homepage: "https://github.com/chalkpot/color#readme", + repository: { + type: "git", + url: "git+https://github.com/chalkpot/color.git", + }, + bugs: { + url: "https://github.com/chalkpot/color/issues", + }, + keywords: [ + "chalkpot", + "color", + "rgb", + "hsl", + ], + }, + postBuild() { + Deno.copyFileSync("LICENSE", `${outDir}/LICENSE`); + Deno.copyFileSync("README.md", `${outDir}/README.md`); + }, +}); diff --git a/advanced_color.ts b/advanced_color.ts new file mode 100644 index 0000000..2f305ae --- /dev/null +++ b/advanced_color.ts @@ -0,0 +1,131 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { Color } from "./color.ts"; +import { Rgb } from "./color/mod.ts"; +import { mixColors } from "./color_effects/mod.ts"; +import { percent } from "./util.ts"; +import { rgbColorWheel } from "./color/rgb_color_wheel.ts"; + +/** + * AdvancedColor is an advanced [RGB] color. + * Like regular `Color`, it mimics the [HSL] model. + * + * [RGB]: https://en.wikipedia.org/wiki/RGB_color_model + * [HSL]: https://en.wikipedia.org/wiki/HSL_and_HSV + * + * ### Example + * + * ```ts + * const darkGreen = new AdvancedColor(33.33, undefined, 25); + * console.log(darkGreen.components); // [0, 127.8, 0] + * + * const paleRed = new AdvancedColor(100, 70, 80); + * console.log(paleRed.components); // [255, 173.3, 173.3] + * ``` + */ +export class AdvancedColor { + public readonly hue: number = 0; + public readonly saturation: number = 0; + public readonly lightness: number = 0; + public readonly red: number = 0; + public readonly green: number = 0; + public readonly blue: number = 0; + public readonly components: Rgb = [0, 0, 0]; + + private hueColor: Color = new Color(false, ...this.components); + private saturationColor: Color = new Color(false, ...this.components); + private lightnessColor: Color = new Color(false, ...this.components); + + /** + * @param hue + * Percentage value of the color wheel from `0` to `100`: + * - Red: `0`; + * - Green: `33.33`; + * - Blue: `66.66`; + * - Red: `100`; + * + * @param saturation + * Percentage value from `0` to `100`: + * - Colorless (grey color): `0`; + * - Hue color: `100`; + * + * @param lightness + * Percentage value from `0` to `100`: + * - Black: `0`; + * - Hue color: `50`; + * - White: `100`; + */ + public constructor( + hue: number, + saturation?: number | undefined, + lightness?: number | undefined, + ) { + this.hue = percent(hue); + this.addHueColor(); + + if (saturation !== undefined) { + this.saturation = percent(saturation); + this.createSaturationColor(); + } + + if (lightness !== undefined) { + this.lightness = percent(lightness); + this.createLightnessColor(); + } + + this.components = this._rgbColor.components; + this.red = this._rgbColor.red; + this.green = this._rgbColor.green; + this.blue = this._rgbColor.blue; + } + + private _rgbColor: Color = new Color(false, ...this.components); + + get rgbColor(): Color { + return this._rgbColor; + } + + private createLightnessColor(): void { + const lightnessValue: number = this.lightness - 0.1; + const ratio: number = (lightnessValue - 30.2) / (100 - 30.2); + const lightness: number = 255 / (100 / (ratio * 140)); + + const newComponents: Rgb = this._rgbColor.components.map( + (component: number) => component - (100 - lightness), + ) as Rgb; + + this.lightnessColor = new Color(false, ...newComponents); + this._rgbColor = this.lightnessColor; + } + + private createSaturationColor(): void { + const saturation: number = ( + this._rgbColor.red + + this._rgbColor.green + + this._rgbColor.blue + ) / 4; + + const color: Color = new Color(false, saturation, saturation, saturation); + const saturationValue: number = this.saturation; + + this.saturationColor = mixColors( + this.hueColor, + color, + 100 - saturationValue, + ); + + this._rgbColor = this.saturationColor; + } + + private addHueColor(): void { + const hueValue: number = this.hue; + + const colorIndex: number = Math.min( + Math.max(rgbColorWheel.length * (hueValue / 100), 0), + rgbColorWheel.length - 1, + ); + + this.hueColor = new Color(false, ...rgbColorWheel[Math.floor(colorIndex)]); + this._rgbColor = this.hueColor; + } +} diff --git a/advanced_color_test.ts b/advanced_color_test.ts new file mode 100644 index 0000000..5a910a9 --- /dev/null +++ b/advanced_color_test.ts @@ -0,0 +1,145 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { assertEquals } from "./dev_deps.ts"; +import { AdvancedColor } from "./advanced_color.ts"; +import { Rgb } from "./color/mod.ts"; +import { Color } from "./color.ts"; + +export function truncComponents(color: AdvancedColor | Color): Rgb { + const [_red, _green, _blue]: Rgb = color.components; + return [Math.trunc(_red), Math.trunc(_green), Math.trunc(_blue)]; +} + +Deno.test("class contains correct fields", async (t) => { + const red = 31; + const green = 10; + const blue = 0; + + const hue = 10; + const saturation = 20; + const lightness = 30; + + const color: AdvancedColor = new AdvancedColor(hue, saturation, lightness); + + assertEquals(Math.trunc(color.red), red, `"color.red"`); + assertEquals(Math.trunc(color.green), green, `"color.green"`); + assertEquals(Math.trunc(color.blue), blue, `"color.blue"`); + + assertEquals(color.hue, hue, `"color.hue"`); + assertEquals(color.saturation, saturation, `"color.saturation"`); + assertEquals(color.lightness, lightness, `"color.lightness"`); + + await t.step("dependent field contains correct values", () => { + assertEquals( + truncComponents(color.rgbColor), + [red, green, blue], + `"color.rgbColor"`, + ); + + assertEquals( + truncComponents(color), + [red, green, blue], + `"color"`, + ); + }); +}); + +Deno.test("HSL conversion of red, green and blue correct", async (t) => { + const red: Rgb = [255, 0, 0]; + const green: Rgb = [0, 255, 0]; + const blue: Rgb = [0, 0, 255]; + + const hue: AdvancedColor = new AdvancedColor(0); + assertEquals(truncComponents(hue), red, `"hue"`); + + await t.step("no lightness or saturation values do not change hue", () => { + const hueSaturation: AdvancedColor = new AdvancedColor(0, 100); + assertEquals(truncComponents(hueSaturation), red, `"hueSaturation"`); + + const hueLightness: AdvancedColor = new AdvancedColor(0, undefined, 50); + assertEquals(truncComponents(hueLightness), red, `"hueLightness"`); + }); + + await t.step("default values do not change hue", () => { + const hueSaturationLightness: AdvancedColor = new AdvancedColor(0, 100, 50); + assertEquals( + truncComponents(hueSaturationLightness), + red, + `"hueSaturationLightness"`, + ); + }); + + await t.step("hue range correct", () => { + const startRedColor: AdvancedColor = new AdvancedColor(0); + assertEquals(truncComponents(startRedColor), red, `"startRedColor"`); + + const greenColor: AdvancedColor = new AdvancedColor(33.33); + assertEquals(truncComponents(greenColor), green, `"greenColor"`); + + const blueColor: AdvancedColor = new AdvancedColor(66.66); + assertEquals(truncComponents(blueColor), blue, `"blueColor"`); + + const endRedColor: AdvancedColor = new AdvancedColor(100); + assertEquals(truncComponents(endRedColor), red, `"endRedColor"`); + }); + + await t.step("saturation range correct", () => { + const redSaturated: Rgb = [255, 0, 0]; + const saturatedColor: AdvancedColor = new AdvancedColor(0, 100); + assertEquals( + truncComponents(saturatedColor), + redSaturated, + `"saturatedColor"`, + ); + + const redUnsaturated: Rgb = [63, 63, 63]; + const unsaturatedColor: AdvancedColor = new AdvancedColor(0, 0); + assertEquals( + truncComponents(unsaturatedColor), + redUnsaturated, + `"unsaturatedColor"`, + ); + }); + + await t.step("lightness range correct", () => { + const black: Rgb = [0, 0, 0]; + const blackColor: AdvancedColor = new AdvancedColor(0, undefined, 0); + assertEquals( + truncComponents(blackColor), + black, + `"blackColor"`, + ); + + const white: Rgb = [255, 255, 255]; + const whiteColor: AdvancedColor = new AdvancedColor(0, undefined, 100); + assertEquals( + truncComponents(whiteColor), + white, + `"whiteColor"`, + ); + }); +}); + +for (let i = 0; i < 100; i++) { + const hue = new AdvancedColor(i, 100).components.toString() + .replace(/,/g, ";") + .replace(/\.\d+/gm, ""); + + const saturation = new AdvancedColor(i, 0).components.toString() + .replace(/,/g, ";") + .replace(/\.\d+/gm, ""); + + const lighntess = new AdvancedColor(i, undefined, 80).components.toString() + .replace(/,/g, ";") + .replace(/\.\d+/gm, ""); + + console.log( + `${i}.`.padEnd(4), + `[${hue}]`.padEnd(11), + `[${saturation}]`.padEnd(13), + `[${lighntess}]:`.padEnd(14), + `\x1b[48;2;${hue}m \x1b[0m`, + `\x1b[48;2;${saturation}m \x1b[0m`, + `\x1b[48;2;${lighntess}m \x1b[0m`, + ); +} diff --git a/color.ts b/color.ts new file mode 100644 index 0000000..66cb1d3 --- /dev/null +++ b/color.ts @@ -0,0 +1,49 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { ColorComponent } from "./color_component.ts"; +import { Rgb } from "./color/mod.ts"; +import { percent } from "./util.ts"; + +/** + * [Color] contains the components, red, green, blue. + * + * [Color]: https://en.wikipedia.org/wiki/RGB_color_model + * + * ### Example + * + * ```ts + * const red = new Color(false, 255, 0, 0) + * const blue = new Color(true, 0, 0, 100); + * ``` + */ +export class Color { + public readonly components: Rgb = [0, 0, 0]; + public readonly red: number = 0; + public readonly green: number = 0; + public readonly blue: number = 0; + + /** + * @param percentage + * Use percentages instead of component range, if true. + * + * @param components + */ + public constructor(percentage: boolean = false, ...components: Rgb) { + const [red, green, blue]: Rgb = percentage + ? this.rgbPercent(...components) + : components; + + this.red = new ColorComponent(red).lightness; + this.green = new ColorComponent(green).lightness; + this.blue = new ColorComponent(blue).lightness; + this.components = [this.red, this.green, this.blue]; + } + + private rgbPercent(...components: Rgb): Rgb { + return [ + (percent(components[0]) / 100) * 255, + (percent(components[1]) / 100) * 255, + (percent(components[2]) / 100) * 255, + ]; + } +} diff --git a/color/mod.ts b/color/mod.ts new file mode 100644 index 0000000..7cd193d --- /dev/null +++ b/color/mod.ts @@ -0,0 +1,4 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +export { rgbColorWheel } from "./rgb_color_wheel.ts"; +export type { Rgb } from "./rgb.ts"; diff --git a/color/rgb.ts b/color/rgb.ts new file mode 100644 index 0000000..e75beb7 --- /dev/null +++ b/color/rgb.ts @@ -0,0 +1,9 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +/** + * The alias describing three colors is [RGB], + * each of which is a component. + * + * [RGB]: https://en.wikipedia.org/wiki/RGB_color_model + */ +export type Rgb = [number, number, number]; diff --git a/color/rgb_color_wheel.ts b/color/rgb_color_wheel.ts new file mode 100644 index 0000000..5229fbb --- /dev/null +++ b/color/rgb_color_wheel.ts @@ -0,0 +1,1537 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { Rgb } from "./rgb.ts"; + +export const rgbColorWheel: Rgb[] = [ + [255, 0, 0], + [255, 1, 0], + [255, 2, 0], + [255, 3, 0], + [255, 4, 0], + [255, 5, 0], + [255, 6, 0], + [255, 7, 0], + [255, 8, 0], + [255, 9, 0], + [255, 10, 0], + [255, 11, 0], + [255, 12, 0], + [255, 13, 0], + [255, 14, 0], + [255, 15, 0], + [255, 16, 0], + [255, 17, 0], + [255, 18, 0], + [255, 19, 0], + [255, 20, 0], + [255, 21, 0], + [255, 22, 0], + [255, 23, 0], + [255, 24, 0], + [255, 25, 0], + [255, 26, 0], + [255, 27, 0], + [255, 28, 0], + [255, 29, 0], + [255, 30, 0], + [255, 31, 0], + [255, 32, 0], + [255, 33, 0], + [255, 34, 0], + [255, 35, 0], + [255, 36, 0], + [255, 37, 0], + [255, 38, 0], + [255, 39, 0], + [255, 40, 0], + [255, 41, 0], + [255, 42, 0], + [255, 43, 0], + [255, 44, 0], + [255, 45, 0], + [255, 46, 0], + [255, 47, 0], + [255, 48, 0], + [255, 49, 0], + [255, 50, 0], + [255, 51, 0], + [255, 52, 0], + [255, 53, 0], + [255, 54, 0], + [255, 55, 0], + [255, 56, 0], + [255, 57, 0], + [255, 58, 0], + [255, 59, 0], + [255, 60, 0], + [255, 61, 0], + [255, 62, 0], + [255, 63, 0], + [255, 64, 0], + [255, 65, 0], + [255, 66, 0], + [255, 67, 0], + [255, 68, 0], + [255, 69, 0], + [255, 70, 0], + [255, 71, 0], + [255, 72, 0], + [255, 73, 0], + [255, 74, 0], + [255, 75, 0], + [255, 76, 0], + [255, 77, 0], + [255, 78, 0], + [255, 79, 0], + [255, 80, 0], + [255, 81, 0], + [255, 82, 0], + [255, 83, 0], + [255, 84, 0], + [255, 85, 0], + [255, 86, 0], + [255, 87, 0], + [255, 88, 0], + [255, 89, 0], + [255, 90, 0], + [255, 91, 0], + [255, 92, 0], + [255, 93, 0], + [255, 94, 0], + [255, 95, 0], + [255, 96, 0], + [255, 97, 0], + [255, 98, 0], + [255, 99, 0], + [255, 100, 0], + [255, 101, 0], + [255, 102, 0], + [255, 103, 0], + [255, 104, 0], + [255, 105, 0], + [255, 106, 0], + [255, 107, 0], + [255, 108, 0], + [255, 109, 0], + [255, 110, 0], + [255, 111, 0], + [255, 112, 0], + [255, 113, 0], + [255, 114, 0], + [255, 115, 0], + [255, 116, 0], + [255, 117, 0], + [255, 118, 0], + [255, 119, 0], + [255, 120, 0], + [255, 121, 0], + [255, 122, 0], + [255, 123, 0], + [255, 124, 0], + [255, 125, 0], + [255, 126, 0], + [255, 127, 0], + [255, 128, 0], + [255, 129, 0], + [255, 130, 0], + [255, 131, 0], + [255, 132, 0], + [255, 133, 0], + [255, 134, 0], + [255, 135, 0], + [255, 136, 0], + [255, 137, 0], + [255, 138, 0], + [255, 139, 0], + [255, 140, 0], + [255, 141, 0], + [255, 142, 0], + [255, 143, 0], + [255, 144, 0], + [255, 145, 0], + [255, 146, 0], + [255, 147, 0], + [255, 148, 0], + [255, 149, 0], + [255, 150, 0], + [255, 151, 0], + [255, 152, 0], + [255, 153, 0], + [255, 154, 0], + [255, 155, 0], + [255, 156, 0], + [255, 157, 0], + [255, 158, 0], + [255, 159, 0], + [255, 160, 0], + [255, 161, 0], + [255, 162, 0], + [255, 163, 0], + [255, 164, 0], + [255, 165, 0], + [255, 166, 0], + [255, 167, 0], + [255, 168, 0], + [255, 169, 0], + [255, 170, 0], + [255, 171, 0], + [255, 172, 0], + [255, 173, 0], + [255, 174, 0], + [255, 175, 0], + [255, 176, 0], + [255, 177, 0], + [255, 178, 0], + [255, 179, 0], + [255, 180, 0], + [255, 181, 0], + [255, 182, 0], + [255, 183, 0], + [255, 184, 0], + [255, 185, 0], + [255, 186, 0], + [255, 187, 0], + [255, 188, 0], + [255, 189, 0], + [255, 190, 0], + [255, 191, 0], + [255, 192, 0], + [255, 193, 0], + [255, 194, 0], + [255, 195, 0], + [255, 196, 0], + [255, 197, 0], + [255, 198, 0], + [255, 199, 0], + [255, 200, 0], + [255, 201, 0], + [255, 202, 0], + [255, 203, 0], + [255, 204, 0], + [255, 205, 0], + [255, 206, 0], + [255, 207, 0], + [255, 208, 0], + [255, 209, 0], + [255, 210, 0], + [255, 211, 0], + [255, 212, 0], + [255, 213, 0], + [255, 214, 0], + [255, 215, 0], + [255, 216, 0], + [255, 217, 0], + [255, 218, 0], + [255, 219, 0], + [255, 220, 0], + [255, 221, 0], + [255, 222, 0], + [255, 223, 0], + [255, 224, 0], + [255, 225, 0], + [255, 226, 0], + [255, 227, 0], + [255, 228, 0], + [255, 229, 0], + [255, 230, 0], + [255, 231, 0], + [255, 232, 0], + [255, 233, 0], + [255, 234, 0], + [255, 235, 0], + [255, 236, 0], + [255, 237, 0], + [255, 238, 0], + [255, 239, 0], + [255, 240, 0], + [255, 241, 0], + [255, 242, 0], + [255, 243, 0], + [255, 244, 0], + [255, 245, 0], + [255, 246, 0], + [255, 247, 0], + [255, 248, 0], + [255, 249, 0], + [255, 250, 0], + [255, 251, 0], + [255, 252, 0], + [255, 253, 0], + [255, 254, 0], + [255, 255, 0], + [254, 255, 0], + [253, 255, 0], + [252, 255, 0], + [251, 255, 0], + [250, 255, 0], + [249, 255, 0], + [248, 255, 0], + [247, 255, 0], + [246, 255, 0], + [245, 255, 0], + [244, 255, 0], + [243, 255, 0], + [242, 255, 0], + [241, 255, 0], + [240, 255, 0], + [239, 255, 0], + [238, 255, 0], + [237, 255, 0], + [236, 255, 0], + [235, 255, 0], + [234, 255, 0], + [233, 255, 0], + [232, 255, 0], + [231, 255, 0], + [230, 255, 0], + [229, 255, 0], + [228, 255, 0], + [227, 255, 0], + [226, 255, 0], + [225, 255, 0], + [224, 255, 0], + [223, 255, 0], + [222, 255, 0], + [221, 255, 0], + [220, 255, 0], + [219, 255, 0], + [218, 255, 0], + [217, 255, 0], + [216, 255, 0], + [215, 255, 0], + [214, 255, 0], + [213, 255, 0], + [212, 255, 0], + [211, 255, 0], + [210, 255, 0], + [209, 255, 0], + [208, 255, 0], + [207, 255, 0], + [206, 255, 0], + [205, 255, 0], + [204, 255, 0], + [203, 255, 0], + [202, 255, 0], + [201, 255, 0], + [200, 255, 0], + [199, 255, 0], + [198, 255, 0], + [197, 255, 0], + [196, 255, 0], + [195, 255, 0], + [194, 255, 0], + [193, 255, 0], + [192, 255, 0], + [191, 255, 0], + [190, 255, 0], + [189, 255, 0], + [188, 255, 0], + [187, 255, 0], + [186, 255, 0], + [185, 255, 0], + [184, 255, 0], + [183, 255, 0], + [182, 255, 0], + [181, 255, 0], + [180, 255, 0], + [179, 255, 0], + [178, 255, 0], + [177, 255, 0], + [176, 255, 0], + [175, 255, 0], + [174, 255, 0], + [173, 255, 0], + [172, 255, 0], + [171, 255, 0], + [170, 255, 0], + [169, 255, 0], + [168, 255, 0], + [167, 255, 0], + [166, 255, 0], + [165, 255, 0], + [164, 255, 0], + [163, 255, 0], + [162, 255, 0], + [161, 255, 0], + [160, 255, 0], + [159, 255, 0], + [158, 255, 0], + [157, 255, 0], + [156, 255, 0], + [155, 255, 0], + [154, 255, 0], + [153, 255, 0], + [152, 255, 0], + [151, 255, 0], + [150, 255, 0], + [149, 255, 0], + [148, 255, 0], + [147, 255, 0], + [146, 255, 0], + [145, 255, 0], + [144, 255, 0], + [143, 255, 0], + [142, 255, 0], + [141, 255, 0], + [140, 255, 0], + [139, 255, 0], + [138, 255, 0], + [137, 255, 0], + [136, 255, 0], + [135, 255, 0], + [134, 255, 0], + [133, 255, 0], + [132, 255, 0], + [131, 255, 0], + [130, 255, 0], + [129, 255, 0], + [128, 255, 0], + [127, 255, 0], + [126, 255, 0], + [125, 255, 0], + [124, 255, 0], + [123, 255, 0], + [122, 255, 0], + [121, 255, 0], + [120, 255, 0], + [119, 255, 0], + [118, 255, 0], + [117, 255, 0], + [116, 255, 0], + [115, 255, 0], + [114, 255, 0], + [113, 255, 0], + [112, 255, 0], + [111, 255, 0], + [110, 255, 0], + [109, 255, 0], + [108, 255, 0], + [107, 255, 0], + [106, 255, 0], + [105, 255, 0], + [104, 255, 0], + [103, 255, 0], + [102, 255, 0], + [101, 255, 0], + [100, 255, 0], + [99, 255, 0], + [98, 255, 0], + [97, 255, 0], + [96, 255, 0], + [95, 255, 0], + [94, 255, 0], + [93, 255, 0], + [92, 255, 0], + [91, 255, 0], + [90, 255, 0], + [89, 255, 0], + [88, 255, 0], + [87, 255, 0], + [86, 255, 0], + [85, 255, 0], + [84, 255, 0], + [83, 255, 0], + [82, 255, 0], + [81, 255, 0], + [80, 255, 0], + [79, 255, 0], + [78, 255, 0], + [77, 255, 0], + [76, 255, 0], + [75, 255, 0], + [74, 255, 0], + [73, 255, 0], + [72, 255, 0], + [71, 255, 0], + [70, 255, 0], + [69, 255, 0], + [68, 255, 0], + [67, 255, 0], + [66, 255, 0], + [65, 255, 0], + [64, 255, 0], + [63, 255, 0], + [62, 255, 0], + [61, 255, 0], + [60, 255, 0], + [59, 255, 0], + [58, 255, 0], + [57, 255, 0], + [56, 255, 0], + [55, 255, 0], + [54, 255, 0], + [53, 255, 0], + [52, 255, 0], + [51, 255, 0], + [50, 255, 0], + [49, 255, 0], + [48, 255, 0], + [47, 255, 0], + [46, 255, 0], + [45, 255, 0], + [44, 255, 0], + [43, 255, 0], + [42, 255, 0], + [41, 255, 0], + [40, 255, 0], + [39, 255, 0], + [38, 255, 0], + [37, 255, 0], + [36, 255, 0], + [35, 255, 0], + [34, 255, 0], + [33, 255, 0], + [32, 255, 0], + [31, 255, 0], + [30, 255, 0], + [29, 255, 0], + [28, 255, 0], + [27, 255, 0], + [26, 255, 0], + [25, 255, 0], + [24, 255, 0], + [23, 255, 0], + [22, 255, 0], + [21, 255, 0], + [20, 255, 0], + [19, 255, 0], + [18, 255, 0], + [17, 255, 0], + [16, 255, 0], + [15, 255, 0], + [14, 255, 0], + [13, 255, 0], + [12, 255, 0], + [11, 255, 0], + [10, 255, 0], + [9, 255, 0], + [8, 255, 0], + [7, 255, 0], + [6, 255, 0], + [5, 255, 0], + [4, 255, 0], + [3, 255, 0], + [2, 255, 0], + [1, 255, 0], + [0, 255, 0], + [0, 255, 1], + [0, 255, 2], + [0, 255, 3], + [0, 255, 4], + [0, 255, 5], + [0, 255, 6], + [0, 255, 7], + [0, 255, 8], + [0, 255, 9], + [0, 255, 10], + [0, 255, 11], + [0, 255, 12], + [0, 255, 13], + [0, 255, 14], + [0, 255, 15], + [0, 255, 16], + [0, 255, 17], + [0, 255, 18], + [0, 255, 19], + [0, 255, 20], + [0, 255, 21], + [0, 255, 22], + [0, 255, 23], + [0, 255, 24], + [0, 255, 25], + [0, 255, 26], + [0, 255, 27], + [0, 255, 28], + [0, 255, 29], + [0, 255, 30], + [0, 255, 31], + [0, 255, 32], + [0, 255, 33], + [0, 255, 34], + [0, 255, 35], + [0, 255, 36], + [0, 255, 37], + [0, 255, 38], + [0, 255, 39], + [0, 255, 40], + [0, 255, 41], + [0, 255, 42], + [0, 255, 43], + [0, 255, 44], + [0, 255, 45], + [0, 255, 46], + [0, 255, 47], + [0, 255, 48], + [0, 255, 49], + [0, 255, 50], + [0, 255, 51], + [0, 255, 52], + [0, 255, 53], + [0, 255, 54], + [0, 255, 55], + [0, 255, 56], + [0, 255, 57], + [0, 255, 58], + [0, 255, 59], + [0, 255, 60], + [0, 255, 61], + [0, 255, 62], + [0, 255, 63], + [0, 255, 64], + [0, 255, 65], + [0, 255, 66], + [0, 255, 67], + [0, 255, 68], + [0, 255, 69], + [0, 255, 70], + [0, 255, 71], + [0, 255, 72], + [0, 255, 73], + [0, 255, 74], + [0, 255, 75], + [0, 255, 76], + [0, 255, 77], + [0, 255, 78], + [0, 255, 79], + [0, 255, 80], + [0, 255, 81], + [0, 255, 82], + [0, 255, 83], + [0, 255, 84], + [0, 255, 85], + [0, 255, 86], + [0, 255, 87], + [0, 255, 88], + [0, 255, 89], + [0, 255, 90], + [0, 255, 91], + [0, 255, 92], + [0, 255, 93], + [0, 255, 94], + [0, 255, 95], + [0, 255, 96], + [0, 255, 97], + [0, 255, 98], + [0, 255, 99], + [0, 255, 100], + [0, 255, 101], + [0, 255, 102], + [0, 255, 103], + [0, 255, 104], + [0, 255, 105], + [0, 255, 106], + [0, 255, 107], + [0, 255, 108], + [0, 255, 109], + [0, 255, 110], + [0, 255, 111], + [0, 255, 112], + [0, 255, 113], + [0, 255, 114], + [0, 255, 115], + [0, 255, 116], + [0, 255, 117], + [0, 255, 118], + [0, 255, 119], + [0, 255, 120], + [0, 255, 121], + [0, 255, 122], + [0, 255, 123], + [0, 255, 124], + [0, 255, 125], + [0, 255, 126], + [0, 255, 127], + [0, 255, 128], + [0, 255, 129], + [0, 255, 130], + [0, 255, 131], + [0, 255, 132], + [0, 255, 133], + [0, 255, 134], + [0, 255, 135], + [0, 255, 136], + [0, 255, 137], + [0, 255, 138], + [0, 255, 139], + [0, 255, 140], + [0, 255, 141], + [0, 255, 142], + [0, 255, 143], + [0, 255, 144], + [0, 255, 145], + [0, 255, 146], + [0, 255, 147], + [0, 255, 148], + [0, 255, 149], + [0, 255, 150], + [0, 255, 151], + [0, 255, 152], + [0, 255, 153], + [0, 255, 154], + [0, 255, 155], + [0, 255, 156], + [0, 255, 157], + [0, 255, 158], + [0, 255, 159], + [0, 255, 160], + [0, 255, 161], + [0, 255, 162], + [0, 255, 163], + [0, 255, 164], + [0, 255, 165], + [0, 255, 166], + [0, 255, 167], + [0, 255, 168], + [0, 255, 169], + [0, 255, 170], + [0, 255, 171], + [0, 255, 172], + [0, 255, 173], + [0, 255, 174], + [0, 255, 175], + [0, 255, 176], + [0, 255, 177], + [0, 255, 178], + [0, 255, 179], + [0, 255, 180], + [0, 255, 181], + [0, 255, 182], + [0, 255, 183], + [0, 255, 184], + [0, 255, 185], + [0, 255, 186], + [0, 255, 187], + [0, 255, 188], + [0, 255, 189], + [0, 255, 190], + [0, 255, 191], + [0, 255, 192], + [0, 255, 193], + [0, 255, 194], + [0, 255, 195], + [0, 255, 196], + [0, 255, 197], + [0, 255, 198], + [0, 255, 199], + [0, 255, 200], + [0, 255, 201], + [0, 255, 202], + [0, 255, 203], + [0, 255, 204], + [0, 255, 205], + [0, 255, 206], + [0, 255, 207], + [0, 255, 208], + [0, 255, 209], + [0, 255, 210], + [0, 255, 211], + [0, 255, 212], + [0, 255, 213], + [0, 255, 214], + [0, 255, 215], + [0, 255, 216], + [0, 255, 217], + [0, 255, 218], + [0, 255, 219], + [0, 255, 220], + [0, 255, 221], + [0, 255, 222], + [0, 255, 223], + [0, 255, 224], + [0, 255, 225], + [0, 255, 226], + [0, 255, 227], + [0, 255, 228], + [0, 255, 229], + [0, 255, 230], + [0, 255, 231], + [0, 255, 232], + [0, 255, 233], + [0, 255, 234], + [0, 255, 235], + [0, 255, 236], + [0, 255, 237], + [0, 255, 238], + [0, 255, 239], + [0, 255, 240], + [0, 255, 241], + [0, 255, 242], + [0, 255, 243], + [0, 255, 244], + [0, 255, 245], + [0, 255, 246], + [0, 255, 247], + [0, 255, 248], + [0, 255, 249], + [0, 255, 250], + [0, 255, 251], + [0, 255, 252], + [0, 255, 253], + [0, 255, 254], + [0, 255, 255], + [0, 254, 255], + [0, 253, 255], + [0, 252, 255], + [0, 251, 255], + [0, 250, 255], + [0, 249, 255], + [0, 248, 255], + [0, 247, 255], + [0, 246, 255], + [0, 245, 255], + [0, 244, 255], + [0, 243, 255], + [0, 242, 255], + [0, 241, 255], + [0, 240, 255], + [0, 239, 255], + [0, 238, 255], + [0, 237, 255], + [0, 236, 255], + [0, 235, 255], + [0, 234, 255], + [0, 233, 255], + [0, 232, 255], + [0, 231, 255], + [0, 230, 255], + [0, 229, 255], + [0, 228, 255], + [0, 227, 255], + [0, 226, 255], + [0, 225, 255], + [0, 224, 255], + [0, 223, 255], + [0, 222, 255], + [0, 221, 255], + [0, 220, 255], + [0, 219, 255], + [0, 218, 255], + [0, 217, 255], + [0, 216, 255], + [0, 215, 255], + [0, 214, 255], + [0, 213, 255], + [0, 212, 255], + [0, 211, 255], + [0, 210, 255], + [0, 209, 255], + [0, 208, 255], + [0, 207, 255], + [0, 206, 255], + [0, 205, 255], + [0, 204, 255], + [0, 203, 255], + [0, 202, 255], + [0, 201, 255], + [0, 200, 255], + [0, 199, 255], + [0, 198, 255], + [0, 197, 255], + [0, 196, 255], + [0, 195, 255], + [0, 194, 255], + [0, 193, 255], + [0, 192, 255], + [0, 191, 255], + [0, 190, 255], + [0, 189, 255], + [0, 188, 255], + [0, 187, 255], + [0, 186, 255], + [0, 185, 255], + [0, 184, 255], + [0, 183, 255], + [0, 182, 255], + [0, 181, 255], + [0, 180, 255], + [0, 179, 255], + [0, 178, 255], + [0, 177, 255], + [0, 176, 255], + [0, 175, 255], + [0, 174, 255], + [0, 173, 255], + [0, 172, 255], + [0, 171, 255], + [0, 170, 255], + [0, 169, 255], + [0, 168, 255], + [0, 167, 255], + [0, 166, 255], + [0, 165, 255], + [0, 164, 255], + [0, 163, 255], + [0, 162, 255], + [0, 161, 255], + [0, 160, 255], + [0, 159, 255], + [0, 158, 255], + [0, 157, 255], + [0, 156, 255], + [0, 155, 255], + [0, 154, 255], + [0, 153, 255], + [0, 152, 255], + [0, 151, 255], + [0, 150, 255], + [0, 149, 255], + [0, 148, 255], + [0, 147, 255], + [0, 146, 255], + [0, 145, 255], + [0, 144, 255], + [0, 143, 255], + [0, 142, 255], + [0, 141, 255], + [0, 140, 255], + [0, 139, 255], + [0, 138, 255], + [0, 137, 255], + [0, 136, 255], + [0, 135, 255], + [0, 134, 255], + [0, 133, 255], + [0, 132, 255], + [0, 131, 255], + [0, 130, 255], + [0, 129, 255], + [0, 128, 255], + [0, 127, 255], + [0, 126, 255], + [0, 125, 255], + [0, 124, 255], + [0, 123, 255], + [0, 122, 255], + [0, 121, 255], + [0, 120, 255], + [0, 119, 255], + [0, 118, 255], + [0, 117, 255], + [0, 116, 255], + [0, 115, 255], + [0, 114, 255], + [0, 113, 255], + [0, 112, 255], + [0, 111, 255], + [0, 110, 255], + [0, 109, 255], + [0, 108, 255], + [0, 107, 255], + [0, 106, 255], + [0, 105, 255], + [0, 104, 255], + [0, 103, 255], + [0, 102, 255], + [0, 101, 255], + [0, 100, 255], + [0, 99, 255], + [0, 98, 255], + [0, 97, 255], + [0, 96, 255], + [0, 95, 255], + [0, 94, 255], + [0, 93, 255], + [0, 92, 255], + [0, 91, 255], + [0, 90, 255], + [0, 89, 255], + [0, 88, 255], + [0, 87, 255], + [0, 86, 255], + [0, 85, 255], + [0, 84, 255], + [0, 83, 255], + [0, 82, 255], + [0, 81, 255], + [0, 80, 255], + [0, 79, 255], + [0, 78, 255], + [0, 77, 255], + [0, 76, 255], + [0, 75, 255], + [0, 74, 255], + [0, 73, 255], + [0, 72, 255], + [0, 71, 255], + [0, 70, 255], + [0, 69, 255], + [0, 68, 255], + [0, 67, 255], + [0, 66, 255], + [0, 65, 255], + [0, 64, 255], + [0, 63, 255], + [0, 62, 255], + [0, 61, 255], + [0, 60, 255], + [0, 59, 255], + [0, 58, 255], + [0, 57, 255], + [0, 56, 255], + [0, 55, 255], + [0, 54, 255], + [0, 53, 255], + [0, 52, 255], + [0, 51, 255], + [0, 50, 255], + [0, 49, 255], + [0, 48, 255], + [0, 47, 255], + [0, 46, 255], + [0, 45, 255], + [0, 44, 255], + [0, 43, 255], + [0, 42, 255], + [0, 41, 255], + [0, 40, 255], + [0, 39, 255], + [0, 38, 255], + [0, 37, 255], + [0, 36, 255], + [0, 35, 255], + [0, 34, 255], + [0, 33, 255], + [0, 32, 255], + [0, 31, 255], + [0, 30, 255], + [0, 29, 255], + [0, 28, 255], + [0, 27, 255], + [0, 26, 255], + [0, 25, 255], + [0, 24, 255], + [0, 23, 255], + [0, 22, 255], + [0, 21, 255], + [0, 20, 255], + [0, 19, 255], + [0, 18, 255], + [0, 17, 255], + [0, 16, 255], + [0, 15, 255], + [0, 14, 255], + [0, 13, 255], + [0, 12, 255], + [0, 11, 255], + [0, 10, 255], + [0, 9, 255], + [0, 8, 255], + [0, 7, 255], + [0, 6, 255], + [0, 5, 255], + [0, 4, 255], + [0, 3, 255], + [0, 2, 255], + [0, 1, 255], + [0, 0, 255], + [1, 0, 255], + [2, 0, 255], + [3, 0, 255], + [4, 0, 255], + [5, 0, 255], + [6, 0, 255], + [7, 0, 255], + [8, 0, 255], + [9, 0, 255], + [10, 0, 255], + [11, 0, 255], + [12, 0, 255], + [13, 0, 255], + [14, 0, 255], + [15, 0, 255], + [16, 0, 255], + [17, 0, 255], + [18, 0, 255], + [19, 0, 255], + [20, 0, 255], + [21, 0, 255], + [22, 0, 255], + [23, 0, 255], + [24, 0, 255], + [25, 0, 255], + [26, 0, 255], + [27, 0, 255], + [28, 0, 255], + [29, 0, 255], + [30, 0, 255], + [31, 0, 255], + [32, 0, 255], + [33, 0, 255], + [34, 0, 255], + [35, 0, 255], + [36, 0, 255], + [37, 0, 255], + [38, 0, 255], + [39, 0, 255], + [40, 0, 255], + [41, 0, 255], + [42, 0, 255], + [43, 0, 255], + [44, 0, 255], + [45, 0, 255], + [46, 0, 255], + [47, 0, 255], + [48, 0, 255], + [49, 0, 255], + [50, 0, 255], + [51, 0, 255], + [52, 0, 255], + [53, 0, 255], + [54, 0, 255], + [55, 0, 255], + [56, 0, 255], + [57, 0, 255], + [58, 0, 255], + [59, 0, 255], + [60, 0, 255], + [61, 0, 255], + [62, 0, 255], + [63, 0, 255], + [64, 0, 255], + [65, 0, 255], + [66, 0, 255], + [67, 0, 255], + [68, 0, 255], + [69, 0, 255], + [70, 0, 255], + [71, 0, 255], + [72, 0, 255], + [73, 0, 255], + [74, 0, 255], + [75, 0, 255], + [76, 0, 255], + [77, 0, 255], + [78, 0, 255], + [79, 0, 255], + [80, 0, 255], + [81, 0, 255], + [82, 0, 255], + [83, 0, 255], + [84, 0, 255], + [85, 0, 255], + [86, 0, 255], + [87, 0, 255], + [88, 0, 255], + [89, 0, 255], + [90, 0, 255], + [91, 0, 255], + [92, 0, 255], + [93, 0, 255], + [94, 0, 255], + [95, 0, 255], + [96, 0, 255], + [97, 0, 255], + [98, 0, 255], + [99, 0, 255], + [100, 0, 255], + [101, 0, 255], + [102, 0, 255], + [103, 0, 255], + [104, 0, 255], + [105, 0, 255], + [106, 0, 255], + [107, 0, 255], + [108, 0, 255], + [109, 0, 255], + [110, 0, 255], + [111, 0, 255], + [112, 0, 255], + [113, 0, 255], + [114, 0, 255], + [115, 0, 255], + [116, 0, 255], + [117, 0, 255], + [118, 0, 255], + [119, 0, 255], + [120, 0, 255], + [121, 0, 255], + [122, 0, 255], + [123, 0, 255], + [124, 0, 255], + [125, 0, 255], + [126, 0, 255], + [127, 0, 255], + [128, 0, 255], + [129, 0, 255], + [130, 0, 255], + [131, 0, 255], + [132, 0, 255], + [133, 0, 255], + [134, 0, 255], + [135, 0, 255], + [136, 0, 255], + [137, 0, 255], + [138, 0, 255], + [139, 0, 255], + [140, 0, 255], + [141, 0, 255], + [142, 0, 255], + [143, 0, 255], + [144, 0, 255], + [145, 0, 255], + [146, 0, 255], + [147, 0, 255], + [148, 0, 255], + [149, 0, 255], + [150, 0, 255], + [151, 0, 255], + [152, 0, 255], + [153, 0, 255], + [154, 0, 255], + [155, 0, 255], + [156, 0, 255], + [157, 0, 255], + [158, 0, 255], + [159, 0, 255], + [160, 0, 255], + [161, 0, 255], + [162, 0, 255], + [163, 0, 255], + [164, 0, 255], + [165, 0, 255], + [166, 0, 255], + [167, 0, 255], + [168, 0, 255], + [169, 0, 255], + [170, 0, 255], + [171, 0, 255], + [172, 0, 255], + [173, 0, 255], + [174, 0, 255], + [175, 0, 255], + [176, 0, 255], + [177, 0, 255], + [178, 0, 255], + [179, 0, 255], + [180, 0, 255], + [181, 0, 255], + [182, 0, 255], + [183, 0, 255], + [184, 0, 255], + [185, 0, 255], + [186, 0, 255], + [187, 0, 255], + [188, 0, 255], + [189, 0, 255], + [190, 0, 255], + [191, 0, 255], + [192, 0, 255], + [193, 0, 255], + [194, 0, 255], + [195, 0, 255], + [196, 0, 255], + [197, 0, 255], + [198, 0, 255], + [199, 0, 255], + [200, 0, 255], + [201, 0, 255], + [202, 0, 255], + [203, 0, 255], + [204, 0, 255], + [205, 0, 255], + [206, 0, 255], + [207, 0, 255], + [208, 0, 255], + [209, 0, 255], + [210, 0, 255], + [211, 0, 255], + [212, 0, 255], + [213, 0, 255], + [214, 0, 255], + [215, 0, 255], + [216, 0, 255], + [217, 0, 255], + [218, 0, 255], + [219, 0, 255], + [220, 0, 255], + [221, 0, 255], + [222, 0, 255], + [223, 0, 255], + [224, 0, 255], + [225, 0, 255], + [226, 0, 255], + [227, 0, 255], + [228, 0, 255], + [229, 0, 255], + [230, 0, 255], + [231, 0, 255], + [232, 0, 255], + [233, 0, 255], + [234, 0, 255], + [235, 0, 255], + [236, 0, 255], + [237, 0, 255], + [238, 0, 255], + [239, 0, 255], + [240, 0, 255], + [241, 0, 255], + [242, 0, 255], + [243, 0, 255], + [244, 0, 255], + [245, 0, 255], + [246, 0, 255], + [247, 0, 255], + [248, 0, 255], + [249, 0, 255], + [250, 0, 255], + [251, 0, 255], + [252, 0, 255], + [253, 0, 255], + [254, 0, 255], + [255, 0, 255], + [255, 0, 254], + [255, 0, 253], + [255, 0, 252], + [255, 0, 251], + [255, 0, 250], + [255, 0, 249], + [255, 0, 248], + [255, 0, 247], + [255, 0, 246], + [255, 0, 245], + [255, 0, 244], + [255, 0, 243], + [255, 0, 242], + [255, 0, 241], + [255, 0, 240], + [255, 0, 239], + [255, 0, 238], + [255, 0, 237], + [255, 0, 236], + [255, 0, 235], + [255, 0, 234], + [255, 0, 233], + [255, 0, 232], + [255, 0, 231], + [255, 0, 230], + [255, 0, 229], + [255, 0, 228], + [255, 0, 227], + [255, 0, 226], + [255, 0, 225], + [255, 0, 224], + [255, 0, 223], + [255, 0, 222], + [255, 0, 221], + [255, 0, 220], + [255, 0, 219], + [255, 0, 218], + [255, 0, 217], + [255, 0, 216], + [255, 0, 215], + [255, 0, 214], + [255, 0, 213], + [255, 0, 212], + [255, 0, 211], + [255, 0, 210], + [255, 0, 209], + [255, 0, 208], + [255, 0, 207], + [255, 0, 206], + [255, 0, 205], + [255, 0, 204], + [255, 0, 203], + [255, 0, 202], + [255, 0, 201], + [255, 0, 200], + [255, 0, 199], + [255, 0, 198], + [255, 0, 197], + [255, 0, 196], + [255, 0, 195], + [255, 0, 194], + [255, 0, 193], + [255, 0, 192], + [255, 0, 191], + [255, 0, 190], + [255, 0, 189], + [255, 0, 188], + [255, 0, 187], + [255, 0, 186], + [255, 0, 185], + [255, 0, 184], + [255, 0, 183], + [255, 0, 182], + [255, 0, 181], + [255, 0, 180], + [255, 0, 179], + [255, 0, 178], + [255, 0, 177], + [255, 0, 176], + [255, 0, 175], + [255, 0, 174], + [255, 0, 173], + [255, 0, 172], + [255, 0, 171], + [255, 0, 170], + [255, 0, 169], + [255, 0, 168], + [255, 0, 167], + [255, 0, 166], + [255, 0, 165], + [255, 0, 164], + [255, 0, 163], + [255, 0, 162], + [255, 0, 161], + [255, 0, 160], + [255, 0, 159], + [255, 0, 158], + [255, 0, 157], + [255, 0, 156], + [255, 0, 155], + [255, 0, 154], + [255, 0, 153], + [255, 0, 152], + [255, 0, 151], + [255, 0, 150], + [255, 0, 149], + [255, 0, 148], + [255, 0, 147], + [255, 0, 146], + [255, 0, 145], + [255, 0, 144], + [255, 0, 143], + [255, 0, 142], + [255, 0, 141], + [255, 0, 140], + [255, 0, 139], + [255, 0, 138], + [255, 0, 137], + [255, 0, 136], + [255, 0, 135], + [255, 0, 134], + [255, 0, 133], + [255, 0, 132], + [255, 0, 131], + [255, 0, 130], + [255, 0, 129], + [255, 0, 128], + [255, 0, 127], + [255, 0, 126], + [255, 0, 125], + [255, 0, 124], + [255, 0, 123], + [255, 0, 122], + [255, 0, 121], + [255, 0, 120], + [255, 0, 119], + [255, 0, 118], + [255, 0, 117], + [255, 0, 116], + [255, 0, 115], + [255, 0, 114], + [255, 0, 113], + [255, 0, 112], + [255, 0, 111], + [255, 0, 110], + [255, 0, 109], + [255, 0, 108], + [255, 0, 107], + [255, 0, 106], + [255, 0, 105], + [255, 0, 104], + [255, 0, 103], + [255, 0, 102], + [255, 0, 101], + [255, 0, 100], + [255, 0, 99], + [255, 0, 98], + [255, 0, 97], + [255, 0, 96], + [255, 0, 95], + [255, 0, 94], + [255, 0, 93], + [255, 0, 92], + [255, 0, 91], + [255, 0, 90], + [255, 0, 89], + [255, 0, 88], + [255, 0, 87], + [255, 0, 86], + [255, 0, 85], + [255, 0, 84], + [255, 0, 83], + [255, 0, 82], + [255, 0, 81], + [255, 0, 80], + [255, 0, 79], + [255, 0, 78], + [255, 0, 77], + [255, 0, 76], + [255, 0, 75], + [255, 0, 74], + [255, 0, 73], + [255, 0, 72], + [255, 0, 71], + [255, 0, 70], + [255, 0, 69], + [255, 0, 68], + [255, 0, 67], + [255, 0, 66], + [255, 0, 65], + [255, 0, 64], + [255, 0, 63], + [255, 0, 62], + [255, 0, 61], + [255, 0, 60], + [255, 0, 59], + [255, 0, 58], + [255, 0, 57], + [255, 0, 56], + [255, 0, 55], + [255, 0, 54], + [255, 0, 53], + [255, 0, 52], + [255, 0, 51], + [255, 0, 50], + [255, 0, 49], + [255, 0, 48], + [255, 0, 47], + [255, 0, 46], + [255, 0, 45], + [255, 0, 44], + [255, 0, 43], + [255, 0, 42], + [255, 0, 41], + [255, 0, 40], + [255, 0, 39], + [255, 0, 38], + [255, 0, 37], + [255, 0, 36], + [255, 0, 35], + [255, 0, 34], + [255, 0, 33], + [255, 0, 32], + [255, 0, 31], + [255, 0, 30], + [255, 0, 29], + [255, 0, 28], + [255, 0, 27], + [255, 0, 26], + [255, 0, 25], + [255, 0, 24], + [255, 0, 23], + [255, 0, 22], + [255, 0, 21], + [255, 0, 20], + [255, 0, 19], + [255, 0, 18], + [255, 0, 17], + [255, 0, 16], + [255, 0, 15], + [255, 0, 14], + [255, 0, 13], + [255, 0, 12], + [255, 0, 11], + [255, 0, 10], + [255, 0, 9], + [255, 0, 8], + [255, 0, 7], + [255, 0, 6], + [255, 0, 5], + [255, 0, 4], + [255, 0, 3], + [255, 0, 2], + [255, 0, 1], + [255, 0, 0], +]; diff --git a/color_component.ts b/color_component.ts new file mode 100644 index 0000000..31a2b76 --- /dev/null +++ b/color_component.ts @@ -0,0 +1,18 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +/** + * [ColorComponent] can be red, green or blue, being the lightness + * of that color. + * + * [ColorComponent]: https://en.wikipedia.org/wiki/RGB_color_model + */ +export class ColorComponent { + public readonly lightness: number = 0; + + /** + * @param lightness - A numerical range from `0` to `255`. + */ + public constructor(lightness: number) { + this.lightness = Math.min(Math.max(lightness, 0), 255); + } +} diff --git a/color_effects/discolor.ts b/color_effects/discolor.ts new file mode 100644 index 0000000..42bd136 --- /dev/null +++ b/color_effects/discolor.ts @@ -0,0 +1,24 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { Color } from "../color.ts"; + +/** + * ### Example + * + * ```ts + * const red = new Color(false, 255, 0, 0); + * const white = new Color(false, 255, 255, 255); + * + * const grey = discolor(red); + * console.log(grey.components); // [85, 85, 85] + * + * const _white = discolor(white); + * console.log(_white.components); // [255, 255, 255] + * ``` + */ +export function discolor(color: Color): Color { + const grey: number = (color.red + color.green + color.blue) / + color.components.length; + + return new Color(false, grey, grey, grey); +} diff --git a/color_effects/discolor_test.ts b/color_effects/discolor_test.ts new file mode 100644 index 0000000..40cc3d8 --- /dev/null +++ b/color_effects/discolor_test.ts @@ -0,0 +1,21 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { assertEquals } from "../dev_deps.ts"; +import { Color } from "../color.ts"; +import { discolor } from "./discolor.ts"; +import { Rgb } from "../color/mod.ts"; + +Deno.test("discolor function correct", () => { + let red: Color = new Color(false, 255, 0, 0); + let green: Color = new Color(false, 0, 255, 0); + let blue: Color = new Color(false, 0, 0, 255); + const grey: Rgb = [85, 85, 85]; + + red = discolor(red); + green = discolor(green); + blue = discolor(blue); + + assertEquals(red.components, grey, `"red.components"`); + assertEquals(green.components, grey, `"green.components"`); + assertEquals(blue.components, grey, `"blue.components"`); +}); diff --git a/color_effects/invert_color.ts b/color_effects/invert_color.ts new file mode 100644 index 0000000..bb9bf47 --- /dev/null +++ b/color_effects/invert_color.ts @@ -0,0 +1,22 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { Color } from "../color.ts"; +import { Rgb } from "../color/mod.ts"; + +/** + * ### Example + * + * ```ts + * const black = new Color(false, 0, 0, 0); + * + * const white = invertColor(black); + * console.log(white.components); // [255, 255, 255] + * ``` + */ +export function invertColor(color: Color): Color { + const newComponents: Rgb = color.components.map((component: number) => + 255 - component + ) as Rgb; + + return new Color(false, ...newComponents); +} diff --git a/color_effects/invert_color_test.ts b/color_effects/invert_color_test.ts new file mode 100644 index 0000000..0dc2a69 --- /dev/null +++ b/color_effects/invert_color_test.ts @@ -0,0 +1,19 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { assertEquals } from "../dev_deps.ts"; +import { Color } from "../color.ts"; +import { invertColor } from "./invert_color.ts"; + +Deno.test("invert function correct", () => { + let red: Color = new Color(false, 255, 0, 0); + let black: Color = new Color(false, 0, 0, 0); + let white: Color = new Color(false, 255, 255, 255); + + red = invertColor(red); + black = invertColor(black); + white = invertColor(white); + + assertEquals(red.components, [0, 255, 255], `"red.components"`); + assertEquals(black.components, [255, 255, 255], `"black.components"`); + assertEquals(white.components, [0, 0, 0], `"white.components"`); +}); diff --git a/color_effects/mix_colors.ts b/color_effects/mix_colors.ts new file mode 100644 index 0000000..6b92019 --- /dev/null +++ b/color_effects/mix_colors.ts @@ -0,0 +1,35 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { Color } from "../color.ts"; +import { Rgb } from "../color/mod.ts"; +import { percent } from "../util.ts"; + +/** + * ### Example + * + * ```ts + * const black = new Color(false, 0, 0, 0); + * const white = new Color(false, 255, 255, 255); + * + * const grey = mixColors(black, white, 50); + * console.log(grey.components); // [127.5, 127.5, 127.5] + * + * const _black = mixColors(black, white, 0); + * console.log(_black.components); // [0, 0, 0] + * + * const _white = mixColors(black, white, 100); + * console.log(_white.components); // [255, 255, 255] + * ``` + */ +export function mixColors( + first: Color, + second: Color, + percentage: number, +): Color { + percentage = percent(percentage) / 100; + const newComponents: Rgb = first.components.map((_, i: number) => + first.components[i] * (1 - percentage) + second.components[i] * percentage + ) as Rgb; + + return new Color(false, ...newComponents); +} diff --git a/color_effects/mix_colors_test.ts b/color_effects/mix_colors_test.ts new file mode 100644 index 0000000..2f10210 --- /dev/null +++ b/color_effects/mix_colors_test.ts @@ -0,0 +1,42 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { assertEquals } from "../dev_deps.ts"; +import { truncComponents } from "../advanced_color_test.ts"; +import { Color } from "../color.ts"; +import { mixColors } from "./mix_colors.ts"; + +Deno.test("mix function correct", async (t) => { + const purple: Color = mixColors( + new Color(false, 255, 0, 0), + new Color(false, 0, 0, 255), + 50, + ); + + assertEquals(truncComponents(purple), [127, 0, 127], `"purple"`); + + await t.step("percentage correct", () => { + const blue: Color = mixColors( + new Color(false, 255, 0, 0), + new Color(false, 0, 0, 255), + 100, + ); + + assertEquals(truncComponents(blue), [0, 0, 255], `"blue"`); + + const red: Color = mixColors( + new Color(false, 255, 0, 0), + new Color(false, 0, 0, 255), + 0, + ); + + assertEquals(truncComponents(red), [255, 0, 0], `"red"`); + + const black: Color = mixColors( + new Color(false, 0, 0, 0), + new Color(false, 0, 0, 0), + 50, + ); + + assertEquals(truncComponents(black), [0, 0, 0], `"black"`); + }); +}); diff --git a/color_effects/mod.ts b/color_effects/mod.ts new file mode 100644 index 0000000..47499c6 --- /dev/null +++ b/color_effects/mod.ts @@ -0,0 +1,7 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +export { discolor } from "./discolor.ts"; +export { invertColor } from "./invert_color.ts"; +export { mixColors } from "./mix_colors.ts"; +export { subtractColors } from "./subtract_colors.ts"; +export { summarizeColors } from "./summarize_colors.ts"; diff --git a/color_effects/subtract_colors.ts b/color_effects/subtract_colors.ts new file mode 100644 index 0000000..11c91be --- /dev/null +++ b/color_effects/subtract_colors.ts @@ -0,0 +1,23 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { Color } from "../color.ts"; +import { Rgb } from "../color/mod.ts"; + +/** + * ### Example + * + * ```ts + * const purple = new Color(false, 128, 0, 128); + * const blue = new Color(false, 0, 0, 128); + * + * const red = subtractColors(purple, blue); + * console.log(red.components); // [128, 0, 0] + * ``` + */ +export function subtractColors(first: Color, second: Color): Color { + const newComponents: Rgb = first.components.map((_, i: number) => + first.components[i] - second.components[i] + ) as Rgb; + + return new Color(false, ...newComponents); +} diff --git a/color_effects/subtract_colors_test.ts b/color_effects/subtract_colors_test.ts new file mode 100644 index 0000000..88234dd --- /dev/null +++ b/color_effects/subtract_colors_test.ts @@ -0,0 +1,13 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { assertEquals } from "../dev_deps.ts"; +import { Color } from "../color.ts"; +import { subtractColors } from "./subtract_colors.ts"; + +Deno.test("subtract function correct", () => { + const purpleColor: Color = new Color(false, 255, 0, 255); + const redColor: Color = new Color(false, 255, 0, 0); + const blueColor: Color = subtractColors(purpleColor, redColor); + + assertEquals(blueColor.components, [0, 0, 255], `"blueColor.components"`); +}); diff --git a/color_effects/summarize_colors.ts b/color_effects/summarize_colors.ts new file mode 100644 index 0000000..2013a68 --- /dev/null +++ b/color_effects/summarize_colors.ts @@ -0,0 +1,23 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { Color } from "../color.ts"; +import { Rgb } from "../color/mod.ts"; + +/** + * ### Example + * + * ```ts + * const red = new Color(false, 128, 0, 0); + * const blue = new Color(false, 0, 0, 128); + * + * const purple = summarizeColors(red, blue); + * console.log(purple.components); // [128, 0, 128] + * ``` + */ +export function summarizeColors(first: Color, second: Color): Color { + const newComponents: Rgb = first.components.map((_, i: number) => + first.components[i] + second.components[i] + ) as Rgb; + + return new Color(false, ...newComponents); +} diff --git a/color_effects/summarize_colors_test.ts b/color_effects/summarize_colors_test.ts new file mode 100644 index 0000000..586c227 --- /dev/null +++ b/color_effects/summarize_colors_test.ts @@ -0,0 +1,17 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { assertEquals } from "../dev_deps.ts"; +import { Color } from "../color.ts"; +import { summarizeColors } from "./summarize_colors.ts"; + +Deno.test("sum function correct", () => { + const redColor: Color = new Color(false, 255, 0, 0); + const blueColor: Color = new Color(false, 0, 0, 255); + const purpleColor: Color = summarizeColors(redColor, blueColor); + + assertEquals( + purpleColor.components, + [255, 0, 255], + `"purpleColor.components"`, + ); +}); diff --git a/color_info.ts b/color_info.ts new file mode 100644 index 0000000..40bc52b --- /dev/null +++ b/color_info.ts @@ -0,0 +1,48 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { colors } from "./deps.ts"; +import { Rgb } from "./color/mod.ts"; + +/** + * `ColorInfo` retrieves similar color information + * from HTML colors and the [Colors] dependencies. + * + * [Colors]: https://github.com/chalkpot/colors + * + * ### Example + * + * ```ts + * const unknownColor = new ColorInfo(255, 0, 0); + * console.log(unknownColor.name); // "red" + * console.log(unknownColor.localize("ru-RU")); // "красный" + * ``` + */ +export class ColorInfo { + public readonly name: string | undefined; + public readonly localize: (localeCode: string) => string | undefined; + + public constructor(...components: Rgb) { + let minDiff = Infinity; + let colorName = ""; + + for (const color in colors) { + const rgb: number[] = colors[color as keyof typeof colors].rgb; + const diff: number = this.colorDiff(components, rgb); + if (diff > minDiff) continue; + + minDiff = diff; + colorName = color; + } + + const color = colors[colorName as keyof typeof colors]; + this.name = color.name; + this.localize = color.localize; + } + + private colorDiff(firstRgb: number[], secondRgb: number[]) { + const rDiff: number = secondRgb[0] - firstRgb[0]; + const gDiff: number = secondRgb[1] - firstRgb[1]; + const bDiff: number = secondRgb[2] - firstRgb[2]; + return Math.sqrt(rDiff * rDiff + gDiff * gDiff + bDiff * bDiff); + } +} diff --git a/color_info_test.ts b/color_info_test.ts new file mode 100644 index 0000000..1c4893e --- /dev/null +++ b/color_info_test.ts @@ -0,0 +1,12 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { assertEquals } from "./dev_deps.ts"; +import { ColorInfo } from "./color_info.ts"; + +Deno.test("getting JSON color object from module correct", () => { + const black: ColorInfo = new ColorInfo(0, 0, 0); + assertEquals(black.name, "black", `"black.name"`); + + const white: ColorInfo = new ColorInfo(255, 255, 255); + assertEquals(white.name, "white", `"white.name"`); +}); diff --git a/color_test.ts b/color_test.ts new file mode 100644 index 0000000..d9e65b0 --- /dev/null +++ b/color_test.ts @@ -0,0 +1,31 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { assertEquals } from "./dev_deps.ts"; +import { Color } from "./color.ts"; + +Deno.test("class contains correct fields", async (t) => { + const red = 10 as const; + const green = 20 as const; + const blue = 30 as const; + + const color: Color = new Color(false, red, green, blue); + + assertEquals(color.red, red, `"color.red"`); + assertEquals(color.green, green, `"color.green"`); + assertEquals(color.blue, blue, `"color.blue"`); + + await t.step("dependent field contains correct values", () => { + assertEquals(color.components, [red, green, blue], `"color.components"`); + }); +}); + +Deno.test("creating components using percentages correct", () => { + const black: Color = new Color(true, 0, 0, 0); + assertEquals(black.components, [0, 0, 0], `"black"`); + + const grey: Color = new Color(true, 50, 50, 50); + assertEquals(grey.components, [127.5, 127.5, 127.5], `"grey"`); + + const white: Color = new Color(true, 100, 100, 100); + assertEquals(white.components, [255, 255, 255], `"white"`); +}); diff --git a/deno.jsonc b/deno.jsonc new file mode 100644 index 0000000..0109217 --- /dev/null +++ b/deno.jsonc @@ -0,0 +1,17 @@ +{ + "tasks": { + // npm publish --access public + "build": "deno run --allow-read --allow-write --allow-net --allow-env --allow-run _build_npm.ts" + }, + "fmt": { + "include": [ + "./" + ] + }, + "exclude": [ + "./.github", + "./.idea", + "./.git", + "./.npm" + ] +} diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..401cbed --- /dev/null +++ b/deno.lock @@ -0,0 +1,111 @@ +{ + "version": "3", + "remote": { + "https://deno.land/std@0.140.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74", + "https://deno.land/std@0.140.0/_util/os.ts": "3b4c6e27febd119d36a416d7a97bd3b0251b77c88942c8f16ee5953ea13e2e49", + "https://deno.land/std@0.140.0/bytes/bytes_list.ts": "67eb118e0b7891d2f389dad4add35856f4ad5faab46318ff99653456c23b025d", + "https://deno.land/std@0.140.0/bytes/equals.ts": "fc16dff2090cced02497f16483de123dfa91e591029f985029193dfaa9d894c9", + "https://deno.land/std@0.140.0/bytes/mod.ts": "763f97d33051cc3f28af1a688dfe2830841192a9fea0cbaa55f927b49d49d0bf", + "https://deno.land/std@0.140.0/fmt/colors.ts": "30455035d6d728394781c10755351742dd731e3db6771b1843f9b9e490104d37", + "https://deno.land/std@0.140.0/fs/_util.ts": "0fb24eb4bfebc2c194fb1afdb42b9c3dda12e368f43e8f2321f84fc77d42cb0f", + "https://deno.land/std@0.140.0/fs/ensure_dir.ts": "9dc109c27df4098b9fc12d949612ae5c9c7169507660dcf9ad90631833209d9d", + "https://deno.land/std@0.140.0/io/buffer.ts": "bd0c4bf53db4b4be916ca5963e454bddfd3fcd45039041ea161dbf826817822b", + "https://deno.land/std@0.140.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3", + "https://deno.land/std@0.140.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09", + "https://deno.land/std@0.140.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b", + "https://deno.land/std@0.140.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633", + "https://deno.land/std@0.140.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee", + "https://deno.land/std@0.140.0/path/mod.ts": "d3e68d0abb393fb0bf94a6d07c46ec31dc755b544b13144dee931d8d5f06a52d", + "https://deno.land/std@0.140.0/path/posix.ts": "293cdaec3ecccec0a9cc2b534302dfe308adb6f10861fa183275d6695faace44", + "https://deno.land/std@0.140.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9", + "https://deno.land/std@0.140.0/path/win32.ts": "31811536855e19ba37a999cd8d1b62078235548d67902ece4aa6b814596dd757", + "https://deno.land/std@0.140.0/streams/conversion.ts": "712585bfa0172a97fb68dd46e784ae8ad59d11b88079d6a4ab098ff42e697d21", + "https://deno.land/std@0.181.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", + "https://deno.land/std@0.181.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", + "https://deno.land/std@0.181.0/fs/_util.ts": "65381f341af1ff7f40198cee15c20f59951ac26e51ddc651c5293e24f9ce6f32", + "https://deno.land/std@0.181.0/fs/ensure_dir.ts": "dc64c4c75c64721d4e3fb681f1382f803ff3d2868f08563ff923fdd20d071c40", + "https://deno.land/std@0.181.0/fs/expand_glob.ts": "e4f56259a0a70fe23f05215b00de3ac5e6ba46646ab2a06ebbe9b010f81c972a", + "https://deno.land/std@0.181.0/fs/walk.ts": "ea95ffa6500c1eda6b365be488c056edc7c883a1db41ef46ec3bf057b1c0fe32", + "https://deno.land/std@0.181.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0", + "https://deno.land/std@0.181.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b", + "https://deno.land/std@0.181.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0", + "https://deno.land/std@0.181.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000", + "https://deno.land/std@0.181.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1", + "https://deno.land/std@0.181.0/path/mod.ts": "bf718f19a4fdd545aee1b06409ca0805bd1b68ecf876605ce632e932fe54510c", + "https://deno.land/std@0.181.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d", + "https://deno.land/std@0.181.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1", + "https://deno.land/std@0.181.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba", + "https://deno.land/std@0.182.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", + "https://deno.land/std@0.182.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", + "https://deno.land/std@0.182.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", + "https://deno.land/std@0.182.0/fs/_util.ts": "65381f341af1ff7f40198cee15c20f59951ac26e51ddc651c5293e24f9ce6f32", + "https://deno.land/std@0.182.0/fs/empty_dir.ts": "c3d2da4c7352fab1cf144a1ecfef58090769e8af633678e0f3fabaef98594688", + "https://deno.land/std@0.182.0/fs/expand_glob.ts": "e4f56259a0a70fe23f05215b00de3ac5e6ba46646ab2a06ebbe9b010f81c972a", + "https://deno.land/std@0.182.0/fs/walk.ts": "920be35a7376db6c0b5b1caf1486fb962925e38c9825f90367f8f26b5e5d0897", + "https://deno.land/std@0.182.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0", + "https://deno.land/std@0.182.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b", + "https://deno.land/std@0.182.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0", + "https://deno.land/std@0.182.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000", + "https://deno.land/std@0.182.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1", + "https://deno.land/std@0.182.0/path/mod.ts": "bf718f19a4fdd545aee1b06409ca0805bd1b68ecf876605ce632e932fe54510c", + "https://deno.land/std@0.182.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d", + "https://deno.land/std@0.182.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1", + "https://deno.land/std@0.182.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba", + "https://deno.land/std@0.204.0/assert/_constants.ts": "8a9da298c26750b28b326b297316cdde860bc237533b07e1337c021379e6b2a9", + "https://deno.land/std@0.204.0/assert/_diff.ts": "58e1461cc61d8eb1eacbf2a010932bf6a05b79344b02ca38095f9b805795dc48", + "https://deno.land/std@0.204.0/assert/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7", + "https://deno.land/std@0.204.0/assert/assert_equals.ts": "d8ec8a22447fbaf2fc9d7c3ed2e66790fdb74beae3e482855d75782218d68227", + "https://deno.land/std@0.204.0/assert/assertion_error.ts": "4d0bde9b374dfbcbe8ac23f54f567b77024fb67dbb1906a852d67fe050d42f56", + "https://deno.land/std@0.204.0/assert/equal.ts": "9f1a46d5993966d2596c44e5858eec821859b45f783a5ee2f7a695dfc12d8ece", + "https://deno.land/std@0.204.0/fmt/colors.ts": "c51c4642678eb690dcf5ffee5918b675bf01a33fba82acf303701ae1a4f8c8d9", + "https://deno.land/x/chalkpot_colors@1.0.0/basic_colors.ts": "f0d4c124c3fff1f8c2f9d8d935493ff620bb21c1857478566a09ba606ffdf0b0", + "https://deno.land/x/chalkpot_colors@1.0.0/colors.ts": "6b42301e547574332db4eb77bb9ab70990348bea9196b2a595a1cd50fad5343f", + "https://deno.land/x/chalkpot_colors@1.0.0/locales/be_BY.ts": "7d93344420094eea8fa5386a8e682183c995dd18c7779d0ba447592ce6abd174", + "https://deno.land/x/chalkpot_colors@1.0.0/locales/en_US.ts": "7ab336fc88ee21cf5c843311e5549917e218a0ece66a3dab5c91a1589fb25a9c", + "https://deno.land/x/chalkpot_colors@1.0.0/locales/locale/localize_color.ts": "19960d6871d426955a4e268fbcd068b8c26b0156bc32d422b028448f9719ad1e", + "https://deno.land/x/chalkpot_colors@1.0.0/locales/locale/mod.ts": "86d808cb2de3cf6050ebd89e49255631eddc770af650ddd4950b2f419ff46b36", + "https://deno.land/x/chalkpot_colors@1.0.0/locales/locale/unformat_locale_code.ts": "24e6ad25f6b2722c96d94a3219ba2f104b8dca236130a758fd092735234be4e8", + "https://deno.land/x/chalkpot_colors@1.0.0/locales/mod.ts": "2339c351eeff7e47af71f0afe74b49740f81b43494afb16d3be8c1aed0ddf6d0", + "https://deno.land/x/chalkpot_colors@1.0.0/locales/ru_RU.ts": "a13f54cb2bbf8f0d21f79de68a2cc1515cb5e0565ea9f410df322b88eef20941", + "https://deno.land/x/chalkpot_colors@1.0.0/locales/uk_UA.ts": "4f6a90dfdb92360a8676ba8259c8e6d551aab17d3640b7817d7422390d848c1e", + "https://deno.land/x/chalkpot_colors@1.0.0/mod.ts": "6e8daa7d2e4bc1bd9c59083e07ee49a20fbb9a5a37dd675f46b3a969099752f7", + "https://deno.land/x/code_block_writer@12.0.0/mod.ts": "2c3448060e47c9d08604c8f40dee34343f553f33edcdfebbf648442be33205e5", + "https://deno.land/x/code_block_writer@12.0.0/utils/string_utils.ts": "60cb4ec8bd335bf241ef785ccec51e809d576ff8e8d29da43d2273b69ce2a6ff", + "https://deno.land/x/deno_cache@0.5.2/auth_tokens.ts": "5d1d56474c54a9d152e44d43ea17c2e6a398dd1e9682c69811a313567c01ee1e", + "https://deno.land/x/deno_cache@0.5.2/cache.ts": "92ce8511e1e5c00fdf53a41619aa77d632ea8e0fc711324322e4d5ebf8133911", + "https://deno.land/x/deno_cache@0.5.2/deno_dir.ts": "1ea355b8ba11c630d076b222b197cfc937dd81e5a4a260938997da99e8ff93a0", + "https://deno.land/x/deno_cache@0.5.2/deps.ts": "26a75905652510b76e54b6d5ef3cf824d1062031e00782efcd768978419224e7", + "https://deno.land/x/deno_cache@0.5.2/dirs.ts": "009c6f54e0b610914d6ce9f72f6f6ccfffd2d47a79a19061e0a9eb4253836069", + "https://deno.land/x/deno_cache@0.5.2/disk_cache.ts": "66a1e604a8d564b6dd0500326cac33d08b561d331036bf7272def80f2f7952aa", + "https://deno.land/x/deno_cache@0.5.2/file_fetcher.ts": "89616c50b6df73fb04e73d0b7cd99e5f2ed7967386913d65b9e8baa4238501f7", + "https://deno.land/x/deno_cache@0.5.2/http_cache.ts": "407135eaf2802809ed373c230d57da7ef8dff923c4abf205410b9b99886491fd", + "https://deno.land/x/deno_cache@0.5.2/lib/deno_cache_dir.generated.js": "18b6526d0c50791a73dd0eb894e99de1ac05ee79dcbd53298ff5b5b6b0757fe6", + "https://deno.land/x/deno_cache@0.5.2/lib/snippets/deno_cache_dir-77bed54ace8005e0/fs.js": "cbe3a976ed63c72c7cb34ef845c27013033a3b11f9d8d3e2c4aa5dda2c0c7af6", + "https://deno.land/x/deno_cache@0.5.2/mod.ts": "0b4d071ad095128bdc2b1bc6e5d2095222dcbae08287261690ee9757e6300db6", + "https://deno.land/x/deno_cache@0.5.2/util.ts": "f3f5a0cfc60051f09162942fb0ee87a0e27b11a12aec4c22076e3006be4cc1e2", + "https://deno.land/x/dir@1.5.1/data_local_dir/mod.ts": "91eb1c4bfadfbeda30171007bac6d85aadacd43224a5ed721bbe56bc64e9eb66", + "https://deno.land/x/dnt@0.38.1/lib/compiler.ts": "209ad2e1b294f93f87ec02ade9a0821f942d2e524104552d0aa8ff87021050a5", + "https://deno.land/x/dnt@0.38.1/lib/compiler_transforms.ts": "f21aba052f5dcf0b0595c734450842855c7f572e96165d3d34f8fed2fc1f7ba1", + "https://deno.land/x/dnt@0.38.1/lib/mod.deps.ts": "30367fc68bcd2acf3b7020cf5cdd26f817f7ac9ac35c4bfb6c4551475f91bc3e", + "https://deno.land/x/dnt@0.38.1/lib/npm_ignore.ts": "57fbb7e7b935417d225eec586c6aa240288905eb095847d3f6a88e290209df4e", + "https://deno.land/x/dnt@0.38.1/lib/package_json.ts": "61f35b06e374ed39ca776d29d67df4be7ee809d0bca29a8239687556c6d027c2", + "https://deno.land/x/dnt@0.38.1/lib/pkg/dnt_wasm.generated.js": "cfb352ae839865f5698c9b35099d4c783510195a1e3c9f9b04d94fac86394ed9", + "https://deno.land/x/dnt@0.38.1/lib/pkg/snippets/dnt-wasm-a15ef721fa5290c5/helpers.js": "45f74f00472b3a399bc16e5dc056966b55dcdd8fa2bd61505c6dfd2f5d33b9f4", + "https://deno.land/x/dnt@0.38.1/lib/shims.ts": "df1bd4d9a196dca4b2d512b1564fff64ac6c945189a273d706391f87f210d7e6", + "https://deno.land/x/dnt@0.38.1/lib/test_runner/get_test_runner_code.ts": "4dc7a73a13b027341c0688df2b29a4ef102f287c126f134c33f69f0339b46968", + "https://deno.land/x/dnt@0.38.1/lib/test_runner/test_runner.ts": "4d0da0500ec427d5f390d9a8d42fb882fbeccc92c92d66b6f2e758606dbd40e6", + "https://deno.land/x/dnt@0.38.1/lib/transform.deps.ts": "e42f2bdef46d098453bdba19261a67cf90b583f5d868f7fe83113c1380d9b85c", + "https://deno.land/x/dnt@0.38.1/lib/types.ts": "b8e228b2fac44c2ae902fbb73b1689f6ab889915bd66486c8a85c0c24255f5fb", + "https://deno.land/x/dnt@0.38.1/lib/utils.ts": "878b7ac7003a10c16e6061aa49dbef9b42bd43174853ebffc9b67ea47eeb11d8", + "https://deno.land/x/dnt@0.38.1/mod.ts": "b13349fe77847cf58e26b40bcd58797a8cec5d71b31a1ca567071329c8489de1", + "https://deno.land/x/dnt@0.38.1/transform.ts": "f68743a14cf9bf53bfc9c81073871d69d447a7f9e3453e0447ca2fb78926bb1d", + "https://deno.land/x/ts_morph@18.0.0/bootstrap/mod.ts": "b53aad517f106c4079971fcd4a81ab79fadc40b50061a3ab2b741a09119d51e9", + "https://deno.land/x/ts_morph@18.0.0/bootstrap/ts_morph_bootstrap.js": "6645ac03c5e6687dfa8c78109dc5df0250b811ecb3aea2d97c504c35e8401c06", + "https://deno.land/x/ts_morph@18.0.0/common/DenoRuntime.ts": "6a7180f0c6e90dcf23ccffc86aa8271c20b1c4f34c570588d08a45880b7e172d", + "https://deno.land/x/ts_morph@18.0.0/common/mod.ts": "01985d2ee7da8d1caee318a9d07664774fbee4e31602bc2bb6bb62c3489555ed", + "https://deno.land/x/ts_morph@18.0.0/common/ts_morph_common.js": "845671ca951073400ce142f8acefa2d39ea9a51e29ca80928642f3f8cf2b7700", + "https://deno.land/x/ts_morph@18.0.0/common/typescript.js": "d5c598b6a2db2202d0428fca5fd79fc9a301a71880831a805d778797d2413c59", + "https://deno.land/x/wasmbuild@0.15.0/cache.ts": "89eea5f3ce6035a1164b3e655c95f21300498920575ade23161421f5b01967f4", + "https://deno.land/x/wasmbuild@0.15.0/loader.ts": "d98d195a715f823151cbc8baa3f32127337628379a02d9eb2a3c5902dbccfc02" + } +} diff --git a/deps.ts b/deps.ts new file mode 100644 index 0000000..b217dd5 --- /dev/null +++ b/deps.ts @@ -0,0 +1,3 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +export { colors } from "https://deno.land/x/chalkpot_colors@1.0.0/mod.ts"; diff --git a/dev_deps.ts b/dev_deps.ts new file mode 100644 index 0000000..cc9ef38 --- /dev/null +++ b/dev_deps.ts @@ -0,0 +1,3 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +export { assertEquals } from "https://deno.land/std@0.204.0/assert/assert_equals.ts"; diff --git a/mod.ts b/mod.ts new file mode 100644 index 0000000..91ddacd --- /dev/null +++ b/mod.ts @@ -0,0 +1,7 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +export { Color } from "./color.ts"; +export { AdvancedColor } from "./advanced_color.ts"; +export { ColorComponent } from "./color_component.ts"; + +export * from "./color_effects/mod.ts"; diff --git a/util.ts b/util.ts new file mode 100644 index 0000000..9c64a09 --- /dev/null +++ b/util.ts @@ -0,0 +1,5 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +export function percent(value: number): number { + return Math.min(Math.max(value, 0), 100); +}